Commit Graph

4271 Commits

Author SHA1 Message Date
Peter Steinberger 0718aedb9d test(cli): remove stale update sidecar fixture (#126126) 2026-08-18 19:13:09 -07:00
Josh Avant 8d6cbee1b5 fix(gateway): avoid Tailscale crash loops after upgrades (#126069)
* fix(gateway): migrate legacy Tailscale routes on upgrade

* fix(gateway): preserve unattributable Tailscale routes
2026-08-18 17:14:49 -07:00
Peter Steinberger 9924e2d7a7 feat(cli): prepare session-host onboarding (#125879)
* feat(cli): prepare session-host onboarding

* fix(cli): gate session-host installer capability
2026-08-18 16:08:48 -07:00
Peter Steinberger e8312171c1 fix: direct Gateway stops wait for active work (#126024)
* fix(gateway): drain active work on direct stop

* test(ui): isolate widget fetch retry mock
2026-08-18 15:29:52 -07:00
Peter Steinberger f97a133254 fix(config): fail config unset on a missing path again (#125958)
runConfigUnset scoped its missing-path error to --dry-run, so the real
invocation printed "No change" and exited 0 while --dry-run on the same
input exited 1 with a specific message. Dry-run exists to predict the
real run, and a typo'd unset in a script reported success.

Restore the failure for both modes, keeping the strict-config assertion
introduced alongside the regression and the JSON5 byte preservation it
was added to guarantee.
2026-08-18 13:45:57 -07:00
Peter Steinberger f59392fdf5 fix(channels): redact logs and reject unknown filters (#125939)
* fix(channels): redact and validate log filters

* fix(logging): preserve filtered redacted channel tails

* fix(channels): match log filters on exact boundaries

* fix(logging): honor redaction off mode
2026-08-18 13:37:17 -07:00
Peter Steinberger bb92dc61c8 fix: stop --tag main from failing during npm pack (#125949)
* fix: refuse unsupported OpenClaw source package updates

* refactor: narrow main update refusal
2026-08-18 12:22:45 -07:00
Peter Steinberger 7ae9cbf3bc fix(cli): stop claiming a write when approvals mutations are no-ops (#125960)
`openclaw approvals allowlist add|remove` printed "Writing local approvals."
from the shared target-resolution helper, before the mutation decision was
made. Both idempotent paths ("Already allowlisted.", "Pattern not found.")
returned without saving, so the CLI announced a write that never happened.
`approvals set` had the same problem: it announced the write and then rejected
unparseable input.

Move the announcement from `loadWritableSnapshotTarget` into the local branch
of `saveSnapshotTargeted`, the function that owns the write. Every caller of
the shared seam is fixed at once and exit codes are unchanged: idempotent add
and remove still leave the requested end state satisfied and exit 0.
2026-08-18 12:12:37 -07:00
Peter Steinberger 153ad5ec27 fix(cli): preserve migration agent ownership (#125948) 2026-08-18 12:10:09 -07:00
Peter Steinberger 91cc7d512b fix(cli): report broadcast delivery failures (#125915)
* fix(cli): report broadcast delivery failures

* test(qa): wait for descendant process exit
2026-08-18 11:28:13 -07:00
Peter Steinberger d8c1d90edb perf(test): consolidate shutdown watchdog proof (#125890) 2026-08-18 09:27:35 -07:00
Peter Steinberger e68e973c05 fix: report unknown gateway service state when inspection fails (#125734)
* fix(daemon): preserve unknown service load state

* test(daemon): update service load-state fixtures

* fix(onboard): preserve loaded service diagnostic

* fix(daemon): preserve unknown lifecycle state

* fix(status): preserve loaded JSON fields

* fix(daemon): fail restart on unknown service state

* fix(daemon): fence unknown service state
2026-08-18 09:20:02 -07:00
Peter Steinberger 13e3d4535b fix(agents): finalize guided creation safely (#125768)
* fix(agents): finalize guided creation safely

Run channel post-write hooks only after config publication, defer portable auth copying until agent creation succeeds without overwriting newer credentials, and provision existing workspaces before publishing updates.

Keep JSON-only guided creation interactive while routing wizard output to stderr so stdout remains one machine-readable summary.

* fix(terminal): preserve note call signature

* fix(agents): pass committed config to setup hooks

* ci: split heavy codex changed-test shards

Cap non-isolated Codex extension processes at 20 files so 4-vCPU changed-target jobs do not starve real-time watches or hit the no-output watchdog.

* test(ci): align codex shard cap fixture

* docs(cli): clarify agents add JSON mode
2026-08-18 08:50:01 -07:00
Peter Steinberger 8dd0434f86 fix(config): redact plugin secrets and preserve safe mutations (#125753)
* fix(config): secure CLI reads and mutations

Use exact plugin metadata for config get redaction, reject impossible SecretRef provider bindings in canonical validation, preserve include CAS provenance, and skip destructive authored no-op rewrites.

* fix(config): preserve inactive SecretRef startup

Keep normal Gateway validation scoped to active secret owners while strict config validation and write paths reject impossible provider/source bindings, including authored no-ops.

* fix(gateway): preserve config patch no-op

Keep unchanged Gateway config.patch requests on the existing no-op path; strict validation remains owned by actual config writes and the config CLI mutation surfaces.
2026-08-18 08:37:21 -07:00
Peter Steinberger 07a0b51703 fix(gateway): enforce shutdown deadline during event-loop stalls (#125863)
Use an off-main-thread watchdog for the process-owning Gateway runner so a CPU-bound shutdown cannot outlive the managed restart deadline. Bound agent-harness disposal so listener teardown can continue.

Release note: Managed Gateway restarts now recover when shutdown work stalls the event loop while preserving graceful cleanup first.

Closes #125840
2026-08-18 08:14:30 -07:00
Josh Lehman eeed2c92cf fix(upgrade): repair stable state before gateway startup (#125483) 2026-08-18 07:40:01 -07:00
Peter Steinberger fc6338c5d0 test(cli): canonicalize update fixture roots (#125846) 2026-08-18 07:39:31 -07:00
Peter Steinberger d92ebbaf72 feat(gateway): reach a Gateway behind an identity-aware proxy from the CLI (#125700)
* feat(gateway): reach a Gateway behind an identity-aware proxy from the CLI

Operator CLI surfaces (tui, attach, call, probe, onboarding, and configure) can present configured gateway.remote.edgeAuth headers to an identity-aware proxy. Headers are origin-bound, WSS-only, never follow redirects, cannot set transport-owned headers, and are redacted. Identity-proxy upgrade rejections are classified and remediated instead of being reported as an unreachable gateway.

* test(gateway): cover config-aware probe calls

Keep status probe expectations aligned with the resolved configuration forwarded for origin-bound edge-auth resolution.

* fix(gateway): preserve edge auth across wizard saves and enforce wss before secret resolution

Preserve gateway.remote.edgeAuth only when the configured Gateway scope is unchanged, and reject non-WSS targets before resolving any edge-auth SecretInput.
2026-08-18 03:29:56 -07:00
Peter Steinberger f0dd7eecaa fix: preserve plugin update recovery after commit (#125739) 2026-08-18 02:08:56 -07:00
Peter Steinberger 2eec047065 fix(mcp): explain an empty probe instead of printing a bare header (#125611)
With no servers configured, mcp probe emitted only its header line and exited
0, while mcp list and mcp doctor both name the condition and the command that
fixes it. Short-circuit the human path with the same guidance and skip building
a runtime for zero servers; JSON output keeps its existing empty envelope.
2026-08-17 22:15:44 -07:00
Peter Steinberger 3ab27a2900 fix(cli): exit non-zero when an agent turn fails (#125557)
The gateway-routed path already mapped terminal run status to an exit code,
but the local embedded path did not, so a failed turn exited 0 while its own
JSON envelope reported status "error". Route both through the canonical
agent-run terminal outcome, and fail closed on an unrecognized status since
the gateway response carries an open string.
2026-08-17 21:31:25 -07:00
Peter Steinberger 01eec285d9 fix(cli): render gateway transport failures as expected conditions (#125556)
* fix(cli): render gateway transport failures as expected conditions

An unreachable gateway is an expected, recoverable operator condition, but
only the devices command family surfaced it through the root failure handler,
where it rendered as "The CLI command failed" with debug hints. Extract
GatewayTransportError into its own module so the failure renderer can classify
it without importing the transport stack, and treat it as an expected CLI
error alongside missing credentials.

* fix(gateway): import the transport error kind used by the JSON shape

* test(cli): extract the process-test gateway harness

The new devices coverage pushed gateway-backed-exit.process.test.ts past the
max-lines budget, and that file is not in the ratchet baseline. Move the mock
Gateway servers into a sibling test-helpers module instead of suppressing the
rule.
2026-08-17 21:18:02 -07:00
Peter Steinberger 7a507d8e66 fix(cli): render missing gateway credentials consistently (#125007)
* fix(cli): unify missing gateway credential output

* test(cli): cover workshop credential rendering
2026-08-17 19:07:18 -07:00
Peter Steinberger 3d00611793 fix(config): keep missing env references unavailable without rejecting literals (#125455)
* fix(config): record unresolved env references as facts

Preserve missing-substitution provenance through config snapshots and runtime activation so unresolved credentials remain unavailable without misclassifying intentional literal placeholder text.

* fix(gateway): preserve config facts across credential clones
2026-08-17 19:05:29 -07:00
Peter Steinberger dc356ce850 fix(skills): report missing skills on verify as not found (#125317)
* fix(skills): report missing skills on verify as not found

* test(skills): align verify mocks with lifecycle
2026-08-17 18:34:26 -07:00
Peter Steinberger 85336be36d fix(cli): honor automation gateway port options (#125474) 2026-08-17 17:39:39 -07:00
Peter Steinberger 7e998a367f fix(cli): avoid exposing provider env values in parse errors (#124714)
* fix(cli): omit provider env values from parse errors

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(config): redact provider env guidance

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(config): redact provider env audit arguments

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 17:26:09 -07:00
Peter Steinberger a996ea25d9 fix(update): support npm before lifecycle allowlists (#125452) 2026-08-17 17:01:23 -07:00
Peter Steinberger 44e8b6f12b fix(onboarding): stop printing gateway token URLs (#124687)
* fix(onboarding): stop printing gateway token URLs

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(onboarding): finish token-free handoff cleanup

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 16:23:16 -07:00
Peter Steinberger fa9ab1d40c perf(test): reuse proxy CLI runtime module (#125387) 2026-08-17 14:39:08 -07:00
Peter Steinberger 45e6784338 feat(gateway): run disposable cloud workers through node transport (#125288)
* feat(gateway): converge cloud workers onto nodes

* fix(gateway): honor public URL for cloud enrollment

* fix(crabbox): execute cloud bootstrap package binary

* fix(gateway): bind cloud nodes in pairing transaction

* fix(crabbox): prefer exact installed cloud bootstrap

* fix(gateway): complete cloud node bootstrap

* fix(gateway): enforce cloud worker capability boundaries

* fix(gateway): complete cloud node migration

* fix(gateway): preserve paired node roles on teardown
2026-08-17 11:49:06 -07:00
Peter Steinberger 8dfbaa6087 fix(cli): report plugin policy refusals as expected conditions (#125304) 2026-08-17 09:49:19 -07:00
Peter Steinberger b834477565 fix(cli): refuse live state reset and uninstall (#125253)
* fix(cli): guard live state cleanup

* fix(cli): preserve linked paths on cleanup failure

* fix(cli): retain gateway ownership through cleanup

* fix(cli): keep cleanup planning read-only

* fix(cli): skip mutating bootstrap for cleanup

* fix(apple): keep identity locks sandbox-writable

* docs(apple): clarify identity lock domains
2026-08-17 09:44:31 -07:00
Peter Steinberger 1298adfca7 fix(cron): distinguish missing automations from empty run history (#125343) 2026-08-17 09:34:38 -07:00
Peter Steinberger 11ebdfc9c3 fix(gateway): normalize TLS certificate pins (#125276)
* fix(gateway): normalize TLS certificate pins

* test(gateway): use valid TLS pin fixtures
2026-08-17 06:02:56 -07:00
Peter Steinberger 914d8f6932 fix(onboard): keep completion permission errors nonfatal (#125263)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 05:48:02 -07:00
Peter Steinberger 4eb6aa375f refactor(gateway): carry authoritative read facts (#125145)
* refactor(gateway): carry authoritative read facts

* fix(gateway): fence prepared device auth rotations

* fix(ci): split oversized session types
2026-08-17 05:13:35 -07:00
Peter Steinberger 2d3aaaa0d5 feat(node-host): support Cloudflare Access service tokens (#125193)
* feat(node-host): support Cloudflare Access service tokens

Carry SecretRef-backed, origin-bound Cloudflare Access credentials across node onboarding, gateway and worker connections, and node-owned worker transfers. Refs #125112.

* chore: align changed gate after rebase

* test(node-host): keep access proof within lint budgets

* style(node-host): keep supervisor within line budget

* fix(node-host): omit absent access config

* fix(node-host): reject Access credentials on plaintext routes

* fix(node-host): reject plaintext before ref resolution

* test: cover Access log redaction over TLS
2026-08-17 04:12:27 -07:00
Peter Steinberger bbe22082b0 fix(cli): keep gateway calls and diagnostics read-only (#125178)
* fix(cli): keep gateway diagnostics read-only

Direct gateway calls and diagnostic probes now preserve shared SQLite ownership instead of creating or mutating state during read-only operations.

Related: #101290
Follow-up to #125102

* fix(cli): keep required status probes read-only
2026-08-17 03:58:57 -07:00
Peter Steinberger 8cae198210 fix(cli): default Windows completion to PowerShell (#125211)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 03:50:52 -07:00
Peter Steinberger 0bc877e889 fix(cron): deliver main reminders in the main session (#125198)
* fix(cron): route main reminders through main session

* refactor(cron): finish main reminder cleanup

* test(cron): align main reminder expectations
2026-08-17 03:35:55 -07:00
Peter Steinberger 076a8cc616 fix(install): avoid unusable checkout directories after failed clones (#124872)
* fix(install): publish fresh git clones transactionally

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(installer): preserve empty clone destinations transactionally

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(update): satisfy transactional clone lint

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(update): type recovery directory assertion

* fix(installer): retain canonical clone checkout

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(update): retain published checkout root

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* test(update): cover package preflight before clone

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 02:40:07 -07:00
Peter Steinberger 323f23495d fix(cli): gateway restart reaches schema-ahead process (#125133)
* fix(cli): keep gateway controls off plugin state

Use core-only config validation for gateway call and restart so schema-ahead recovery can reach the running Gateway without opening newer persisted plugin metadata.\n\nFixes #125115

* test(infra): isolate browser open SSH environment

* test(cli): cover gateway call validation policy
2026-08-17 02:30:55 -07:00
Peter Steinberger 5ac714e31b fix(update): defer source-runtime startup migrations (#125124)
* fix(update): defer startup migrations

Amp-Thread-ID: https://ampcode.com/threads/T-01a00a6a-b64e-74a5-8b15-2d3b966a468d

* fix(update): defer mutable state admission

Amp-Thread-ID: https://ampcode.com/threads/T-01a00a6a-b64e-74a5-8b15-2d3b966a468d

* test(update): cover deferred startup bootstrap

Amp-Thread-ID: https://ampcode.com/threads/T-01a00a6a-b64e-74a5-8b15-2d3b966a468d

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 02:29:23 -07:00
Peter Steinberger a2c857ea0e fix: model setup detects CLI logins when AI access checks time out (#125114)
* fix(system-agent): detect CLI logins on setup timeout

* style(macos): format setup detection timeout

* fix(macos): bound setup restart reconciliation
2026-08-17 02:27:18 -07:00
Peter Steinberger 1df264d3f5 test: use per-run temp roots in update-cli and migrate suites (#125171)
update-cli.test.ts used a fixed /tmp/openclaw-update-tests root with
deterministic case-dir names; some cases write real fixture files there
and cleanup rm -rf's them, so concurrent runs on one machine (CI shards,
sibling checkouts) deleted each other's live fixtures — observed as 34
spurious failures on PR #124997 run 31992421445. migrate.test.ts had the
same shape via a fixed mocked resolveStateDir root rm -rf'd in
beforeEach/afterEach.

Both suites now use per-run mkdtemp roots, realpath'd for the macOS
/var -> /private/var symlink, removed on suite exit.
2026-08-17 02:22:23 -07:00
Peter Steinberger 42a46250d4 fix(update): keep a committed post-core result when stopping the child signals (#125150)
* fix(update): keep a committed post-core result when stopping the child signals

The post-core wait settles from three places: a result-file poll, child "error",
and child "exit". The poll stopped the child before claiming the settle, and
stopping delivers a signal, so the still-unclaimed exit handler could reject with
"post-update process terminated by signal SIGTERM" for an update whose child had
already written a valid result. The outer catch then restored the tentative
plugin index, rolling back work that actually succeeded.

Claim the settle first, then stop. The exit handler sees settled and returns.
Net zero production lines; pure reordering plus the invariant comment.

This is the error that leaked across tests in the agentic-cli shard on
2026-08-17 (run 31997770370), where it surfaced inside an unrelated test and
cascaded into 34 failures in src/cli/update-cli.test.ts.

Regression test drives the exact ordering: the child commits its result, then the
parent's stop delivers SIGTERM. It fails on pre-fix code with
"promise rejected ... instead of resolving / post-update process terminated by
signal SIGTERM".

* test(update): satisfy strict indexed access in the post-core signal regression
2026-08-17 01:19:47 -07:00
Peter Steinberger 05bbd48c51 docs(install): clarify lifecycle script trust (#124727)
* docs(install): approve OpenClaw lifecycle scripts

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(update): bind npm lifecycle policy to install owner

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(update): gate npm lifecycle policy before mutation

* test(update): cover npm lifecycle ownership

* fix(update): defer backup cleanup until package preflight passes

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* fix(update): preflight npm policy before service stop

Amp-Thread-ID: https://ampcode.com/threads/T-01a00ae0-190d-718b-8a76-b75f3e8d1fae

* docs(install): avoid unsupported lifecycle claim

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-08-17 01:00:17 -07:00
Peter Steinberger 83d279a4c1 fix(cli): honor channel resolve agent ownership (#125109)
* fix(cli): honor channel resolve agent ownership

Forward explicit channel owners through command-time secret collection and later workspace/channel resolution, preventing AGENT_SELECTION_REQUIRED in multi-agent configurations.

* fix(cli): narrow explicit agent option value

Use runtime string narrowing for the Commander option so agent-owner forwarding remains assertion-free and satisfies the assertion-safety ratchet.

* docs(cli): document channel resolve agent owner
2026-08-16 23:50:52 -07:00
Peter Steinberger a3eb8787ff fix(cli): keep offline gateway RPCs read-only (#125102)
Gateway health, suspend, and resume now preserve shared SQLite state when the target is unreachable.

Related: #101290

Follow-up to #123674
2026-08-16 23:29:30 -07:00