* fix(crabbox): preserve UTF-16 boundaries in CLI failure detail truncation
commandDetail replaced raw .slice(0, MAX_ERROR_DETAIL_CHARS) with
truncateUtf16Safe on the whitespace-compressed error detail output.
A 511-code-unit prefix with an emoji at the boundary produces a lone
high surrogate (U+D83D) on current main; the shared surrogate-aware
helper backs the cut up to preserve well-formed UTF-16.
* fix(crabbox): add provider-path UTF-16 regression test for inspect boundary
The existing test exercised commandDetail directly; ClawSweeper's P1
requires proof through the real provider boundary. The new test calls
provider.inspect() with a CLI runner that returns 511 ASCII + emoji in
stderr, proving commandDetail → truncateUtf16Safe works through the
full inspect → commandError → commandDetail chain.
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor(crabbox): keep error proof on provider path
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* improve(pr): trust origin/main-matching wrappers when the canonical checkout is parked elsewhere
* improve(crabbox): hint at lease expiry when reused-lease runs fail fast
* fix(pr): pin the wrapper trust anchor to the remote-tracking ref
* feat(sessions): durable session state events with parent invalidation
Parents no longer act on stale child-session state: a durable, typed
signal log (session_state_events + per-agent heads) records direct human
messages to children, child spawn/terminal outcomes, goal changes, and
compaction at the seams where those facts are created. A frozen-watermark
cursor protocol (session_watch_cursors) delivers one coalesced system
notice to the parent through the existing system-event + heartbeat wake
idiom, acknowledged at the shared generic drain, with a deferred startup
sweep for restart recovery. session_status gains stateVersion and
changesSince (with exact pruned-history gap signaling); sessions_list
rows gain stateVersion.
Closes#104565
* chore: regenerate docs map and prompt snapshots for session_status changesSince
* fix(outbound): preserve backticks on <code> tags with attributes
The plain-text sanitizer only matched bare <code> openers, so attributed
variants such as <code class="language-ts"> lost their backtick wrapping
and were stripped to raw text before channel delivery.
Allow optional attributes on the opening <code> tag, consistent with the
existing handling for <h[1-6]> and <li> in the same function.
Fixes#104117
* fix(outbound): preserve attributed inline formatting
Co-authored-by: chengzhichao-xydt <chengzhichao-xydt@users.noreply.github.com>
* test(outbound): compact attributed tag coverage
* fix(outbound): normalize attributed formatting tags
* docs(outbound): clarify attribute normalization invariant
* fix(outbound): preserve native formatting semantics
* docs(plugin-sdk): document sanitizer markup styles
* docs(plugin-sdk): refresh docs map
---------
Co-authored-by: moguangyu5-design <moguangyu5-design@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: chengzhichao-xydt <chengzhichao-xydt@users.noreply.github.com>
* feat(tooling): extend strict-ratchet lane to all remaining leaf packages
* fix(packages): burn down indexed-access debt in ai and agent-core
All 196 noUncheckedIndexedAccess errors fixed behavior-identically
(iteration, .at()/slices, DataView byte math, guarded queue peeks) plus
cleanup finds: a sparse-tool diagnostic bug, deduplicated Responses
call/item ID parsing with an honest string|undefined splitter, and a
clearer local failure for redacted-thinking blocks missing signatures.
Removes all 17 remaining non-null assertions across ai, gateway-client,
and llm-core so the assertion ban aligns 1:1 with the ratchet lane.
speech-core joins memory-host-sdk as structurally deferred (imports
src/** via plugin-sdk path mappings).
* feat(fleet): add openclaw fleet cell supervisor for multi-tenant hosting
* test(fleet): cover cell profile, registry, containers, and service flows
* docs(fleet): document multi-tenant hosting and the fleet CLI
* fix(fleet): verify upgrade replacements and release foreign-collision reservations
* fix(fleet): gate upgrade commit on replacement health
* docs(fleet): mark fleet experimental and pin its single-host scope
* test(fleet): make incomplete-profile casts explicit for test-type lane
* fix(state): regenerate kysely schema artifacts after rebase conflict
* fix(gateway): allow macOS app platform version refresh without re-pairing
When macOS updates (e.g. 26.5.0 → 26.5.1), the Mac app detects a
platform mismatch against its paired record and sends a repair request.
The approval dialog enters an infinite loop because the pending request
TTL (5 min) expires before the user clicks Approve, causing "unknown
requestId" errors that trigger a new repair request ad infinitum.
iOS and Android already had silent platform version refresh via
normalizeMobileAppPlatformPin — this extends the same treatment to the
macOS native app by recognizing "macos X.Y.Z" as the same platform
family regardless of version, renaming the helper to
normalizeNativeAppPlatformPin.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(gateway): validate macOS platform version refreshes
* fix(gateway): avoid native platform family marker collisions
* test(gateway): type node client name
---------
Co-authored-by: 骆毅 <luoyifu.lyf@digital-engine.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(file-transfer): audit dir fetch archive size
* test(file-transfer): guard dir fetch audit archive test on Windows
* test(file-transfer): format dir fetch audit guard
* fix(file-transfer): verify directory archive audit metadata
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>