* feat: add session discussion panel seam
* fix: keep discussion iframe cookie-capable and changelog release-owned
* test: cover cookie-capable discussion iframe sandbox
* fix: stretch discussion panel host so the embed fills the rail
* fix: keep provider failures retryable and probe discussion availability before showing the action
* fix: block same-origin discussion embeds, show action on catalog sessions, close stale panel on reconnect
* fix: scope discussion probes and panel callbacks to the issuing connection
* fix: dedupe in-flight discussion probes per session
* fix: retry superseded discussion probes and key-scope panel results
* fix: regenerate Swift protocol models and extend advertised-method expectations
* style: format chat-pane-header
* fix: regenerate Kotlin protocol models and date discussion methods in the 2026.7 train
* chore: restore release-owned changelog to main state
* chore: keep changelog untouched relative to merge-base
* feat(agents): authoritative write diffs end to end
The write tool now reports what actually happened: no-op (changed:false),
created files (created:true with a bounded numbered diff), and overwrites
(created:false with a real old-to-new diff when the old content is
readable text within byte, line, and edit-distance budgets — unknown
removals are never fabricated). The gateway history projection forwards
the changed/created flags, the web and iOS write rows prefer the
authoritative diff and suppress the +N -0 stat when creation is not
proven, and the iOS transcript cache persists one bounded apply_patch
envelope so patch diffs survive cold opens.
* chore(i18n): sync native inventory
* feat(clients): adopt model controls, session management, and keyboard history recall on iOS
* chore(i18n): translate iOS adoption strings and realign locale artifacts
* refactor(clients): drop test-only group response inits flagged by the shared dead-code intersect
* chore: retrigger ci
* chore(i18n): resync inventory after voice-unification main rebase
* chore(i18n): resync inventory after main rebase
* chore(i18n): resync inventory after main rebase
* chore(i18n): realign locale artifacts after main rebase
* fix(clients): preserve native chat API and locale copy
* fix(ios): retain public session DTO initializers
* refactor(clients): delete test-only session DTO inits flagged dead instead of suppressing
* feat(chat-ui): tool-diff follow-ups from PR review
Persist bounded applied-diff details in the transcript cache so cold
opens keep inline diffs; parse apply_patch envelopes into per-file diff
sections with stats; thread tool-result isError so failed calls suppress
proposal diffs and read as failures; replace per-line truncation with
horizontal scrolling for long diff lines.
* chore(i18n): sync native inventory for tool-diff follow-ups
* fix(chat-ui): render move-only patches and drop zero diffstats
* feat(chat-ui): inline diffs for edit and write tool rows
Port the web Control UI's kind-aware diff rendering to the shared SwiftUI
tool rows: persisted details.diff parses into numbered add/del/ctx lines,
edit/write/text-editor args fall back to a local capped line diff, the
collapsed row shows a +N/-M diffstat, and the expanded surface renders the
diff with the result summary or error diagnostic beneath it.
* fix(chat-ui): preserve tool-result details through message reconciliation
Canonical-adoption rebuilds enumerated message fields and silently dropped
details, so inline diffs vanished after cache-warm history reconciliation
(every app relaunch). Carry details through adoptingCanonicalMessage and
messageWithTimestampIfNeeded and lock it in with regression tests.
* chore(i18n): sync native inventory for tool diff rows
* fix(chat-ui): render diffstat and line numbers as verbatim text
* fix(chat-ui): use theme tokens for diff colors
* refactor(chat-ui): drop test-only parseDetailsDiff wrapper
* fix(chat-ui): address diff-row review findings
Interpret details.diff only for edit/write/patch tool names so plugin
detail schemas stay opaque; number write previews from line 1 with an
80-line cap and a subtractive char budget while keeping the exact stat;
bound per-line rendering to 2000 unicode scalars; announce add/del rows
and collapsed skip markers to assistive tech.
* chore(i18n): sync native artifacts for diff-row labels
* fix(chat-ui): announce diff line numbers to assistive tech
Live-append voice transcripts into the agent session and persist a per-agent SQLite call record across relay and client transcript paths.
Add run-scoped spoken confirmation for high-impact actions, mutation digests, bootstrap-context injection, talk.client.transcript and talk.client.close protocol methods, and Control UI adoption. This adds zero new configuration.
Co-authored-by: Clifton King <clifton@users.noreply.github.com>
* feat(apple): copy or save rendered widgets as images from the chat transcript
* chore(i18n): regenerate native locale artifacts for widget export strings
* chore(i18n): resync native locale artifacts after main i18n advance
* feat(macos): add Quick Chat power features
* docs(macos): document Quick Chat power features
* chore(i18n): refresh native locale artifacts for Quick Chat power features
* fix(macos): update DEBUG test helper sendProvider to the reasoning-threaded arity
Add optional per-job pacing bounds across the cron API, CLI, tool schema, public output, and SQLite job envelope, requiring at least one bound. Allow only the currently running paced job to record a one-shot next_check proposal and carry it through isolated-run completion.
After successful runs, clamp the proposal to the job bounds and persist an exact one-shot slot marker so maintenance preserves only that timestamp. Clear the marker on runs, edits, and schedule normalization; preserve existing no-proposal, skip, timeout, and error scheduling behavior.
* feat(webchat): reply-to a message with hydrated reply context
Control UI replies now carry the target transcript id as replyToId on
chat.send. The Gateway resolves the replied-to message from session
history and hydrates the channel-agnostic ReplyToId/ReplyToBody/
ReplyToSender envelope fields, so agents receive reply_to_id,
has_reply_context, and the untrusted reply-target block exactly like
Discord replies (mirrors #90263). Reply targets without a persisted
transcript id keep the inline-quote fallback.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(webchat): keep non-reply chat.send dispatch ordering and satisfy CI gates
* docs(webchat): match reply-context doc to webchat conversation-info policy
* fix(webchat): hydrate reply bodies from display-visible content only
---------
Co-authored-by: openclaw-clawsweeper[bot] <openclaw-clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>
* refactor(chat-ui): render tool calls as flat expandable rows
Replace the nested ToolCallCard/ToolResultCard/pending-tool cards inside
assistant bubbles with flat rows that mirror the web Control UI: chevron +
kind icon + title + one-line mono detail, result folded into the row and
revealed on tap (Show all for long outputs). Tool-only messages no longer
render bubble chrome.
* chore(i18n): sync native inventory + translations for tool-row strings
* feat(ui): custom session icons with agent-drawable SVG and nav-parity pinned rows
* wip: slice-2 interleaved sidebar zone (pre-review)
* fix(ui): trim icon exports, bypass protocol barrel in startup bundle, regen Swift protocol client
* fix(ui): preserve unknown-agent zone entries on writes, prune entries on any unpin
* fix(ui): reset keeps unloaded session slots; enforce SVG byte cap on canonical form
* fix(ui): archiving a pinned session retires its sidebar zone slot
* fix(ui): persist drag-pinned zone slot only after the pin patch lands
* fix(ui): recompute drop insertion against freshest zone order on pin ack
* fix(ui): consume self-drop events before the zone bailout
* docs(ui): note the non-sidebar unpin pruning contract on pruneSidebarSessionEntry
* refactor(ui): extract pure session-tree projection; drop unused zone type export
* feat(clients): gateway session groups, batch operations, session inspector, and new-session options
* chore(i18n): translate session management strings and regenerate catalogs
* chore(i18n): complete translation artifacts for session management strings
* fix(clients): fail closed when a transport cannot honor agent or base-ref session options
* fix(clients): authoritative agent identity for new-session parents and revision-keyed sidebar group refresh
* fix(clients): refetch session groups on remote catalog events and correct Swedish repository-root translation
* fix(clients): resilient new-session popover, revision-keyed group manager, and popover string translations
* fix(clients): scope reset fallback to plain new-session requests and revision-key the inspector groups
* fix(clients): reject empty agent catalogs and refresh sessions on remote group events
* refactor(clients): drop unused agents fetch wrapper and runtime memberwise init flagged by periphery
* chore(i18n): realign locale artifacts after rebase onto model-controls main
* chore(clients): split session creation into the session-actions extension and realign i18n after ask-user main rebase
* chore(i18n): resync derived artifacts after question-card main rebase
* feat(system-agent): hatch into the agent after a fresh setup applies
The hatch is a ceremony: a fresh-install setup apply now announces the hatch
and hands straight off (open-tui in the terminal, open-agent for gateway
clients); the web custodian page lands in agent chat with the birth-sequence
opener prefilled as a draft so one Send wakes the seeded BOOTSTRAP. Non-setup
persistent operations keep their in-place replies.
* fix(system-agent): hatch only on clean post-write verification
* fix(ui): scope hatch draft to setup handoffs
* fix(onboarding): seed hatch handoffs across clients
* fix(i18n): refresh native hatch inventory
* fix(onboarding): seed remote gateway hatch handoff
* fix(macos): localize hatch draft
* fix(onboarding): gate hatch on pending bootstrap
* fix(i18n): sync hatch source to ios catalog
* fix(onboarding): gate hatch on canonical pending state