* fix(gateway): record workspace recovery failures
Persist bounded, deduplicated recovery-attempt failures through the session transcript while preserving pending workspace result fences, and prefer current recovery errors over stale terminal reasons.\n\nRefs #128850
* fix(gateway): revalidate recovery transcript ownership
Recheck the canonical session mapping inside the queued transcript transaction so a rebound session cannot receive a stale workspace recovery diagnostic.\n\nRefs #128850
* fix: prevent dollar-pattern injection in prompt template and approval substitution
Three call sites used String.replace/replaceAll with a string replacement
fed a runtime variable, causing dollar-amp/dollar-1/dollar-backtick
sequences in user-supplied args or approval ids to corrupt the rendered text.
Switch each to a function replacement so the value is treated literally:
- prompt-template-arguments: dollar-ARGUMENTS and dollar-@ substitution
corrupted slash-command args containing dollar signs
- get-reply-inline-actions: bundle command template expansion had the
same issue with normalizedArgs
- approval-reaction-runtime: approval id placeholder rendering mangled
ids containing dollar signs; the iMessage sibling
(extensions/imessage/src/approval-text.ts) already escapes this
* fix: rebase, drop unproven approval rewrite, add dollar regression
Address review: the approval placeholder helper has no canonical
/approve <id> producer in the plugin-SDK manual fallback path, so its
rewrite is unproven - revert it. Keep the two reachable prompt-template
fixes and add an owner-boundary regression covering literal dollar
sequences in dollar-ARGUMENTS and dollar-@ substitution (fails on the
old string replacement form, passes with the callback form).
* test(auto-reply): cover literal dollar bundle command arguments
* fix(agent-core): resolve prompt placeholders in a single substitution pass
* fix(cli): image-heavy Claude CLI turns abort after about fifteen screenshots
The Claude CLI emits every image tool result twice in its stream-json
output: once inside `message.content[].tool_result.content[]` and once in
the `tool_use_result` field it echoes alongside the message. The
normalizer added in #119486 only walks the message copy, so the echoed
copy still counts against the 8 MiB per-turn raw-output budget and is
still retained in the live-turn line buffer.
Walk the whole parsed user record instead, so both copies are stubbed,
and cover the `tool_use_result.file.base64` shape the built-in image
read echoes. openclaw never reads `tool_use_result` (no references in
src), so nothing downstream changes.
[AI-assisted]
* fix(cli): make echoed-payload normalization stack-safe
Addresses the review finding on the recursive walker. The normalizer now
lives in its own module as one canonical entry point, walks the record
iteratively with an explicit stack, and falls back to raw accounting when
a record is too deeply nested for `JSON.stringify` to re-serialize.
Adds a 50,000-deep regression record, built as text because
`JSON.stringify` itself cannot serialize one that deep.
[AI-assisted]
* fix(cli): normalize Agent SDK REPL binary echoes
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(update): make managed handoff own successor
Park the exact native service before Gateway close and coalesce same-root handoff requests so only the detached updater can activate and restart.
* refactor(update): reuse restart ownership helpers
* test(gateway): isolate supervisor restart fixtures
* fix(update): cancel handoff before restart fallback
* fix(update): harden managed service handoff
* fix(update): use canonical SQLite opener
* fix(update): preserve lifecycle runtime boundaries
* feat(ui): configure capabilities before session start
Reuse the active-chat Plus menu on new sessions, move Draft into it, and persist admin-scoped tool overrides before the initial turn. Closes#128079.
* test(ui): follow new-session Draft menu
* refactor(ui): reconcile new-session capability ownership
* fix(ui): gate terminal launch on capability overrides
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
---------
Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(node-host): retry worker supervisor initialization
Clear failed initialization ownership for retry, retain valid container supervisors after transient reconciliation errors, and retry from the runtime until capacity becomes authoritative or shutdown cancels the lifecycle.\n\nRefs #128794
* fix(node-host): preserve permanent container mismatch failures
Keep durable engine and daemon-context mismatches on the actionable disabled path while retrying only transient supervisor reconciliation failures.\n\nRefs #128794
* fix(node-host): withdraw hosting on late context mismatch
Stop retrying when a later reconciliation attempt proves a permanent container context mismatch, close the supervisor, and withdraw worker hosting from runner inventory.\n\nRefs #128794
Preserve native provider commentary as keyed progress items across live delivery and history reloads while keeping cursor pagination reachable.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Queue Telegram-visible Mantis proofs at workflow level so only one shared-user run allocates a runner at a time.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>