Commit Graph

8 Commits

Author SHA1 Message Date
Vyctor H. Brzezowski e7ba2e1f6b fix(ui): give the Gateway update a visible, truthful outcome (#121686)
* fix(ui): give the Gateway update a visible, truthful outcome

Confirming an update in the Control UI could end in nothing the operator
could see. The sidebar card only knew `updateRunning`, which clears as soon
as `update.run` answers, so a dev-channel handoff — git pull, install, full
build, restart — spent minutes back on the stale "N commits behind" call to
action. A verified install then published a null banner, so success was
never announced at all, and the reload that a verified install triggers
would have destroyed any in-memory notice anyway.

The lifecycle was already recorded; nothing rendered it. Feed the sidebar
the reconciliation fact the settings page already uses, narrate the wait in
the shell callout that survives the restart, and record the verified result
so it outlives the reload it causes.

Failures now name their cause. The updater already stores the failing step
and its captured output in the restart sentinel and `update.status` returns
it whole, so a disk-full install reads "The update failed at install:
ENOSPC: no space left on device" instead of a reason slug plus "see the
gateway logs". Missing handoff-reason guidance is filled in, and the
duplicate post-restart banner resolver is folded into the shared one.

Also fixes a callout clipped by the fixed shell chrome controls, and the
"Available 246 commits behind" double framing in the confirmation.

* fix(ui): report the Gateway update in the dialog that starts it

Follow-up to the first pass: the shell-top callout was the wrong surface for
this. The dialog the operator clicked is now the one that reports the whole
update, and the ambient surfaces are the fallback for anyone who leaves it.

Confirming no longer closes the dialog. It becomes stateful — the danger
button turns into a disabled "Updating…" with a spinner, and the body
narrates the phases in place: installing, then "The Gateway is restarting.
This page disconnects and reconnects on its own." The dialog is mounted on
document.body, outside the shell, so losing the connection cannot unmount
the only surface still reporting. A request the Gateway never accepts stops
spinning after a bounded grace and says so.

A failure lands in the dialog with its recorded cause and next step. Success
still arrives after the reload a verified install triggers, so it stays a
toast — no dialog exists by then.

The shell-top status callout is gone. The same outcome now renders beside
the sidebar update card that started the update, and stays hidden while the
dialog owns the report so the two surfaces never duplicate each other.

Splits the wire-payload readers out of update-overlay-helpers into
update-schedule-dto and moves update.run answer classification next to them,
keeping both owners under the file-size budget.

* fix(ui): keep the update dialog open through the install in E2E and use a defined warn token

* refactor(ui): wire the update progress stream into the floating card and drop unused video capture

* fix(ui): report the current update, not the previous failure

The dialog subscribed to progress before starting the update. Producers
replay their current snapshot synchronously on subscribe, so a retry
still carrying the previous attempt's failure banner painted that old
error as this update's outcome.

Start the request first, and treat a failure present on the subscribe
emit as the previous attempt's: an accepted run clears the banner before
its first await, so a failure that survives means the request was
refused, which the accept timer already reports truthfully.

* fix(ui): keep update helpers internal

* chore(perf): raise startup-JS budget to 350 KiB

Approved by maintainer Vyctor on 2026-08-11.

Trigger: after #121734, main measured 326650 B—6 B below the prior 319 KiB hard ceiling. Current main subsequently moved the ceiling to 320 KiB; this records the authorized final 350 KiB decision for #121686.

* fix(ui): announce update success without session storage

Show the verified install identity directly when the current document does not reload, so denied session storage cannot suppress the operator-visible outcome.

* test(ui): isolate update toast in overlay tests

The Node-only overlay suite now reaches the direct non-reload success toast. Mock the DOM-owned toast boundary so reconciliation assertions can complete without a browser document.
2026-08-11 13:49:12 -03:00
Vincent Koc 8d3f3377da fix(ci): make Control UI artifact validation consistent (#122086) 2026-08-12 00:11:22 +08:00
Peter Steinberger db73b59c04 refactor: burn wrapper shadowing baseline entries (#122040)
* refactor: burn wrapper shadowing entries

* chore: refresh wrapper shadowing baselines

* test: update secrets runtime state mocks

* fix(ci): absorb Control UI build identity variance
2026-08-11 08:24:03 -07:00
Peter Steinberger 8dace97c2e perf(test): cut workflow guard overhead (#122038)
Co-authored-by: Amp <amp@ampcode.com>
2026-08-11 06:29:08 -07:00
Peter Steinberger fa03d9b913 refactor: consolidate coercion helpers (#121366)
* refactor: consolidate coercion helpers

* fix: remove duplicate coercion imports

* fix: preserve serialized coercion guard

* chore: ratchet coercion helper carve-outs

* fix(test): keep gauntlet subprocess startup lean

* fix: preserve imported session timestamp semantics

* fix: preserve catalog timestamp string semantics

* chore: align plugin SDK surface ratchet

* fix: preserve trajectory and SDK string contracts

* fix(test): preserve QA record assertion semantics

* fix: complete standalone record guard rename

* refactor(cron): use canonical string coercion

* fix(acpx): preserve Pi timestamp parsing

* test(channels): adapt custody test harnesses

* test(telegram): classify media harness as test support

* test(acpx): split timestamp contract coverage

* test(channels): support generated custody contracts

* chore: ban the full coercion helper name set

Extends the declaration guard to all eleven consolidated helper names and
renames the cron schedule-identity readNumber wrapper to readScheduleInteger
so the banned generic name cannot regrow.

* fix(scripts): repair release-validation guard drift and lint cause

Restores the renamed isJsonRecord guard in assertTrustedWorkflowHarness after
main added isRecord call sites in parallel, and attaches the caught YAML error
as the thrown error cause (preserve-caught-error was red on main).

* fix: preserve Claude timestamp string semantics

* fix: preserve persisted timestamp string semantics

* fix: preserve date-first timestamp contracts

* fix(openai): harden delegation failure formatting

* chore: close coercion helper guard gaps

* test(openai): model non-error delegation rejection

* chore: refresh plugin SDK API contract

* fix(tasks): use canonical string field reader

* fix(ai): use canonical provider error field coercion

* fix(browser): migrate native bootstrap coercion

* docs(plugin-sdk): clarify text record export compatibility

* fix(gateway): normalize approval execution identity

* test(outbound): isolate message action poll harness
2026-08-11 00:02:18 -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
Peter Steinberger 5207c4765d feat(ui): float task-suggestion cards top-right with copy-prompt action (#121259)
* feat(ui): float task-suggestion cards top-right with copy-prompt action

- Float a compact tray in .chat-main__conversation with absolute positioning, min(400px, 100% - margins) sizing, elevation, and internal scrolling.
- Remove the icon column, keep dismiss in the header row, and move a compact split button to the bottom-right.
- Add Copy prompt to the menu via shared copyToClipboard, copying the raw prompt while display-only sanitization remains documented inline.

Release note: Suggested-task cards now float as compact cards at the chat top-right and offer Copy prompt in the action menu.

* style(ui): neutral grey task-suggestion card and actions

Drop the accent-tinted card border/background, mute the eyebrow, and use default grey button treatment for the split control per operator direction.

* fix(ui): ungate copy-prompt and surface clipboard outcomes

- Menu now always renders with the client-local Copy prompt while acceptance-mode items stay capability+scope gated (addresses ClawSweeper finding 1).
- Copy success shows a transient Copied label and failures surface through the pane error path (finding 2).
- Task-suggestion pane logic extracted to chat-pane-task-suggestions.ts and the tray adapter moved into the component to keep files under the 700-line cap.

* fix(ui): test task suggestions through tray adapter

* test(ui): cover task-suggestion clipboard failure

* test(ui): split task-suggestion pane coverage

* chore(ui): raise startup JS budget for task-suggestion card feature

QA-profile measurement was 324617-324620 B versus the 324608 B effective budget; this owner-directed PR #121259 bump follows the baseline file’s documented feature-growth precedent.

* chore(ui): raise startup JS ceiling to 318 KiB for task-suggestion cards

The fixed 317 KiB ceiling (324608 B) was within ~20 B of CI-measured startup bytes after accumulated main drift; the task-suggestion card feature crossed it. Ceiling raised with in-file maintainer-approval comment per its own convention; ratchet baseline set to CI-measured 324626 B.

* fix(ui): keep task-suggestion copy available read-only

Remove the stale accept-or-dismiss tray guard now that Copy prompt is a client-local action. Keep Gateway-backed accept and dismiss controls independently gated, with a regression for operators who can only list suggestions.

* test(ui): cover list-only task-suggestion copy

Update the mocked-Gateway E2E to match the repaired read-only behavior: the suggestion remains visible, its mutating Start action is disabled, and Copy prompt stays available.
2026-08-09 18:45:47 -07:00
Peter Steinberger c70aee247e refactor(scripts): migrate JavaScript tools to TypeScript (#121005)
* refactor(scripts): migrate JavaScript tools to TypeScript

* fix(ci): keep changed-scope preflight zero-install

* fix(ci): preserve zero-install script owners

* fix(ci): complete script migration follow-through

* fix(release): keep stable closeout zero-install

* fix(scripts): preserve standalone execution boundaries

* fix(scripts): repair standalone loader boundaries

* fix(scripts): normalize gateway observation ids

* fix(scripts): keep Docker packager standalone

* test(scripts): preserve rebase cleanup helpers

* test(sessions): use tracked temp directory
2026-08-09 07:21:35 -07:00