* feat(ui): publish carapace embed font stacks to MCP apps
Adopt the carapace embed contract's sandbox-safe font stacks: publish
--font-sans for the first time and switch --font-mono from the host's
JetBrains-led token to the embed mono stack. Both are static, system-
resolvable values byte-identical to carapace candidate/embed.css, since
the sandbox font-src policy silently drops brand faces.
* feat(ui): emit data-theme-resolved alongside theme attributes
Carapace CSS selects on [data-theme-resolved]; keep it in lockstep with
data-theme-mode at boot (index.html IIFE) and on every runtime theme
change (bootstrap publish path). Rename applyStartupPresentation to
applyThemePresentation: it runs on every theme change, not just startup.
* fix(ui): resolve undefined --success/--warning tokens and drop dead hex fallbacks
--success and --warning were never defined (real tokens: --ok/--warn),
so sites with literal fallbacks rendered off-palette one-off colors and
sites without them silently dropped declarations (invalid color-mix in
the chat sidebar warn banner). Map all uses to the semantic tokens
across board, chat sidebar/layout, layout, and components styles, and
strip the stale dead var() hex fallbacks in these global stylesheets.
Code-syntax palette hexes in the file view are documented as deliberate.
* refactor(agents): validate attestation hashes structurally
* fix(agents): reject Windows reserved device names in attestation filenames
* refactor(agents): close attestation filename set with an ASCII markdown charset
The attachment parser accumulated two parallel message strings via
conditional appends inside the offload loop (all markers vs non-image
markers). Markers are presentation-only now that MediaFact[] carries
identity, so the parser builds one message and the routing decision in
chat-send-attachments projects the image-stripped variant from the
structured offloaded refs (stripImageMediaMarkers) exactly where
routeImageOffloadsAsMediaPaths chose a string before. Marker order,
trailing placement, and trim semantics are byte-identical; goldens
unchanged.
* fix(gmail-setup): skip python interpreters gcloud can't use
resolvePythonExecutablePath accepted the first python3/python found on
PATH without checking its version, so macOS' bundled Python 3.9 (earlier
on PATH than a Homebrew 3.10-3.14 install) was chosen as CLOUDSDK_PYTHON
and gcloud failed to load. Query each candidate's version and skip any
outside gcloud's supported 3.10-3.14 range so a compatible interpreter
later on PATH is selected instead.
Closes#112712
* test(gmail): cover gcloud Python upper bound
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(microsoft-foundry): bound az login device-code subprocess
Add a 5-minute timeout to the az login spawn so a stalled Azure CLI
does not block the caller indefinitely. The timeout kills the child
process and rejects the promise with a descriptive message.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(microsoft-foundry): reject login timeout immediately
* refactor(microsoft-foundry): use shared process timeout
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* feat(sqlite): migrate persisted media to canonical facts and stop legacy writes
PR 3 of the media legacy retirement program — the operator-approved
canonical cutover.
- openclaw doctor --fix owns one idempotent migration: active
transcript_events rows canonicalize to __openclaw.media (facts-first
gap-fill, bare legacy kinds to fact.kind, transcribed indexes and
workspace dirs onto per-fact fields) via the transcript replacement
owner; cold plain/.zst archives rewrite through temp-file + codec
readback + event/id verification + atomic replace; trajectory
runtime snapshots canonicalize IN PLACE (telemetry preserved, never
row deletion). Invalid JSON, genuinely ambiguous legacy-only sparse
alignment, or a changed source aborts that owner without partial work;
reruns are no-ops.
- Per-agent schema advances to v16 as a pure downgrade guard (main
independently took v15 for board/session-sharing tables; no
columns/tables/indexes change here, shared-state DB untouched). v15
databases repair canonical indexes before the version assertion so
repairable installations never strand.
- The user-turn builder stops writing top-level legacy Media* fields;
shouldPersistStructuredMediaEntries and the aligned projection mode
are deleted; the generic transcript append boundary canonicalizes
every message role so SDK/mirror writers cannot mint new legacy rows.
- Internal persisted-reader legacy fallbacks are removed; the public
SDK projection stays until retirement PR 4's window expires.
Hardening from three adversarial review rounds, each with fixture
regressions: in-place trajectory canonicalization instead of row
deletion; repair-before-assert on the v15 path; all-roles append
canonicalization; duplicate-preserving exact row rewrites; v0-v15
reopen guards; complete canonical facts bypass compact legacy
projections (PR-1 dual-write rows migrate cleanly); SQLite LIKE
underscore escaped so populated foreign databases are never claimed.
* fix(sqlite): align schema-support metadata and gates with the v16 cutover
package.json agent schema support advances to 16; verifier and board
parity fixtures run doctor migration before steady-state access (the
production guards were correct); two test-only exports removed; the
migration module registered in the doctor raw-SQLite allowlist.
The runtime retirement already shipped: busy deferral is automatic,
reasoning payloads stay internal, the HEARTBEAT_OK ack budget is fixed at
300 chars, the Heartbeats prompt section follows cadence, and tool-error
warnings are always on. Docs still advertised skipWhenBusy, ackMaxChars,
includeReasoning, includeSystemPromptSection, and suppressToolErrorWarnings
as live options; this aligns seven pages with the fixed policies and the
strict heartbeat field list, locks the claw-profile skipWhenBusy rejection
diagnostic with a dedicated test, renames includeReasoning-era test/comments,
and canonicalizes claw add-plan workspace path assertions (macOS realpath).