Skip to content

Commit fc6cfc7

Browse files
committed
Merge remote-tracking branch 'upstream/main' into codex/rescue-watchdog
2 parents 22b231e + 8bc163d commit fc6cfc7

933 files changed

Lines changed: 48159 additions & 26670 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
.git
22
.worktrees
3+
4+
# Sensitive files – docker-setup.sh writes .env with OPENCLAW_GATEWAY_TOKEN
5+
# into the project root; keep it out of the build context.
6+
.env
7+
.env.*
8+
39
.bun-cache
410
.bun
511
.tmp

.github/workflows/ci.yml

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77

88
concurrency:
99
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
10-
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
10+
cancel-in-progress: true
1111

1212
env:
1313
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
@@ -38,9 +38,8 @@ jobs:
3838
id: check
3939
uses: ./.github/actions/detect-docs-changes
4040

41-
# Detect which heavy areas are touched so PRs can skip unrelated expensive jobs.
42-
# Push to main keeps broad coverage, but this job still needs to run so
43-
# downstream jobs that list it in `needs` are not skipped.
41+
# Detect which heavy areas are touched so CI can skip unrelated expensive jobs.
42+
# Fail-safe: if detection fails, downstream jobs run.
4443
changed-scope:
4544
needs: [docs-scope]
4645
if: needs.docs-scope.outputs.docs_only != 'true'
@@ -82,7 +81,7 @@ jobs:
8281
# Build dist once for Node-relevant changes and share it with downstream jobs.
8382
build-artifacts:
8483
needs: [docs-scope, changed-scope]
85-
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
84+
if: github.event_name == 'push' && needs.docs-scope.outputs.docs_only != 'true' && needs.changed-scope.outputs.run_node == 'true'
8685
runs-on: blacksmith-16vcpu-ubuntu-2404
8786
steps:
8887
- name: Checkout
@@ -141,14 +140,21 @@ jobs:
141140

142141
checks:
143142
needs: [docs-scope, changed-scope]
144-
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
143+
if: needs.docs-scope.outputs.docs_only != 'true' && needs.changed-scope.outputs.run_node == 'true'
145144
runs-on: blacksmith-16vcpu-ubuntu-2404
146145
strategy:
147146
fail-fast: false
148147
matrix:
149148
include:
150149
- runtime: node
151150
task: test
151+
shard_index: 1
152+
shard_count: 2
153+
command: pnpm canvas:a2ui:bundle && pnpm test
154+
- runtime: node
155+
task: test
156+
shard_index: 2
157+
shard_count: 2
152158
command: pnpm canvas:a2ui:bundle && pnpm test
153159
- runtime: node
154160
task: extensions
@@ -160,40 +166,47 @@ jobs:
160166
task: test
161167
command: pnpm canvas:a2ui:bundle && bunx vitest run --config vitest.unit.config.ts
162168
steps:
163-
- name: Skip bun lane on push
164-
if: github.event_name == 'push' && matrix.runtime == 'bun'
165-
run: echo "Skipping bun test lane on push events."
169+
- name: Skip bun lane on pull requests
170+
if: github.event_name == 'pull_request' && matrix.runtime == 'bun'
171+
run: echo "Skipping Bun compatibility lane on pull requests."
166172

167173
- name: Checkout
168-
if: github.event_name != 'push' || matrix.runtime != 'bun'
174+
if: github.event_name != 'pull_request' || matrix.runtime != 'bun'
169175
uses: actions/checkout@v6
170176
with:
171177
submodules: false
172178

173179
- name: Setup Node environment
174-
if: matrix.runtime != 'bun' || github.event_name != 'push'
180+
if: matrix.runtime != 'bun' || github.event_name != 'pull_request'
175181
uses: ./.github/actions/setup-node-env
176182
with:
177183
install-bun: "${{ matrix.runtime == 'bun' }}"
178184
use-sticky-disk: "false"
179185

180186
- name: Configure Node test resources
181-
if: (github.event_name != 'push' || matrix.runtime != 'bun') && matrix.task == 'test' && matrix.runtime == 'node'
187+
if: (github.event_name != 'pull_request' || matrix.runtime != 'bun') && matrix.task == 'test' && matrix.runtime == 'node'
188+
env:
189+
SHARD_COUNT: ${{ matrix.shard_count || '' }}
190+
SHARD_INDEX: ${{ matrix.shard_index || '' }}
182191
run: |
183192
# `pnpm test` runs `scripts/test-parallel.mjs`, which spawns multiple Node processes.
184193
# Default heap limits have been too low on Linux CI (V8 OOM near 4GB).
185194
echo "OPENCLAW_TEST_WORKERS=2" >> "$GITHUB_ENV"
186195
echo "OPENCLAW_TEST_MAX_OLD_SPACE_SIZE_MB=6144" >> "$GITHUB_ENV"
196+
if [ -n "$SHARD_COUNT" ] && [ -n "$SHARD_INDEX" ]; then
197+
echo "OPENCLAW_TEST_SHARDS=$SHARD_COUNT" >> "$GITHUB_ENV"
198+
echo "OPENCLAW_TEST_SHARD_INDEX=$SHARD_INDEX" >> "$GITHUB_ENV"
199+
fi
187200
188201
- name: Run ${{ matrix.task }} (${{ matrix.runtime }})
189-
if: matrix.runtime != 'bun' || github.event_name != 'push'
202+
if: matrix.runtime != 'bun' || github.event_name != 'pull_request'
190203
run: ${{ matrix.command }}
191204

