Commit Graph

5450 Commits

Author SHA1 Message Date
Peter Steinberger c8f88a8b38 fix(ui): recover newer builds after stale probes (#126628)
* fix(ui): recover newer builds after stale probes

* fix(ui): elect newest stale-build recovery target
2026-08-20 04:21:57 -07:00
Peter Steinberger 2ebe24e9b2 fix(ui): keep sidebar chat rows separated during resize (#126610) 2026-08-20 02:18:34 -07:00
Peter Steinberger 1d2986b06f fix: prevent incompatible cloud runtime dispatches (#126585)
* fix(ui): gate cloud profiles by runtime mode

* test(gateway): expect cloud placement mode

* test(gateway): keep route suite within lint budget
2026-08-20 01:31:27 -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 83978aec63 fix(ui): refresh approval history when decisions resolve (#126579) 2026-08-20 01:13:42 -07:00
Peter Steinberger 764622342c fix(ui): keep empty session groups compact (#126565) 2026-08-20 00:58:54 -07:00
Peter Steinberger 531fc9b365 fix(ui): read-only Agents identity editor stays stuck on Saving (#126568)
* fix(ui): show accurate save state for read-only agents

* test(ui): use canonical text content in agent save assertion
2026-08-20 00:48:17 -07:00
Peter Steinberger 828f1fa851 perf(test): gate lazy recovery proof capture (#126583) 2026-08-20 00:43:50 -07:00
Alix-007 2a79f74701 fix(ui): prioritize active session quota provider (#120557) (#122053) 2026-08-20 00:22:30 -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 0a8226c3db fix(ui): give embedded settings sections the shared section rhythm (#126541)
* fix(ui): give embedded settings sections the shared section rhythm

The agents tab panel hosted settings sections in a bare div, so sections
stacked with zero separation; the bespoke .agents-main margin rule in
agents.css missed the nested tabpanel entirely. Descriptions also pulled
up to 4px under control-height header actions (squeezed Verify/Save rows).

Add a .settings-stack primitive to settings.css for embedded surfaces,
use it on the agent tab panel, delete the page-local margin fork, and let
section descriptions clear action-bearing headers.

* test(agents): export getRuntimeConfigSourceSnapshot from runtime-snapshot mock

Main's checks-node-compact-large shard is red: #126531 routed
provider-model-routes through projectConfigOntoRuntimeSourceSnapshot,
which reads getRuntimeConfigSourceSnapshot, and this suite's explicit
vi.mock factory did not export it (24 failures). Return null so the
projection no-ops and resolvers keep reading the provided config.
2026-08-19 22:31:35 -07:00
Peter Steinberger f289685bf3 fix(ui): stabilize settings and update recovery E2E (#126538)
* test(ui): await settings takeover in app chrome E2E

* test(ui): assert current build after update recovery
2026-08-19 21:39:26 -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 916eef4e99 fix(ui): balance completed-work spacing (#126303)
* fix(ui): balance completed-work spacing

* fix(ui): preserve touch work spacing

* fix(ui): balance touch work spacing

* fix(ui): open completed-work spacing
2026-08-20 00:17:32 -03:00
Patrick Erichsen 6eb9344e7d fix(ui): preserve dashboard side-panel selection (#126511) 2026-08-19 19:11:13 -07:00
Peter Steinberger 0a86702241 feat(github): authorize agent identities from Settings (#126474)
* feat(github): add device authorization lifecycle

* fix(github): harden device authorization lifecycle

* fix(github): refresh native tool display snapshot

* fix(github): refresh config and UI baselines

* refactor(github): break OAuth identity import cycle

* test: make gateway retry deadline assertion scheduler-safe
2026-08-19 17:41:58 -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
Vyctor H. Brzezowski 16b09ad307 fix(ui): sync Terminal with live theme changes (#126297)
* fix(ui): sync terminal with live theme changes

* test(ui): cover terminal theme lifecycle

* test(ui): supply resolved theme in gateway fixture
2026-08-19 20:21:26 -03:00
Erick Kinnee ee70dbcb14 test(ui): split dynamic catalog convergence e2e test into its own file
Keeps chat-flow.models-reasoning.e2e.test.ts under the 1000-line max-lines
budget; the ratchet forbids new suppressions. The moved test is unchanged.
2026-08-20 00:11:29 +01:00
Erick Kinnee 09d419683e test(ui): cover dynamic catalog projection convergence 2026-08-20 00:11:29 +01:00
Erick Kinnee cc445a32bb fix: refresh dynamic model metadata in session controls 2026-08-20 00:11:29 +01:00
Josh Avant a4f17833ad fix(gateway): make config revision tokens opaque (#126464)
* fix(gateway): make config revision tokens opaque

* test(gateway): cover config revision key startup phase
2026-08-19 16:10:27 -07:00
Peter Steinberger 33e6daa3bd fix(ui): show mixed-role node connectivity (#126428)
Devices keeps machine-wide liveness while showing node-role offline/manual-wake state accurately.
2026-08-19 15:24:31 -07: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
Peter Steinberger a3ca8466ee fix(ui): refresh device labels after rename (#126432)
* fix(ui): refresh device labels after rename

* fix(ci): classify device label refresh event for mobile

* chore(protocol): regenerate Android gateway events
2026-08-19 14:18:50 -07:00
Peter Steinberger 513ec6218c fix(crabbox): harden worker desktop setup (#126417)
* fix(crabbox): harden desktop provisioning

* docs(gateway): clarify worker desktop routes
2026-08-19 14:13:06 -07: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 108a737552 test(ui): await anchored model picker geometry (#126438) 2026-08-19 13:47:20 -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 84c2111b30 fix: restore cloud worker Desktop on node-backed Crabbox workers (#126393)
* fix(gateway): carry cloud worker desktops over nodes

* fix(crabbox): restore node-backed worker desktops

* refactor(crabbox): split worker provider owners
2026-08-19 11:50:48 -07:00
Peter Steinberger 5976e74d1c fix(ui): close dashboard side panel in split view (#126397) 2026-08-19 11:36:46 -07:00
Peter Steinberger e47637809c fix(ui): render one assistant reply when history and the terminal event race (#126382)
* fix(ui): render one assistant reply when history and the terminal event race

A finished run's reply reached the Control UI twice: the durable transcript
row and the pane's own terminal projection shared no identity, so the
projection reducer kept both and the transcript collapsed them behind the
"x2" duplicate badge. The gateway's chat final event carries no message id,
and a durable assistant row carries no run id, so the reducer's same-run
promotion could never match them. A WeakMap side channel hid the duplicate
only when history happened to be applied before the terminal event arrived,
which made the badge look intermittent.

The pane now admits the durable assistant row of the run it is finishing
through the reducer, attributed to that run, so the durable row adopts the
terminal projection in place; the reducer refuses to downgrade a row that
already carries a transcript id back to an id-less projection.

Splits the run-terminal bookkeeping tests into a sibling file to stay under
the max-lines ratchet.

* fix(ui): bind a late reply row to its run only when it carries that reply

The terminal tombstone outlives its run by design, so attributing every
unowned assistant row to it could stamp a delayed older row with a newer
run's id; the reducer then matched that row to the newer run's terminal
projection and replaced the answer the user should see. The tombstone now
claims only the row carrying the reply already projected for that run.
2026-08-19 11:33:22 -07:00
ClawSweeper 76fc15c515 fix(ui): dedupe streamed final assistant messages (#126367)
Co-authored-by: RoboClaw <309084314+roboclaw-bot@users.noreply.github.com>
2026-08-19 12:26:01 -06:00
Peter Steinberger 0606e31d0e feat(gateway): broker GitHub publication (#126306)
* feat(gateway): broker GitHub publication

* refactor(gateway): split publication owners

* fix(gateway): enforce publication branch authority

* fix(gateway): bind publication to remote identity

* fix(gateway): bind publication recovery to remote state

* fix(gateway): preserve publication git state

* fix(gateway): retain publication recovery authority

* fix(gateway): commit publication index atomically

* fix(gateway): narrow publication index errors

* refactor(gateway): keep publication CAS errors private

* fix(gateway): recover publication index transactions

* fix(agents): describe GitHub publication tool

* fix(gateway): harden publication base fetch

* fix(gateway): reject publication filter semantics

* fix(gateway): verify publication creation base

* refactor(agents): align publication tool options

* fix(gateway): isolate publication object lineage

* refactor(gateway): use shared table probe

* test(gateway): keep publication helpers in routed suite

* perf(ui): lazy-load GitHub publication request

* fix(gateway): preserve publication support contracts

* fix(gateway): recover publication before authority checks

* fix(gateway): fence local publication snapshots

* fix(android): format generated protocol models

* fix(gateway): harden publication recovery

* fix(gateway): fence publication recovery

* fix(ui): reset completed publication cycles
2026-08-19 11:05:12 -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
Peter Steinberger 1d52299bca fix(ui): preserve device token state across reconnects (#126362) 2026-08-19 10:51:42 -07:00
Peter Steinberger 55fb2c8606 fix(ui): prevent duplicate assistant bubbles after history refresh (#126364)
* fix(ui): stabilize chat history dedupe identity

* fix(ui): narrow chat history dedupe identity
2026-08-19 10:48:33 -07:00
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