* fix(security): fence external hook job name in isolated-agent prompts
buildSafeExternalPrompt wrapped the hook message inside the external-content
boundary but placed the job name on a Task: line above it, unsanitized. The job
name comes from the same hook-controlled configuration or request data as the
message, so a crafted name could inject a forged end-marker and instruction-like
text into the trusted prompt region.
Pass the job name to wrapExternalContent as taskName so it is sanitized and
rendered as a Task: metadata line inside the boundary, matching the sender and
subject handling. Job ID and Received remain in the trusted prefix because they
are OpenClaw-generated.
* fix(security): fence external hook job name in isolated-agent prompts
Move hook-controlled job names into the existing sanitized external-content metadata boundary. Keep generated job IDs and timestamps in the trusted prefix.
Replays and narrows openclaw/openclaw#112501.
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(agents): preserve CRLF line endings in apply_patch update hunks
applyUpdateHunk split file contents on "\n" and rejoined with "\n", so
every line the hunk covered lost its carriage return, including the
context lines the patch declares unchanged. On a CRLF working tree a
one-line patch left a mixed-ending file on disk.
Detect the file line ending, run the hunk matcher on LF-normalized lines,
and restore the original ending on write. The line-ending helpers move
out of the edit tool into src/agents/line-endings.ts so both file-mutating
tools share one implementation.
* fix(agents): avoid normalizing mixed line endings
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(plugin-sdk): add missing thinking stream hooks to provider-stream-family exports
The provider-stream-family subpath was missing re-exports for deprecated
thinking-stream hook constants (MOONSHOT_THINKING_STREAM_HOOKS,
GOOGLE_THINKING_STREAM_HOOKS, KILOCODE_THINKING_STREAM_HOOKS,
MINIMAX_FAST_MODE_STREAM_HOOKS, OPENROUTER_THINKING_STREAM_HOOKS,
TOOL_STREAM_DEFAULT_ON_HOOKS) that are defined in provider-stream.js.
This caused @openclaw/moonshot-provider to fail at load time with:
SyntaxError: does not provide an export named 'MOONSHOT_THINKING_STREAM_HOOKS'
Fixes#115580
* test(plugin-sdk): preserve provider stream family exports
* test(plugin-sdk): cover provider stream compatibility exports
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(ui): rename the Memory Palace browser to Memory Wiki and document it
* refactor(memory-wiki): drop the old memory-palace module files
* docs: refresh generated docs map
* test(ui): align dream-diary hub-tab assertion with the wiki sub-tab id
* docs: describe memory wiki clustering behavior accurately
* docs(memory-wiki): record the wiki.overview rename decision at the registration site
* test(ui): query the Agents channels hub tab by tab role after the hub-tabs refactor
* fix(tlon): stop reconnecting after SSE client close
* fix(tlon): cancel SSE reconnect timers when monitoring stops
Preserve the original Tlon SSE reconnect fix while canceling both retry timers at stopReceiving(), the real monitor shutdown boundary.
Verified against an authenticated, SSRF-guarded loopback SSE server; both reconnect waits settle immediately without changing replay, close cleanup, or uninterrupted reconnection.
Co-authored-by: wahaha1223 <0668001153@xydigit.com>
* fix(tlon): prepare conflict-free reconnect refresh
Prepare a conflict-free refresh of the original Tlon SSE shutdown correction without changing its ownership or losing the contributor commit.
Co-authored-by: wahaha1223 <0668001153@xydigit.com>
* fix(tlon): cancel reconnect timers when monitoring stops
Cancel both Tlon SSE reconnect waits at stopReceiving(), the monitor-owned shutdown boundary, while preserving guarded HTTP, durable same-channel replay, and the original contributor's fix.
Verified with authenticated loopback SSE, both real retry delays, normal reconnection, all 252 Tlon tests, extension type checks, lint, and focused owner regressions.
Co-authored-by: wahaha1223 <0668001153@xydigit.com>
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* feat(gateway): add loopback locality controls
* fix(gateway): keep loopback auth delays enforced under concurrency
The pending-timer cap let an attacker park cheap failures in every slot and then guess without penalty. Delays now key off a per-key deadline, so parallel guesses wait out the same escalating penalty and are still bounded by the max delay.
* fix(gateway): share one loopback penalty timer per key
Concurrent failures on a key now share a single timer and deadline instead of allocating one per in-flight request. Also corrects the security doc: the delay raises the cost of repeated guessing from one source, but credentials are compared before the failure response is delayed, so it is not a defense against parallel fan-out.
* docs(gateway): record why loopback delay stays post-verification
* docs: refresh generated docs map
* docs: refresh plugin SDK API baseline
* test: update loopback locality CI expectations
* fix(cron): prevent stalled schedules and lost heartbeat work
* fix(heartbeat): preserve global task wake flush barriers
* fix(cron): canonicalize symlinked store locks
* refactor(config): move model normalization to input owners
* fix(config): merge canonical doctor model rows
* fix(config): align touched model map identities
* ci(env): lower production variable budget
* chore: leave changelog to release automation
* fix(agents): keep subagent run ID mask from splitting UTF-16 surrogate pairs
* fix(agents): drop unnecessary export on run ID mask and test through warnings
* test(agents): avoid String(unknown) in run ID mask warning capture
CI check-lint (oxlint typescript/no-base-to-string) rejects String() on an
unknown-typed field; the toMatchObject assertion above already pins the
shape, so read runId as a string field directly.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(agents): refresh Unicode run-id contributor baseline
Restore the original run-id lifecycle files to the reviewed upstream baseline before preserving the contributor branch and applying the verified Unicode fix.
Co-authored-by: chengzhichao-xydt <cheng.zhichao@xydigit.com>
* fix(agents): preserve Unicode subagent run identities
Preserve valid Unicode run identifiers through subagent lifecycle masking and prove authenticated plugin Gateway admission, registry tracking, and idempotent retries.
Co-authored-by: chengzhichao-xydt <cheng.zhichao@xydigit.com>
---------
Co-authored-by: chengzhichao-xydt <chengzhichao-xydt@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
fix(accessibility): restore web view navigation and layout-aware shortcuts
* commit 'fd28cd3becfded364107f236f526b08422f8ebab':
fix(ui): support shortcuts on non-Latin keyboards
fix(macos): enable keyboard navigation in web views
* fix(ai): tool calls fail when an unsupported schema keyword is nested
The strip walked only properties, items, anyOf, oneOf and allOf, copying every
other value through untouched. A keyword the model rejects therefore survived
inside additionalProperties, prefixItems, patternProperties, contains,
propertyNames, not, if/then/else, dependentSchemas and $defs, and the request
was refused by the provider even though the strip reported success.
Walk the same containers the caller already enumerates in
agent-tools-parameter-schema.ts.
* fix(ai): cover all nested schema containers
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>