192205
# Types, lint, and format check.
193206
check:
194207
name: "check"
195208
needs: [docs-scope, changed-scope]
196-
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
209+
if: needs.docs-scope.outputs.docs_only != 'true' && needs.changed-scope.outputs.run_node == 'true'
197210
runs-on: blacksmith-16vcpu-ubuntu-2404
198211
steps:
199212
- name: Checkout
@@ -239,7 +252,7 @@ jobs:
239252
compat-node22:
240253
name: "compat-node22"
241254
needs: [docs-scope, changed-scope]
242-
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
255+
if: github.event_name == 'push' && needs.docs-scope.outputs.docs_only != 'true' && needs.changed-scope.outputs.run_node == 'true'
243256
runs-on: blacksmith-16vcpu-ubuntu-2404
244257
steps:
245258
- name: Checkout
@@ -272,7 +285,7 @@ jobs:
272285

273286
skills-python:
274287
needs: [docs-scope, changed-scope]
275-
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true' || needs.changed-scope.outputs.run_skills_python == 'true')
288+
if: needs.docs-scope.outputs.docs_only != 'true' && needs.changed-scope.outputs.run_skills_python == 'true'
276289
runs-on: blacksmith-16vcpu-ubuntu-2404
277290
steps:
278291
- name: Checkout
@@ -365,7 +378,7 @@ jobs:
365378

366379
checks-windows:
367380
needs: [docs-scope, changed-scope]
368-
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_windows == 'true')
381+
if: needs.docs-scope.outputs.docs_only != 'true' && needs.changed-scope.outputs.run_windows == 'true'
369382
runs-on: blacksmith-32vcpu-windows-2025
370383
timeout-minutes: 45
371384
env:
@@ -727,7 +740,7 @@ jobs:
727740
728741
android:
729742
needs: [docs-scope, changed-scope]
730-
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_android == 'true')
743+
if: needs.docs-scope.outputs.docs_only != 'true' && needs.changed-scope.outputs.run_android == 'true'
731744
runs-on: blacksmith-16vcpu-ubuntu-2404
732745
strategy:
733746
fail-fast: false

.jscpd.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"gitignore": true,
3+
"noSymlinks": true,
4+
"ignore": [
5+
"**/node_modules/**",
6+
"**/dist/**",
7+
"dist/**",
8+
"**/.git/**",
9+
"**/coverage/**",
10+
"**/build/**",
11+
"**/.build/**",
12+
"**/.artifacts/**",
13+
"docs/zh-CN/**",
14+
"**/CHANGELOG.md"
15+
]
16+
}

AGENTS.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
- Framework: Vitest with V8 coverage thresholds (70% lines/branches/functions/statements).
133133
- Naming: match source names with `*.test.ts`; e2e in `*.e2e.test.ts`.
134134
- Run `pnpm test` (or `pnpm test:coverage`) before pushing when you touch logic.
135+
- For targeted/local debugging, keep using the wrapper: `pnpm test -- <path-or-filter> [vitest args...]` (for example `pnpm test -- src/commands/onboard-search.test.ts -t "shows registered plugin providers"`); do not default to raw `pnpm vitest run ...` because it bypasses wrapper config/profile/pool routing.
135136
- Do not set test workers above 16; tried already.
136137
- If local Vitest runs cause memory pressure (common on non-Mac-Studio hosts), use `OPENCLAW_TEST_PROFILE=low OPENCLAW_TEST_SERIAL_GATEWAY=1 pnpm test` for land/gate runs.
137138
- Live tests (real keys): `CLAWDBOT_LIVE_TEST=1 pnpm test:live` (OpenClaw-only) or `LIVE=1 pnpm test:live` (includes provider live tests). Docker: `pnpm test:docker:live-models`, `pnpm test:docker:live-gateway`. Onboarding Docker E2E: `pnpm test:docker:onboard`.
@@ -201,6 +202,35 @@
201202
## Agent-Specific Notes
202203

