Commit Graph

5358 Commits

Author SHA1 Message Date
Peter Steinberger 543b4a85cf fix(ui): keep retained dashboards warm (#126339) 2026-08-19 09:31:53 -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 3e0c980aaf fix(models): honor per-agent model metadata (#126194)
* fix(models): honor per-agent model metadata

Resolve per-agent aliases, bare providers, fallbacks, and catalog tags consistently across runtime, CLI, Gateway, sessions, and the Control UI.

* fix(models): preserve projection ownership

* fix(models): carry agent scope through fallbacks

* test(models): complete compaction fallback mock

* test(models): complete startup fallback mock

* test(agents): isolate recovery id expectations

* refactor(protocol): split public schema barrel

* test(cron): await child readiness events

* fix(models): scope native catalogs to session agent

* perf(ui): tighten agent model option projection

* perf(ui): reduce agent model projection overhead
2026-08-19 06:04:24 -07:00
Peter Steinberger 0f1670d895 test: remove moving-tip redundancies (#126312) 2026-08-19 05:48:14 -07:00
Peter Steinberger a7f9a7fdd4 refactor(gateway): interrupt at admission; sessions.steer delegates to chat.send (#126291)
* refactor(gateway): interrupt at admission; sessions.steer delegates to chat.send

chat.send queueMode interrupt now aborts the captured current operation
at the session-work admission owner (exact-instance abort, never a
same-key successor) and dispatches the new turn after the abort
settles; channel-originated interrupts share the same primitive.
sessions.steer keeps its validation, sharing/access checks, and
response shape but becomes a thin deprecated adapter over that path -
its private inflight/retry and hard-abort machine is deleted. The
Control UI /redirect command rides canonical chat.send. Compaction's
use of the old hard-interrupt helper moves unchanged to
session-run-interruption.ts.

* fix(gateway): interrupt non-reply admissions
2026-08-19 04:36:57 -07: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 e71fc902ee fix(gateway): make activeRunIds presence mean a complete exact run set (#126106)
* fix(gateway): make activeRunIds presence mean a complete exact run set

Session rows no longer emit activeRunIds: [] while hasActiveRun is
true. Presence now means the complete exact set of direct run ids;
omission means identities are unavailable (projected/embedded owners);
[] only ever represents proven idle. Consumers stop guessing:
soleActiveSessionRunId() replaces the arbitrary [0] fallbacks in the
observer digest, transcript cache key, activity inspector, and
stale-terminal reconciliation, each falling back to its owner fact.

Follows the maintainer direction from #125983: the field stays as
Gateway-owned exact facts; producer-side liveness/observer projections
are a named follow-up.

* fix(gateway): clear unavailable active run ids in events

* fix(gateway): preserve idle active run sets

* fix(clients): close active run id cache gaps

* test(android): isolate history run snapshot
2026-08-19 02:08:57 -07:00
Peter Steinberger 94eb34fa78 fix(skills): require re-review when proposals change (#126156)
* fix(skills): bind workshop decisions to reviewed revisions

* chore(i18n): refresh native source inventory

* test(skills): align revision proof with inspect projection

* test: align skill workshop regression fixtures

* fix(ui): align workshop revision admission proof

* fix(ui): keep revision errors out of startup
2026-08-19 01:52:11 -07:00
Peter Steinberger 67750753a2 fix: capture GitHub identity from authenticated sign-in (#126114)
* fix: capture GitHub identity from authenticated sign-in

Automatically persist verified GitHub identities from Cloudflare Access and Tailscale Serve while keeping public Git co-author credit as a separate opt-in.

* test: stabilize cleanup and activity capture

* fix(security): bind GitHub profiles by account id

* test: scope activity capture to route

* fix(security): gate profile requests on identity sync

* fix(security): close pending profile authorization gaps

* test(ui): stabilize terminal continuation menu

* test: stabilize startup recovery timing

* test: keep one Codex attempt tools owner

* fix(plugins): allow profile-independent gateway reads
2026-08-19 01:35:52 -07:00
Peter Steinberger 80934e5639 feat(ui): dispatch sessions to paired devices (#126187) 2026-08-19 01:11:49 -07:00
Peter Steinberger ca0935ae58 fix(ui): preserve active run ownership across steering (#126230) 2026-08-19 01:03:14 -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 0d14434d0e feat(secrets): add explicit protected and agent-readable access (#126088)
* feat(secrets): add explicit agent access modes

Distinguish protected write-only secrets from agent-readable Gateway environment values, expose policy-bound Gateway exec aliases to Codex, and activate Node environment proxy support for destination-bound egress.\n\nCloses #125975

* fix(gateway): bind lifecycle dispatch to owning instance

* test(ui): preserve mock gateway recovery state

* fix(codex): avoid unavailable gateway process guidance

* fix(harness): keep run correlation host-owned

* fix(gateway): bind restart delivery to instance

* test(codex): construct tools through test host capability
2026-08-18 22:51:15 -07:00
Peter Steinberger 49231ff781 fix(ui): load workspace icons after dashboard bootstrap (#126200)
Paired Control UI device credentials now share the canonical same-origin read authorizer, while session-derived routes retain read+owner policy. Fresh dashboard handoffs and reloads can therefore render workspace, channel, and plugin icons without exposing or persisting the shared Gateway secret.

Remove the old shared-secret-first UI workaround.
2026-08-18 22:50:55 -07:00
Peter Steinberger 5a0a96f327 fix(ui): keep workshop revisions retryable until admitted (#126166)
* fix(ui): preserve workshop revisions until admission

Skill Workshop revision instructions now remain retryable until the Gateway admits the request, including navigation and overlapping admission failures.

* fix(ui): materialize workshop revision binding

Manifest-only Skill Workshop proposals now resolve their revision hash inside the durable admission owner, and retries reuse the same binding and idempotency key.

* chore(ui): keep revision types internal
2026-08-18 22:25:57 -07:00
Peter Steinberger e38a06439e refactor: trim locale and QA fixture debt (#126139)
* refactor: trim locale and QA fixture debt

* fix(qa): preserve shared flow portability

* chore(qa): document shared flow branch

* fix(docs): align plugin SDK subpath catalog

* fix(ci): align shared docs and flow contracts
2026-08-18 22:17:19 -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
Peter Steinberger 57e5ab7a87 fix(apps): show native gateway and notification failures (#125909)
* fix(apps): surface native action failures

Make iOS gateway reconnect attempts return visible closed outcomes, route macOS gateway deep links through primary setup confirmation, and expose pending/sent/error notification test results across native and Dashboard settings.

* chore(apps): refresh native i18n inventory

* test(macos): isolate gateway cancel state

* fix(ui): accept permission-only notification status

* test(gateway): drain accepted agent run before fixture reset

* fix(ui): notify clients after service worker claim

* test(gateway): wait for accepted root work to drain

* test(ui): isolate widget theme observer window

* test(ui): await durable attachment draft before teardown

* test(agents): use race-safe MCP process cleanup

* test(ui): await cloud startup runtime before error probe

* test(ui): align startup and teardown probes with current owners
2026-08-18 20:15:52 -07:00
Peter Steinberger 7097ccc7bd perf(test): gate Skill Workshop proof capture (#126051) 2026-08-18 20:13:50 -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 64776a0489 fix(sessions): preserve committed results across reconnects (#125904)
* fix(sessions): preserve committed operation results

Report post-commit create failures through the existing runError response and retain confirmed same-client Control UI mutations across reconnects while fencing replacement clients.

* test(ui): await new-session ownership state

* test(ui): clarify draft teardown durability

* fix(ui): preserve reconnect refresh failures

* test(ui): poll absent text targets safely

* test(sms): await ingress spool ownership

* test(ui): await cloud startup failure state

* test(ui): await canonical place selection

* test(ui): scope activity feed to route owner

* test(ui): stabilize route-owned activity states
2026-08-18 19:13:58 -07: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
Peter Steinberger a8bc60a119 refactor(ui): generalize session placement startup (#126118) 2026-08-18 18:59:50 -07:00
ClawSweeper 22665ae71f fix(ui): fill expanded mobile side panel (#126111)
Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-08-18 18:55:09 -07:00
Peter Steinberger 948a444d63 fix(ui): require exact active run ownership (#126116) 2026-08-18 18:54:58 -07:00
ClawSweeper 05817086cc fix(ui): keep memory header stable across tabs (#125568)
* fix(ui): keep memory hub header stable across tabs

* test(ui): tolerate subpixel layout rounding

* fix(ui): keep memory header padding stable

* test(ui): scope memory layout assertion

* test(ui): satisfy promise executor lint

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
Co-authored-by: Colin Johnson <colin@solvely.net>
2026-08-18 18:45:36 -07:00
Josh Avant 784676537c feat(ui): enable link favicons by default (#126109) 2026-08-18 18:41:54 -07:00
Peter Steinberger fea2198319 fix(ui): keep New Session folder picker usable while menus close (#126032)
* fix(ui): track overlapping place popover hides

* test(ui): stabilize activity grouping across timezones
2026-08-18 18:29:49 -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
Peter Steinberger 4fac990321 fix(test): run the shared Control UI lane on the cross-file cleanup runner (#126071)
* fix(test): run the shared Control UI lane on the cross-file cleanup runner

ui/vitest.config.ts drives CI's checks-ui job (pnpm --dir ui test). Its
unit project sets isolate:false but never wired
runner: nonIsolatedRunnerPath, so the per-file cleanup in
test/non-isolated-runner.ts — module-graph reset, repo-owned custom
element dropping, DOM body reset, timer and spy restoration — never ran
in the lane CI actually uses. Only the repo-root lane behind
scripts/run-vitest.mjs loaded it.

Files sharing a worker therefore kept the previous file's evaluated
modules, so whichever file imported a component first pinned it to the
real dependency and a later file's vi.mock factory never reached
production code, surfacing as "expected 0 to be 1" in whichever sibling
the size sequencer happened to pack alongside it. This is the class
PR #123512 diagnosed and fixed at the runner; the fix never reached this
lane, so the repo kept absorbing it one uiIsolatedTestFiles entry at a
time.

browser stays exempt (the runner imports node:fs and server modules that
cannot load in browser mode) and unit-node stays exempt (it carries the
Playwright-driven layout tests whose browser lives in module scope, which
per-file module resets churn). The config test asserted runner was
undefined for every project, pinning the broken wiring; it now asserts
the invariant and fails on the pre-fix config.

* fix(agents): stop passing an ignored resolver to instance-bound announce dispatch

check-prod-types is red on main: #126062 threaded resolveGatewayContext
into the announce dispatch call, but that call now goes through
dispatchGatewayLifecycleMethod, whose options type does not carry the
field.

The type checker is right that it does not belong there. That dispatcher
hands work to runtime.dispatchAgent, which resolves context from the
Gateway instance it is bound to and forwards a fixed option allowlist, so
a caller-supplied resolver was already being ignored. Dropping it is
behavior-preserving.

The delivery test asserted the resolver was forwarded, but production now
binds to the instance dispatcher while the test injects a mock, so that
assertion only proved the mock. It now asserts the resolver is
deliberately not forwarded.

Left for the owner of #126062: sendSubagentAnnounceDirectly and its
callers still accept and thread resolveGatewayContext, which is now
vestigial on this path. Deleting that chain or teaching the instance
runtime to honor the resolver is a design call on a just-landed change.
2026-08-18 17:42:00 -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
Peter Steinberger 1d9cda833f feat(ui): show machine CPU and RAM in the cloud picker (#125696)
The cloud machine picker described each class in prose ("Cheap smoke checks
and small repos"), which was the widest thing in the row, got ellipsized, and
did not say what the operator actually picks on. Machine options now carry the
class shape and the picker renders "32 vCPU · 64 GB" instead.

Crabbox reports per-provider class shapes from `providers --json`; the plugin
reads that catalog once per lifecycle and attaches cpu/memoryGb to each option.
A missing binary, failed command, unparseable output, absent classes, or an
unmatched provider all degrade to label-only rows, so an older Crabbox keeps
working.

`description` was never released, so it is removed rather than deprecated, and
listMachineOptions becomes async for the catalog read. Deletes the duplicate
machine-option projector in the environments server method.
2026-08-18 15:38:15 -07:00
Peter Steinberger f7db0a4c51 fix: show named CLI sessions in the sidebar (#126043)
* fix(gateway): preserve explicit session names

* test(ui): keep session visibility fixture isolated
2026-08-18 15:33:43 -07:00
Peter Steinberger e8312171c1 fix: direct Gateway stops wait for active work (#126024)
* fix(gateway): drain active work on direct stop

* test(ui): isolate widget fetch retry mock
2026-08-18 15:29:52 -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 cd0cdfd521 fix(ui): keep the empty side panel closed (#126047)
Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-18 15:11:24 -07:00
ClawSweeper 20b6a04036 fix(ui): vertically center session row actions (#126041)
Center sidebar session pin and menu actions across the full two-line row while reserving text width on hover and touch. Add browser geometry regression coverage.

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-18 15:10:22 -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
ClawSweeper 670f61200b improve(ui): slow new session spinner (#126044)
Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-18 15:06:55 -07:00
Jacqueline Henriksen 14d43ad93c fix(ui): reflect inherited agent skill allowlists (#124429)
* fix(ui): honor inherited agent skill filters

* test(ui): cover inherited agent skill allowlists

* test(ui): publish real gateway skill proof

* chore(proof): remove generated UI evidence

* fix(ui): show inherited skills in agent context

* fix(ui): show inherited skills in agent context

* docs(proof): record rebased gateway UI verification

* docs(proof): capture current-head agent skills UI

* docs(proof): bind agent skills capture to final head

* chore(ui): remove PR-only proof artifacts

* fix(ui): preserve list-form agent skill overrides

* fix(ui): preserve list-form agent mutations

* fix(ui): use canonical list skill replace path

* docs(ui): attach inherited skills gateway proof

* chore(proof): keep visual evidence out of source tree

* fix(ui): remove misleading enable-all action

* test(ui): reflect removed enable-all action

* fix(ui): describe skill reset as inherited defaults

* fix(ui): keep skill reset on canonical roster

* fix(ui): reset list-roster skill overrides

* fix(ui): satisfy inherited skills proof checks

* fix(ui): keep agent skill reset on canonical entries

* test(ui): focus inherited skill regression proof

---------

Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-18 15:06:28 -07:00