Commit Graph

216 Commits

Author SHA1 Message Date
Peter Steinberger ef95d8f55e feat(secrets): agent-requested credentials the model never sees (#129670)
* feat(secrets): agent-requested credentials the model never sees

The new main-session secrets tool lets the agent request a credential by
name: the human enters the value in a masked question card (Control UI,
/ask/<id> deep link, iOS/macOS/Android), and the gateway diverts the
answer straight into the shared secret store at question.resolve. The
record, broadcast, waitAnswer, tool result, transcript, and model context
only ever carry a synthetic stored marker.

- protocol: additive secretStore binding, secretStoreExisting replacement
  metadata, and resolve-time secretStoreAllowedHosts (since 2026.8)
- gateway: store-bound question validation, admin-gated minting (blocks
  questions-scope self-answer escalation past secrets.store.set), shared
  redaction-first store write service reused by secrets.store.set
- tool: secrets request/list/delete; write-only by design, delete carries
  verified agent runtime identity; channel delivery is link-only so chat
  text is never captured as a secret
- Control UI: masked composer card with requester identity, store banner,
  editable allowed hosts, replacement warning, retry-on-validation-error,
  a standalone /ask/<id> page, and a named startup-JS baseline bump
- mobile: SecureField / password transformation for isSecret questions,
  no answer echo in terminal summaries; new native string registered in
  the locale-refresh inventory (generated artifacts stay workflow-owned)
- regression: claimed harness secret input stays out of session transcripts

Live-proven on an isolated dev gateway: real model turn, masked entry via
Playwright, value present only in secret_store_entries, absent from every
transcript, log, and the DOM.

* chore(protocol): regenerate protocol models and tool display

* fix(cli): read image string options through a typed helper

PR #129463 added four commander option narrowings in image.ts without
SAFETY coverage, leaving the assertion-safety ratchet red (21 > 17) for
every branch on current main. Replace the casts with a typeof-checked
read so the assertions are removed rather than annotated; each value is
still validated by its normalizer. SAFETY comments cannot work in this
file: the ratchet's raw scanner never rescans template tokens, so
comments after the first substitution template are unreadable to it.

* chore(protocol): refresh Swift models against current main

* chore(i18n): re-baseline the native inventory on current main

* docs(secrets): state the default-on tool policy and how to disable it

* fix(secrets): tell the model what the store actually does

The shipped tool description named the three actions and nothing else,
and no parameter carried a description. The model could not tell that
request blocks a human, that reason is shown to that human, what secret
and env select, or - the silent-failure case - that a secret stored with
no allowedHosts can never be substituted, so a successful request could
produce a permanently unusable credential. Move the description to the
presets module beside ask_user and document every parameter.

* refactor(agents): share one blocking-question lifecycle between tools

ask_user and secrets each carried their own registration, wait, and
cancel logic, and they had diverged: ask_user recovers an answer that
lands between its wait timeout and the cancel, while secrets discarded
it and reported no_answer even though the Gateway had already stored the
credential. One shared canceller and answer reader fixes that race for
both, folds the two divergent gateway-call types into one, and drops two
type assertions in favour of the canonical record guard (ask_user's
assertion baseline shrinks 11 -> 8).

Net +49 production lines: the shared module costs more than the
duplication it removes, and buys the correctness fix plus a single owner
for question lifecycle.

* fix(ui): keep the allowed-hosts field readable as an input

Main's composer restructure moved the free-text input styling into the
option-row context, so the store-request hosts field - which sits outside
a row - lost its border and read as static text. It is the one field the
operator is meant to review and edit before releasing a credential, so
give it its own border and focus ring.

* fix(secrets): close two credential-boundary holes in agent requests

Requests are now protected-secret only. list renders env values, so an
agent could request kind=env, watch a human type it into a masked box
under a no-visibility promise, then read it straight back; the tool text
even claimed values are never returned. Environment values stay operator
-set in Settings or the CLI, where they are agent-readable by design.

Store-bound questions are also bound to the run that requested them. The
resolve path authorized only the answering client, so a terminated or
replaced agent run could still have a credential written on its behalf -
the recorded runId was provenance, not closure-bound authority. Minting
now requires a runId and resolution revalidates that exact live run
immediately before the store write, with no await in between, failing
closed as QUESTION_REQUESTER_INACTIVE.

Both reported by ClawSweeper as P1 credential-boundary findings.
2026-08-26 08:10:16 -07:00
RoboClaw 44d60a29e6 fix: preserve unread reminder for open sessions (#129386)
* fix: preserve manual unread markers in open sessions

* fix: distinguish explicit session reads

* fix(ui): gate unread contract on gateway capability

* perf(ui): keep server capabilities out of startup bundle

* test(gateway): keep agent fixtures roster-consistent

* fix(sessions): preserve legacy read compatibility

* test(gateway): type agent fixture configs

* fix(ui): remove unread gateway fallback

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>

* test(infra): avoid fixed SSH tunnel port

* fix(ui): acknowledge unread after history commit

* docs: clarify unread upgrade boundary

* test(ui): drive mobile session menu by tap

* fix(ios): remove stale read reconciliation call

---------

Co-authored-by: roboclaw-bot <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-26 05:04:39 -07:00
Peter Steinberger 84c469a76c fix(apple): bind widget snapshots to their document owner (#129666) 2026-08-25 17:59:47 -07:00
ZYV5ge 43ffe41a4b fix(sessions): search visible categories across clients (#118912)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-25 14:15:52 -07:00
Peter Steinberger 7a5de93228 refactor(apple): share chat payload normalization (#129113)
Amp-Thread-ID: https://ampcode.com/threads/T-01a037b7-9244-7298-b368-3faab8a11cbf

Co-authored-by: Amp <amp@ampcode.com>
2026-08-25 02:54:40 -07:00
Peter Steinberger 2b8fe12f0b fix(apple): surface rejected chat session settings (#128737) 2026-08-24 06:49:50 -07:00
Peter Steinberger 0155d95524 feat(ios): adopt gateway user accent in chat (#128599)
* feat(ios): adopt gateway user accent in chat

The iOS chat surface previously always used the hardcoded brand accent.
Read ui.prefs.accent ?? ui.seamColor (the Control UI user-accent
contract) from the existing config.get branding refresh and feed it to
the shared chat kit's userAccent seam, matching the macOS chat window.
Invalid values fall through; accent resets on gateway switch.

* fix(ios): contrast-aware accent ink and live config.changed refresh

Address ClawSweeper review findings: the shared chat kit now derives
user-text/send-glyph ink from the accent via the Control UI WCAG rule
(relative luminance > 0.179 -> black), fixing unreadable light accents
on iOS and macOS alike; the iOS server-event switch routes
config.changed through the guarded branding refresh so an accent
change reaches a connected app without reconnect.
2026-08-24 02:46:06 -07:00
clawSean af384662f7 fix(ios): keep tool details visible in dark mode (#124021) 2026-08-24 01:05:45 -07:00
Peter Steinberger bb6e4b1dee fix(apps): prevent stale Now Playing after ownership changes (#128381) 2026-08-23 15:20:21 -07:00
Peter Steinberger a534817b4e fix(apps): prevent Unicode numerals from freezing code highlights (#128364) 2026-08-23 14:23:21 -07:00
Peter Steinberger 0e8136b554 fix(macos): prevent duplicate New Chat sessions and stale navigation (#127693)
* fix(macos): fence new chat creation

* chore(i18n): refresh native source inventory
2026-08-21 17:31:58 -07:00
Peter Steinberger 923e972564 fix(apple): gate gateway RPC polling on the hello method catalog (#126559)
* fix(apple): gate gateway RPC polling on the hello method catalog

Released 2026.7.x gateways authorize before method dispatch and reject
unknown methods with INVALID_REQUEST / "missing scope: operator.admin",
which never names the method, so the shared Swift kit's error-text
matchers could not detect an unsupported gateway: queued sends wedged in
a delay-free sessions.branches.list reconcile loop, question.list burned
its retry budget per health event, and progressCard.get fired a rejected
fetch per event.

Port the Android fix pattern (#126540): generalize the progressCard-only
transport seam into tri-state gatewayAdvertisesMethod(_:), make hello
catalog parsing distinguish absent (nil) from empty, route branch
listing through a catalog-checking dispatch point with a typed
BranchListingUnadvertisedError, tighten error-text matching to the
modern "unknown method:" shape, and skip question.list/progressCard.get
when unadvertised. Regression tests encode the exact 2026.7.1-2 wire
shape and fail pre-fix (A/B verified).

* fix(apple): keep explicit unsupported branch-listing replies releasing sends

ClawSweeper P1: the tightened matcher dropped the shipped acceptance of
explicit unsupported/unimplemented GatewayResponseError replies that
name sessions.branches.list, which would wedge queued sends on a
pre-catalog gateway emitting that shape. Collapse the matcher onto the
bridged localizedDescription (errorDescription always prefixes the
method name), preserving both legacy qualifier shapes while still
rejecting bare missing-scope denials and the old false-positive-prone
INVALID_REQUEST arm; add the releasing-send regression test.
2026-08-20 07:31:04 -07:00
Peter Steinberger 3e0c980aaf fix(models): honor per-agent model metadata (#126194)
* fix(models): honor per-agent model metadata

Resolve per-agent aliases, bare providers, fallbacks, and catalog tags consistently across runtime, CLI, Gateway, sessions, and the Control UI.

* fix(models): preserve projection ownership

* fix(models): carry agent scope through fallbacks

* test(models): complete compaction fallback mock

* test(models): complete startup fallback mock

* test(agents): isolate recovery id expectations

* refactor(protocol): split public schema barrel

* test(cron): await child readiness events

* fix(models): scope native catalogs to session agent

* perf(ui): tighten agent model option projection

* perf(ui): reduce agent model projection overhead
2026-08-19 06:04:24 -07:00
Peter Steinberger e71fc902ee fix(gateway): make activeRunIds presence mean a complete exact run set (#126106)
* fix(gateway): make activeRunIds presence mean a complete exact run set

Session rows no longer emit activeRunIds: [] while hasActiveRun is
true. Presence now means the complete exact set of direct run ids;
omission means identities are unavailable (projected/embedded owners);
[] only ever represents proven idle. Consumers stop guessing:
soleActiveSessionRunId() replaces the arbitrary [0] fallbacks in the
observer digest, transcript cache key, activity inspector, and
stale-terminal reconciliation, each falling back to its owner fact.

Follows the maintainer direction from #125983: the field stays as
Gateway-owned exact facts; producer-side liveness/observer projections
are a named follow-up.

* fix(gateway): clear unavailable active run ids in events

* fix(gateway): preserve idle active run sets

* fix(clients): close active run id cache gaps

* test(android): isolate history run snapshot
2026-08-19 02:08:57 -07:00
Peter Steinberger b8ff4fe3d7 fix: show sessions waiting for concurrency slots (#125654)
* fix: show sessions waiting for concurrency slots

* test: align queued session integration fixtures

* test: distinguish queued and reactivated followups

* fix: preserve queued state in workboard and android

* fix: project queued status through chat history

* test(ui): keep queued sidebar case under line cap
2026-08-18 02:31:39 -07:00
Peter Steinberger 561effac2e docs(apps): time-box the progress-card legacy plan fallback to 2026-10-18 (#125643)
The stream:"plan" fallback on both native platforms is deliberate compatibility
debt with a fixed expiry, not a permanent contract. Record the sunset date, point
each platform at its twin and at the tracking issue, and correct the Android note
to v2026.8.x (the newest released tag also lacks progressCard.get).

Refs #125639
2026-08-17 23:38:55 -07:00
Peter Steinberger 122fc1c786 fix(apps): render legacy plan events when the Gateway lacks the progress-card store (#125588)
* fix(apps): render legacy plan events when the Gateway lacks the progress-card store

progressCard.get ships in no released Gateway tag, so iOS/macOS on any current
release silently showed no status card after the durable-card migration. Restore
legacy stream:"plan" rendering, synthesized into the unified progress card and
gated on a tri-state capability probe so a dual-emitting Gateway never fights the
durable store. Mirrors the Android fix in #125444.

* fix(apps): invalidate progress-card capability on gateway route replacement

A replacement route may be a different Gateway, so a cached known-absent store
must not authorize the legacy plan fallback against a new Gateway that dual-emits
both sources. Clear and re-probe on .routeChanged.
2026-08-17 22:40:55 -07:00
Peter Steinberger 60920998c0 feat(apps): migrate iOS/macOS plan surface to the durable progress card (#125442)
* feat(apps): migrate iOS/macOS plan surface to the durable progress card

Replace the legacy stream:"plan" agent-event pipeline (runId-scoped state,
run-gated pill) with the sessionKey-scoped progress-card store: the shared
chat surface now renders progressCard.get snapshots, refetches on
progressCard.changed pokes with revision dedupe, clears on null-revision
pokes, and persists the card after the run completes. The card renders
markdown through the shared markdown view plus typed steps. Legacy Apple-side
plan handling (agent-event case, run-snapshot plan reconciliation,
OpenClawChatPlanStep parsing) is deleted; gateway emission stays for Android.
Removes the ios progressCard.changed coverage allowlist entry so the check
enforces the handler.

* chore(i18n): refresh native inventory for the progress-card rename

* fix(apps): keep the last progress card when a refresh fails

A transient progressCard.get failure no longer clears an already-rendered
durable card; only a successful null fetch or a null-revision poke clears it.
2026-08-17 18:07:17 -07:00
Peter Steinberger 916932b007 fix(agents): standardize image inspection as view_image (#125024)
* chore: refresh CI after main fix

* fix(agents): standardize image inspection as view_image

* fix(agents): preserve view_image activity display

* fix(agents): satisfy view_image display gates

* fix(ui): snapshot cloud worker draft before save

* perf(ui): compact fallback tool catalog

* fix(agents): preserve view_image upgrade boundaries

* chore(ui): refresh historical image display snapshot
2026-08-17 03:01:12 -07:00
ClawSweeper c12745429a fix(ui): fork active sessions from stable history (#123718)
* fix(ui): fork active sessions from stable history

* fix(protocol): align active fork types

* test(ui): match main-session fork routing

* fix(sessions): unify stable fork admission

* fix(native): fork active sessions from stable history

* fix(android): fork active sessions from stable history

* style(android): simplify active fork result handling

* fix(native): preserve legacy fork transport API

* test(native): complete legacy fork transport stub

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-14 14:13:25 -07:00
Pavan Kumar Gondhi 5eb18c1387 fix(ios): keep authenticated Control UI pages bound to the trusted Gateway [AI] (#119906)
* fix(ios): enforce gateway TLS pins in control pages

* test(ios): run control UI trust regressions in CI

* test(ios): avoid nested Testing macros

* fix(ios): preserve control page navigation

* fix(ios): keep authenticated control pages on origin

* fix(ios): canonicalize control page IPv6 hosts

* chore(ios): refresh native i18n inventory

* fix(ios): normalize default TLS challenge ports

* fix(apps): share gateway TLS authority matching

* test(apps): fix authority CI validation

* chore(ci): drop control UI test routing
2026-08-12 15:18:19 +05:30
Peter Steinberger db9bdb4a11 fix(gateway): preserve session identity through archive transitions (#121169)
* fix(sessions): fence lifecycle mutations by identity

* fix(sessions): finalize lifecycle identity fences
2026-08-11 16:43:10 -07:00
Peter Steinberger cb51cf7d3e feat(apps): Apple chat adopts the system-notice family (#122255)
* feat(apps): adopt the system-notice family in Apple chat (OpenClawChatUI)

Decode internal_system provenance and __openclaw history markers, classify
once into message/notice/divider rows (web-parity kinds), render minimal
hairline notice/divider SwiftUI rows, preserve metadata through history
reconciliation, live transport, and the transcript cache, and align the
transcript exporter with visible classification instead of leaking raw
[System] prompts.

* fix(apps): satisfy OpenClawKit periphery gate

Remove the dead visibleMessages projection (rows path replaced its
consumers) and annotate the provenance test-fixture initializer with the
repo-standard periphery:ignore rationale.

* fix(apps): refresh native i18n inventory after periphery cleanup
2026-08-11 14:47:19 -07:00
Peter Steinberger 73ae583263 refactor(tasks): simplify subagent activity tracking (#122198)
* refactor(tasks): simplify subagent activity tracking

* fix(android): single-source subagent activity expiry clock

* chore(i18n): refresh native source baseline
2026-08-11 12:30:49 -07:00
Peter Steinberger 4b46a14a54 feat(apple): show live subagent activity in chat (#121815)
* feat(apple): show live subagent activity in chat

* chore(apple): refresh native localization inventory
2026-08-10 21:50:13 -07:00
Peter Steinberger d4fd9cc96a fix(ui): restore settings search, media previews, clipboard, and native chat (#116654)
* fix(ui): restore search media and native text

* fix(native): unify visible chat text projection

* fix(ui): search composed array schemas

* fix(ui): keep config search off startup constraints

* fix(ui): honor schema and media path boundaries
2026-08-09 22:07:28 -07:00
Colin Johnson 5cd184c91b fix(ios): keyboard unavailable after tapping chat composer (#120723)
* fix(ios): restore composer keyboard focus

* test(ios): cover composer focus in screenshot CI

Co-authored-by: Colin <colin@solvely.net>

* test(ios): make composer focus proof device-aware

Co-authored-by: Colin <colin@solvely.net>

* fix(ios): stabilize sidebar layout under keyboard

Co-authored-by: Colin <colin@solvely.net>

* chore(ios): refresh native i18n inventory

Co-authored-by: Colin <colin@solvely.net>

* test(ios): keep focus proof in screenshot helper

Co-authored-by: Colin <colin@solvely.net>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-08 21:56:46 -07:00
Peter Steinberger a74738c16e feat(chat): add four rare working-claw stances and raise surprise odds (#120826)
* feat(chat): add four rare working-claw stances and raise surprise odds

* test(ui): assert claw surprises against the exported allowlist

* fix(ci): refresh native i18n inventory and drop test-only surprise export
2026-08-08 19:56:31 -07:00
Dallin Romney 2a0bbd23f5 feat: expose session classification facts (#106832)
* feat: expose session presentation metadata

* fix: restrict session titles to safe display metadata

* fix: preserve saved session display names

* fix(protocol): tolerate future session presentation values

* fix(gateway): keep direct peer names out of presentation

* fix(protocol): connect session presentation to native rows

* fix(gateway): canonicalize session presentation metadata

* fix(gateway): satisfy session presentation CI checks

* feat(gateway): flatten session classification facts

* fix: repair session classification generated models

* fix(gateway): canonicalize session classification keys

* fix(gateway): classify spawned delivery sessions

* fix(android): retain session classification facts

* test(android): make scripted gateway calls concurrency-safe

* test(live-updater): isolate fixture git commands
2026-08-07 14:56:56 +08:00
Vincent Koc a842f482d5 fix(ios): keep attachments in composer when route is unavailable (#116787)
* fix(ios): retain attachments when delivery route is unavailable

Refs #116724

* chore(i18n): refresh native source inventory
2026-08-03 12:53:48 +08:00
Jason (Json) d3c5ac85ae fix(chat): preserve trace across history reloads (#118332) 2026-08-02 21:08:09 -06:00
metaforismo 102a5915ef fix(ios): restore Magic Keyboard return in chat composer (#116042)
* fix(ios): restore hardware return in chat composer

* test(ios): cover hardware return composer flow

* fix(ios): route history keys through native editor

* fix(ios): satisfy composer lint gates

* test(ios): fix snapshot app lookup

* test(ios): keep snapshot helper nonthrowing

---------

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-07-31 16:21:41 -07:00
Peter Steinberger 0021e51f22 feat(apple): media renditions, Now Playing, video upload (#116051)
* feat(apple): complete media playback and uploads

* fix(apple): preserve movie picker metadata

* fix(apple): harden rendition and picker routing

* style(apple): fix macOS media formatting
2026-07-29 15:50:18 -04:00
Peter Steinberger afae681085 feat(apple): add inline media players (#115903) 2026-07-29 10:36:38 -04:00
Peter Steinberger 68a3d28906 fix: keep content after HTML-backed disclosures visible (#115877)
* fix(chat): close disclosures in coalesced HTML

Keep model-authored details closers visible to the shared disclosure contract when CommonMark absorbs them into type-6 HTML blocks across the Control UI and native apps.

* refactor(apps): isolate disclosure unfolding

Keep the native disclosure segmenter below its lint complexity and type-size limits, and refresh the source-owned native i18n inventory after the move.

* fix(apps): align disclosure helper visibility

Keep the extracted same-file helper compatible with Swift access control while leaving its implementation types hidden outside the source file.

* fix(apps): align source replacement visibility

Keep the source replacement helper at the same file-private boundary as the extracted disclosure unfolding types.
2026-07-29 10:24:46 -04:00
Peter Steinberger 1ab4e08d62 fix: expanded disclosures render their content on Apple platforms (#115863)
* fix(apps): render disclosure body content on Apple platforms

* chore(apps): refresh native i18n inventory
2026-07-29 08:14:17 -04:00
Peter Steinberger 85afb973e4 fix(ios): keep stop available for staged voice notes (#115744) 2026-07-29 04:31:07 -04:00
Peter Steinberger 844329284e fix(ios): prevent duplicate native chat replies after tool runs (#115678) 2026-07-29 02:59:25 -04:00
Peter Steinberger 138675aeeb feat(apps): render collapsible details natively (#115641)
* feat(apps): render collapsible details natively in chat

* fix(apps): preserve reference definitions when folding disclosures

* fix(apps): keep authored details summaries unlocalized

* fix(apps): keep raw-HTML disclosure examples literal

* refactor(apps): isolate summaries and raw HTML contexts

* fix(apps): honor all CommonMark raw HTML contexts in disclosures

* chore(apps): refresh native i18n inventory for disclosure strings
2026-07-29 02:52:54 -04:00
Peter Steinberger df9a940872 feat(chat): show live run telemetry across clients (#113084)
* feat(chat): show live run telemetry across clients

* fix(chat): satisfy native validation gates

* fix(chat): settle advertised terminal runs

* fix(android): clear stale run usage on gaps

* chore(i18n): align native source inventory

* fix(chat): reconcile telemetry with current projections

* refactor(chat): keep run state in owner extensions

* chore(i18n): refresh native source inventory

* test(ui): expect persistent working telemetry through streaming
2026-07-29 01:27:58 -04:00
Peter Steinberger 49f4942760 fix(chat): preserve literal Markdown image examples (#113904) 2026-07-28 16:12:08 -04:00
Peter Steinberger 4b05d83035 fix: generated images do not appear in native chat (#115042)
* fix(chat): render managed images in native clients

Co-authored-by: Francesco Giannicola <francescogiannicola1@gmail.com>

* chore: keep release changelog owned

* refactor(macos): split managed image loading

* test(apple): prove managed image header policy

* test(native): stabilize managed image proof

* test(apple): satisfy strict concurrency checks

---------

Co-authored-by: Francesco Giannicola <francescogiannicola1@gmail.com>
2026-07-28 04:39:53 -04:00
Vincent Koc 7838c6a6fd fix(apps): fence stale mobile delivery state 2026-07-28 08:15:52 +02:00
Peter Steinberger a4d60af42b fix: sharpen working-claw silhouette into a toothed pincer (#114939) 2026-07-28 01:18:36 -04:00
Peter Steinberger 1e3a4a69b5 fix: preserve native trace heading typography (#103436)
* fix(ios): preserve native trace heading typography

* test(ios): attach trace heading visual proof

* test(ios): import shared chat UI for visual proof
2026-07-28 00:01:44 -04:00
Peter Steinberger 4aa96a118d fix(sessions): prevent stale and cross-agent observer status after reconnect (#114548)
* fix(sessions): prevent stale and cross-agent observer status

* fix(sessions): sync native observer source inventory

* fix(android): satisfy observer ownership formatting gate
2026-07-27 08:39:29 -04:00
Peter Steinberger c56689416e fix(ui): scope global route resolution by agent 2026-07-27 05:43:19 -04:00
Peter Steinberger 64bf485ba2 fix(sessions): scope observer state by agent 2026-07-27 05:43:19 -04:00
Peter Steinberger 51f228f6fe fix(ui): preserve agent-owned session navigation
Add agent ownership to observer digests, scope global observer delivery and reconciliation, and centralize application session selection across navigation and reconnects.

Co-authored-by: xbrxr03 <abrarhabib03@gmail.com>
2026-07-27 05:43:19 -04:00
Peter Lee 0406e66369 fix(ui): keep stable chat rows in insertion order and only sort live tool/stream items by timestamp (#113266)
* fix(ui): keep stable chat rows in insertion order and only sort live tool/stream items by timestamp

* fix(ui): keep live rows within current turn

* fix(ui): keep current work above queued turns

* fix(ui): keep streamed replies above queued turns

* fix(ui): preserve reconnecting run order

* fix(ui): preserve causal terminal ordering

* fix(ui): bound replay rows to owning turns

* fix(ui): keep question summaries in owning turns

* fix(ui): scope question run ownership to session

* fix(ui): restore reconnecting chat run identity

* fix(ui): remove unused chatItemTimestamp import in chat-thread-build.ts

* fix(ui): correlate question summaries with agent runs

Co-authored-by: Peter Lee <li.xialong@xydigit.com>

* chore(i18n): refresh native source baseline

Co-authored-by: Peter Lee <li.xialong@xydigit.com>

* fix(ui): remove unused chatItemTimestamp export and split tool-stream test file

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-27 02:08:22 -04:00