Commit Graph

79 Commits

Author SHA1 Message Date
Peter Steinberger b5b17c654b fix: keep Workboard visible in the sidebar (#125473)
* fix(ui): keep workboard in sidebar navigation

* test(ui): align workboard navigation ownership

* fix(ui): preserve saved workboard sidebar slots

* test(ui): shrink assertion safety baseline

* fix(plugins): bind native routes to bundled owners

* refactor(plugins): isolate native route policy
2026-08-17 18:44:39 -07:00
Peter Steinberger b228c83bfc feat(dashboard): add session:progress board tile rendering the live progress card (#125438)
* feat(dashboard): add session:progress board tile rendering the live progress card

Advertise the core-owned widget kind via hello controlUiWidgetKinds at operator.read.
Render it inline without an iframe from the session-progress-cards store.
Pin it with dashboard tool widget_put using pluginKind session:progress and optional props.sessionKey.
Follow up the progress-card unification from #125125.

* fix(dashboard): surface session progress load failures

Record protected progress-card read failures in the shared per-session store.
Render an actionable board-tile error with retry instead of indefinite loading.
Cover the rejected-read and successful-retry flow at the widget boundary.

* fix(dashboard): honor progress tile access and activity

Avoid progress-card reads while a retained board is inactive.
Distinguish sharing denial from transient load failures and show the correct remedy.
Qualify cross-session pinning docs and cover activation plus denial behavior.
2026-08-17 16:56:23 -07:00
Peter Steinberger de9b367214 fix(ui): generic mock chat sends show a visible outcome (#125347)
* fix(ui): make generic mock chat sends observable

* test(ui): stabilize control UI e2e timing
2026-08-17 11:40:56 -07:00
Peter Steinberger 2915e563d6 feat(workboard): show full boards on session dashboards (#125094)
* feat(workboard): full-board dashboard widget

Adds a third trusted plugin widget kind, workboard:board, rendering the
complete Kanban board (all columns, live plugin.workboard.changed
refresh) inside a session dashboard. Props {boardId} scope it to one
board; without it the widget shows every board, matching workboard:mini
semantics. Card rendering reuses the workboard page renderColumn with an
explicit surface option so page and widget cannot drift; the shared
board filter moved to ui/src/lib/workboard/board-filter.ts. Mutations
follow the connection's canMutate; read-only connections get a
view-only board.

Proof: pnpm test ui/src/lib/board ui/src/pages/workboard
ui/src/lib/workboard extensions/workboard (9,494 passed), i18n baseline
green, autoreview clean (codex/gpt-5.6-sol). tsgo core/ui/extensions
green locally; remote check:changed blocked by Daytona capacity and the
tsgo:core Daytona exit reproduced locally as a heavy-check lock race,
passing on retry.

* test(ui): seed workboard fixtures in the mocked dev server

* fix(ci): register workboard proof capture script
2026-08-16 23:19:30 -07:00
Peter Steinberger fa642a305e fix(ui): drop duplicate plan card summary (#124895) 2026-08-16 16:45:23 -07:00
Peter Steinberger 68762ad22c fix(ui): give queued-outbox badges their own outbox icon (#124842)
The sidebar queued-message badge and the composer queue reused the clock
glyph that also marks attached automations, so a session with both showed
two identical clocks distinguishable only by tooltip. Add an outbox tray
icon (Lucide inbox with the roof swapped for a rising arrow) and use it
for queued-to-send surfaces; the clock stays automation/cron-only. The
mock dev fixture now flags one session with hasAutomation so the badge
renders in mocked-dashboard proofs.
2026-08-16 14:29:41 -07:00
Ayaan Zaidi 1425d944ca fix(ui): show Claude Code logo in mock Control UI sidebar (#123496)
The mock catalog used id claude-code, but the sidebar only brands registered plugin ids (claude).
2026-08-14 05:37:33 +00:00
Peter Steinberger 9415181b75 fix(ui): make active visibility pill distinct from its hover state (#123173)
* fix(ui): make active visibility pill distinct from its hover state

* test(ui): advertise sessions.create in the control-ui mock harness

* ci: refresh pull_request run after zombie-queued Blacksmith jobs
2026-08-13 12:42:40 -07:00
Peter Steinberger 6f39f953ec fix(ui): show each chat panel button once, in the pane header (#122507)
* test(ui): advertise terminal and browser panels in the mock harness

The mocked Control UI never advertised browser.request or terminal.open and
left terminalEnabled false, so the chat header's panel toggles were invisible
in the harness and could not be visually verified.

* fix(ui): give the chat pane header the only panel toggle row

The session workspace rail header rendered Terminal, Browser, Ask OpenClaw and
Changes alongside its own dock/refresh/collapse controls. Terminal and Changes
already lived in the chat pane header, so both rendered twice at once, while
Browser was reachable only from inside a files rail and Ask OpenClaw sat in a
per-session rail despite being a global surface that already owns a sidebar
entry (settings route 'custodian').

The rail header now owns workspace-file actions only. Browser moves up to the
pane header beside Terminal and into the narrow-header overflow menu; the
duplicated Terminal and Changes buttons and the Ask OpenClaw toggle are gone.

Production LOC: +21 -84.

* test(ui): stop the vite stub from shadowing the mock bootstrap config

ui/vite.config.ts registers a placeholder /control-ui-config.json middleware
and config-file plugins load before inline ones, so the mock gateway plugin's
bootstrap body never reached the app and every scenario bootstrap field was
silently dropped. Marking the mock plugin 'pre' lets it answer first.
2026-08-12 00:13:13 -07:00
Peter Steinberger ee7fae8a90 fix(ui): native command settings no longer require Raw mode (#121832)
* fix(ui): render native command settings controls

Render boolean-or-auto command settings as safe On/Off/Auto controls instead of forcing Raw mode, while preserving typed config values and fail-closed handling for unsafe unions.

* fix(ui): preserve oneOf union exclusivity
2026-08-10 21:28:06 -07:00
Peter Steinberger b81946d6af fix(ui): make Cloud Worker startup responsive (#121200)
* fix(openai): filter platform-only ChatGPT catalog rows

* fix(ui): show Cloud Worker startup progress

* fix(ui): keep cloud startup out of app bootstrap

* fix(ui): reduce cloud startup bootstrap cost

* fix(ui): satisfy cloud startup lint

* fix(ui): keep cloud startup within UI limits

* fix(ui): satisfy cloud startup CI limits

* fix(ui): isolate concurrent cloud startup

* fix(ui): address cloud startup review findings

* fix(ui): persist cloud startup recovery per session

* style(ui): format cloud startup chat props
2026-08-09 22:42:45 -07:00
Patrick Erichsen d4c3b9e783 refactor(sessions): remove custom icon feature (#121263)
* refactor(sessions): remove custom icon feature

* test(sessions): expect legacy icons to be stripped

* fix(gateway): preserve retired icon request compatibility

* chore(plugin-sdk): refresh API baseline

* fix(plugins): reserve retired session icon slot
2026-08-10 04:51:56 +00:00
Vyctor H. Brzezowski 45da07ed20 improve(ui): align session context menu rows, icons, and shortcut hints (#121383)
Menu rows stacked Web Awesome's shadow icon margin on top of our flex gap
(~17px gutter), let the icon slot baseline-align ~2px above the label centre,
drew shortcut hints at 550 weight beside 400-weight labels, and left the submenu
chevron 4px inside the hint column at a heavier size.

Rows now use a single icon column, optically centred icons, quiet mono keycap
hints on one rail, a chevron sharing that rail, and a divider inset to the same
columns. The control UI mock harness also advertises the session mutation
methods so the menu renders enabled instead of fully disabled.
2026-08-10 01:18:35 -03:00
Peter Steinberger ea50fe8453 fix(ui): open mock catalog sessions without crashing (#120444) 2026-08-07 23:21:54 -07:00
Peter Steinberger faf2602d22 fix(ui): keep native context menus out of the sidebar and make session catalogs hideable (#118217)
* fix(ui): keep native context menus out of the sidebar and make session catalogs hideable

Suppress the WKWebView default context menu across the sidebar while preserving editable inputs, and route agent cards and session-catalog headers to the existing menus. Persist hidden session sections in localStorage and expose live-synced Show controls under Settings → Appearance → Sidebar.

Co-authored-by: Codex <codex@openai.com>

* test(ui): serve mock session catalogs so the sidebar catalog sections are exercisable in dev:ui:mock

Advertises sessions.catalog.list and returns synthetic Codex/Claude Code
catalogs, enabling reproducible live proof of the catalog header context
menu and hide/restore preference flow.

Co-authored-by: Codex <codex@openai.com>

---------

Co-authored-by: Codex <codex@openai.com>
2026-08-02 16:02:53 -07:00
Vincent Koc 1065c1d697 fix(ui): identify source builds in settings footer (#116134)
* fix(ui): identify source builds in settings footer

* fix(release): classify all official Control UI builds
2026-07-30 08:58:34 +08:00
Peter Steinberger d885f9175d feat(ui): move settings save feedback into the sidebar footer (#115679)
* feat(ui): move settings save feedback to sidebar

* test(ui): support stateful config writes in mock gateway

* test(ui): add save indicator to memory sidebar test
2026-07-29 04:10:56 -04:00
Peter Steinberger 6fbaa4d232 ui: complete contextual Settings documentation links (#115665)
* feat(config): require docs decisions for root settings

* feat(ui): link settings pages to guides

* refactor(ui): keep model providers page compact

* fix(ui): style page subtitles and carry base hints in mock dev
2026-07-29 03:35:28 -04:00
Peter Steinberger 7a1aa4eb4f feat(ui): Talk settings page with catalog-driven realtime pickers (#115409)
* feat(talk): emit realtime models and voices in talk.catalog and mirror create-time readiness

* feat(ui): add curated Talk settings page with catalog-driven pickers

* docs(talk): correct stale claims and add one-page GPT-Live setup path

* fix(ui): refresh Talk catalog on config-hash advance and neutralize GPT-Live badge

* fix(ui): provider-aware Talk selection, atomic provider switch, focus refresh

* fix(ui): resolve Talk provider fallbacks via catalog and make Default a true reset

* fix(ui): provider-compatible transports and race-free Talk catalog loads

* fix(ui): never resolve an unknown explicit Talk provider to the active one

* docs(talk): note Android relay readiness caveat for browser-only models

* fix(ui): keep the relay transport when switching Talk provider to Auto

* fix(ui): align section-ownership test and drop unused export after rebase
2026-07-28 17:38:15 -04:00
Peter Steinberger 699315e7d7 feat(ui): redesign Ask OpenClaw — mascot, shared surface, dockable panel (#115123)
* refactor(ui): share custodian chat surface

* feat(ui): add dockable custodian panel

* refactor(ui): drop write-only panel-close latch from custodian store

* feat(ui): demo custodian in mock gateway

* chore(ui): update raw-copy baseline for custodian strings

* fix(ui): clean custodian surface/page/mock lint debris
2026-07-28 08:05:38 -04:00
Peter Steinberger add9205d1a fix(ui): explain every channel setting and link its docs (#114844)
* feat(config): give shared channel settings help text

* fix(ui): space the settings tiers and stop repeating help on list items

* feat(ui): link each channel detail to its docs page

* test(ui): mirror production channel hints in the mock dev server

* docs: note the shared channel help inheritance for plugin authors

* fix(config): let a channel suppress shared help with an empty string

* chore(config): regenerate bundled channel metadata for the new WhatsApp hints

* fix(ci): check bundled channel metadata locally

* chore(release): keep changelog release-owned

* chore(release): keep changelog release-owned

* fix(ui): keep shared channel help contract-neutral
2026-07-28 05:25:58 +00:00
Peter Steinberger fbb3525368 fix(ui): show a simple channel settings view with a flip to advanced (#114741)
* test(ui): make channel settings renderable in the mock dev server

* fix(ui): hide advanced channel settings behind the shared advanced tier

* fix(ui): widen the tier renderer callback to lit's nothing

* fix(ui): keep the advanced collapse control on advanced-only channel forms

* docs: note the shared advanced tier on channel settings
2026-07-27 16:39:23 -04:00
Peter Steinberger 762f04da5a refactor(ui): redesign channels DM access requests, drop channel-health JSON card (#114717)
* feat(ui): serve DM pairing fixtures from the mock dev harness

* refactor(ui): align channels DM access requests with the settings design language and drop the channel-health JSON card
2026-07-27 16:15:54 -04:00
Peter Steinberger f23928e418 fix(ui): keep channel action labels on one line and surface QR next to actions (#114708)
* fix(ui): keep channel action labels on one line and surface QR next to actions

* fix(test): drop duplicate prewarm test from attempt-extra shard config
2026-07-27 15:55:38 -04:00
Peter Steinberger fa2b84697b feat(dev): add cron fixtures to the Control UI mock server (#114248) 2026-07-26 23:08:22 -04:00
Peter Steinberger c59d38138e fix(scripts): make the mock Control UI exec approval opt-in via --fixture=approval (#114246) 2026-07-26 23:06:03 -04:00
Peter Steinberger f90cef67c8 feat(ui): drag custom sidebar groups between built-in session zones (#113948)
* feat(ui): drag custom sidebar groups between built-in session zones

* test(ui): remove stale split ratio fixture

* perf(ui): raise startup budget baseline for session-section ordering pref
2026-07-25 19:11:25 -07:00
Peter Steinberger ce5ab8adb8 refactor(gateway): remove dead sessions.observer.ask rpc (#113791)
* refactor(gateway): remove dead sessions.observer.ask rpc

* docs: record btw and companion contract split

* fix(gateway): unexport observer model sanitizer after ask removal
2026-07-25 14:44:02 -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 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 aa35dc8c40 feat(ui): builtin observer board card with digest timeline (#112565)
* feat(ui): builtin observer board card with digest timeline

* fix(ui): satisfy type and deadcode gates for observer board card
2026-07-22 01:44:04 -07:00
Peter Steinberger 1a8583ba45 feat(gateway,ui): ask-the-observer questions from the session HUD (#112448)
* feat(gateway,ui): ask-the-observer card input over sessions.observer.ask

* refactor(ui): single home for observer run-identity helper after restack

* test(ui): drop duplicated observer hud test after restack

* test(ui): give the observer ask flow its own colocated suite

* refactor(gateway): leaf observer contract and ask module split for ci gates

* refactor(gateway): drop observer contract re-export shims
2026-07-21 20:59:32 -07:00
Peter Steinberger 1f0a3ecc68 feat(ui): session observer HUD, sidebar subtitles, and settings (#112260)
* feat(ui): session observer HUD, subtitle integration, and settings

* test(ui): observer demo fixtures for the mock control-ui harness

* fix(ui): satisfy lint and deadcode gates for observer surfaces

* test(ui): adopt renamed pull-request summary api after rebase

* fix(ui): clean rebase artifacts in observer test files
2026-07-21 17:05:14 -07:00
Peter Steinberger 025e6ceee0 fix(ui): theme board fixture dropdowns (#111998) 2026-07-21 07:22:16 -07:00
Peter Steinberger a370785bab fix(ui): populate mock profile identity (#112296) 2026-07-21 05:55:46 -07:00
Peter Steinberger a44efc0348 improve(ui): device-family icons in Places and shared platform labels (#112209)
Places rows now carry destination icons: monitor for the Gateway and
Mac-family nodes, a phone glyph for phone-family devices, and a server
glyph for cloud workers. The platform prettifier moves from the devices
inventory page into ui/src/lib/platform-label.ts so place-picker
tooltips and Settings/Devices render identical platform names (macOS,
not darwin).
2026-07-21 01:46:11 -07:00
Peter Steinberger dd6e366d94 improve(ui): show real machine identity in the place picker (#112162)
* improve(ui): show real machine identity in the place picker

The place picker labeled the gateway destination with a hardcoded
'Gateway · local' and let duplicate device names collide. The gateway
destination now shows the host's machine name via the existing
system.info method (falling back when unavailable), node rows carry
platform/model/IP facts as tooltips, and duplicate labels — same-named
devices and same-basename recent folders — get a deterministic muted
suffix chosen collision-only (model, then IP, then id; parent folder,
then path, then node facts for recents). IP addresses never render
inline by default. Phone-family nodes get a phone chip icon.

* fix(ui): appease prod-type and no-shadow gates in place identity helpers
2026-07-21 00:12:27 -07:00
Peter Steinberger 94b3345623 improve(ui): unify new-thread folder and where pickers into one place picker (#112035)
* improve(ui): unify new-thread folder and where pickers into one place picker

The new-thread draft asked for one decision (where does this thread run)
through two chips with separate popovers, a dead-end target-list panel
with a disabled back button, and a machine menu that rendered even when
the Gateway was the only choice. One chip now carries the (destination,
folder) pair; its popover stacks a root menu (workspace, recent places
derived from the session list, browse, places, worktree) over the folder
browser, back and Escape pop one level, and the destination axis only
appears when there is a real choice or an existing selection.

* fix(ui): give recentPlaces a production consumer module for the knip gate

Knip's production scan rejects test-only exports; the recents derivation
moves to recent-places.ts, imported by the place picker, and the unit
test follows it.

* fix(ui): drop stale place-picker.test.ts left behind by the rename
2026-07-20 22:00:33 -07:00
Peter Steinberger e2e394e1ab fix(ui): give roster rows their avatar-text gap and add presence mock fixtures (#111689)
* fix(ui): add avatar-text gap in roster menu and presence mock fixtures

* refactor(ui): keep presence snapshot helper out of the connect auth hunk
2026-07-19 23:38:40 -07:00
Peter Steinberger 40d31f3481 feat(control-ui): show relative commit age and hover-only copy button on About (#111495)
The About page commit row now embeds the commit's committer timestamp
(commitAt, advisory like branch/dirty) and renders it as an always-relative
age with the exact localized date-time on hover. The copy button becomes a
compact borderless icon revealed on hover/focus only where hover exists;
touch keeps it visible.
2026-07-19 11:13:25 -07:00
Peter Steinberger 3a5da4faa8 feat(ui): live agent activity subtitles on running sidebar sessions (#111221)
* feat(ui): live agent activity subtitles on running sidebar sessions

* refactor(ui): lazy-load narration controller off the startup chunk, unexport test-only symbols

* chore(ui): raise startup JS budget to 312 KiB for the lazy narration feature

* test(ui): restore real timers after narration controller cases
2026-07-19 01:08:06 -07:00
Peter Steinberger 6c2973dee4 feat(ui): automatic session attention states in the sidebar (#111035)
* feat(ui): automatic session attention states in the sidebar (question, approval, failed run)

* test(ui): split attention presentation and read-marker cases under line budgets

* fix(ui): restore precise chat-pane test-support signatures
2026-07-18 17:43:59 -07:00
Peter Steinberger 9e0780c5a0 fix(ui): styling sweep — compact number steppers, one accent for check controls, composite-page cleanups (#110845) 2026-07-18 18:34:19 +01:00
Peter Steinberger 8a66aa76dd feat(ui): session board grid engine and board view (#110644)
* feat(ui): add session board grid view

* fix(ui): use shared board controls

* fix(ui): keep board cell registration type-safe

* chore(ui): drop unused board cell class export
2026-07-18 09:40:41 -07:00
Peter Steinberger 88e5af7097 feat(ui): interleaved sidebar zone with custom session icons and drag ordering (#110682)
* 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
2026-07-18 17:13:09 +01:00
Peter Steinberger 74880cb56f feat(ui): manage MCP servers directly from Settings → MCP (#110654)
* feat(ui): manage MCP servers directly on the Settings MCP page

* refactor(ui): mcp config section owned by the MCP settings page only

* chore(ui): drop test-only McpServersCard export for knip
2026-07-18 12:54:05 +01:00
Peter Steinberger 6032dec3ba fix(ui): make mock sessions archive flow usable (#110556)
* fix(ui): complete mock sessions archive flow

* fix(ui): scope archive filtering to stateful fixtures
2026-07-18 09:27:01 +01:00
Peter Steinberger f93bfc240b fix(ui): render pinned sessions headerless like sidebar nav entries (#110476) 2026-07-18 08:20:52 +01:00
Peter Steinberger 75e4103c57 feat(ui): five-zone sidebar — agent identity card, threads/groups/coding, footer bar (#110259)
* feat(ui): five-zone sidebar with agent identity card, threads/groups/coding zones, and footer bar

* fix(ui): promote main-session children via the gateway row's literal key

* fix(ui): filter and sort promoted main-session threads; hide empty Coding count

* fix(ui): collapsed zones no longer consume the visible session page budget

* fix(ui): a11y — offline card label and catalog lists outside the Coding list container

* fix(ui): zone headers use pre-pagination counts so paged-out zones stay visible

* chore(ui): document catalog-adoption dedup invariant on promoted threads

* chore(ui): seed five-zone sidebar fixtures in the mock-dev harness

* fix(ui): resolve the canonical global main key for the identity card under global scope

* fix(ui): global scope resolves the global sentinel as canonical main even pre-hello

* fix(ui): drop dead channelDisplayLabel, avoid map-spread, type zone test helper
2026-07-18 02:39:17 +01:00
Peter Steinberger 2ecc6b6b6b fix(ui): show restart banner for unapplied config (#107577)
* fix(ui): derive config apply state from gateway

* test(ui): align applied config hash coverage

* test(ui): follow config autosave flow

* fix(ui): guard applied config refreshes

* fix(ui): reconcile patched config revisions

* fix(ui): prevent stale config apply polling

* chore: leave release notes to release flow

* refactor(config): split applied revision helpers

* style(config): format gateway methods

* fix(i18n): refresh Korean native glossary hash
2026-07-14 08:43:35 -07:00