203204
- Vocabulary: "makeup" = "mac app".
205+
- Parallels macOS retests: use the snapshot most closely named like `macOS 26.3.1 fresh` when the user asks for a clean/fresh macOS rerun; avoid older Tahoe snapshots unless explicitly requested.
206+
- Parallels macOS smoke playbook:
207+
- `prlctl exec` is fine for deterministic repo commands, but it can misrepresent interactive shell behavior (`PATH`, `HOME`, `curl | bash`, shebang resolution). For installer parity or shell-sensitive repros, prefer the guest Terminal or `prlctl enter`.
208+
- Fresh Tahoe snapshot current reality: `brew` exists, `node` may not be on `PATH` in noninteractive guest exec. Use absolute `/opt/homebrew/bin/node` for repo/CLI runs when needed.
209+
- Preferred automation entrypoint: `pnpm test:parallels:macos`. It restores the snapshot most closely matching `macOS 26.3.1 fresh`, serves the current `main` tarball from the host, then runs fresh-install and latest-release-to-main smoke lanes.
210+
- Gateway verification in smoke runs should use `openclaw gateway status --deep --require-rpc`, not plain `--deep`, so probe failures go non-zero.
211+
- Harness output: pass `--json` for machine-readable summary; per-phase logs land under `/tmp/openclaw-parallels-smoke.*`.
212+
- Fresh host-served tgz install: restore fresh snapshot, install tgz as guest root with `HOME=/var/root`, then run onboarding as the desktop user via `prlctl exec --current-user`.
213+
- For `openclaw onboard --non-interactive --secret-input-mode ref --install-daemon`, expect env-backed auth-profile refs (for example `OPENAI_API_KEY`) to be copied into the service env at install time; this path was fixed and should stay green.
214+
- Don’t run local + gateway agent turns in parallel on the same fresh workspace/session; they can collide on the session lock. Run sequentially.
215+
- Root-installed tarball smoke on Tahoe can still log plugin blocks for world-writable `extensions/*` under `/opt/homebrew/lib/node_modules/openclaw`; treat that as separate from onboarding/gateway health unless the task is plugin loading.
216+
- Parallels Windows smoke playbook:
217+
- Preferred automation entrypoint: `pnpm test:parallels:windows`. It restores the snapshot most closely matching `pre-openclaw-native-e2e-2026-03-12`, serves the current `main` tarball from the host, then runs fresh-install and latest-release-to-main smoke lanes.
218+
- Gateway verification in smoke runs should use `openclaw gateway status --deep --require-rpc`, not plain `--deep`, so probe failures go non-zero.
219+
- Always use `prlctl exec --current-user` for Windows guest runs; plain `prlctl exec` lands in `NT AUTHORITY\SYSTEM` and does not match the real desktop-user install path.
220+
- Prefer explicit `npm.cmd` / `openclaw.cmd`. Bare `npm` / `openclaw` in PowerShell can hit the `.ps1` shim and fail under restrictive execution policy.
221+
- Use PowerShell only as the transport (`powershell.exe -NoProfile -ExecutionPolicy Bypass`) and call the `.cmd` shims explicitly from inside it.
222+
- Harness output: pass `--json` for machine-readable summary; per-phase logs land under `/tmp/openclaw-parallels-windows.*`.
223+
- Parallels Linux smoke playbook:
224+
- Preferred automation entrypoint: `pnpm test:parallels:linux`. It restores the snapshot most closely matching `fresh` on `Ubuntu 24.04.3 ARM64`, serves the current `main` tarball from the host, then runs fresh-install and latest-release-to-main smoke lanes.
225+
- Use plain `prlctl exec` on this snapshot. `--current-user` is not the right transport there.
226+
- Fresh snapshot reality: `curl` is missing and `apt-get update` can fail on clock skew. Bootstrap with `apt-get -o Acquire::Check-Date=false update` and install `curl ca-certificates` before testing installer paths.
227+
- Fresh `main` tgz smoke on Linux still needs the latest-release installer first, because this snapshot has no Node/npm before bootstrap. The harness does stable bootstrap first, then overlays current `main`.
228+
- This snapshot does not have a usable `systemd --user` session. Treat managed daemon install as unsupported here; use `--skip-health`, then verify with direct `openclaw gateway run --bind loopback --port 18789 --force`.
229+
- Env-backed auth refs are still fine, but any direct shell launch (`openclaw gateway run`, `openclaw agent --local`, Linux `gateway status --deep` against that direct run) must inherit the referenced env vars in the same shell.
230+
- `prlctl exec` reaps detached Linux child processes on this snapshot, so a background `openclaw gateway run` launched from automation is not a trustworthy smoke path. The harness verifies installer + `agent --local`; do direct gateway checks only from an interactive guest shell when needed.
231+
- When you do run Linux gateway checks manually from an interactive guest shell, use `openclaw gateway status --deep --require-rpc` so an RPC miss is a hard failure.
232+
- Prefer direct argv guest commands for fetch/install steps (`curl`, `npm install -g`, `openclaw ...`) over nested `bash -lc` quoting; Linux guest quoting through Parallels was the flaky part.
233+
- Harness output: pass `--json` for machine-readable summary; per-phase logs land under `/tmp/openclaw-parallels-linux.*`.
204234
- Never edit `node_modules` (global/Homebrew/npm/git installs too). Updates overwrite. Skill notes go in `tools.md` or `AGENTS.md`.
205235
- When adding a new `AGENTS.md` anywhere in the repo, also add a `CLAUDE.md` symlink pointing to it (example: `ln -s AGENTS.md CLAUDE.md`).
206236
- Signal: "update fly" => `fly ssh console -a flawd-bot -C "bash -lc 'cd /data/clawd/openclaw && git pull --rebase origin main'"` then `fly machines restart e825232f34d058 -a flawd-bot`.

0 commit comments

Comments
 (0)