Commit Graph

3763 Commits

Author SHA1 Message Date
Peter Steinberger
3e44b5f5dd refactor(ui): split chat pane (#113406)
* refactor(ui): split chat pane

* refactor(ui): keep chat pane entrypoint local
2026-07-24 14:25:20 -07:00
Franck MEYER
5e3007cc23 fix(ui): preserve session identity across gateway snapshots (#113322)
* fix(ui): preserve session identity across gateway snapshots

Co-authored-by: openclaw-repo-broker[bot] <285669409+openclaw-repo-broker[bot]@users.noreply.github.com>

* test(ui): cover session identity transitions

Co-authored-by: openclaw-repo-broker[bot] <285669409+openclaw-repo-broker[bot]@users.noreply.github.com>

* test(ui): model identity reconnect snapshot accurately

* style(ui): format session identity test import

* test(ui): isolate assistant identity snapshot coverage

---------

Co-authored-by: openclaw-repo-broker[bot] <285669409+openclaw-repo-broker[bot]@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-24 13:17:23 -07:00
scotthuang
2900026b33 fix: stop selected channel sessions from WebChat (#111108)
* fix: stop selected channel sessions from WebChat

* fix: clear channel working state after stop

* fix: cancel queued turns before session abort

* fix: replay pending stops after reconnect

* fix: align stop lifecycle test fixtures

* fix(ui): bind pending aborts to gateway client

* test(ui): keep chat pane specs within line limit

* chore(ios): refresh native i18n inventory

* chore: retrigger PR checks

* fix(system-agent): avoid blocking TUI catalog discovery

* fix: preserve session abort ownership

* test: align abort coverage with current main

* test: assert scoped session abort broadcast

* fix(agent-runs): expose SDK runtime abort state

* fix(ui): clear queued main-session stops by scope

* fix(ui): replay only exact run aborts

* fix(gateway): protect session abort cleanup

* fix(ui): narrow session abort intent

* test(ui): avoid unbound request assertions

---------

Co-authored-by: scotthuang <scotthuang@tencent.com>
Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-07-24 14:36:18 -05:00
Peter Steinberger
9c2ae380bc refactor(ui): split chat message rendering (#113363)
* refactor(ui): split chat message rendering

* refactor(ui): tighten chat message exports
2026-07-24 09:41:53 -07:00
Peter Steinberger
70a8c2a1c9 fix(ui): chat bubbles overlap after switching to the dashboard face (#113356)
* fix(ui): keep chat transcript rows measured across dashboard face switches

* test(ui): satisfy lint in transcript measure regression test
2026-07-24 09:06:58 -07:00
Peter Steinberger
049a17860c refactor(ui): split chat composer (#113338)
* refactor(ui): split chat composer

* refactor(ui): align composer split ownership

* test(ui): clarify custom combobox inventory
2026-07-24 08:11:54 -07:00
Peter Steinberger
44c3ec10ed fix(ui): paginate sidebar session sections independently (#113343) 2026-07-24 07:48:40 -07:00
Jason (Json)
aee46707ba feat(plugins): support manifest-declared MCP Apps in native plugins (#113224)
* feat(plugins): load native manifest MCP servers

* fix(gateway): advertise proxied plugin surface ports

* fix(codex): retain MCP App transcript previews

* fix(codex): render native MCP apps inline

* fix(mcp-apps): resolve harness-native views by session

* fix(codex): normalize null MCP result metadata

* fix(ui): give inline MCP apps full message width

* test(codex): use generic native MCP App fixtures

* chore(plugin-sdk): refresh harness runtime baseline

* refactor(codex): isolate native MCP App contracts

* fix(codex): satisfy native app CI contracts

* fix(ci): scope automation app tokens

* chore(ci): defer token scopes to current main
2026-07-24 01:43:48 -06:00
Peter Steinberger
9c486d1297 test(ui): consolidate chat view fixtures (#113245) 2026-07-24 00:02:28 -07:00
Peter Steinberger
3b7b2a2a1f chore: update dependencies and migrate major contracts (#112963)
* build(deps): complete latest dependency migrations

* fix(deps): satisfy updated dependency types

* fix(deps): hold incompatible build tooling

* fix(deps): preserve portable tooling contracts

* build(deps): allow reviewed fresh transitive releases

* fix(deps): repair major upgrade validation

* build(deps): regenerate current dependency graph

* fix(logging): keep tslog adapter type private

* fix(agents): narrow grep subprocess handle

* fix(codex): prefer pinned managed binary

* fix(codex): fence managed native provenance

* build(deps): align codex ACP with managed harness

* fix(slack): use socket-mode Undici runtime

* fix(slack): detect cross-runtime responses

* fix(slack): bridge package-owned fetch types

* fix(deps): retain tslog v4 JSON contract

* build(plugin-sdk): refresh logging API manifest
2026-07-23 21:21:01 -07:00
Peter Steinberger
90aee82793 feat(sessions): suggestion queue + typing indicator (#113173)
* feat(protocol): add session collaboration contracts

* feat(gateway): add session suggestion queue and typing

* feat(ui): add session suggestion controls

* fix(collaboration): restrict suggestion resolution

* fix(collaboration): dedupe suggestion dispatch modes

* fix(collaboration): preserve resolver identity

* fix(collaboration): reconcile suggestion state

* fix(collaboration): filter identityless suggestion events

* fix(ui): expose full suggestion text

* fix(collaboration): durably claim suggestion dispatch

* fix(collaboration): harden suggestion events and typing

* fix(collaboration): reconcile suggestion races

* fix(ui): reconcile suggestion capabilities

* fix(collaboration): close suggestion privacy races

* test(ui): satisfy suggestion lifecycle lint

* fix(collaboration): fence resolved suggestion events

* test(collaboration): type deferred audit result

* fix(collaboration): fence delayed typing events

* fix(ui): coalesce suggestion refreshes

* fix(ui): preserve resolved self suggestions

* fix(collaboration): enforce draft suggestion visibility

* fix(collaboration): fence post-dispatch finalization

* fix(ui): retain suggestions across visibility changes

* fix(collaboration): fence suggestion context and archives

* fix(collaboration): fence suggestion resolve lifecycle

* fix(collaboration): map suggestion replacement races

* refactor(gateway): extract session typing state

* fix(collaboration): integrate suggestion storage with session nodes

* refactor(gateway): extract session sharing snapshot cache

* fix(collaboration): satisfy protocol and deadcode gates

* fix(ci): register iOS release script entrypoints

* fix(collaboration): fence typing by session instance

* fix(collaboration): enforce incognito suggestion privacy

* docs(ui): clarify solo suggestion dormancy

* test(gateway): preserve incognito literal type

* test(gateway): split session typing coverage

* test(gateway): register collaboration method expectations
2026-07-23 18:59:58 -07:00
Peter Steinberger
bb657eec93 refactor(config): retire redundant settings (#113174)
* refactor(config): retire redundant settings

* style: apply current formatter

* chore: update plugin sdk baseline

* fix: keep Codex tool caps context-aware

* chore: remove stale imports

* test: align WhatsApp QA debounce config

* fix(config): clean up retired config checks

* fix(ci): align config cleanup checks
2026-07-23 17:45:02 -07:00
Peter Steinberger
1603781bb0 improve(ui): unify sidebar footer into a full-width identity card (#113156)
* feat(ui): unify sidebar footer into full-width identity card

Footer becomes one card (avatar + name + chevron) mirroring the top agent
card; identity menu gains email header, Settings (with platform shortcut
hint), and Usage; Usage leaves default sidebar pins; settings shortcut now
also binds Ctrl+Shift+Comma; offline state lives in the card subtitle and
menu retry action and the card persists while disconnected.

* test(ui): align persisted-sidebar fallback default with usage removal
2026-07-23 17:40:30 -07:00
Jason (Json)
09c6d66d19 fix(ui): render managed chat media under base paths (#113163) 2026-07-23 16:49:14 -06:00
Peter Steinberger
fc92b9fd91 feat(ui): merge creator avatar into sidebar leading slot, move creator filter into Threads menu (#113150)
* feat(ui): merge creator avatar into sidebar leading slot and move creator filter into Threads menu

The per-row creator chip previously rendered next to the leading state
indicator, so rows with a known creator started their titles at a
different x-offset than rows without one. The avatar now occupies the
single fixed leading slot: unread renders as a corner badge on it,
running as a spinner ring, and open/merged PR state as a colored corner
badge, while attention and pinned icons keep the slot. Child rows keep
their status badges and no longer render owner chips.

The standalone 'Filter by creator' select above the session list is
gone; the Threads funnel menu gains a People radio section with owner
chips, and the funnel trigger shows an accent dot while a creator
filter is active. The empty Threads header stays visible when ownership
chrome is active so the filter can always be cleared. Mock dev fixtures
gain two creator identities so the ownership chrome is demonstrable.

* test(ui): guard parent row spread in child-avatar ownership case
2026-07-23 15:26:56 -07:00
Peter Steinberger
cbf94c0d8b feat(sessions): drafts UX — create-as-draft, promote, admin ghost treatment (#113127)
* feat(protocol): support draft session creation

* feat(ui): add draft session workflows

* docs: explain multi-user drafts

* test(ui): tighten draft ownership fixture

* test(ui): satisfy draft E2E lint

* test(ui): keep draft fixtures strictly typed

* docs: add drafts implementation report

* docs: clarify implementation LOC summary

* test: strengthen draft compatibility coverage

* docs: correct drafts cleanup report

* fix: harden draft availability policy

* docs: update draft policy review notes

* test(ui): type draft policy mock control

* fix: preserve keyed draft creation retries

* fix: keep disabled draft retries idempotent

* docs: finalize drafts cleanup report

* fix(ui): keep draft ownership helper internal

* docs: refresh drafts docs map
2026-07-23 13:06:35 -07:00
Peter Steinberger
c519e01a24 feat(gateway): chat.send expectedLeafEntryId precondition keeps stale panes off switched branches (#113073) 2026-07-23 12:33:31 -07:00
Peter Steinberger
013b24dd6d feat(sessions): archive attribution (archivedBy) (#113116)
* feat(sessions): attribute archive transitions

* docs: add archive attribution report

* fix(sessions): restore alias layout after archive audit failure

* docs: update archive attribution report

* fix(sessions): isolate archive audit rollback

* docs: record final archive rollback design

* fix(sessions): make archive audit note best-effort

* docs: record best-effort archive audit policy

* chore: refresh native i18n baseline
2026-07-23 11:23:30 -07:00
Jason (Json)
2f5e7cfc5d fix(ui): prevent duplicate image prompt and flicker (#113113)
* fix(ui): stabilize initial image prompt handoff

* chore(protocol): refresh sessions create model

* chore(i18n): refresh native source inventory
2026-07-23 12:11:52 -06:00
Peter Steinberger
0cd7ea0089 fix(update): avoid dirty checkouts after source builds (#113094)
* fix(update): prevent build artifact drift

* fix(update): preserve excluded UI artifacts
2026-07-23 09:52:22 -07:00
Peter Steinberger
54f8f61167 refactor(ui): split agent menu by scope — account items move to the footer identity menu (#113046)
* refactor(ui): split agent menu by scope — account items move to footer identity menu; fix facepile tooltip anchors

* test(ui): match footer identity button by its name-bearing aria label

* refactor(ui): move sidebar menu rendering out of the menus controller

* perf(ui): lazy-load sidebar menu rendering outside the startup chunk

* fix(ui): inherit knownSessionGroups signature from organizer host
2026-07-23 09:36:37 -07:00
Peter Steinberger
acd92f6a3d chore(deps): refresh repository dependencies (#112453)
* build(deps): update QA broker dependency

* build(deps): refresh repository dependencies

* build(deps): reconcile rebased shrinkwraps

* test(plugins): remove stale loader test state

* test(deps): stabilize updated dependency coverage

* fix(swift): use caller-isolated TaskLocal overload

* build(deps): regenerate rebased shrinkwraps

* test(msteams): preserve DNS validation in fetch helper

* fix(deps): avoid vulnerable optional image stack

* test(deps): validate generated LRU override

* refactor(ui): extract chat resizable divider

* test(ui): update divider ownership path

* fix(matrix): retain restart-compatible SDK

* style(cron): format update test
2026-07-23 16:17:13 +00:00
Peter Steinberger
09672312c4 feat(gateway): incognito sessions for the web Control UI (#113006)
* feat(gateway): add web-only incognito sessions held in process memory

* feat(ui): add incognito toggle and badges to the web new-session flow

* fix(sessions): classify incognito by key shape, fail closed on stale keys, and gate memory writes

* fix(codex): start harness threads ephemeral for incognito sessions

* fix(sessions): reshape internal-effects incognito keys and add doctor repair for reserved key collisions

* refactor(plugin-sdk): export canonical incognito key classifier and guard the sentinel path

* fix(state): classify incognito DB handles from the recorded open-time set

* fix(gateway): isolate incognito sessions from durable lineage and allocation on read-only misses

* docs(sessions): pin the reserved incognito namespace ownership decision

* feat(gateway): admin-scope incognito visibility and incognito-blind cross-session surfaces

* fix(ci): repair kysely guardrails, dead export, docs map, protocol bindings, and ACP reset rotation

* fix(gateway): remove non-admin observability side channels for incognito sessions

* fix(gateway): enforce admin-scope incognito access and cover all parent-reference creation paths
2026-07-23 09:04:36 -07:00
Peter Steinberger
dedf85a34d refactor(ui): split chat-send.ts along ack/request/drain/lifecycle seams (#113052)
* refactor(ui): split chat-send.ts along ack/request/drain/lifecycle seams

chat-send.ts was ~2,330 lines under a grandfathered max-lines
suppression, mixing ack normalization, wire requests/routing, the
stored-outbox drain scheduler, retry/steer actions, and the send
lifecycle. Mechanical extraction into owned modules:

- chat-send-contract.ts absorbs ack normalization (it owns the ack shape)
- chat-send-request.ts: wire requests + session routing
- chat-outbox-drain.ts: drain lanes, retry timers, head reconciliation —
  colocated with the outbox ownership boundary from the composer split
- chat-send-actions.ts / chat-send-queue-state.ts / chat-send-submit.ts:
  retry/steer actions, queue-state helpers, submission routing
- chat-send.ts keeps the send lifecycle (719 lines); its max-lines
  suppression and baseline entry are removed

No compatibility re-exports; cycles broken by hoisting ChatHost into the
contract module and injecting the drain's two lifecycle callbacks.

Closes #112742.

* fix(ui): extract chat-send ack shapes into a leaf module to break the madge type cycle
2026-07-23 08:51:29 -07:00
Peter Steinberger
29d5dcfac6 feat(ui): restructure chat transcript for multi-user sessions (#112938)
* feat(ui): restructure chat transcript for multi-user sessions

Viewer-relative alignment: attributed messages from other participants
(senderId != viewer) render left-aligned as peers with their avatar,
name, and identity tint; only the viewer's own messages stay right-aligned.
System-role transcript entries (e.g. local command output) now render as
centered notice rows instead of a pseudo-participant with a question-mark
avatar. In threads with 2+ attributed senders, assistant replies carry a
'Replying to <name>' attribution chip derived from the preceding attributed
user turn; unattributed turns clear the attribution rather than mislabeling.
Also drops redundant role lowercasing on already-normalized roles.

* docs(web): describe multi-user chat transcript layout

* docs(web): refresh chat transcript docs map
2026-07-23 07:46:34 -07:00
Peter Steinberger
1e3192c0b4 refactor(ui): model gateway connection state as one closed phase union (#112909)
* refactor(ui): model gateway connection state as one closed phase union

ApplicationGatewaySnapshot carried connected + reconnecting as parallel
booleans whose illegal combination (both true) was representable, and
every consumer re-derived the same flag logic. The snapshot now carries
phase: "stopped" | "connecting" | "connected" | "reconnecting" |
"offline"; offlineStable stays as the store-owned 2s debounced
presentation boolean, and lastError/lastErrorCode are unchanged.

Mapping preserves shipped behavior exactly: never-connected terminal
closes return to "stopped" (login gate), established-connection drops
with retry are "reconnecting" (shell stays mounted), without retry
"offline". Component props stay boolean, derived once at the app-host
boundary; no compat aliases remain on the snapshot.

Closes #112741.

* fix(ui): migrate rebased-in test fixtures to the gateway phase union

* fix(ui): migrate post-rebase gateway snapshot readers to the phase union

* fix(ui): migrate document-title test harness snapshot to the phase union
2026-07-23 07:00:26 -07:00
Peter Steinberger
babf04ca0f refactor(ui): split terminal panel into chrome renderers and a PTY controller (#113020) 2026-07-23 06:35:27 -07:00
Peter Steinberger
3023d69fd8 feat(gateway): carry reviewer-only detail on plugin approvals (#113027)
* feat(gateway): carry reviewer-only detail on plugin approvals

* chore(protocol): regenerate projections for plugin approval detail

* chore(plugin-sdk): budget reviewer-detail surface additions
2026-07-23 06:28:23 -07:00
Peter Steinberger
ad505a7b55 fix(swarm): keep collector results reliable through races and restarts (#112989)
* fix(swarm): harden collector lifecycle and dashboards

* fix(swarm): initialize collector completion state

* test(swarm): satisfy cross-environment type checks

* test(codex): allow direct request handler calls

* style(ui): avoid Swarm widget shadowing

* test(swarm): keep internal helpers private

* refactor(ui): own Swarm roster helpers in runtime
2026-07-23 06:26:31 -07:00
Peter Steinberger
856f534880 feat(ui): mirror active destination and connection state in the dashboard title (#112929)
* feat(ui): mirror active destination and connection state in the dashboard title

* feat(ui): title agent main chats with the agent name

* test(ui): split document-title shell tests to satisfy max-lines
2026-07-23 06:10:54 -07:00
Peter Steinberger
8a3e2cff73 fix(mcp): harden concurrent writes and diagnostics (#113026) 2026-07-23 09:04:30 -04:00
Peter Steinberger
6251343384 feat(sessions): visibility states, membership, and server-enforced participation (#112787)
* feat(sessions): enforce visibility and membership

* feat(ui): add session sharing controls

* docs: add session sharing implementation report

* refactor(sessions): use canonical creator identity

* fix(sessions): adopt creator ownership contract

* docs: refresh session sharing rebase report

* docs: record final creator integration proof

* docs: record final main rebase

* chore: drop worktree report artifact

* fix(sessions): keep drafts owner-only

* fix(ui): preserve redacted session restrictions

* fix(sessions): preserve scoped sharing authorization

* fix(sessions): re-verify session instance inside sharing mutation queue

* test(sessions): cover stale sharing mutation

* fix(sessions): bind membership to session instance, gate absence blocking on sharing

* fix(sessions): preserve entry normalization on rebase

* fix(sessions): atomic visibility instance guard, reset visibility on recreate

* docs(ui): name the absence-heuristic tradeoff and link follow-up

* feat(protocol): expose session sharing row state

* docs: note generated creator identity type

* fix(sessions): bind member writes and visibility rollback to session instance

* fix(ui): discard stale-connection sharing loads; drop worktree scratch files

* fix(ui): block composer only on observed sharing state, never on list absence

* fix(gateway): authorize agent runs against the resolved session (close keyless bypass)

* chore(protocol): allowlist Control UI-only session.sharing event for mobile

* test(config): record session.sharing keys in common-tier snapshot

* refactor(sessions): unexport internal sharing helpers

* test(gateway): update sessions changed routing assertions

* fix(sessions): align sharing identity with created actor

* fix(sessions): align membership identities and storage keys

* fix(gateway): re-filter drafts against fresh sharing state in sessions.list

* fix(gateway): drafts stay owner+admin only in the sessions.list fresh filter

* fix(ui): re-export sharing protocol types for the Control UI

* fix(ui): keep SessionSharingRole internal to satisfy deadcode gate

* fix(gateway): read runtime config lazily in session-mutation authorization

authorizeSessionMutation ran on every gateway request but eagerly called
context.getRuntimeConfig() — a non-trivial config resolve — for methods that
are never session mutations. Read config only once a real session-mutation
target is resolved. Also register the four session sharing methods in the
2026.7 release-train inventory test.

* fix(gateway): share one config snapshot across session-mutation authorization

Group rename/delete discovery and the authorization loop were each resolving
runtime config separately after the lazy-read change. Memoize the resolve so
non-session requests still pay nothing, while any session mutation resolves
config at most once and both discovery and authorization use that single
snapshot (no double reload, no mid-request config-change split).

* fix(gateway): resolve session-sharing CI gates

- isGatewayAdmin: null-safe connect access so internal/plugin-runtime runs
  (which reach authorization with a connect-less client) do not crash.
- emitSessionsChanged: scope only to a concrete session key; a [undefined]
  sessionKeys scope filters nothing correctly and would strip draft gating.
- session stores: mark the sync TOCTOU re-read and the sqlite_master
  existence probe as narrowly-justified raw SQLite primitives.
- tests: provide getRuntimeConfig to the session-action contract context,
  drop a shadowed 'call' binding, use structuredClone, and assert the
  agent-scoped sessions.changed broadcast shape.

* docs(gateway): note best-effort participation gate + refresh native i18n baseline

Session ownership/visibility are usability features, not a security boundary
(docs/concepts/multi-user.md, SECURITY.md); document that the pre-dispatch
authorization is intentionally not commit-bound to the resolved instance.
Also refresh apps/.i18n/native-source.json after the session-sharing protocol
codegen shifted line numbers of existing native strings (position-only).

* test(gateway): reset session sharing snapshots

* style(gateway): format sharing reset import
2026-07-23 08:53:57 -04:00
Peter Steinberger
f3b4f9cfa2 refactor(ui): split browser panel into chrome renderers and a lifecycle controller (#113017)
* refactor(ui): split browser panel into chrome renderers and a lifecycle controller

* fix(ui): keep browser panel mode internal

* refactor(ui): clarify normalized browser panel request
2026-07-23 08:42:51 -04:00
Peter Steinberger
9ca500db98 refactor(ui): split config form into per-domain field renderers (#113016)
* refactor(ui): split config form into per-domain field renderers

* fix(ui): retain config search type consumer
2026-07-23 08:30:43 -04:00
Peter Steinberger
28971b4143 refactor(ui): split chat markdown renderer into cohesive modules (#113015)
* refactor(ui): split chat markdown renderer into cohesive modules

* refactor(ui): keep markdown streaming split type private
2026-07-23 08:07:23 -04:00
Peter Steinberger
1e5096c519 refactor(ui): one job per sidebar zone — shell chrome controls, header presence, slim footer (#112936)
* refactor(ui): one job per sidebar zone — move search/collapse to shell chrome, presence to chat header, slim footer

* test(ui): point drawer-collapse e2e step at shell chrome nav toggle

* refactor(ui): unexport lobsterLookStyleVars after logo stand-in removal

* docs(web): describe shell chrome controls, slim footer, and header presence facepile

* fix(ui): keep cluster search on native-nav hosts; draft-aware collapsed new-thread
2026-07-23 05:54:39 -04:00
Vincent Koc
e0a692658e test(ui): cover bundled CLI brand icons 2026-07-23 17:43:10 +08:00
Vincent Koc
84d149bf6f fix(ui): use bundled model setup icons 2026-07-23 17:43:10 +08:00
Peter Steinberger
f466c3de32 refactor(ui): collapse sidebar inheritance tower (#112969) 2026-07-23 04:44:25 -04:00
Peter Steinberger
6a90ad0573 refactor(ui): move sidebar menus into a reactive controller (#112940) 2026-07-23 03:15:20 -04:00
Peter Steinberger
07f671724c test(ui): wire catalog project activity case through sessionData catalogs 2026-07-22 23:03:16 -07:00
Peter Steinberger
d9c9dcf71e test(ui): update sidebar-customization e2e to current nav defaults (custodian in settings, advanced-tier search, plugin tabs in sidebar) 2026-07-22 22:56:27 -07:00
Jason (Json)
6504cf85f2 fix(ui): restore project hierarchy and session activity (#112924)
* fix(ui): restore catalog project type hierarchy

* feat(ui): show catalog session activity

* chore(ui): update startup budget baseline

* test(ui): isolate catalog activity coverage
2026-07-22 23:43:46 -06:00
Peter Steinberger
5678c74e4d fix(ui): keep system agents out of page scopes (#112889)
* fix(ui): exclude system agents from page scopes

* perf(ui): keep scope filtering within startup budget
2026-07-23 01:38:11 -04:00
Peter Steinberger
b74f04ada8 refactor(ui): move sidebar mutations and groups into one organizer controller (#112923)
* refactor(ui): move sidebar mutations and groups into controllers

* refactor(ui): lazy-load session organizer operations

* fix(ui): order organizer mutation scope before options
2026-07-23 01:37:18 -04:00
Peter Steinberger
6b470b1fe8 fix(ui): thread-changes button leads to a dead end when the workspace is not a git checkout (#112914)
* fix(ui): disable the thread-changes button when the workspace is not a git checkout

* chore(protocol): regenerate Swift gateway models for sessions.files.list gitCheckout
2026-07-23 01:33:35 -04:00
Peter Steinberger
89cfea034a refactor(ui): consolidate workboard controller tests (#112897)
* test(ui): consolidate workboard fixtures

* test(ui): classify workboard fixtures as test-only
2026-07-23 01:25:18 -04:00
Jason (Json)
c2578bddfd fix: commentary no longer repeats after steering a task (#112859)
* fix(ui): preserve stream boundary across steers

* fix(ui): keep stream boundary current during reconciliation
2026-07-22 22:03:25 -06:00
Jason (Json)
3c25222fb4 fix(ui): pin session observer to pane header (#112866) 2026-07-22 21:55:27 -06:00
Peter Steinberger
efc19faca4 refactor(ui): move sidebar session data into controller (#112853) 2026-07-22 23:45:55 -04:00