The single InstalledDistScanBudget is consumed across all three prune
walks (legacy-deps prepass, dist file listing, empty-dir sweep). During
an npm upgrade the dist dir transiently holds old+new content-hashed
files, so a real upgrade scan totals ~24k entries against the 25k cap;
one more release of dist growth would make 'npm install -g openclaw'
throw InstalledDistScanLimitError for every upgrading user. Raise the
cap to 100k for real headroom while keeping the unbounded-scan guard,
and ratchet the cap in the test so it cannot be lowered back.
* feat: correlate native search outcomes in audit history
Metadata-only audit ledger for agent runs and tool actions in the shared
state DB: stable event identity, closed action/status/error vocabularies,
one-way-hashed tool-call ids, never-inferred terminal outcomes for native
web-search (explicit completed/failed only; otherwise unknown), bounded
retention, audit.list gateway RPC and openclaw audit CLI. Squashed from
the 82-commit audit stack for replay onto current main.
* feat(audit): add audit.enabled config gate (default on)
The metadata-only audit ledger records by default: an audit trail enabled
only after an incident cannot explain the incident, and the rows are
strictly less sensitive than the transcripts every install already
stores. audit.enabled=false stops new writes at the gateway subscription
seam; audit.list and openclaw audit keep serving existing records until
they expire. Documented in the configuration reference, protocol page,
and CLI reference.
* fix: repair full-matrix CI findings after rebase
- break the dynamic-tools/dynamic-tool-execution import cycle by
extracting resolveCodexToolAbortTerminalReason into a leaf module
- restore main's session-worktree protocol exports lost in the
index.ts auto-merge
- register the audit event writer worker as a knip entry point
- docs table formatting; subagent wait-cancellation test scoped to its
audit intent (outcome + timing) and advanced past main's new
lifecycle-timeout retry grace
* fix(build): fall back to tsx for build TypeScript scripts
* fix(build): use tsx across TypeScript build scripts
---------
Co-authored-by: Steffen Moeller <moeller@debian.org>
Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
* style: restore exec approval e2e formatting
* fix(install): trap SIGINT so Ctrl+C exits cleanly during upgrade doctor
Three changes to fix the install script's Ctrl+C handling:
1. Add INT/TERM signal traps that clean up temp files and exit with
the correct signal exit codes (130 for SIGINT, 143 for SIGTERM).
2. Preserve signal exit codes (>128) through run_quiet_step so the
doctor path can distinguish user cancellation from normal errors.
Non-signal failures still return 1, preserving existing caller
semantics for all other installer steps.
3. Fix guardCancel in onboard-helpers.ts: exit(0) changed to exit(1)
so Clack prompt cancellation (Escape/Ctrl+C) is treated as failure,
not success. This prevents the installer from continuing with plugin
updates after the user explicitly cancelled.
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(install): abort dashboard launch on doctor cancellation
When a user cancels the interactive upgrade-doctor prompt (Clack
cancellation exits 1, SIGINT exits 130), clear should_open_dashboard
so the installer does not launch a dead dashboard after an incomplete
upgrade.
Also propagate non-zero exit from run_doctor() so the non-interactive
upgrade path correctly skips dashboard launch on failure.
* fix: guard every run_doctor caller and add focused tests
The existing-config path called run_doctor without checking its return
value, so a failed or cancelled doctor would still launch the dashboard.
Now both run_doctor call sites guard the return value with if-then.
Adds focused tests verifying: every run_doctor caller is guarded,
dashboard flag is cleared on doctor failure, signal exit codes
propagate through run_quiet_step, and SIGINT (exit 130) triggers
abort_install_int.
* retrigger proof check
* fix: exit 130 on Clack cancellation so installer treats it as SIGINT
guardCancel now exits with 130 (SIGINT convention) instead of 1. When
the user presses Ctrl+C at an interactive doctor prompt, the installer
sees doctor_exit=130 and calls abort_install_int, aborting cleanly
instead of continuing after exit 1.
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix: narrow exit 130 to doctor-prompter path only
Revert guardCancel to exit 0 by default (matching main) and pass
exit code 130 only from doctor-prompter where the installer needs
to distinguish user cancellation from normal failures.
This preserves the existing cancellation behavior for configure,
wizard, gateway, and daemon prompts while keeping the SIGINT
convention for the installer's doctor subprocess.
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
---------
Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(diffs): share SSR preloads and repair language-pack hydration
Render viewer and file documents from a single @pierre/diffs SSR preload
per file (mode=both previously ran the full diff+highlight pipeline
twice; 651ms -> 303ms on an 8-file patch), apply the file-mode font bump
as a document-level override, and keep hydration payloads
variant-faithful.
Fix the language-pack runtime downgrading pack-only languages to plain
text at hydration by defining a per-target build flag and forwarding it
to payload normalization.
Also: case-insensitive language hints, identical before/after
short-circuit with details.changed, patch input failures classified as
tool input errors, canonical config values now win over deprecated
aliases, hash-pinned viewer runtime served immutable, truthful
browser-vs-render errors, timing-safe artifact token compare, unref
idle browser timer.
* docs(changelog): link diffs rendering entry to PR
* test(diffs): narrow manifest validation results before value access
* test(tooling): allowlist diffs viewer-client define suppression