* fix(cli): show exit code when npm install returns empty output
installPackageDir previously produced 'npm install failed:' with an empty
suffix when npm exited non-zero without writing to stdout or stderr. Users
running 'openclaw plugins install @openclaw/acpx' saw only that empty line
followed by the misleading hook-pack fallback error, leaving nothing
actionable in the output.
Add a small helper that keeps npm's own output when it exists but falls
back to reporting the exit code, signal, and termination reason when both
streams are empty. Regression tests cover the empty-output exit case and
the signal-terminated case; the existing stderr surfacing test still
passes unchanged.
Refs #98484
* fix(cli): narrow npm install failure diagnostics
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(slack): guard relay WebSocket frame JSON.parse against malformed input
Slack Socket Mode relay receives WebSocket frames from external
infrastructure. parseRelayFrame() used bare JSON.parse() which would
throw raw SyntaxError on malformed frames, potentially crashing the
relay connection.
Wrap JSON.parse in try/catch and throw SlackRelayMalformedFrameError
with the original SyntaxError as cause, so callers can distinguish
transport errors from parse errors.
D4 dimension — all competitors have zero coverage.
Signed-off-by: lsr911 <liao.shirong@xydigit.com>
* fix(slack): repair relay frame guard tests
---------
Signed-off-by: lsr911 <liao.shirong@xydigit.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Preserve the Tailscale timeout cleanup from #98134 and the Feishu TDZ fix from #98137 while satisfying the repository lint rules.
Credit: @zhangLei99586 authored both underlying fixes.
Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
Co-authored-by: zhangLei99586 <zhang.lei162@xydigit.com>
5.22 already drops the tool-error WARNING text via payloads.ts, but the
error tool-result payload was still delivered as channel progress unless
sourceReplyDeliveryMode was message_tool_only. Operators who opt into
messages.suppressToolErrors expect no tool-error noise in chat at all.
Add a config-gated early-return in the onToolResult dispatch path so the
visible progress delivery is dropped too, matching the warning-text policy.
No-op unless messages.suppressToolErrors is true. Folds the mac-mini deploy
hotfix into the tracked branch.
(cherry picked from commit a973410e6d3ddbbaa4c3fb308ad4247274a9633a)
Co-authored-by: amittell <mittell@me.com>
The checkBinary helper used Promise.race with a setTimeout-based timeout
but never cleared the timer when runExec completed first. Wrap the race
in a try/finally that clears the timer handle to avoid a dangling timer.
The finish() closure referenced timer which was declared with const after
finish was defined. If finish(false) ran via the abort signal check at
line 99 or via the abort event listener before the const timer assignment,
accessing timer in the temporal dead zone would throw a ReferenceError.
Hoist timer as a let binding above finish so it is safely undefined when
finish fires early, and the guard in finish handles it.
* fix(matrix): bound raw transport response reads to prevent OOM
* test(matrix): add real node:http server proof for bound transport
Two new integration-style tests drive performMatrixRequest against a real
node:http server (no stubRuntimeFetch mock) using real undici + SSRF
dispatcher and ssrfPolicy.allowPrivateNetwork:
- over-cap: server declares Content-Length > MATRIX_SDK_RESPONSE_MAX_BYTES
with maxBytes omitted → rejects MatrixMediaSizeLimitError (68 ms wall)
- under-cap: server returns small payload with maxBytes omitted → Buffer
returned correctly (12 ms wall)
Addresses ClawSweeper feedback: previous proof showed only Vitest mock
output; these tests exercise the real Matrix runtime fetch path end-to-end.
* test(matrix): satisfy lint for transport proof
* fix(matrix): preserve encrypted media download limits
* test(matrix): add streaming OOM guard proof via real node:http server without Content-Length
Drive readResponseWithLimit directly by omitting Content-Length so that
enforceDeclaredResponseSize is a no-op and the streaming byte cap is the
sole enforcement path. A 20 MiB chunked server response with a 16 MiB
cap confirms the stream is canceled before full buffering (chunksWritten
< TOTAL_CHUNKS). A second case verifies under-cap payloads pass through.
* test(matrix): fix lint errors in real HTTP server proof (curly)
* test(matrix): add under-cap proof to real HTTP server test
An IRC sender mask is nick!user@host where only host is server verified;
nick and user (ident) are client supplied and spoofable. The allowlist
identity classifier treated any entry containing "!" or "@" as a verified
stable identity, so a host-less nick!user entry was classified stable and
matched by the host-less nick!user subject candidate. With
dangerouslyAllowNameMatching at its secure default (off), the mutable
identifier policy only strips entries owned by a dangerous field, so the
host-less entry was never stripped and a remote sender presenting the same
nick and ident was admitted regardless of host.
Require a verified @host component before an entry or subject is classified
stable. Host-less nick and host-less nick!user are now both routed to a
dangerous (mutable) field so they are gated by the same name-matching policy.
The doctor mutable-allowlist detector now also flags host-less nick!user
entries so operators who typed that undocumented shape get a warning. The
documented full nick!user@host mask stays stable and unaffected.
* fix: #94432 classify Cloudflare challenge 403 as upstream_html instead of auth_html
* chore: trigger CI re-run for Real behavior proof validation
* fix: align Cloudflare challenge detector with shared challenge markers
Extend CLOUDFLARE_CHALLENGE_RE to also match cdn-cgi/challenge-platform
and challenge-error-text — patterns already recognized by the shared
STANDALONE_HTML_ERROR_HINT_RE in assistant-error-format.ts.
Add regression tests for both new marker variants to ensure coverage.
* fix(embedded-agent): suppress raw Cloudflare HTML in console after upstream_html reclassification
- Add upstream_html to RAW_ERROR_CONSOLE_SUPPRESSED_FAILURE_KINDS so
Cloudflare challenge 403 pages classified as upstream_html do not
leak raw HTML into lifecycle/failover console rawError= diagnostics
- Add regression test verifying upstream_html suppression in
failover observation console messages
Re: #94432
---------
Co-authored-by: lzyyzznl <lzyyzznl@users.noreply.github.com>
Co-authored-by: lizeyu-xydt <lizeyu@xydigit.com>
* fix(message-tool): apply messages.responsePrefix to outbound sends
* fix(message-tool): interpolate responsePrefix templates on sends and skip unresolved model tokens
* fix(agents): skip implicit provider discovery when models.mode is 'replace' [AI-assisted]
resolveProvidersForModelsJsonWithDeps unconditionally awaited the implicit
provider resolver before honoring models.mode. With mode: 'replace' the user
opts out of discovery, so add a 3-line early-return guard that returns only the
explicit providers — eliminating the (slow) discovery pass for replace-mode.
Closes#66957.
AI-assisted contribution.
* chore: re-trigger CI (transient checkout/flaky core-check failures + cancelled gates; no code change)