* fix(scripts): bound tsgo runs with the managed-command watchdog
run-tsgo bypassed the repo's managed-command seam and called spawnSync
directly, so a wedged tsgo blocked its caller indefinitely: no timeout, no
process-group cleanup, and no SIGKILL escalation.
Observed in the wild as a tsgo holding 2.85 GB for 90+ minutes on 41s of
total CPU with RSS frozen to the byte, ignoring SIGTERM, with its wrapper
reparented to init. Because shouldReclaimLock() treats a live PID as a valid
lock owner, that orphan also held the heavy-check lock until every other
invocation hit the 10-minute lock timeout and threw.
Route the run through runManagedCommand, which already owns process-group
termination and SIGKILL escalation on timeout, and bound it with
OPENCLAW_TSGO_TIMEOUT_MS (default 45m) through the shared readPositiveEnvInt
helper, mirroring OPENCLAW_CLI_STARTUP_BUILD_TIMEOUT_MS in
ensure-cli-startup-build.mts.
* fix(scripts): saturate the tsgo watchdog at Node's timer ceiling
An OPENCLAW_TSGO_TIMEOUT_MS above 2147483647 reached setTimeout unchanged,
where Node collapses it to a 1ms delay, so raising the override killed
healthy typechecks immediately instead of loosening the bound.
* fix(scripts): make the tsgo watchdog opt-in and stop the harness leaking
ClawSweeper review on 6ba02c9d0a raised two findings.
[P1] The 45-minute default applied an unproven deadline to every tsgo
invocation. No supported duration contract covers every host and project, and
CI already bounds its own tsgo jobs at 15-20 minutes, so the default could only
ever fire outside CI where it was least validated. Drop it: an unset
OPENCLAW_TSGO_TIMEOUT_MS keeps the pre-existing unbounded wait, so no existing
run changes behavior, and operators opt in per host. Documented in
docs/help/testing.md beside the sibling Vitest watchdog.
[P2] The regression harness could leak its wedged child. The fake compiler
ignores SIGTERM by design, so a pre-fix or otherwise failing run left the tree
running after spawnSync gave up. Bound the fixture's loop as a backstop.
* fix(scripts): set the tsgo watchdog default from measured lane duration
ClawSweeper on c7a699ee82 reversed its earlier guidance: the opt-in default
adopted last iteration "deliberately preserves the indefinite tsgo hang that
this PR is meant to fix". Its objection was never that a default existed, only
that 45 minutes was unmeasured.
Measured instead of guessed: hosted tsgo lanes (check-test-types, and its core
stripes) complete in 1-2 minutes across recent successful main runs, against CI
job caps of 15-20 minutes. 30 minutes is 15-30x the observed duration, leaves
room for a far slower local host, and still bounds the 90-minute and multi-hour
wedges that motivated this PR. OPENCLAW_TSGO_TIMEOUT_MS remains the documented
override for hosts that need longer.
* test(scripts): reap the wedged fake tsgo tree on the harness outer timeout
ClawSweeper on 0d9f3604e8 flagged that the harness can still leave a detached
pre-fix process tree alive after its outer timeout. The bounded fixture loop
added earlier only capped the leak; it did not terminate the tree.
spawnSync's killSignal reaches the direct child only. runManagedCommand spawns
the compiler detached into its own process group, so the fake tsgo is a
grandchild that never receives that signal. The fixture now records its pid and
the harness reaps that group in a finally, with the bounded loop kept as a
last-resort backstop.
Verified: pid file written with the live pid, and killing that group terminates
the tree; focused suite 16/16 with no surviving fake-tsgo processes.
* fix(scripts): harden the tsgo watchdog after two-phase code review
Review fixes on top of the watchdog change, from one native pass and six cold
passes:
- A rejected OPENCLAW_TSGO_TIMEOUT_MS escaped main() as a raw module rejection.
It now reports one actionable line and exits 1. Strict validation was kept
rather than switching to coercion, so a typo cannot silently fall back to the
30-minute default.
- The rejection message named a numeric range while the parser enforces plain
decimal digits, so 1e5 and 007 were refused by a message saying they
qualified. It now names the real format and states that the watchdog cannot
be disabled.
- The timer ceiling is declared locally rather than imported from packages/.
A static import there resolves before the sparse-checkout guard runs, which
turned a clean sparse skip into ERR_MODULE_NOT_FOUND and flipped
check-changed's typecheck lane from exit 0 to exit 1.
- The wedge test asserted the kill message but not the outcome; it now captures
the wedged pid and asserts the process group is gone.
- Three near-duplicate "not killed" cases are table-driven.
- Doc bullet corrected: values ABOVE the ceiling saturate at it, and the
rejected-value list now includes non-decimal input.
Deferred follow-up, not fixed here: scripts/lib/tsx-cli-shim.mjs shares a
5000ms force-kill delay with managed-child-process, so Ctrl-C can still orphan
a wedged compiler about one run in three. Measured base 4/4 orphaned versus
4/10 here, so this change improves it; the fix is out of diff and shared with
four other wrappers.
* fix(scripts): close tsgo signal cleanup race
* fix(scripts): make tsgo watchdog opt-in
---------
Co-authored-by: ClawSweeper <steipete+clawsweeper@gmail.com>
Give maintainers immediate visibility when Mantis is requested. Bare mentions now react, link the active run, and keep one run-owned status comment through proof, short-circuit, or failure.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Add trusted ClawSweeper-label and maintainer-comment dispatch for Mantis Telegram proof. Short-circuit non-visible PRs before desktop setup while preserving exact-head, fork, credential, and comment-ownership boundaries.
User-facing name is now OpenClaw (the system speaks); internal code name is
system-agent. Gateway methods crestodian.* -> openclaw.chat/openclaw.setup.*,
agent tool -> openclaw, reserved agent ids openclaw + retired crestodian.
openclaw setup routes: onboarding flags -> onboard, -m/--yes -> system agent,
bare configured interactive -> OpenClaw chat, unconfigured -> onboarding.
Hidden crestodian CLI and /crestodian TUI aliases kept; docs moved to
docs/cli/openclaw.md with redirect stub. macOS/Android strings in lockstep.
Refs #107237
* test: wire Control UI suite into CI, fix its broken tests, drop dead harness surface
- fix 7 Control UI tests broken on main: module-mock factories are unreliable
under isolate:false shared workers; use RealtimeTalkSession prototype spies
and real jsdom storage instead (chat-realtime, chat-pull-requests)
- add gated checks-ui CI job (runUiTests changed-scope output): chromium
provisioning, lint:ui:no-raw-window-open, pnpm --dir ui test; ~30s on a
4vcpu runner, runs only when ui-affecting paths change
- add weekly node22-compat workflow exercising the supported lower Node bound
with the same command set as the dispatch-only ci.yml job
- delete the unreachable channels entry in EXTENSION_TEST_CONFIG_ROUTES and
the never-populated extensionRoutedChannelTestFiles override machinery
(born empty in 2ccb5cff22); resolved globs are provably identical
- guard run-vitest.mjs hardcoded path maps with existence tests so renames
cannot silently drop extended stall watchdogs
- remove unenforced coverage thresholds; test:coverage is informational, docs
updated (reference/test, help/testing, plugins/sdk-testing)
Closes#104321
* test: pin OPENCLAW_CI_RUN_UI_TESTS in the manifest env expectation
* test(ui): capture the realtime start spy instead of referencing the unbound prototype method
* test(ui): raise ui vitest timeouts for real-browser layout tests on small CI runners
Summary:
- The branch adds `useAutoCleanupTempDirTracker()`, broadens the temp-dir warning reporter to flag new manual helper imports/usages, updates docs, and migrates two script tests to the new helper.
- PR surface: Tests +301, Docs +1, Other +248. Total +550 across 8 files.
- Reproducibility: not applicable. this is test/tooling cleanup, and the changed behavior is exercised through helper/reporter tests and CI evidence rather than a user reproduction path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: test: harden temp dir helper guard
- PR branch already contained follow-up commit before automerge: test: clarify auto cleanup temp dir helper name
- PR branch already contained follow-up commit before automerge: test: cover existing mkdtemp temp dir forms
- PR branch already contained follow-up commit before automerge: test: read staged temp helper source from index
Validation:
- ClawSweeper review passed for head 1fdd7d2a9a.
- Required merge gates passed before the squash merge.
Prepared head SHA: 1fdd7d2a9a
Review: https://github.com/openclaw/openclaw/pull/93209#issuecomment-4705653665
Co-authored-by: Mason Huang <masonxhuang@tencent.com>
Approved-by: hxy91819
* fix: harden package URL downloads
Guard package acceptance URL downloads with HTTPS-only validation, no embedded credentials, private/special-use DNS and IP rejection, manual redirect checks, bounded timeout/size limits, pinned lookup, and atomic temp-file writes. Add tooling tests for unsafe URLs, redirect validation, size limits, and successful writes.
* fix: cancel redirect response bodies before closing dispatcher
ClawSweeper P2: the redirect branch in openPackageDownloadResponse cleared
the timeout and awaited dispatcher.close() without first cancelling
response.body. Undici's close() is graceful — it waits for in-flight
requests to complete — so a malicious redirect with a slow/never-ending
body could hang the hardened downloader.
Fix: call response.body?.cancel() before dispatcher.close() to abort the
redirect body immediately.
Test: add a regression test that uses a ReadableStream with an indefinite
interval to simulate a hanging body, and asserts cancel() was called.
Refs: clawsweeper review on PR #85512
* test: harden redirect body cancellation race in regression test
Guard the ReadableStream controller.enqueue() call with a cancelled
flag and try/catch to prevent ERR_INVALID_STATE when the interval
fires after cancel() closes the controller.
* fix: cancel final response body before closing dispatcher in downloadUrl
ClawSweeper P2: the HTTP-error and declared-oversize early-exit paths
in downloadUrl threw before consuming or canceling response.body. The
finally block then cleared the timeout and awaited graceful
dispatcher.close() with the body still open, allowing a slow/never-ending
response to hang release tooling.
Fix: add response.body?.cancel() in the finally block before
dispatcher.close().
Tests: add two regressions:
- HTTP 500 with slow body: asserts cancel() called before dispatcher close
- Declared content-length oversize with slow body: same assertion
* fix: add trusted package URL source policy
* fix: keep package URL resolver dependency-free
* test: cover encoded IPv6 package URL bypasses
* docs: sync package acceptance source overview
* docs: restore release doc formatting
* docs: sync package acceptance trusted-url source
* test: cover dotted IPv4 embedded IPv6 package URLs
* fix: parse dotted IPv4 embedded in IPv6 package URLs
* test: isolate anthropic pruning defaults
* test: move anthropic dated model coverage
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary:
- This PR routes bare `openclaw` to classic onboarding for missing, empty, or metadata-only configs; keeps aut ... cs/changelog/tests; and narrows a Docker E2E boundary-check exception for an existing source-checkout lane.
- Reproducibility: not applicable. this is a feature/default-routing PR rather than a bug report. The branch p ... ill includes a fresh-state terminal run reaching `OpenClaw setup` and tests for the relevant config states.
Automerge notes:
- PR branch already contained follow-up commit before automerge: feat: start onboarding for fresh CLI installs
Validation:
- ClawSweeper review passed for head f4b2572f2e.
- Required merge gates passed before the squash merge.
Prepared head SHA: f4b2572f2e
Review: https://github.com/openclaw/openclaw/pull/85519#issuecomment-4522938004
Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>