Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
849ba02
ci: add GitHub→GitLab mirror workflows
Mar 8, 2026
ea5e38c
Merge branch 'develop' into main for 0.3.3 release
Keith-CY Mar 9, 2026
c944fd4
chore: bump version to 0.3.3
github-actions[bot] Mar 9, 2026
2d668d8
fix(ci): proper JSON escaping + skip .sig files in GitLab mirror
Mar 10, 2026
1d116a8
feat(site): geo-aware download links (CN→GitLab, others→GitHub)
Mar 8, 2026
9763562
fix(ci): skip .sig/large files in GitLab release mirror
Mar 8, 2026
3a44dfc
fix(ci): remove 50MB limit, use HTTP/1.1 for stable large uploads
Mar 8, 2026
92adcc4
fix: validate download URLs against trusted host allowlist
Mar 8, 2026
f5fadc2
Merge pull request #112 from lay2dev/feat/geo-download
stwith Mar 10, 2026
26a55ae
ci: add auto-deploy workflow for docs/site
Mar 10, 2026
6c4e20b
feat: add recipe authoring workbench (#116)
Keith-CY Mar 12, 2026
29148a9
feat: import external recipe libraries
Keith-CY Mar 12, 2026
7993293
fix: simplify dedicated agent recipe import fixture
Keith-CY Mar 12, 2026
9c072e7
feat: allow deleting workspace recipe drafts
Keith-CY Mar 12, 2026
766e6ba
refactor: restyle workspace recipe draft cards
Keith-CY Mar 12, 2026
526c954
test: add dockerized openclaw recipe e2e
Keith-CY Mar 12, 2026
0374156
ci: scope e2e workflow for recipe branch
Keith-CY Mar 12, 2026
e1f0ded
feat: polish bundled recipe workflows
Keith-CY Mar 12, 2026
c6bf6f0
docs: add recipe authoring guide
Keith-CY Mar 12, 2026
d9f8276
feat: expand recipe runner action surface
Keith-CY Mar 12, 2026
ba8460e
docs: update recipe authoring and runner boundaries
Keith-CY Mar 12, 2026
3550eeb
fix: preserve recipe content newlines
Keith-CY Mar 13, 2026
b240dca
feat: align recipe actions with openclaw cli
Keith-CY Mar 13, 2026
39c1223
docs: align recipe action documentation
Keith-CY Mar 13, 2026
f3b0e90
fix: fallback remote recipe discovery to config
Keith-CY Mar 13, 2026
1f8e27b
docs: add local docker openclaw debug guide
Keith-CY Mar 13, 2026
3c78eb7
fix: support recipe URLs and bundled seed lookup
Keith-CY Mar 13, 2026
ba41bd7
fix: resolve bundled recipe assets from _up_
Keith-CY Mar 13, 2026
70a695f
feat: load recipes from single recipe folders
Keith-CY Mar 13, 2026
57cf7f8
feat(seo): add SEO/GEO optimization
Mar 13, 2026
680f427
fix: update softwareVersion to 0.3.3
Mar 13, 2026
5315c70
feat: unify recipe source import flow
Keith-CY Mar 13, 2026
e2feb58
fix: make recipe folder picker non-blocking
Keith-CY Mar 13, 2026
d852a19
Merge pull request #120 from lay2dev/feat/seo-geo-optimization
stwith Mar 13, 2026
0bdb226
feat: add recipe approval and bundled upgrades
Keith-CY Mar 13, 2026
123d3f3
docs: describe recipe trust and upgrade flow
Keith-CY Mar 13, 2026
28cea2f
fix: scope cook auth blockers to active recipe
Keith-CY Mar 13, 2026
979ecb7
fix: stabilize recipe docker approval and identity sync
Keith-CY Mar 13, 2026
98f7150
refactor: defer agent workspaces to openclaw defaults
Keith-CY Mar 13, 2026
6986bff
Merge remote-tracking branch 'origin/main' into feat/recipe-import-li…
dev01lay2 Mar 16, 2026
f16624a
merge: resolve develop conflicts in commands/mod.rs
dev01lay2 Mar 16, 2026
083920c
merge: sync develop into feat/recipe-import-library
dev01lay2 Mar 16, 2026
9b6706f
feat: progressive guild channel loading with layered cache (#128)
dev01lay2 Mar 16, 2026
48c1d42
style: cargo fmt lib.rs import line wrapping
dev01lay2 Mar 16, 2026
80e12df
fix: remove duplicate tauri command definitions from mod.rs
dev01lay2 Mar 16, 2026
4e611e8
perf: initialize ParamForm dropdowns from persisted cache
dev01lay2 Mar 16, 2026
3e7da10
plan: Discord channels progressive loading on Channels page
dev01lay2 Mar 16, 2026
d1efc92
feat: progressive Discord channel loading UI on Channels page
dev01lay2 Mar 16, 2026
cbc18ed
fix: enable fast path for channels route + fix stale cache guard
dev01lay2 Mar 16, 2026
8cf11db
feat: ship bundled recipe workflows
dev01lay2 Mar 17, 2026
ef94313
fix: write model registrations to correct config path (#148)
stwith Mar 20, 2026
fadb76d
Merge origin/develop into feat/recipe-import-library
Keith-CY Mar 20, 2026
13aad45
Share agents per instance and trim cook planning checks
Keith-CY Mar 20, 2026
4b35e2e
fix: share instance-scoped channel and model caches
Keith-CY Mar 20, 2026
7c4fa49
style: format rust sources for ci
Keith-CY Mar 20, 2026
7a5f06a
feat: add recipe GUI E2E test harness with Docker + Xvfb + Selenium
dev01lay2 Mar 20, 2026
c93dfc6
fix: add always() to artifact upload steps, improve debug output
dev01lay2 Mar 20, 2026
2771e6f
fix: wait for SSH connection to establish before recipe execution
dev01lay2 Mar 20, 2026
677c765
fix: click Check button to initiate SSH connection before entering in…
dev01lay2 Mar 20, 2026
2190b22
fix: increase sshd MaxSessions/MaxStartups, add sftp subsystem, reduc…
dev01lay2 Mar 20, 2026
e7a2a4e
fix: Dockerfile line continuation backslashes for sshd_config
dev01lay2 Mar 20, 2026
f8d93f0
fix: remove duplicate sftp subsystem (already in sshd_config)
dev01lay2 Mar 20, 2026
c0f78df
fix: add SSH keepalive, debug logging, and connection verification
dev01lay2 Mar 20, 2026
bbc95df
fix: inner container exits immediately because openclaw gateway start…
dev01lay2 Mar 20, 2026
a3e7c41
fix: add fake apiKey for auth check, increase review wait timeout to 60s
dev01lay2 Mar 20, 2026
785af48
fix: auth check hangs due to unreachable Anthropic API
dev01lay2 Mar 20, 2026
c106854
fix: add gateway log dump and API status check for debugging auth hang
dev01lay2 Mar 20, 2026
29a587d
fix: gateway never started — use 'openclaw gateway run' for foregroun…
dev01lay2 Mar 20, 2026
9bd5aac
fix: gateway readiness check — use curl without -f flag
dev01lay2 Mar 20, 2026
b49041c
fix: simplify Check button XPath and improve SSH connection detection
dev01lay2 Mar 20, 2026
c93456c
fix: wait for SSH auto-check to complete before proceeding
dev01lay2 Mar 20, 2026
f0a08a9
fix: remove gateway auth token to simplify CLI ↔ gateway communication
dev01lay2 Mar 20, 2026
8d5e5de
fix: restore gateway auth token, use real Anthropic baseUrl for fast 401
dev01lay2 Mar 20, 2026
d34c885
fix: pre-provision auth profiles, model profiles, and apiKey in config
dev01lay2 Mar 20, 2026
f0f761e
fix: add openclaw CLI wrapper to prevent SSH semaphore exhaustion
dev01lay2 Mar 20, 2026
b9645f8
fix: restore anthropic provider with fake apiKey for model access step
dev01lay2 Mar 20, 2026
c582e08
fix: restore anthropic provider config, add debug screenshots, broade…
dev01lay2 Mar 21, 2026
dec8f43
debug: add page text polling during execution to diagnose hang
dev01lay2 Mar 21, 2026
2c6f7e7
fix: increase timeouts - job 90min, execution wait 600s
dev01lay2 Mar 21, 2026
2feb068
debug: disable SFTP subsystem to test if it causes execution hang
dev01lay2 Mar 21, 2026
7b715e3
fix: rewrite Dockerfile - fix line continuation syntax error
dev01lay2 Mar 21, 2026
1224915
fix: add 30s timeout + exec fallback for SFTP write, 15s timeout for …
dev01lay2 Mar 21, 2026
627904b
fix: revert to empty providers to avoid auth check hang
dev01lay2 Mar 21, 2026
d1b8d95
fix: skip Home page agent check — verify via SSH config instead
dev01lay2 Mar 21, 2026
abb6d8a
fix: fill emoji field to prevent identity step being skipped
dev01lay2 Mar 21, 2026
02cce58
fix: make IDENTITY.md check soft — identity step may be skipped
dev01lay2 Mar 21, 2026
62d0384
fix: skip Channel/Agent Persona Pack tests gracefully when Discord un…
dev01lay2 Mar 21, 2026
195eafe
fix: increase job timeout to 120 min
dev01lay2 Mar 21, 2026
8e3b00c
fix: add 30s timeout to exec fallback + increase execution wait to 900s
dev01lay2 Mar 21, 2026
7ee279b
perf: reduce SFTP timeouts from 30s/15s to 5s for faster fallback
dev01lay2 Mar 21, 2026
128f41a
fix: reset SSH connections between recipes + soft-fail agent persona …
dev01lay2 Mar 21, 2026
f3cfaac
perf: sftp_write respects read backoff — skip SFTP after first timeout
dev01lay2 Mar 21, 2026
5abf9d1
feat: mock Discord guild/channel cache for Channel Persona Pack test
dev01lay2 Mar 21, 2026
fcae371
fix: remove invalid Discord channel config from openclaw.json
dev01lay2 Mar 21, 2026
747d702
perf: short-circuit gateway restart/stop/status in openclaw wrapper
dev01lay2 Mar 21, 2026
80d88fb
perf: eliminate redundant SSH operations in recipe execution
dev01lay2 Mar 21, 2026
07ef2a7
fix: update cached config after __config_write__ in apply loop
dev01lay2 Mar 21, 2026
6066528
fix: re-read config after CLI commands that modify openclaw.json
dev01lay2 Mar 21, 2026
5f4c77b
feat: improve perf report with all 3 recipes and human-readable times
dev01lay2 Mar 21, 2026
2b8d62a
feat: add local mode E2E test (ClawPal + OpenClaw same machine)
dev01lay2 Mar 21, 2026
d8ba2d3
fix: reuse SSH harness image as base for local mode
dev01lay2 Mar 21, 2026
f397945
feat: Discord id cache, one-by-one resolve fallback, and instant tab-…
Keith-CY Mar 21, 2026
b7d3643
fix: register discord module in commands/mod.rs to resolve compilation
Keith-CY Mar 21, 2026
2c28f96
fix: resolve Channels page infinite refresh and data loading failure …
stwith Mar 21, 2026
f870abc
merge: resolve conflicts with origin/feat/recipe-import-library
Keith-CY Mar 21, 2026
a1214ba
fix(test): treat HTTP 429 as success in profile e2e probe
Keith-CY Mar 21, 2026
6ccd782
merge: resolve PR 150 into recipe import library
Keith-CY Mar 21, 2026
aeb2d01
feat: add cook activity audit trail (#151)
Keith-CY Mar 22, 2026
c308de7
test: add comprehensive test coverage for PR #118 recipe platform
Mar 22, 2026
0671f73
test: expand test coverage — execution spec, markdown document, cook …
Mar 22, 2026
dc32f6b
style: fix cargo fmt in cli_runner test assertions
Mar 22, 2026
ba5c07c
style: cargo fmt --all
Mar 22, 2026
9c59796
fix: correct test types and cargo fmt for CI
Mar 22, 2026
29be7b9
test: expand recipe store/workspace tests + fix BackupsPanel TS error
Mar 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/deploy-site.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Deploy Site

on:
push:
branches: [main]
paths:
- 'docs/site/**'
workflow_dispatch:

jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy docs/site --project-name=clawpal
41 changes: 41 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,58 @@ on:
branches:
- main
- develop
- feat/recipe
pull_request:
branches:
- main
- develop
- feat/recipe

concurrency:
group: e2e-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
recipe-docker-e2e:
name: Docker Recipe E2E
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libappindicator3-dev \
librsvg2-dev \
patchelf \
libssl-dev \
libgtk-3-dev \
libsoup-3.0-dev \
libjavascriptcoregtk-4.1-dev

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri

- name: Verify Docker is available
run: docker info

- name: Run recipe docker e2e
env:
CLAWPAL_RUN_DOCKER_RECIPE_E2E: "1"
run: cargo test -p clawpal --test recipe_docker_e2e -- --nocapture --test-threads=1
working-directory: src-tauri

profile-e2e:
name: Provider Auth E2E
runs-on: ubuntu-latest
environment: ${{ (github.base_ref == 'main' || github.ref == 'refs/heads/main') && 'production' || 'development' }}
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/metrics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:

TOTAL_COMMITS=$(git rev-list --no-merges $BASE..$HEAD | wc -l)
PASSED_COMMITS=$(( TOTAL_COMMITS - FAIL_COUNT ))

echo "fail=${FAIL}" >> "$GITHUB_OUTPUT"
echo "total=${TOTAL_COMMITS}" >> "$GITHUB_OUTPUT"
echo "passed=${PASSED_COMMITS}" >> "$GITHUB_OUTPUT"
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/mirror-gitlab.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Mirror to GitLab
on:
push:
branches: ['**']
tags: ['**']
delete:

jobs:
mirror:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Mirror to GitLab
uses: yesolutions/mirror-action@master
with:
REMOTE: 'https://oauth2:${{ secrets.GITLAB_TOKEN }}@gitlab.com/lay2dev/clawpal.git'
GIT_PUSH_ARGS: '--force --tags'
53 changes: 53 additions & 0 deletions .github/workflows/mirror-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Mirror Release to GitLab
on:
release:
types: [published]

jobs:
mirror-release:
runs-on: ubuntu-latest
steps:
- name: Sync release assets to GitLab
env:
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
GITLAB_PROJECT_ID: ${{ secrets.GITLAB_PROJECT_ID }}
GH_TOKEN: ${{ github.token }}
run: |
TAG="${{ github.event.release.tag_name }}"
BODY=$(echo '${{ toJSON(github.event.release.body) }}')

# Create GitLab release
curl --fail-with-body -X POST \
"https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/releases" \
-H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"tag_name\": \"${TAG}\", \"description\": ${BODY}}" || true

# Download GitHub release assets
mkdir -p /tmp/assets
gh release download "$TAG" -D /tmp/assets -R "${{ github.repository }}" || exit 0

# Upload each asset to GitLab (skip .sig and latest.json)
for file in /tmp/assets/*; do
[ -f "$file" ] || continue
filename=$(basename "$file")

case "$filename" in
*.sig|latest.json) echo "Skip: $filename"; continue ;;
esac

echo "Uploading: $filename ..."

# Upload file (force HTTP/1.1 for large file stability)
upload_url=$(curl --http1.1 --fail-with-body -X POST \
"https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/uploads" \
-H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
-F "file=@${file}" | jq -r '.full_path')

# Link to release
curl --fail-with-body -X POST \
"https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/releases/${TAG}/assets/links" \
-H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"name\": \"${filename}\", \"url\": \"https://gitlab.com${upload_url}\"}"
done
150 changes: 150 additions & 0 deletions .github/workflows/recipe-gui-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
name: Recipe GUI E2E

on:
pull_request:
branches: [develop, main]
workflow_dispatch:

permissions:
contents: read
pull-requests: write

concurrency:
group: recipe-gui-e2e-${{ github.head_ref || github.ref }}
cancel-in-progress: true

jobs:
recipe-gui-e2e:
name: Recipe GUI E2E
runs-on: ubuntu-24.04
timeout-minutes: 120

steps:
- uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event.pull_request.head.ref || github.ref }}
fetch-depth: 0

- name: Build inner OpenClaw image
run: |
docker build \
-t clawpal-recipe-openclaw:latest \
-f harness/recipe-e2e/openclaw-container/Dockerfile \
.

- name: Build recipe GUI E2E harness
run: |
docker build \
-t clawpal-recipe-harness:latest \
-f harness/recipe-e2e/Dockerfile \
.

- name: Run recipe GUI E2E
run: |
mkdir -p recipe-gui-e2e/screenshots recipe-gui-e2e/report
docker run --rm \
--network host \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ${{ github.workspace }}/recipe-gui-e2e/screenshots:/screenshots \
-v ${{ github.workspace }}/recipe-gui-e2e/report:/report \
-e OPENCLAW_IMAGE=clawpal-recipe-openclaw:latest \
clawpal-recipe-harness:latest

- name: Fix permissions
if: always()
run: sudo chown -R $(id -u):$(id -g) recipe-gui-e2e/

- name: Upload perf report
if: always()
uses: actions/upload-artifact@v4
with:
name: recipe-gui-e2e-perf-${{ github.sha }}
path: recipe-gui-e2e/report/perf-report.json
retention-days: 30

- name: Upload screenshots
if: always()
uses: actions/upload-artifact@v4
with:
name: recipe-gui-e2e-screenshots-${{ github.sha }}
path: recipe-gui-e2e/screenshots/
retention-days: 30

- name: Build local mode harness
if: always() && !cancelled()
run: |
docker build -t clawpal-recipe-local:latest -f harness/recipe-e2e/Dockerfile.local .

- name: Run recipe GUI E2E (local mode)
if: always() && !cancelled()
run: |
mkdir -p recipe-gui-e2e-local/screenshots recipe-gui-e2e-local/report
docker run --rm -v ${{ github.workspace }}/recipe-gui-e2e-local/screenshots:/screenshots -v ${{ github.workspace }}/recipe-gui-e2e-local/report:/report clawpal-recipe-local:latest

- name: Fix local permissions
if: always()
run: sudo chown -R $(id -u):$(id -g) recipe-gui-e2e-local/ 2>/dev/null || true

- name: Upload local perf report
if: always()
uses: actions/upload-artifact@v4
with:
name: recipe-gui-e2e-local-perf-${{ github.sha }}
path: recipe-gui-e2e-local/report/perf-report.json
retention-days: 30

- name: Upload local screenshots
if: always()
uses: actions/upload-artifact@v4
with:
name: recipe-gui-e2e-local-screenshots-${{ github.sha }}
path: recipe-gui-e2e-local/screenshots/
retention-days: 30

- name: Generate PR perf comment
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
run: |
node <<'EOF'
const fs = require("fs");
const report = JSON.parse(fs.readFileSync("recipe-gui-e2e/report/perf-report.json", "utf8"));
const rows = report.recipes.map((recipe) => {
if (recipe.skipped) {
return `| ${recipe.recipe_name} | — | — | — | — | ⚠️ Skipped: ${recipe.reason || "unknown"} |`;
}
const fmtMs = (ms) => ms >= 1000 ? `${ms} (${(ms/1000).toFixed(1)}s)` : `${ms}`;
return `| ${recipe.recipe_name} | ${fmtMs(recipe.page_load_ms)} | ${fmtMs(recipe.form_fill_ms)} | ${fmtMs(recipe.execution_ms)} | ${fmtMs(recipe.verification_ms)} | ${fmtMs(recipe.total_ms)} |`;
}).join("\n");
const body = [
"<!-- recipe-gui-e2e -->",
"## Recipe GUI E2E Perf",
"",
`Artifacts: [perf report](https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID})`,
"",
"| Recipe | Page Load (ms) | Form Fill (ms) | Execution (ms) | Verification (ms) | Total (ms) |",
"| --- | ---: | ---: | ---: | ---: | ---: |",
rows,
"",
"> Harness: Docker + Xvfb + tauri-driver + Selenium",
"",
].join("\n");
fs.writeFileSync("/tmp/recipe_gui_e2e_comment.md", body);
EOF

- name: Find existing recipe GUI E2E comment
uses: peter-evans/find-comment@v3
id: recipe_comment
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: '<!-- recipe-gui-e2e -->'

- name: Create or update recipe GUI E2E comment
uses: peter-evans/create-or-update-comment@v4
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
with:
comment-id: ${{ steps.recipe_comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body-path: /tmp/recipe_gui_e2e_comment.md
edit-mode: replace
Loading
Loading