Commit Graph

30 Commits

Author SHA1 Message Date
Vincent Koc
04e103d10e fix(terminal): stabilize skills table width across Terminal.app and iTerm (#42849)
* Terminal: measure grapheme display width

* Tests: cover grapheme terminal width

* Terminal: wrap table cells by grapheme width

* Tests: cover emoji table alignment

* Terminal: refine table wrapping and width handling

* Terminal: stop shrinking CLI tables by one column

* Skills: use Terminal-safe emoji in list output

* Changelog: note terminal skills table fixes

* Skills: normalize emoji presentation across outputs

* Terminal: consume unsupported escape bytes in tables
2026-03-11 09:13:10 -04:00
Peter Steinberger
1d3dde8d21 fix(update): re-enable launchd service before updater bootstrap 2026-03-09 07:27:11 +00:00
Ayaan Zaidi
05c240fad6 fix: restart Windows gateway via Scheduled Task (#38825) (#38825) 2026-03-07 18:00:38 +05:30
Tak Hoffman
1be39d4250 fix(gateway): synthesize lifecycle robustness for restart and startup probes (#33831)
* fix(gateway): correct launchctl command sequence for gateway restart (closes #20030)

* fix(restart): expand HOME and escape label in launchctl plist path

* fix(restart): poll port free after SIGKILL to prevent EADDRINUSE restart loop

When cleanStaleGatewayProcessesSync() kills a stale gateway process,
the kernel may not immediately release the TCP port. Previously the
function returned after a fixed 500ms sleep (300ms SIGTERM + 200ms
SIGKILL), allowing triggerOpenClawRestart() to hand off to systemd
before the port was actually free. The new systemd process then raced
the dying socket for port 18789, hit EADDRINUSE, and exited with
status 1, causing systemd to retry indefinitely — the zombie restart
loop reported in #33103.

Fix: add waitForPortFreeSync() that polls lsof at 50ms intervals for
up to 2 seconds after SIGKILL. cleanStaleGatewayProcessesSync() now
blocks until the port is confirmed free (or the budget expires with a
warning) before returning. The increased SIGTERM/SIGKILL wait budgets
(600ms / 400ms) also give slow processes more time to exit cleanly.

Fixes #33103
Related: #28134

* fix: add EADDRINUSE retry and TIME_WAIT port-bind checks for gateway startup

* fix(ports): treat EADDRNOTAVAIL as non-retryable and fix flaky test

* fix(gateway): hot-reload agents.defaults.models allowlist changes

The reload plan had a rule for `agents.defaults.model` (singular) but
not `agents.defaults.models` (plural — the allowlist array).  Because
`agents.defaults.models` does not prefix-match `agents.defaults.model.`,
it fell through to the catch-all `agents` tail rule (kind=none), so
allowlist edits in openclaw.json were silently ignored at runtime.

Add a dedicated reload rule so changes to the models allowlist trigger
a heartbeat restart, which re-reads the config and serves the updated
list to clients.

Fixes #33600

Co-authored-by: HCL <chenglunhu@gmail.com>
Signed-off-by: HCL <chenglunhu@gmail.com>

* test(restart): 100% branch coverage — audit round 2

Audit findings fixed:
- remove dead guard: terminateStaleProcessesSync pids.length===0 check was
  unreachable (only caller cleanStaleGatewayProcessesSync already guards)
- expose __testing.callSleepSyncRaw so sleepSync's real Atomics.wait path
  can be unit-tested directly without going through the override
- fix broken sleepSync Atomics.wait test: previous test set override=null
  but cleanStaleGatewayProcessesSync returned before calling sleepSync —
  replaced with direct callSleepSyncRaw calls that actually exercise L36/L42-47
- fix pid collision: two tests used process.pid+304 (EPERM + dead-at-SIGTERM);
  EPERM test changed to process.pid+305
- fix misindented tests: 'deduplicates pids' and 'lsof status 1 container
  edge case' were outside their intended describe blocks; moved to correct
  scopes (findGatewayPidsOnPortSync and pollPortOnce respectively)
- add missing branch tests:
  - status 1 + non-empty stdout with zero openclaw pids → free:true (L145)
  - mid-loop non-openclaw cmd in &&-chain (L67)
  - consecutive p-lines without c-line between them (L67)
  - invalid PID in p-line (p0 / pNaN) — ternary false branch (L67)
  - unknown lsof output line (else-if false branch L69)

Coverage: 100% stmts / 100% branch / 100% funcs / 100% lines (36 tests)

* test(restart): fix stale-pid test typing for tsgo

* fix(gateway): address lifecycle review findings

* test(update): make restart-helper path assertions windows-safe

---------

Signed-off-by: HCL <chenglunhu@gmail.com>
Co-authored-by: Glucksberg <markuscontasul@gmail.com>
Co-authored-by: Efe Büken <efe@arven.digital>
Co-authored-by: Riccardo Marino <rmarino@apple.com>
Co-authored-by: HCL <chenglunhu@gmail.com>
2026-03-03 21:31:12 -06:00
Shadow
b0bcea03db fix: drop discord opus dependency 2026-03-03 12:23:19 -06:00
Gustavo Madeira Santana
f26853f14c CLI: dedupe config validate errors and expose allowed values 2026-03-02 20:05:12 -05:00
Peter Steinberger
b1c30f0ba9 refactor: dedupe cli config cron and install flows 2026-03-02 19:57:33 +00:00
tda
d145518f94 fix(cli): wait for process exit before restarting gateway on Windows (openclaw#27913) thanks @tda1017
Verified:
- pnpm vitest src/cli/update-cli/restart-helper.test.ts
- pnpm check
- pnpm build

Co-authored-by: tda1017 <95275462+tda1017@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-02 08:31:03 -06:00
Xinhua Gu
7bbfb9de5e fix(update): fallback to --omit=optional when global npm update fails (#24896)
* fix(update): fallback to --omit=optional when global npm update fails

* fix(update): add recovery hints and fallback for npm global update failures

* chore(update): align fallback progress step index ordering

* chore(update): label omit-optional retry step in progress output

* chore(update): avoid showing 1/2 when fallback path is not used

* chore(ci): retrigger after unrelated test OOM

* fix(update): scope recovery hints to npm failures

* test(update): cover non-npm hint suppression

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-02-26 21:35:13 -05:00
Peter Machona
097a6a83a0 fix(cli): replace stale doctor/restart command hints (#24485)
* fix(cli): replace stale doctor and restart hints

* fix: add changelog for CLI hint updates (#24485) (thanks @chilu18)

---------

Co-authored-by: Muhammed Mukhthar CM <mukhtharcm@gmail.com>
2026-02-24 14:49:59 +05:30
Peter Steinberger
f442a3539f feat(update): add core auto-updater and dry-run preview 2026-02-22 17:11:36 +01:00
Peter Steinberger
a04cdc0390 refactor(cli): share update global command runner adapter 2026-02-21 21:40:39 +00:00
Peter Steinberger
905e355f65 fix: verify gateway restart health after daemon restart 2026-02-21 18:02:14 +01:00
Peter Steinberger
e93ba6ce2a fix: harden update restart service convergence 2026-02-21 17:40:28 +01:00
Peter Steinberger
20004711df fix(update): restart daemon after service refresh 2026-02-20 00:02:53 +01:00
Vincent Koc
45d9b20692 fix(cli): refresh gateway service env during update (#21071)
* changelog: add security deepMerge prototype-pollution fix entry

* update: refresh gateway service env during update restart

* test(cli): fix daemon install mock assertion

* test(cli): guard update restart false path
2026-02-19 08:32:56 -08:00
Peter Steinberger
a4da6cfd53 test(update-cli): dedupe restart script test setup helpers 2026-02-19 07:33:16 +00:00
Peter Steinberger
61c0c147ad refactor(update-cli): share timeout option validation 2026-02-18 22:49:39 +00:00
Peter Steinberger
005e1d5fd1 refactor(cli): share styled select prompt helper 2026-02-18 17:48:02 +00:00
Peter Steinberger
b8b43175c5 style: align formatting with oxfmt 0.33 2026-02-18 01:34:35 +00:00
Peter Steinberger
31f9be126c style: run oxfmt and fix gate failures 2026-02-18 01:29:02 +00:00
Sebastian
366da7569a fix(cli): honor update restart overrides 2026-02-17 08:47:25 -05:00
cpojer
d0cb8c19b2 chore: wtf. 2026-02-17 13:36:48 +09:00
Sebastian
ed11e93cf2 chore(format) 2026-02-16 23:20:16 -05:00
Peter Steinberger
ed74f48bd5 refactor(status): share update channel display + one-liner 2026-02-17 00:32:34 +00:00
cpojer
90ef2d6bdf chore: Update formatting. 2026-02-17 09:18:40 +09:00
artale
b1d5c71609 fix(cli): use standalone script for service restart after update (#17225)
The updater was previously attempting to restart the service using the
installed codebase, which could be in an inconsistent state during the
update process. This caused the service to stall when the updater
deleted its own files before the restart could complete.

Changes:
- restart-helper.ts: new module that writes a platform-specific restart
  script to os.tmpdir() before the update begins (Linux systemd, macOS
  launchctl, Windows schtasks).
- update-command.ts: prepares the restart script before installing, then
  uses it for service restart instead of the standard runDaemonRestart.
- restart-helper.test.ts: 12 tests covering all platforms, custom
  profiles, error cases, and shell injection safety.

Review feedback addressed:
- Use spawn(detached: true) + unref() so restart script survives parent
  process termination (Greptile).
- Shell-escape profile values using single-quote wrapping to prevent
  injection via OPENCLAW_PROFILE (Greptile).
- Reject unsafe batch characters on Windows.
- Self-cleanup: scripts delete themselves after execution (Copilot).
- Add tests for write failures and custom profiles (Copilot).

Fixes #17225
2026-02-17 00:00:16 +01:00
Peter Steinberger
dece9e8b07 refactor(update): share package.json readers 2026-02-16 00:41:28 +00:00
Peter Steinberger
02684b913b refactor(cli): split update command modules 2026-02-13 19:08:37 +00:00
0xRain
971ac0886b fix(cli): guard against read-only process.noDeprecation on Node.js v23+ (#14152)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 11bb9f141a
Co-authored-by: 0xRaini <190923101+0xRaini@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Reviewed-by: @steipete
2026-02-12 18:30:14 +01:00