* feat(control-ui): stream live draft previews in the typing indicator
Multi-identity sessions now show what a teammate is typing, not just that
they are typing: the composer's per-keystroke session.typing sends carry a
bounded tail of the draft (optional preview field, 400 code points max),
the gateway throttle re-emits on changed payloads at 250ms (boolean-only
stays at 1s, trailing edge keeps the latest draft), and the transcript
renders a per-actor bubble with the live text plus a blinking caret.
Actors without preview data keep the three-dot bubble.
Previews are ephemeral presence: never persisted, never part of the
session transcript or model context, excluded from aria-live regions, and
gated by the existing >=2-live-viewers, sharing-role, and incognito
checks. No new config surface.
* chore(protocol): regenerate Swift gateway models for typing preview
* fix(gateway): aggregate typing previews across same-actor connections
A boolean-only session.typing update from a second connection of the same
actor (another tab or device) erased their live draft preview, because
typing liveness aggregated per actor while the broadcast preview came only
from the latest request. Preview aggregation now lives with the connection
aggregation owner: updateTypingConnections tracks per-connection previews
and returns the newest non-empty preview among live connections, so the
broadcast keeps the active draft until its connection stops or expires.
Regression fails pre-fix (event lost its preview field).
`main` is red: `check-lint-core-5` fails with
ui/src/pages/cron/view.test.ts
1124:4 error File has too many lines (1004). eslint(max-lines)
The file has been growing for a while (1104 lines at fa75cdd01c, 1116 at
2acfc47b7f) and crossed the 1000 code-line cap at a4b3f63a87 (#126945). Every
PR opened since inherits the failure, so this is not any one PR's fault to fix
in passing -- it blocks the merge gate for everyone.
Repo policy forbids a `max-lines` suppression, so the file is split along the
seam it already had: three top-level describes, one of which was two thirds of
the file. `cron view editor` moves to `view.editor.test.ts`; `cron view list
pane` and `cron view selects` stay in `view.test.ts`. The four DOM helpers the
blocks shared move into the existing `view.test-support.ts` sibling rather than
being duplicated, and each file imports only what it uses.
No test content changed: 42 tests before, 42 after, same 41 `it(` declarations.
Sizes drop to 373 / 721 / 143 lines, all well under the cap.
Control UI now preserves active-run commentary and tool progress when a follow-up steers the same run, while fresh sends still clear stale projection state.
Fixes#126938.
Reviewed-by: @shakkernerd
* fix(ui): surface provider-usage failures instead of empty panels
* fix(ui): complete typed route-data fixtures and stop reporting cancelled usage requests as failed
- Add providerUsageUnavailable to the five UsageRouteData fixtures in
gateway-source-replacement.test.ts; check-test-types passes again.
- requestProviderUsage reports failed only for non-cancelled rejections; an
aborted request is the caller superseding its own load, not an outage.
- Cover answered, failed, and cancelled outcomes.
* chore(ui): keep ProviderUsageFetch local to its module
* fix(ui): clear the provider failure flag when an aggregate usage load fails
- A failed aggregate refresh says nothing about provider usage; the stale
flag no longer keeps claiming the last provider request failed after a
later usage.cost or sessions.usage rejection.
- Sequential regression: usage.status failure, then an aggregate failure,
ends with the flag cleared.
* test(ui): type the usage route data on the test element
* test(ui): cover provider usage request outcomes
* fix(ui): model provider usage request outcome
* fix(ui): preserve provider usage outcomes
* fix(ui): resolve provider usage build
Host zlib versions compress identical startup assets into different bytes, causing false Linux budget failures. Emit canonical shipped pako gzip sidecars, restore the 512 B ratchet tolerance, and lower the startup baseline from 348351 B to 344531 B.