Commit Graph

3723 Commits

Author SHA1 Message Date
Peter Steinberger
8b5337caf8 refactor(ui): split chat state container (#113780)
* refactor(ui): split chat state container

* refactor(ui): keep lightbox helper private
2026-07-25 11:23:44 -07:00
Peter Steinberger
6277c35d9a fix(ui): restore one-of skill binary setup and installation (#113767)
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-07-25 11:01:25 -07:00
openclaw-mantis[bot]
81ea782ca5 chore(ui): refresh control ui locales (#113184)
* chore(ui): refresh control ui locales

* fix(ui): translate external session label

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-25 10:37:42 -07:00
Peter Steinberger
916625eef2 fix(ui): show configured primary model in general settings (#113769)
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-07-25 10:37:08 -07:00
Peter Steinberger
1a2252e1a7 fix(ui): keep cron history matched to the latest request (#113765)
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-07-25 10:30:32 -07:00
Peter Steinberger
f6e8446e55 fix(ui): generalize external session label (#113759) 2026-07-25 10:08:44 -07:00
Peter Steinberger
e279076010 fix(ui): carapace follow-ups — embed font stacks, data-theme-resolved, undefined status tokens (#113724)
* 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.
2026-07-25 09:32:56 -07:00
Peter Steinberger
1a11f5394e refactor(ui): split workboard view (#113730) 2026-07-25 08:29:39 -07:00
Peter Steinberger
bab4b2973a refactor(ui): split config view panels (#113715) 2026-07-25 08:28:40 -07:00
Peter Steinberger
f808147f62 refactor(ui): split chat thread projection (#113714)
* refactor(ui): split chat thread projection

* refactor(ui): tighten chat thread module boundaries

* refactor(ui): type chat stream grouping locally
2026-07-25 08:28:02 -07:00
Peter Steinberger
4032ae5247 fix: preserve repeated messages while chat history reloads (#113690)
* fix: preserve repeated messages while chat history reloads

* fix: reconcile repeated chat turns by authoritative identity

---------

Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-07-25 08:18:11 -07:00
Peter Steinberger
a95486cefc feat: session rail with read-only session companion in Control UI chat (#113698)
* feat(protocol): add session companion schemas

* feat(gateway): add session companion service

* feat(gateway): expose session companion rpc

* fix(gateway): harden companion runtime limits

* test(gateway): fix companion type assertions

* test(gateway): align companion test target

* feat(ui): replace observer HUD and side chat with session rail

* docs: session rail companion for control ui

* test(ui): align session rail client mock

* fix(ui): drop stale chat search import

* fix: satisfy session companion lint contracts

* refactor(gateway): isolate companion state contract

* fix(ui): keep session rail reachable while idle

* fix(agents): clamp derived openai prompt cache keys at boundary

* fix(ai): clamp chatgpt responses session_id affinity header

* fix(ci): align session companion branch gates

* fix(ui): require run id for sessionless terminal chat events

* fix(agents): scope internal run events to transcript

* chore: revert changelog edit (release generation owns changelog)
2026-07-25 08:14:32 -07:00
Peter Steinberger
4acf03fce6 fix(ui): restore Control UI theme colors (#113726)
* fix(ui): use canonical theme tokens

* chore(ui): leave release notes to release prep
2026-07-25 08:09:34 -07:00
Peter Steinberger
c1987081c7 fix(ui): drop the sidebar agent menu below its card (#113719) 2026-07-25 07:51:09 -07:00
Peter Steinberger
35ce322a6c fix: reconnect after browser gateway handshake errors (#113689)
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-07-25 06:59:44 -07:00
Peter Steinberger
fdc8d472c7 fix(ui): align shadow-DOM token fallbacks with real token values (#113684)
Shadow-DOM components carried fallback colors that never matched the
actual tokens: panel-tab-strip fell back to teal #4ec9a8 for the coral
--accent, resizable-divider to Bootstrap blue #007bff, and --border to a
generic #333. Align all fallbacks with the claw-family values in
styles/base.css so token-less rendering matches the product palette.

Also document the intentionally dark image-lightbox chrome and the
terminal theme's hand-mirrored token values, and regenerate the drifted
values in ui/docs/design-system/color-tokens.md (--muted, --muted-strong,
--primary, --danger, --info, light status colors) from base.css truth.
2026-07-25 06:48:49 -07:00
Peter Steinberger
d170459c70 refactor(ui): reactive controller consolidations (#113647)
* refactor(ui): consolidate dock panel layout

* refactor(ui): centralize realtime camera lifecycle

* refactor(ui): centralize async gateway scopes

* refactor(ui): centralize stream auto-follow

* refactor(ui): centralize dropdown menu lifecycle

* Revert "refactor(ui): centralize async gateway scopes"

This reverts commit 04f120b0e2.

* fix(ui): align controller refactor checks
2026-07-25 06:39:50 -07:00
Peter Steinberger
14eaedc40e fix(ui): give run state its own color instead of brand red (#113688) 2026-07-25 06:30:22 -07:00
Peter Steinberger
a2acc8a755 fix(ui): keep subagent details in task panel (#113671) 2026-07-25 06:13:06 -07:00
Peter Steinberger
d56a270ffc fix(ui): keep the sidebar run indicator on the left (#113645) 2026-07-25 06:04:05 -07:00
Peter Steinberger
3c5415805c refactor(ui): mechanical dedup batch (#113649)
* refactor(ui): share sidebar menu contracts

* refactor(ui): share segmented controls

* refactor(ui): deduplicate slash menu keys

* refactor(ui): share persisted set storage

* refactor(ui): centralize fnv hashing

* refactor(ui): reuse workboard helpers

* refactor(ui): remove stale terminal style

* fix(ui): align sidebar menu callback type
2026-07-25 05:37:57 -07:00
Peter Steinberger
b26776fbca feat(ui): syntax-highlight read-only cron script payloads (#113632)
Locked script/command automations rendered their source in a plain textarea. They now render as a resizable, highlighted read-only code block reusing the existing highlight.js path.
2026-07-25 05:14:06 -07:00
Peter Steinberger
fde3cdf27b perf: multi-select archiving no longer stalls a second per row (#113623)
* perf(ui): refresh the session list once per batch action

Batch sidebar actions patched each row and then forced a full sessions.list
replacement per row, so archiving a nine-row multi-select paid nine list
rebuilds on top of nine patches. Measured against the gateway handlers on a
60-session store, sessions.list costs ~2.9s versus ~176ms for sessions.patch.

Batch rows now pass deferListRefresh and each batch helper issues one refresh
per owning agent after its last row; pushed sessions.changed events keep rows
reconciled while the batch runs. Single-row actions are unchanged.

* test(ui): prove batch archive costs one list refresh in the browser

Adds a Control UI e2e case that cmd-clicks three sidebar rows, archives the
selection from the batch menu, and asserts the Gateway saw three sessions.patch
calls in row order plus exactly one sessions.list. It holds past the batch so a
late per-row refresh would still be caught.

Before the batch-refresh change this flow issued one full sessions.list per
archived row.
2026-07-25 05:06:07 -07:00
Peter Steinberger
f43fac21c7 fix(gateway): stop showing retired HEARTBEAT.md in the agent files editor (#113621)
* fix(gateway): drop retired HEARTBEAT.md from agent core files

* fix(ci): stop asserting retired HEARTBEAT.md in docker release smoke

* docs: align HEARTBEAT.md references with cron scratch

* docs(agents): drop retired HEARTBEAT.md from workspace read comment
2026-07-25 04:58:31 -07:00
Peter Steinberger
421e287c45 fix(ui): show Swarm progress in Chat (#113619)
* fix(ui): show Swarm progress in chat

* style(ui): format rebased Swarm integration

* fix(ui): bound inline Swarm progress height
2026-07-25 04:36:50 -07:00
Peter Steinberger
d2ff17acc3 fix(ui): prevent Zod eval under strict Content Security Policy (#113617)
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
2026-07-25 04:16:17 -07:00
Peter Steinberger
66615987d3 fix(control-ui): keep polling gateway-driven setup progress (#113613) 2026-07-25 04:04:56 -07:00
Peter Steinberger
e069b9dbdd fix(ui): repair settings titles, scope form-unsafe banner, consolidate advanced settings (#113160)
* feat(ui): repair settings titles, scope form-unsafe banner, consolidate advanced tier

- Advanced/Notifications settings headers rendered raw i18n keys
  (tabs.advanced/tabs.notifications); configPageTitle now resolves through
  the nav registry titleForRoute, deleting the drifting key map.
- Form-unsafe banner is value-aware (only when the user's config has a value
  at a form-unsupported path in the active scope), names the paths, offers an
  Open Raw editor action, and sits in the content column instead of full-bleed.
- Advanced tier collapses to one synced toggle: hidden advanced fields render
  a ghost row that enables the toggle; the Advanced page always reveals and
  hides the toggle; per-section details state and the controlled-open dance
  are deleted; toggle visibility mirrors the renderer's tier split.
- schema.tags no longer tags facet-less paths as "advanced" (common fields
  like update.channel wore a lying chip); the chip is no longer rendered in
  form rows while tag:advanced search keeps working.

* fix(config): dev bootstrap writes canonical agents.entries; finish stale agents.list sweep

- openclaw gateway run --dev failed on a fresh state dir: the bootstrap wrote
  the retired agents.list array and validation rejected its own config
  (Unrecognized key: list). It now writes the keyed agents.entries record;
  new dev.test.ts validates the written shape against the zod schema.
- Revive the dead gateway hot-reload rule: prefix agents.list never matched
  canonical config diffs, so per-agent heartbeat edits fell through to the
  agents:none tail rule; the rule now matches agents.entries.
- config set replacement protection moves from the dead agents.list array
  to the agents.entries map (joins plugins.entries/auth.profiles family).
- Sweep remaining stale agents.list config-path strings in hints, fix-it
  messages, elevated gates, doctor hints, audit text, and type docs to
  agents.entries.*; RPC ids, the internal list projection, and doctor
  legacy-migration references intentionally keep the old name.

* test(ui): derive nav i18n audit from route registry; fix stale bootstrap hint assertion

- Knip flagged navigationCopyEntries (test-only export); the audit now walks
  ALL_ROUTES through prod titleForRoute/subtitleForRoute and rejects raw
  dotted-key output, so no export exists solely for the test.
- commands-context-report expected the retired agents.list[] hint wording.

* fix(config): align rebase resolution with main's roster-aware diagnostic

- tool-policy-diagnostic: keep main's test expectations (dotted
  agents.entries.<id> paths from the roster-aware implementation); our
  pre-rebase bracket-style assertions no longer match any code.
- Reapply the placeholder sweep the conflict resolution dropped:
  generic agents.list[] fallbacks in tool-policy-diagnostic and the audit
  sandbox-mode hint now say agents.entries.*.
2026-07-25 00:51:57 -07:00
Peter Steinberger
29e02e84cd fix(ui): prevent dashboard startup flash (#113558) 2026-07-25 00:49:03 -07:00
Peter Steinberger
3018e8b78a refactor: deduplicate micro helpers onto canonical homes (#113534)
* refactor: deduplicate micro helpers

* fix(ai): keep hash prefix helper internal
2026-07-25 00:41:01 -07:00
Jason (Json)
cc1dd8d558 fix(ui): status labels in Control UI fail WCAG AA contrast on their own tint (#113526)
* fix(ui): meet WCAG AA for Control UI status tokens

Status labels (--ok/--warn/--danger/--info) are rendered as text on their
own 8% -subtle tint. Composited over --card and --bg, several pairs fell
below WCAG AA 4.5:1 -- every light-mode token, and --danger/--info in dark.

Retune the failing bases one Tailwind step and re-derive the matching
-subtle/-muted rgba so each pair clears 4.5:1 on card and bg across all six
theme families. Add the missing --info-subtle and adopt it in
.session-avatar--group, whose --ok/--warn siblings were already tokenised.

Non-text uses (status dots, meters, chart bars) only gain contrast, and the
one solid --danger fill carrying white text improves 4.83:1 -> 6.47:1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(ui): state the bound the status contrast audit actually proves

The audit comments named their card/bg bound but not what falls outside it, so
they read as a general guarantee at the exact site the next contributor will
trust. Status labels also land on hover, muted and input surfaces, and one of
those is reachable with real text: the plugins error row sits on a hovered
background at 4.28:1 under dash-light. It improves on the 3.23:1 it replaced,
but it is not AA and the comment should not imply otherwise.

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 01:23:31 -06:00
Peter Steinberger
7eb9fa3389 refactor(media): read persisted media facts first across all consumers (#113496)
* refactor(media): read persisted media facts first across all consumers

PR 2 of the media legacy retirement program. Gateway display projection,
Control UI (history filtering, attachment rendering, initial-turn
handoff), embedded and plugin-harness hydration, replay/prune, late-media
reconstruction, hooks, media understanding, and trajectory capture now
read nested __openclaw.media facts first. Legacy top-level Media* fields
survive only in the narrow persisted-message compatibility reader (rows
predating the PR-1 dual-write) and the public SDK projection.

Non-goals pinned by tests: rendered batches, reply-payload dedupe,
durable session/outbound queues, and lowercase ReplyPayload.mediaUrl(s)
are untouched contracts.

Consumer matrix covers {legacy-only, facts-only, both-equal,
both-conflict, sparse, type-only, media-only} inputs across every
consumer family; prompt/cache goldens byte-identical; 131-file legacy
consumer sweep run individually (two failures reproduce unchanged on
clean main); 1,047 broad media tests and the full UI lane (5,553) green.

* refactor(media): drop caller-less staging predicate and localize empty-user-row classification

The consumer flip left hasStagedMediaProjection without production
callers (facts-only staging uses hasStagedMediaFacts); delete it and
retest the staged merge matrix against the facts predicate. Unexport
LEGACY_MEDIA_CONTEXT_KEYS (internal only; the derived type stays public).
Move isEmptyUserTextOnlyMessage beside the other message-shape
classifiers in ui/src/lib/chat/message-extract.ts where chat-history
imports it cross-module.

* chore(ui): drop unused hasTranscriptMediaFacts import after predicate move

* chore(ui): localize hasTranscriptMediaFacts after its last external consumer moved in

* style: format staged-media matrix assertion
2026-07-24 23:02:53 -07:00
Jason (Json)
5cd60fd9fb feat(ui): publish host style variables to embedded MCP apps (#113464)
* feat(ui): publish host style variables to MCP apps

An embedded MCP app received only the `theme` string, so it knew which
appearance was active but nothing about what that appearance resolves to.
Every app therefore had to ship its own palette, and an app installed through
a plugin looked like itself rather than like the surface hosting it.

Publish the Control UI theme as `hostContext.styles.variables`, the field the
MCP Apps specification defines for exactly this. The key set is closed by the
specification, so the mapping is a table from Control UI custom properties to
specification keys; the canonical meaning of each key lives in the carapace
embed contract.

Only keys Control UI can honestly source are published. The specification
lets a host publish any subset and apps resolve the rest from their own
fallbacks, so omitting is preferable to inventing. The body font is
deliberately omitted: it leads with a webfont, and an embedded app may load
fonts only from resource domains it declares itself, so publishing it would
silently resolve to an arbitrary system face. Apps own their sans stack until
Control UI adopts the carapace embed tokens, which define a sandbox-safe one.

Values are read as computed custom properties so nested references are
substituted before crossing into the app's separate origin, where a Control
UI token name would have nothing to resolve against.

Live updates come free: the existing theme subscription already re-sends host
context, and `theme` continues to be published alongside this.

* fix(ui): align MCP app host theme semantics
2026-07-24 23:06:33 -06:00
Peter Steinberger
c30c07071f feat(setup): download-model actions on web and macOS onboarding (#113476)
* feat: add local model download setup actions

* chore(i18n): refresh native source inventory

* fix(setup): satisfy model setup lint checks
2026-07-24 20:52:58 -07:00
Peter Steinberger
cd76809d9a feat(ui): render chat notice rows as markdown (#113450)
System-notice rows (local slash-command output such as /help) now render
through the shared sanitized markdown pipeline (code-block chrome off,
DOMPurify allowlist, breaks preserved) instead of literal pre-wrap text,
so authored bold/inline-code formatting displays properly. Block content
(lists, pre, blockquote) centers as a block but reads left-aligned.
Follow-up to #112938.
2026-07-24 18:50:07 -07:00
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
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