Commit Graph

905 Commits

Author SHA1 Message Date
Ayaan Gazali 2213d569ce fix(ui): clear terminal session activity indicators (#120327)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-21 11:52:00 -07:00
SunnyShu 9a0e11df06 fix(ui): reach identity-menu footer controls with keyboard (#122066)
* fix(ui): restore identity menu footer keyboard navigation

Co-authored-by: SunnyShu0925 <shu.zongyu@xydigit.com>

* test(ui): synchronize identity menu hide lifecycle

* test(ui): keep identity keyboard proof in one menu lifecycle

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-21 11:48:36 -07:00
Peter Steinberger 2bd6efb919 fix(ui): restore editable map-valued settings (#127336) 2026-08-21 11:13:21 -07:00
Shakker d15f570742 fix: dismiss sidebar session menu tooltip (#127044)
Dismiss the sidebar session tooltip whenever its overflow menu opens, preserving unobstructed menu actions and stable row semantics.

Refs #127039.
2026-08-21 07:14:13 +01:00
Peter Steinberger ab2bbd42df test: trim UI and tooling test seams (#126937) 2026-08-20 19:04:18 -07:00
Peter Steinberger 0d555266e4 refactor(nodes): retire legacy runner inventory parsing (#126773) 2026-08-20 11:53:00 -07:00
Peter Steinberger 9dc391c75b perf(ui): keep config render helpers lazy (#126754)
Restore the cross-platform Control UI startup gzip budget by keeping render-only sensitive-path helpers outside the startup config-draft graph. Preserve existing behavior and caller APIs while moving generic schema, search, and path helpers to their existing startup owner.
2026-08-20 10:22:55 -07:00
Peter Steinberger bbbd70542b feat(sessions): recover offline device placements (#126284)
* feat(sessions): recover offline device placements

* chore(protocol): refresh session placement models

* perf(ui): lazy-load session placement recovery

* test(ui): remove dropdown timing assertion

* test(ui): await committed cloud recovery route

* fix(sessions): complete explicit abandonment locally

* fix(sessions): fence lists by runner availability

* fix(ui): preserve canonical session freshness

* fix(sessions): preserve recovery contracts after rebase

* test(ui): await durable cloud recovery entry

* test(gateway): complete current runner fixtures

* fix(gateway): publish runner availability edges

* fix(ui): preserve shared session freshness

* fix(ui): preserve canonical sidebar session state

* fix(sessions): preserve abandoned partials and run-owned replies

* fix(sessions): resume durable abandonment retries

* test(gateway): compose provisioning replay with runner availability

* fix(sessions): publish recovered move transitions
2026-08-20 09:59:59 -07:00
Hiroshi Tanaka 55f1738d50 fix(control-ui): config form save corrupts 64-bit id strings in string|number fields (#126402)
* fix(control-ui): stop config form save from corrupting 64-bit id strings

Saving the schema-driven config form coerced every numeric-looking string
to a JS number before submission. For union-typed fields such as
tools.elevated.allowFrom.* (anyOf: string | number), string entries
holding 64-bit ids (Discord/Telegram snowflakes) were rewritten through
Number(), which rounds past 2^53:
"1048113311314608148" -> 1048113311314608100. The corruption also hit
untouched fields, because serialization coerces the whole form, so merely
saving an unrelated setting silently broke elevated-approval allowlists
(fail-closed: the real user id no longer matched).

Two guards fix this:
- coerceFormValues keeps a string that already satisfies a string variant
  of an anyOf/oneOf union instead of parsing it into another variant's
  number.
- coerceConfigFormNumberString refuses lossy integer parses: plain
  integer text beyond Number.MAX_SAFE_INTEGER that does not round-trip
  through BigInt stays a string, so pure number/integer fields fail
  validation loudly instead of storing a corrupted id.

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

* fix(control-ui): harden 64-bit config id preservation

* fix(control-ui): validate mixed-union scalar branches

* test(control-ui): prove real gateway id preservation

* test(control-ui): use communications route for config proof

* test(control-ui): grant config proof admin scope

* test(control-ui): reopen raw config for proof

* fix(control-ui): preserve explicit union input types

* test(control-ui): exercise union collection draft

* ci: retry flaky control ui e2e

* fix(control-ui): preserve mixed scalar branch types

* ci: retry service worker e2e

* fix(control-ui): preserve typeless string union branches

* fix(control-ui): reject lossy decimal coercion

* fix(control-ui): reject lossy pure numeric input

* fix(control-ui): preserve exact numeric branch semantics

* ci: retry checkout rate limit

* ci(control-ui): capture real gateway proof

* test(control-ui): frame config proof values

* ci: retry checkout download

* test(control-ui): prove Gateway-served production bundle

* fix(control-ui): preserve exact incremental union edits

* refactor(control-ui): isolate scalar edit session state

* fix(control-ui): keep scalar edit branch type internal

* fix(control-ui): avoid detached focus selector

* fix(control-ui): round-trip exact numeric branches

* refactor(control-ui): share exact scalar formatting

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 08:50:24 -07:00
ClawSweeper 8c6c7a30cf improve(ui): make mobile image previews zoomable (#126528)
* improve(ui): make mobile image previews zoomable

* fix: harden mobile image viewer

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Shakker <shakkerdroid@gmail.com>
2026-08-20 16:39:49 +01:00
Peter Steinberger 974917f520 fix(ui): keep pending approvals visible throughout Settings (#126698) 2026-08-20 08:10:06 -07:00
Peter Steinberger 855599d7e9 fix(ui): keep sidebar icon endcap intact in single-line session rows (#126567)
With message preview off, rows collapse to one line and the second-row icon
logic (spinner, unread dot, badges, facepile, trail) rides beside the title.
Two defects broke that:

- Long titles crushed the icon endcap: the single-line title used flex-basis
  auto, so overflow shrink was distributed onto the endcap (24px -> ~7px),
  clipping the status icons. Basis 0 now mirrors the two-line subtitle
  contract: text absorbs all shrink before icons do.
- Native catalog session rows always rendered the two-line skeleton with an
  empty details line (46px vs 30px) and never collapsed, in both preview
  modes. Catalog rows never carry preview text, so they are now always
  single-line.

Regression coverage: long-title endcap geometry in
chat-flow.sidebar-presentation.e2e.test.ts (fails pre-fix), and
codex-sessions.e2e.test.ts density assertions updated to the new
all-single-line contract.
2026-08-20 07:37:21 -07:00
Vyctor H. Brzezowski 68ae235318 improve(ui): refine chat widget host and image actions (#125250)
* improve(ui): refine chat widget host actions

* fix(ui): keep widget pin presentation unchanged

* fix(ui): compact widget actions and restore rounded host

* style(ui): format widget action menu

* test(canvas): refresh widget host document contract

* test(ui): model the widget host wrapper

* fix(ui): preserve retained widget downloads

* fix(ci): register Codex tool coverage

* fix(protocol): keep version exports compact

* fix(ui): preserve widget action outcomes

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-20 05:27:56 -03:00
Peter Steinberger 764622342c fix(ui): keep empty session groups compact (#126565) 2026-08-20 00:58:54 -07:00
Vyctor H. Brzezowski 689ab6ec82 fix(ui): contain narrated tool details (#126348)
* fix(ui): contain narrated tool details

* fix(ui): repair narrated tool details
2026-08-20 04:04:53 -03:00
Vito Cappello f612675284 fix(models): keep Claude CLI OAuth available in Control UI (#125471)
* fix(models): honor Claude CLI OAuth ownership in Control UI

Co-authored-by: XX441 <169966250+XX441@users.noreply.github.com>

* test(models): preserve OAuth fixture literal type

* fix(models): preserve persisted CLI runtime ownership

* fix(auth): discover Claude CLI credentials for Anthropic scope

* fix(models): honor CLI-owned OAuth over legacy metadata

* fix(models): migrate CLI OAuth profile ownership

* fix(models): centralize CLI metadata normalization

* fix(doctor): keep CLI migration result internal

* test(models): type CLI OAuth fixtures

* refactor(models): isolate auth status projection

* refactor(models): split auth status API key projection

* fix(auth): preserve legacy CLI metadata on failed migration

* fix(auth): retain healthy CLI OAuth migration state

* fix(doctor): type CLI migration store fallback

* test(doctor): type CLI migration store mock

* fix(models): retain non-CLI credential expiry status

* fix(models): preserve independent auth route status

* fix(models): retain independently configured alias auth

* test(ui): stabilize activity feed fixture clock

* fix(auth): preserve legacy CLI recovery metadata

* fix(auth): scope legacy CLI migration to Claude

* fix(auth): preserve MiniMax CLI expiry ownership

---------

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: XX441 <169966250+XX441@users.noreply.github.com>
Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-08-19 23:05:32 -07:00
Peter Steinberger 70b6f44f13 improve: one alert surface, explained by Ask OpenClaw (#126155)
* refactor(ui): unify sidebar alerts with custodian

* refactor(ui): move custodian alert state

* fix(ui): use the defined mono token in the custodian alert card

* fix(ui): break the update-watcher import cycle

Type the watcher against a structural leaf contract instead of
Pick<ApplicationContext,...>; context.ts reaches this module through
overlays-types.ts, so naming the context type closed a madge cycle.

* fix(ui): re-arm the alert explanation when an incident recurs

Failed-automation and model-auth alerts keep one incident id across
recover-then-fail-again, so an id-keyed dedupe showed the renewed alert
and never explained it. Scope ask-once to the presentation instead.
2026-08-19 21:33:31 -07:00
Vyctor H. Brzezowski 3aff572d74 fix(ui): dismiss session hovercard before its menu opens (#126345)
* fix(ui): dismiss session hovercard before menu

* test(ui): keep hovercard regression focused

* fix(ui): dismiss catalog session hovercards

* test(ui): use typed catalog session key
2026-08-19 21:41:25 -03:00
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 e741649856 fix(ui): keep prose fences fully visible (#126346) 2026-08-19 21:05:51 -03:00
ClawSweeper fa407417f0 fix(ui): honor categories for child sessions (#126388)
* fix(ui): honor categories for child sessions

* fix(ui): admit categorized child sessions as roots

* fix(ui): keep sidebar files within line budget

* fix(ui): include cached categorized children

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Jason (Json) <263060202+fuller-stack-dev@users.noreply.github.com>
2026-08-19 15:39:24 -06:00
ClawSweeper d8fd2937aa fix(ui): keep mobile sidebar session menus reachable (#126355)
* fix(ui): keep mobile sidebar menus in viewport

* fix(ui): bound compact sidebar menu height

* fix(ui): restore Open PR cursor marker

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

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-19 14:00:39 -07:00
Peter Steinberger 5eda48ed99 fix(ui): recover failed lazy surfaces (#126409) 2026-08-19 12:27:35 -07:00
Peter Steinberger 0b715e3f5b refactor(ui): share Control UI resource route contract (#126386)
* refactor(ui): share Control UI resource route contract

Gateway and Control UI now share browser-safe resource route grammar, while authorization and domain validation remain handler-owned.

* perf(ui): keep resource routes out of startup

Narrow browser-safe contract modules and the lazy authenticated avatar loader keep route/cache code out of the startup chunk while the stable Gateway barrel remains compatible.
2026-08-19 12:20:22 -07:00
Peter Steinberger 51599041bc fix: explain preserved session worktrees accurately (#126347)
* fix(sessions): report worktree preservation reasons

* fix(sessions): align preservation checks with current main

* perf(ui): keep preservation copy within startup budget

* perf(ui): reuse localized preservation copy

* test(ui): match preserved worktree confirmation copy

* test(ui): await committed raw config state
2026-08-19 10:59:42 -07:00
Peter Steinberger 1410ffcd23 fix(ui): show real avatars in session hovercards (#126372)
* fix(ui): show channel avatars in session hovercards

* fix(ui): preserve hovercard avatar fallback
2026-08-19 10:54:56 -07: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 1fa82e9795 fix: browser screenshots fail on routed Control UI pages (#126290)
* fix(browser): validate proxied file ownership

* fix(ui): separate route and resource base paths

* test(ui): align resource base fixtures

* test(ui): align route-base fixtures with focus routes

* perf(ui): keep profile avatar URLs out of startup
2026-08-19 04:36:07 -07: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 80934e5639 feat(ui): dispatch sessions to paired devices (#126187) 2026-08-19 01:11:49 -07:00
Peter Steinberger 9b43f1c82e improve(ui): fix sidebar session row hierarchy and add a message-preview toggle
Pinned sessions inherited the nav zone's muted colour on the session *title*, so a
pinned row's preview line outshone its own name and the same session read dimmer
pinned than unpinned. A title is content in every zone; only glyphs, meta and the
hover fill follow the zone. The subtitle drops to plain --muted, already proven AA
against every surface by theme-contrast.test.ts.

Rows with no preview text reserved a fixed 18px second line anyway, leaving a dead
band or a lone spinner hanging below-right of the title. They now collapse to one
line via a --single-line class plus a CSS variant, so the endcap rides beside the
title. Rows also gained a little vertical air and reclaimed the right-hand gutter
inside the row, leaving the deliberate scrollbar clearance from #124879 intact.

Adds a localStorage-backed "Show message preview" toggle to the session sort menu
(default on). Operator-actionable state is exempt: attention, the queued
concurrency-slot explanation, and critical observer headlines (stuck /
waiting-on-user) always show, because hiding them behind a display preference is
the silent-failure class.

Also registers extensions/codex/src/app-server/run-attempt-tools.test.ts, which
arrived in #126189 with no shard claim and left main red.
2026-08-19 00:08:07 -07:00
Peter Steinberger 57a65def4f fix(ui): restore sidebar session hovercards (#126222)
* fix(ui): restore sidebar session hovercards

* test(codex): include run-attempt tools in full suite
2026-08-19 00:07:05 -07:00
Peter Steinberger 7f60af7f8b fix(ui): tear down hidden Desktop presenters (#126203)
Scope embedded Desktop refresh and connection ownership to the active presented sidebar slot. Hidden retained panels now invalidate pending work and disconnect RFB, while reactivation returns to a freshly loaded picker without silently reconnecting.
2026-08-18 23:20:44 -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 a89c568068 fix(ui): center dashboard widget controls on hover (#126076)
* fix(ui): center dashboard widget hover controls

* fix(ui): gate resize handle with centered hover

* fix(ui): preserve iframe clicks with centered controls

* fix(ui): preserve corner actions when centering controls

* fix(ui): compact centered controls at intermediate widths

* test(plugins): align SDK subpath docs contract wording
2026-08-18 21:32:37 -07:00
ClawSweeper 7e69b1d5ab fix(ui): make Guardian review activity subtle (#125395)
* fix(ui): make guardian reviews subtle

* fix(ui): correlate Guardian warning cleanup

* fix(ui): retain ambiguous Guardian warnings

* fix(codex): preserve Guardian review state

Keep command-owned review state durable across reconnect and persisted history, with conservative bounded outcomes and producer-owned routine warning correlation. Verify native user-home app-server auth instead of injecting stored profiles.

* refactor(ui): split workspace conflict rendering

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-08-18 20:28:23 -07:00
ClawSweeper bf420e92c6 fix(ui): keep mobile session actions reachable (#126124)
* fix(ui): keep mobile session actions reachable

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

* test(ui): use placement startup capability

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

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Takhoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-18 19:46:34 -07:00
Vyctor H. Brzezowski 2a469c1cb2 fix(ui): dismiss completed progress cards (#126102)
* test(ui): cover completed progress card dismissal

* test(ui): capture both completed card themes

* fix(ui): dismiss completed progress cards

* style: format progress card dismissal

* test(ui): assert visible dismissal lifecycle

* test(ui): wait for reloaded composer proof

* refactor(ui): reuse progress card action styles

* chore(protocol): refresh Swift progress card params

* style(ui): format progress card test

* fix(ui): hide progress dismissal from viewers

* test(ui): use Vitest viewer assertion
2026-08-18 23:39:31 -03:00
Peter Steinberger 15fb00eb6b fix: surface paired-device runtime requirements (#126067)
* fix: surface paired-device runtime requirements

* test: cover session runtime placement metadata

* test(gateway): stabilize runtime catalog fixtures

* fix(gateway): reject incompatible device moves
2026-08-18 19:10:41 -07:00
Peter Steinberger d1f327a4e4 fix(ui): refresh Browser when sidebar tab activates (#126058) 2026-08-18 19:05:20 -07:00
Vyctor H. Brzezowski 421104253b feat(ui): proxy opt-in link favicons through gateway (#121906)
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
2026-08-18 17:44:57 -07:00
Vyctor H. Brzezowski 1110cd09bd improve(ui): make online sidebar section collapsible (#125963)
* improve(ui): make online sidebar section collapsible

* improve(ui): show online avatars in compact state

* improve(ui): align online section heading

* fix(ui): satisfy sidebar CI gates

* fix(ui): keep online expanded on first visit
2026-08-18 20:28:38 -03:00
Josh Lehman a91f1202d9 fix(ui): keep Plugins hub navigation stable (#126061)
* fix(ui): keep Plugins hub navigation stable

* chore: format release validation skill
2026-08-18 16:08:41 -07:00
ClawSweeper d39a24c687 fix(ui): identify current user in owner filters (#126052)
Pin the authenticated profile first and label it as Name (You) in the shared session owner menus.

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-18 15:49:33 -07:00
Patrick Erichsen f6f426c8e8 feat(ui): add copy session id action (#124059) 2026-08-18 22:29:20 +00:00
Peter Steinberger efff6964e0 fix(ui): make assign-to-me update session owner (#126031)
Make the self shortcut use the same canonical owner payload as the Assign to submenu so Control UI ownership updates reliably.

Refs #126026
2026-08-18 15:11:50 -07:00
ClawSweeper 20c09b8088 improve(ui): label new session picker menus (#126045)
Show Agents, Environments, Projects, and Branches headings when the four New Session pickers open.

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-18 15:10:04 -07:00
Peter Steinberger 8032e6c75e fix(ui): restore session link hovercards (#125968)
* fix(ui): restore session link hovercards

* chore: defer session hovercard release note
2026-08-18 13:51:35 -07:00
Peter Steinberger c1527822ce feat: add dashboard fullscreen modes (#125806)
* feat(ui): add dashboard fullscreen modes

* docs(ui): document dashboard fullscreen modes

* fix(ui): scope dashboard fullscreen lifecycles

* test(ui): align dashboard e2e grant fixture

* fix(ui): surface dashboard document load failures
2026-08-18 12:09:07 -07:00
Peter Steinberger 97a4d324f5 fix(gateway): allow non-admin cloud sessions (#125787)
* fix(gateway): allow non-admin cloud sessions

Admin-provisioned shared runners are now usable by operator.write while raw environment, config, and pairing controls remain admin-only.

Closes #125602

* chore(test): prune assertion safety baseline

* refactor(gateway): isolate cloud reclaim lifecycle

* test(gateway): declare Codex dispatch ownership

* test(ui): cover session-scoped cloud cleanup

* perf(ui): trim tooltip startup path

* fix(gateway): fence cloud placement activation

* test(gateway): update move recovery dispatch contract

* fix(gateway): fail closed on placement recovery

* docs(gateway): explain fail-closed move recovery

* refactor(gateway): consolidate session mutation target keys
2026-08-18 11:33:54 -07:00