v0.12.0 — Grok Build, Needs You, transcript streaming, iOS UX
Grok Build — first-class backend
- Full xAI OAuth flow (device-auth),
~/.grok/auth.jsonmirrored per mission workspace, container-aware--cwdtranslation,grok-builddefault model exposed via/api/providers. /goal <objective>for Grok. Grok ships no native goal mode, so sandboxed.sh drives the loop: a sentinel protocol (<goal_complete/>/<goal_continue/>/<goal_aborted reason="…"/>) is injected into the first-turn prompt, then anAgentFinishedautomation re-fires a short continuation prompt every turn until the model declares done, the iteration budget (25) is hit, or two consecutive sentinel-missing turns trigger an auto-abort. Iteration / status events use the same SSE shape as codex so the dashboard's iter-N pill and the Automations panel light up without UI changes. Cancellation cleanly tears the loop down (aborted:cancelled).- Pre-existing Grok bugs fixed. Grok no longer inherits the global
DEFAULT_MODEL(wasanthropic/claude-opus-4-6, which the CLI rejected). Continuations use-s/--session-id(upsert semantics) instead of--resumeso orphan sessions from a failed first turn self-heal.
"Needs You" mission lifecycle
- New
MissionStatus::AwaitingUser/Acknowledgedvariants. Turn-complete-with-no-follow-up parks the mission inAwaitingUserinstead ofCompleted. Opening the mission stampsfirst_viewed_at; a 1 h grace timer promotes the mission toAcknowledged. Any new user message wakes it back toActive. - Dashboard column rewired: Needs You =
awaiting_user; Finished =completed / acknowledged / failed / interrupted / blocked / not_feasiblewith green/red tone viafinishedTone(status). NewPOST /api/control/missions/:id/openedbroadcasts the state change so other open clients re-tint without a refresh. - New
GET /api/control/missions/:id/{transcript,trace}endpoints split the mission view: chat paints fromtranscript(small, fast) and tool/thinking activity hydrates fromtraceafter first paint. Storage backends (sqlite/memory/file) updated withfirst_viewed_at+ idempotent migration.
iOS UX responsiveness pass
- Mission switch is cache-first — opening a recent mission renders instantly instead of behind a spinner.
- Parallelized RTTs —
loadMission/switchToMissionfan out metadata + events viaasync let;BackendAgentServicewalks per-backend configs and agents via twowithTaskGroups instead of N sequential awaits. - Synchronous-optimistic gestures everywhere: queue swipe-to-delete + clear, mission delete, automation toggle / delete, mission status menu, mission cancel chip, send-message bubble (
isPending), FIDO approve/deny — all mutate local state on the same frame as the gesture, then fire the network call. - Files browser: per-path LRU cache with stale-while-revalidate so navigation doesn't blank.
- Skeleton scaffolds on History, Files, Workspaces initial loads (replaces full-screen
LoadingView). - Cosmetic latency deleted:
SetupSheet500 ms post-success sleep, Terminal 500 ms "fake connect" timer, 300 ms workspace-switch reconnect delay. Terminal now promotes to.connectedon first message with a 3 s safety fallback for silent shells.
Transcript performance & correctness
- Mission history streams newest-first; cache hydrates instantly on reopen.
- "Load older messages" pinning bug fixed on web + iOS:
metaTotalis now computed from the loadable subset ofevent_countsonly. - Deferred trace merge deduplicates by
sequence(webMap, iOS[Int64: StoredEvent]).
Cleanup & fixes
- Amp/ampcode backend removed.
- Local dashboard API-base inference; config naming aligned.
- xAI add-provider modal now selects
["opencode", "grok"]for both OAuth-method and direct-provider paths. - Thinking panel default reverted to closed (auto-show on thinking-start remains).
- Trace API
limit/offsetuse!== undefinedsooffset: 0survives. - Favicon dot colors aligned with
STATUS_DOT_COLORSpalette. - Clippy clean against Rust 1.95.
Files: ~30 sources across src/api/, src/backend/, dashboard/src/, ios_dashboard/SandboxedDashboard/. Version bump 0.11.5 → 0.12.0 in Cargo.toml, Cargo.lock, dashboard/package.json. PR #433.