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.
* fix(workboard): make ownership updates atomic
Persist launch intent before worker acceptance, reconcile accepted identities,
fence cross-host card mutations, and deduplicate session capture in SQLite.
Closes#125932
* test(workboard): keep race fixtures plugin-local
Use a plugin-local synchronization helper and update the sessions-page capture
expectation for the new store-owned RPC.
* fix(workboard): fence lifecycle and restore races
Apply terminal lifecycle state only while the matched association is current,
and converge concurrent archived session restores on the active winner.
* fix(auth): preserve WHAM classifications and failure recording
WHAM 401/403 state now drives accurate re-auth guidance, while inline hook failures are contained after persistence so recorded failures cannot escape or be masked.
* docs(plugin-sdk): define auth cooldown classifications
document the additive cooldown diagnostic contract and cover its canonical public-SDK projection.
* fix(auth): keep WHAM diagnostics source-compatible
keep cooldownReason canonical, persist exact WHAM diagnostics in optional cooldownClassification, and preserve operator guidance plus failure-hook containment.
* fix(auth): keep failover on canonical cooldown reasons
ensure optional WHAM diagnostics never drive scheduling and discard mismatched persisted reason/classification pairs.
* fix(voice-call): expose realtime/streaming stream paths through tailscale serve/funnel
Tailscale serve/funnel now auto-exposes the realtime and streaming WebSocket stream paths when those audio modes are enabled; previously Twilio <Connect><Stream> could not reach wss://<ts-host><streamPath> and realtime calls dropped after ~1s with no log.
Also: CLI voicecall expose mounts/clears stream paths symmetrically, partial tailscale mounts roll back on failure, and a warning now fires when a call's stream WebSocket never arrives within the token TTL. Reported/observed live by Peter Steinberger.
* fix(voice-call): make tailscale stream exposure atomic
Preserve configured public Tailscale prefixes when mapping realtime and streaming routes, and roll back the full route set when any mount fails. The CLI now uses the same transactional setup path and reports failure instead of accepting a partial exposure.
* fix(voice-call): expose Twilio's configured streaming path
Keep realtime routes under the public webhook prefix they advertise, while mounting streaming.streamPath exactly as Twilio emits it. This preserves the canonical public-to-local route list without expanding the provider API outside the scoped repair.
* fix(voice-call): grace realtime stream disconnects
Share reconnect grace by CallSid and stream ID across classic and realtime streams while cleaning realtime bridge resources immediately.
Log terminal call reasons and document Twilio inbound voice and status callback setup.
* test(voice-call): align reconnect grace after rebase
Preserve the newly landed realtime generation and inactivity coverage while updating its terminal expectations for shared delayed finalization.
Remove the redundant replacement cross-product case so the lifecycle suite remains below the max-lines limit.
Realtime call teardown previously depended on an object-identity guard
that silently skipped ending the call record when bridge instances were
replaced, and had no transport-liveness backstop: a WS close that never
propagated left an answered call running forever. Bindings are now
socket-bound with current-generation terminal ownership, predecessor
audio is retired on successor admission (the overlapping-voices bug),
a 30s media-inactivity watchdog with 2s grace ends calls whose
transport dies silently, and every realtime call end is logged with
its cause.
* feat(agents): unify agent status into a durable progress_card
Replace the write-only update_plan to-do tool and the fragmented plan
rendering with one durable status artifact per session: progress_card
({plan?, markdown?}, replace-on-write, 8 KiB markdown / 50-step caps).
Cards persist in a lazy-additive session_progress_cards table in the
per-agent DB (no schema-version bump), broadcast progressCard.changed,
and render from the store with exactly one live placement per view
(session rail when visible, else the composer-adjacent bar); transcripts
collapse to one-line receipts, and the sidebar hovercard shows other
sessions' cards inline (markdown + <progress>, DOMPurify allowlist, no
iframes). The three stream-derived plan renderers and their dedup
heuristics are deleted.
Codex runs disable the native plan tool per thread
(tools.update_plan.enabled=false) and receive progress_card via the
dynamic-tool bridge; compaction restore now reinjects the card (steps +
bounded markdown). Card writes still emit the legacy plan stream event so
native apps and channels keep working until their per-platform
migrations. Policy names map update_plan -> progress_card; the shipped
tools.updatePlan=false kill switch is honored.
Net -277 production LOC; -480 test LOC.
* test(agents): regenerate Codex prompt snapshots for update_plan thread-config disable
* chore(protocol): allowlist progressCard.changed for native apps pending card migration
* fix(ci): repair progress card integration checks
* fix(codex): canonicalize native progress cards
* test(gateway): reconcile progress card method order
* test(codex): stabilize native approval fixture
Plugins holding a remote URL had no non-deprecated Plugin SDK path to turn it into managed media; saveMediaSource was only reachable through the deprecated media-runtime barrel while docs pointed at media-store. Re-export it from the focused subpath and move the bundled qa-channel plugin off the deprecated barrel. Maintainer decision: full saveMediaSource (local path + HTTP(S)) is the supported media-store contract.
Fixes#125259
* feat(workboard): full-board dashboard widget
Adds a third trusted plugin widget kind, workboard:board, rendering the
complete Kanban board (all columns, live plugin.workboard.changed
refresh) inside a session dashboard. Props {boardId} scope it to one
board; without it the widget shows every board, matching workboard:mini
semantics. Card rendering reuses the workboard page renderColumn with an
explicit surface option so page and widget cannot drift; the shared
board filter moved to ui/src/lib/workboard/board-filter.ts. Mutations
follow the connection's canMutate; read-only connections get a
view-only board.
Proof: pnpm test ui/src/lib/board ui/src/pages/workboard
ui/src/lib/workboard extensions/workboard (9,494 passed), i18n baseline
green, autoreview clean (codex/gpt-5.6-sol). tsgo core/ui/extensions
green locally; remote check:changed blocked by Daytona capacity and the
tsgo:core Daytona exit reproduced locally as a heavy-check lock race,
passing on retry.
* test(ui): seed workboard fixtures in the mocked dev server
* fix(ci): register workboard proof capture script
* feat(workboard): reference the automation job that owns a board's prompt
Boards can now record automationJobId, linking a board to the cron
automation whose prompt/model/schedule categorize its cards. The cron
job remains the single owner of that configuration; workboard stores
only the reference. The board toolbar shows an Automation chip linking
to the cron page when set. Deleting a board never deletes the job.
Proof: pnpm test extensions/workboard packages/workboard-contract
ui/src/pages/workboard ui/src/lib/workboard (9,492 passed), autoreview
clean (codex/gpt-5.6-sol). check:changed blocked by remote capacity
(Blacksmith down, Daytona lease cap); local fallback lanes green except
a parent-branch lint finding fixed on that branch.
* fix(ui): describe workboard automation destination