Commit Graph

88 Commits

Author SHA1 Message Date
Vyctor H. Brzezowski 02be7fea97 improve(ui): unify resize handles (#125066)
* improve(ui): unify resize handles

* perf(ui): trim resize handle startup cost

* fix(ui): stop resize drags on blur

* perf(ui): absorb resize blur cleanup

* perf(ui): unify resize drag listener target

* refactor(ui): unify resize drag state

* perf(ui): remove duplicate resize styles

* refactor(ui): let layouts own resize edges

* fix(ui): preserve resize interaction contracts

* test(ui): satisfy resize event lint
2026-08-19 21:11:39 -03:00
Vyctor H. Brzezowski b24430fd04 improve(ui): unify transient surface elevation (#125065)
* refactor(ui): unify transient surface tokens

* test(ui): reveal transient session menu before click

* test(ui): scope transient menu surface to session row

* test(ui): target transient session menu by accessible owner

* test(ui): capture transient surface proof

* fix(ci): register Codex tool coverage

* fix(protocol): keep version exports compact
2026-08-19 11:44:35 -03:00
Peter Steinberger 4af09d4961 feat(ui): unify focused presentation routes (#126143)
* feat(ui): unify focused presentation routes

/focus/<target> replaces unshipped standalone query links across dashboard, terminal, desktop, and native apps.

Gateway-served index assets are anchored so nested documents resolve their bundles from the Control UI base path.

* test(gateway): narrow emitted asset URLs

Fixes check:test-types TS18048/TS2322 by dropping unmatched optional captures before comparing emitted asset URLs.

* test(docs): follow centralized cloud secret guidance

Fixes the stale current-main docs test after #126132 centralized GCP and Hetzner setup in docker-vm-runtime.

* test(ui): retry missing locator reads

The 500ms locator text read can time out while the menu label is still rendering, causing expect.poll to reject instead of using its owning 10s retry window. Treat only Playwright TimeoutError as a missing value so the outer poll retries while page-closure and arbitrary failures still surface.

* test(android): capture TLS probe coroutine

The TLS probe test inferred its coroutine from mutable scope children, racing unrelated child startup and teardown in CI. Capture the exact Job from inside the probe coroutine and join that owner before asserting the stale-attempt guard.

* fix(gateway): preserve plugin focus routes

Keep approval handling ahead of plugin dispatch, but treat focus documents as an unclaimed Control UI fallback after plugin authentication and routing. Exact and prefix plugin routes therefore retain ownership, while unclaimed reads serve the focus document and other methods return 404.

* fix(ui): migrate released terminal links

Preserve stable v2026.7.1 terminal query compatibility by rewriting the root/base ?view=terminal URL once to the canonical /focus/terminal path with history.replace. Keep URL parsing path-only, and leave the removed desktop and dashboard query forms as a hard cut.

* test(codex): assign run-attempt tools shard

Cached filtered configs caused duplicate ownership, and the test lacked a canonical full-suite owner.

* test(ui): keep cloud recovery proof state-owned

The recovery test should assert owner state and reload identity, while dedicated tests own transient alert visibility.

* test(qa): wait for outbound bus state

* fix(qa): reserve gateway ports through staging

* refactor(qa): keep socket creation in gateway owner
2026-08-19 03:41:29 -07:00
Peter Steinberger 41ed3c3460 fix(ui): buttons use the default cursor instead of the link hand (#126153)
* fix(ui): reserve pointer cursors for links

* test: align cursor and docs contracts
2026-08-18 21:40:52 -07:00
Peter Steinberger bdbb0444ee fix: share Control UI terminals with chat agents (#125758)
* fix: share Control UI terminals with chat agents

* fix: terminate canceled shared terminal opens

* perf(ui): keep terminal binding behind lazy boundary

* perf(ui): reuse terminal session scope for bottom dock

* perf(ui): reuse session route decision

* fix: keep shared terminal cleanup server-owned

* fix: preserve shared terminal session identity
2026-08-18 07:51:48 -07:00
Peter Steinberger ac5c8be001 fix(ui): keep agent terminals backgrounded (#125101) 2026-08-16 23:32:06 -07:00
Peter Steinberger b8a95e082b fix(ui): make terminal open failures retryable (#124890) 2026-08-16 16:15:24 -07:00
ClawSweeper a4efa7c22b fix(ui): replace the broken terminal tab underline (#124875)
* fix(ui): redesign dock panel tabs

* fix(ui): remove stale terminal tab overrides

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-16 16:11:30 -07:00
Peter Steinberger d61202b128 fix(ui): redact errors across Control UI surfaces (#124552)
* fix(ui): redact errors through canonical formatter

* fix(ui): route remaining error paths through canonical redacting formatter

* fix(ui): route worktrees-page and remaining raw error renders through redacting formatter

* style(ui): normalize labs import order

* fix(ui): preserve structured error messages through formatter

* test(ui): align memory refresh warning with canonical formatter

* fix(ui): redact chat background-task rail failures

* fix(ui): redact all externally-sourced text at render boundaries

* fix(ui): keep external redaction paths type-safe
2026-08-16 08:09:50 -07:00
Peter Steinberger 1384e277af refactor(types): enforce chained-assertion guard in AI and UI (#124361)
* refactor(types): drain chained-assertion ledger — ai and ui

* refactor(ui): extract chat state contract

* fix(ai): preserve strict Claude request cleanup

* test(ui): synchronize terminal timeout clock

* fix(ui): validate observer digest before run mutation
2026-08-15 22:25:42 -07:00
Peter Steinberger e68f3d8ad1 fix(ui): surface rejected terminal actions (#124046)
Mark stale terminal tabs exited when the Gateway rejects input or resize, so operators see an actionable outcome instead of silently losing keystrokes.
2026-08-15 19:53:47 -07:00
Vyctor H. Brzezowski aed4510bd0 improve(ui): unify chat side rails in a tabbed panel (#123874)
* Control UI: unify chat rails in a tabbed panel

* fix(ui): compact chat side panel navigation

* Polish rail separators around the active tab

* Soften rail tab separators

* Inset the rail tab strip from the resize handle

* Remove the rail tab strip bottom rule

* Add compact close controls to rail tabs

* Redistribute rail tabs after closing a surface

* Restore bottom docking from the rail terminal

* Fade clipped rail tab labels at the edge

* Add drag reordering to rail tabs

* Polish terminal tab chrome

* Polish rail tab close controls

* Regularize rail tab separators

* Space rail tabs evenly

* Add feedback to inactive rail tabs

* Smooth rail tab selection

* Hide unavailable rail menu items

* Preserve browser multi-tab entry

* Support bottom-docked rail tabs

* Polish rail tab sizing

* Refine side panel actions

* Neutralize rail empty-state icons

* Separate dark rail surfaces

* Fade only clipped rail tab labels

* Compact rail header controls

* Refine the surface picker

* Raise and tighten the surface empty state

* Keep Browser and Tasks in the chat topbar

* Unify surface list cards

* Keep embedded rails inside their dock

* Reveal rail tab close actions on demand

* Show full rail labels only when clipped

* Let rail tabs use available space

* Align chat topbar surface controls

* Unify rail surface empty states

* Center rail tab glyphs

* Fade clipped rail labels smoothly

* Keep rail tab labels visible

* Tighten rail tab separator and label fade

* Keep the new-tab control beside the rail tabs

* Keep rail tab separators from reflowing on activation

* Anchor the new-tab control outside the rail tab scroll

* Scroll rail tabs at the floor instead of clipping them

* Tighten spacing between rail tabs

* Report an unusable terminal open response as a readable failure

* Keep the terminal session menu inside the panel

* Share one dock destination cluster across rails, terminal and browser

* Align the terminal mini rail with its management icons

* Tidy panel pickers, browser chrome and task detail retry

* Type the sidebar callbacks object so tsgo:ui passes

* Space out the panel picker rows

* Measure tab strip edges by rect and cancel superseded installs

* Validate every terminal session field and release unusable sessions

* Fold the terminal rail stretch rules into one

* test(ui): match rail tab checks to the tabbed panel header

Anchoring the new-tab control outside the scroll area wrapped the strip in
.side-panel__header-tabs, and every query written as a direct-child chain
started matching nothing. The assertions did not fail loudly: they compared
an empty label list, so three side-panel journeys and the background-tasks
rail went red on a selector detail rather than on behaviour.

Give the label query one named owner scoped to the panel's own header, so
Terminal and Browser strips in the panel body stay excluded while header
layout can keep moving. Freeing that width also means two short tabs now
fit where they used to be squeezed, so the closing step asserts the honest
invariant - a strip that fits again releases the fade - while the overflow
and tooltip regime stays proven earlier in the same journey.

Settle the shared side-panel helper on whichever surface renders: an empty
panel offers its type list and a populated one offers the header menu, and
probing before either existed left it waiting for a control that never
comes. Also drop a shadowed seed binding and an unused locator that oxlint
flagged in the same file.

* fix(ui): adapt session discussion slot to the unified panel layout

* test(ui): capture the bottom dock evidence with a resting divider

* fix(ui): drop the dead previousDock toggle path

* test(ui): align sibling suites with the tabbed panel decisions

* fix(ui): keep narrow-pane hides above the icon-button styling cascade

* fix(ui): create tooltip descriptions via ownerDocument

* fix(lint): merge duplicate terminal header styles and drop dead branches

* refactor(ui): extract embedded panel templates from the pane render

* refactor(ui): delete rail-era dead exports

* test(ui): repair type drift after the rebase

* fix(ui): keep the workspace toggle module-local and settle test caps

* fix(ui): give side-panel tabs their runtime and their own header actions

The tabbed side panel dropped two things the old rails owned. The discussion
tab lost its only runtime registration, so `openclaw-session-discussion` was
never defined and the tab rendered as a permanently blank box; it now loads
through the per-slot lazy runtime map like the other panel types.

Panels also have no header of their own anymore, so any action on the active
panel's content had to reach the shared header. The header now takes panel
contributed actions instead of a discussion-only open-url special case, which
brings back the side-chat "Clear thread" overflow menu — its gateway reset had
no reachable entry point at all in the embedded rail.

* test(ui): anchor the sidebar scroll proof to the panel host

The bounding contract moved from `.sidebar-column__panel` to
`.side-panel__panel`; mounting the detail panel under the removed class let it
grow instead of scroll, so the test failed for its harness rather than for the
behavior it guards.

* refactor(ui): move side-panel wiring out of the chat render monolith

`chat-pane-render.ts` crossed its line budget. The region callbacks are layout
policy, so they resolve in the layout module with the pane injecting only what
it owns, and the two panel-action producers collapse into the single header
contribution the region consumes.

* fix(ui): keep one terminal intent queue per document

A session route mounts the side-panel terminal beside the shell instance kept
for the bottom dock. Each owned a private action array over one sessionStorage
key, so their whole-array writes erased each other's intents and a freshly
mounted panel drained through a reconnect fence it never saw.

The queue, its persisted record, and the fence now belong to the document;
panels bind as executors while connected. The chat pane records a toggle intent
where it observes it, instead of parking the raw event in memory and handing it
to a panel that may not be mounted yet — a service-worker reload in that window
dropped the request, thread id and all, with nothing explaining why. That makes
the deferred-restore handshake dead weight, so it goes.

* fix(ui): let the panel that starts a terminal intent finish it

Opening a catalog terminal from a chat route mounts the side-panel terminal
right after the request, which swapped the queue's executor mid-flight and
stranded the in-flight action; the panel's own mount restore then opened a
plain session instead. The executor that began an action stays responsible for
it as long as it can still run.

* test(ui): cover closed legacy side docks

* refactor(ui): split side panel controllers

* fix(ui): stabilize embedded panel handoffs

* style(ui): format browser panel refresh

* test(ui): settle catalog prepend paint incrementally

* docs(ui): describe the unified chat side panel

* test(ui): settle catalog clock transitions

---------

Co-authored-by: Jason (Json) <263060202+fuller-stack-dev@users.noreply.github.com>
2026-08-15 20:40:00 -06:00
Vyctor H. Brzezowski f4910cbb38 fix(ui): standardize scrollbar styling across the Control UI (#124285)
* fix(ui): standardize scrollbar styling across the Control UI

Give the Control UI one canonical scrollbar definition (a 12px hit
target with a thin, muted-at-rest, 6px painted thumb, derived from
--muted so every theme family and both modes follow with no override)
and delete the sixteen scattered per-surface overrides that used to
make every scroll container look different.

Shadow-DOM parity ships in the same change: a grouped ::part() rule
covers Web Awesome menus/listboxes, and a shared Lit fragment covers
the terminal/browser/desktop panels' own shadow roots, since neither
::-webkit-scrollbar* rules nor scrollbar-width cross a shadow
boundary on their own.

Fixes #124272

* fix(ui): reach every Web Awesome scroll part through generic selectors

The canonical scrollbar group enumerated six menu hosts plus the settings
select, so every unlisted Web Awesome surface kept the raw platform
scrollbar: a Chromium probe against the previous stylesheet reports
width:auto and a fully transparent thumb for wa-dropdown::part(menu),
wa-select::part(listbox), and wa-popover::part(body).

Style the three generic part families instead -- the same host group the
shared corner treatment already uses at base.css:435 -- which covers every
dropdown, listbox, and popover in the UI and removes 23 production lines.

The new-session composer's ten-line cap test asserted thinness as a
<=6px hit target, which was the old shrink-the-target recipe the canonical
profile replaces. It now asserts the real contract: a 12px hit target
painting a 6px thumb through the transparent border. The chat-page e2e
gains a genericity guard that walks every wa-dropdown/wa-select/wa-popover
on the page and requires each scroll part to report the canonical width,
so an unlisted component cannot silently regress.
2026-08-15 18:41:08 -03:00
WhatsSkiLL 632581477f fix(session-catalog): preserve explicit agent ownership across UI and CLI (#123899)
* fix(session-catalog): preserve explicit agent ownership across UI and CLI

* fix(session-catalog): repair owner routing regressions

* Fix-session-catalog-CI-checks

* test(ui): split chat catalog pane coverage

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* refactor(session-catalog): bind Codex homes per request

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* refactor(session-catalog): centralize owner resolution

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* fix(codex): resolve session fork against the adopted home

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>

* refactor(ui): extract chat session discussion

* test(sessions): stabilize archive worker responsiveness check

---------

Co-authored-by: IWhatsskill <284122573+IWhatsskill@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-15 04:47:28 -07:00
Vyctor H. Brzezowski 9955b70211 fix(ui): toggle terminal main content layout (#122464) 2026-08-15 01:06:54 -03:00
Peter Steinberger ee6c2cb50d fix(ui): terminal actions disappear during Gateway updates (#123578)
* fix(ui): replay terminal actions across refresh fences

* refactor(ui): isolate terminal pending action journal

* refactor(ui): remove terminal storage import cycle

* test(ui): release worker update fence explicitly

* test(ui): gate worker install with held response

* fix(ui): fence stable-client terminal reconnects

* fix(ui): carry selected agent through terminal toggle

* fix(ui): keep terminal toggle event shape stable
2026-08-14 04:34:51 -07:00
Peter Steinberger 204be37803 fix(ui): stale tabs lose terminal owner after Gateway updates (#123526)
* fix(ui): refresh stale clients before terminal reconnect

* fix(ui): hold reconnect fence through worker activation

* fix(ui): isolate reconnect worker refresh

* refactor(ui): own reconnect fence in terminal lifecycle

* test(ui): satisfy reconnect refresh lint
2026-08-14 01:32:33 -07:00
Vyctor H. Brzezowski f73b436f05 refactor(ui): make chat rails full-height resizable columns (#122475)
* refactor(ui): make chat rails resizable columns

* fix(ui): preserve board runtime across rail modes

* fix(ui): unify chat rail chrome

* fix(ui): unify rail header controls

* refactor(ui): normalize rail header chrome

* fix(ui): render background tasks rail

* test(ui): preserve workspace collapse semantics

* fix(ui): keep companion separator single

* test(ui): distinguish companion sheet and column borders

* test(ui): compare shared rail focus chrome

* test(ui): drive rail focus with keyboard

* fix(ui): align single-panel rail headers

* fix(ui): add custodian rail toggle label

* test(ui): narrow mock chat request params

* test(ui): follow shared rail controls

* test(ui): keep rich rail state visible

* fix(ui): center terminal rail actions

* test(ui): keep chat notices in conversation column

* test(ui): detect focus inside rail shadow roots

* test(ui): respect desktop overlay interactions

* test(ui): restore rails after route navigation

* test(ui): rebuild route-scoped rail matrix

* test(ui): preserve custodian rail during matrix

* chore(ui): keep chat pane within lint budget

* test(ui): tolerate subpixel icon geometry
2026-08-13 19:49:11 -03:00
Peter Steinberger dbea5a77f0 fix(ui): make Control UI terminal readable in light mode (#123184)
The light terminal theme reused the dark-background ANSI palette (1.4-2.6:1
contrast on #f7f8fa; brightWhite was 1.06), and the intro banner hardcoded
256-color indices 223/216 that bypass the client theme entirely.

Light mode now gets its own darkened ANSI-16 palette (>=4.5:1, bright
variants darker for emphasis, brightWhite maps to strongest ink), and the
banner emits themable ANSI-16 yellow/bright-red so each mode owns its
rendering. Dark mode is visually unchanged.
2026-08-13 14:14:35 -07:00
Peter Steinberger 8fa897a3f1 improve(ui): align transient menu chrome with design-system geometry (#122109)
* improve(ui): align transient menu chrome with design-system geometry

Use one shared transient-menu recipe across Control UI panels and items.

Match the carapace reference: 6px item radius plus 4px inset yields a 10px panel radius, with restrained motion for fixed menus.

* test(ui): align gateway picker menu expectations

* test(cli): keep benign sqlite diagnostics out of ACP exit stderr assertions

* fix(ui): restore 44px menu touch targets on coarse pointers
2026-08-11 10:08:53 -07:00
Shakker e5adfc3565 fix: settle tab hosts before focus recovery 2026-08-11 18:20:37 +02:00
Peter Steinberger a12e0decd6 refactor(ui): simplify terminal replay lifecycle (#121925)
Behavior-preserving follow-up cleanup related to #121637.

Make replay a required structured contract, move stream currentness into AbortSignal ownership, keep controller construction private to the session owner, and remove the optional replay fallback, exported factory, tab factory state, and nested currentness callbacks.
2026-08-11 00:54:43 -07:00
Peter Steinberger 0b0d9f5811 fix(ui): prevent terminal garble after Gateway reconnect (#121637)
* fix(ui): recreate terminal runtime after replay gaps

Replace Ghostty's in-place reset with a fresh controller/runtime for authoritative recovery replay so Gateway reconnects cannot expose stale WASM terminal state. Preserve replay ordering, focus and tab visibility, and dependency cleanup.\n\nFixes #121636

* test(ui): fix terminal replay type coverage

* fix(ci): repair current-main validation blockers

* test(discord): align progress fixtures with callbacks

* fix(ui): restore focus after cancelled terminal replay

* chore(ci): drop superseded baseline fixups

* fix(ui): stage terminal replay replacements safely

* fix(ui): serialize asynchronous terminal replay

* fix(ui): guard superseded terminal replay recovery

* fix(ui): invalidate superseded terminal replay callbacks

* fix(ui): keep staged terminal replay inert
2026-08-10 13:27:28 -07:00
Peter Steinberger a6a464f4c0 feat(terminal): fullscreen /terminal route and dot-matrix claw intro (#121451)
* feat(ui): add fullscreen /terminal route and open button

* feat(terminal): dot-matrix claw intro banner and CLI mascot

* fix(terminal): satisfy lint and wizard-header assertions for the new mascot

* ci: account for fullscreen terminal startup bytes

* test(terminal): split session manager coverage
2026-08-09 23:52:59 -07:00
Vyctor H. Brzezowski 32ced3053d fix(ui): scope the Control UI cursor convention to app-like display modes (#121258)
* fix(ui): scope the Control UI cursor convention to app-like display modes

The app-chrome cursor convention from #103357/#103411 was applied
unconditionally, so an ordinary browser tab lost the pointer hand on
buttons, menus, tabs, rails, selects and accordion summaries — the only
hover affordance a page owns. The convention is correct for the installed
window the manifest declares ("display": "standalone"), not for every
window the same bundle is served into.

base.css now owns one policy token, --cursor-action, selected by display
mode: pointer by default, the desktop arrow under standalone, minimal-ui
and window-controls-overlay. A low-specificity rule maps generic
actionable controls onto that token, restoring the affordance on the
surfaces #103411 stripped bare, while every component rule that owns a
semantic cursor (not-allowed, disabled, grab, resize, zoom-in, text,
wait) keeps winning without !important.

The 92 cursor: pointer declarations that had drifted back into ui/src
since July now consume the token instead of hardcoding the hand, so they
stop contradicting the policy in an installed window. Real hyperlinks
keep the pointer in every mode. The pre-boot mount fallback repeats the
policy locally because it must render when the bundle fails to load.

Closes #121242

* test(ui): run the cursor policy browser test in the node-driven project

ui/vitest.config.ts routes Playwright-from-Node .browser.test.ts files to the
unit-node project; without registering the new cursor policy test there, the
in-browser chromium project tried to import it and failed on node:fs/playwright.

* fix(ui): keep the desktop arrow in the native app hosts

The macOS dashboard embeds the Control UI in a plain web view, which
reports `display-mode: browser`, so the display-mode-only policy would
have handed it the browser-tab pointer. It already announces itself with
`openclaw-native-macos`/`-nav`/`-web-chrome` on `<html>`, the same markers
`ui/src/styles/layout.css` matches on, so the policy reads those too.
2026-08-09 22:23:00 -03:00
Peter Steinberger 909509a5db fix(codex): resume catalog sessions with the catalog's CODEX_HOME; add main-content terminal placement (#120708)
* fix(codex): pin catalog CODEX_HOME onto terminal resume spawns

The Codex session catalog lists threads through the plugin's supervision
app-server connection, which can run on the agent-scoped Codex home
(homeScope: "agent"). The terminal resume plan spawned a bare
'codex resume <threadId>' under the operator login shell, so the CLI
resolved its default ~/.codex and failed with "No saved session found".

Terminal plans now carry the catalog connection's CODEX_HOME (local and
paired-node paths), the gateway merges plan env into the PTY spawn, and
the triplicated home-scope resolution collapses into one shared
resolveCodexAppServerLocalHomeDir.

* feat(ui): add main-content terminal placement

The terminal panel gains a third dock placement, "main", filling the
content region next to the sidebar like the transcript pane. The panel
header gets a bottom/right/main placement switcher (persisted in the
existing openclaw.terminal.panel.v1 store), and opening a Codex/Claude
session from the session catalog selects main mode so resumed sessions
appear as a full window instead of a bottom strip.
2026-08-08 14:33:20 -07:00
Peter Steinberger dd99bf5fc1 test(ui): consolidate terminal connection fixtures (#118164) 2026-08-02 13:18:25 -07:00
Vincent Koc 702892e1c3 fix(ui): dismiss picker after focus leaves widget 2026-07-30 03:58:24 +08:00
Vincent Koc 2ad7427e16 fix(ui): keep picker trigger inside focus boundary 2026-07-30 03:27:24 +08:00
Vincent Koc 14e65ab6b3 test(ui): split terminal accessibility coverage 2026-07-30 02:54:10 +08:00
Vincent Koc 8d6dae1e81 test(ui): cover terminal picker pointer paths 2026-07-30 02:46:37 +08:00
Vincent Koc e677b8cbc8 fix(ui): type terminal shadow focus checks 2026-07-30 02:19:21 +08:00
Vincent Koc 1294df882a fix(ui): make terminal session picker keyboard accessible 2026-07-30 02:06:44 +08:00
Vincent Koc 099b806a9b fix(ui): reduce embedded terminal font size 2026-07-29 22:22:17 +08:00
Vincent Koc 755eea5e97 fix(ui): localize remaining control surfaces (#115730)
* feat(ui): add localization keys for control surfaces

* fix(ui): localize relative time and durations

* fix(ui): localize update and recovery notices

* fix(ui): localize chat controls and command results

* fix(ui): localize memory management views

* fix(ui): localize shared tool surfaces

* fix(ui): localize settings and action notices

* chore(ui): tighten localization raw-copy baseline

* fix(ui): preserve localized status copy

* fix(ui): preserve compact sidebar time label

* fix(ui): preserve near-future sidebar direction

* test(ui): align screenshot localization assertion
2026-07-29 16:34:35 +08:00
Peter Steinberger c41ca078a6 refactor(ui): adopt @lit/task across remaining page surfaces (#115274)
* refactor(ui): adopt @lit/task across remaining page surfaces

* refactor(ui): keep approval history pagination explicit

* fix(ui): preserve task refresh ordering
2026-07-28 12:44:34 -04:00
Peter Steinberger 1c0ccdddcd fix(ui): hide the terminal dock while Settings is open (#114737)
* fix(ui): hide docked terminal and browser panels during settings takeover

* test(ui): align browser panel casts with core test typecheck

* test(ui): split dock suppression coverage
2026-07-27 17:08:52 -04: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 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 babf04ca0f refactor(ui): split terminal panel into chrome renderers and a PTY controller (#113020) 2026-07-23 06:35:27 -07:00
Peter Steinberger e9fe7c748b feat(ui): session dashboard shell — board face, chat dock, reset guard (#110728)
* feat(ui): add session dashboard shell

* fix(ui): defer confirmed reset during active runs

* fix(ui): align dashboard shell with shared controls

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-18 10:01:47 -07:00
Peter Steinberger f594a8f7c6 perf(ci): split straggler bin pairings and drop needless jsdom environments (#110477)
* perf(ci): drop compact bin cap to 190s to split straggler pairings

Fresh census from green run 29633628994: every fan-out job queues 65s,
the pack sits at ~160s, but compact-large-3 ran 195s because the 235s
cap let core-runtime-media-ui (hint 124) and core-unit-src-security
(hint 95) share one bin. A 190s cap forbids such pairings; the plan goes
from 21 to 25 compact bins and the hinted max drops accordingly, so the
run wall tracks the pack instead of one straggler. Costs ~4 extra
runners per run; wall is the optimization target.

* perf(test): run DOM-free Control UI tests in the node environment

35 ui/src test files whose transitive import closure never touches DOM
APIs or the lit runtime carried the ui config's jsdom default anyway; on
CI the per-file jsdom construction dominates the shard (environment
95.2s vs tests 59.4s in run 29633628994). Annotate them with the
repo-standard @vitest-environment node docblock (29 files in ui/ already
use it). Verified: full ui config run passes with the annotations; the
only failing files are three storage tests that fail identically on a
clean checkout under local Node 26 and are untouched here.

* chore: kick dropped push event for PR head ingest
2026-07-18 08:49:37 +01:00
Peter Steinberger ff54749b1b test: speed up more control UI async polling (#110530) 2026-07-18 08:37:57 +01:00
Peter Steinberger 104581904b test: speed up control UI async polling (#110375) 2026-07-18 06:27:40 +01:00
Peter Steinberger d7fe43acc3 fix(ui): tolerate transient gateway stalls in terminal liveness probe (#109317) 2026-07-16 14:45:10 -07:00
Peter Steinberger 761eabad25 fix(ui): show dead reattached terminals as exited (#109281)
* fix(ui): show dead terminal sessions as exited

* chore: leave changelog to release flow
2026-07-16 12:34:52 -07:00
Peter Steinberger 20d748a4f0 feat(agents): agent-owned gateway terminals with operator co-attach 2026-07-16 09:12:50 -07:00
Peter Steinberger cf029ea29e feat(agents): screen tool drives Control UI layout 2026-07-16 05:43:02 -07:00
Peter Steinberger a864c64d8a refactor(ui): unify terminal and browser panel tab strips (#108651)
* refactor(ui): share one panel tab strip between terminal and browser

Extract the terminal tab strip (tab + attached close button as one
surface, from #108611) into a shared panel-tab-strip module and migrate
the in-app browser panel onto it. The browser tabs inherit the attached
close design; terminal tabs gain middle-click close and long-label
ellipsis; both get the empty-group workaround and a strip that shrinks
inside the flex header. Net -24 prod LOC; duplicated tp-/bp- strip CSS
deleted.

* fix(ui): keep shared panel new-tab button stable
2026-07-16 00:44:23 -07:00