feat(onboarding): clearer provider signposting + official install commands#1
Merged
Conversation
…mands Prompted by watching a new tester hit a Codex quota wall that read as "broken": the first-launch sheet had no way to show "signed in but out of usage", and gave little help installing a CLI. - Out-of-usage card state: wire usageSummary into FirstLaunchSheet so a signed-in provider at ~100% shows "100% used / resets HH:MM" + a quota bar (reuses the sidebar Model Usage card pieces; no new infra). - Status-dot legend under section 1 so a red dot isn't read as one single failure (not installed vs not signed in vs out of usage). - New sections: "You stay in control" (graduated approvals + permission presets) and "Track your usage & spend" (Model Usage pointer + mock). - Sign-in mechanics primer: terminal-login vs in-app OAuth vs API key, plus a note that Cursor/Grok dots stay amber (their CLI auth isn't observable). - Ensemble preview now shows all six providers (adds Cursor + Grok); helper notes to get one provider working first. - Copyable official CLI install commands (new ProviderInstallCommands), in both the onboarding sheet and Settings -> Providers, from each vendor's own install docs. - Copy fixes: intro names 6 providers (was 4); permission chip "red" (was "orange"); file mention "-@" (was "@", now a participant DM). typecheck clean; 3104 tests pass; lint clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
boggspa
added a commit
that referenced
this pull request
Jun 6, 2026
…eplaces segmented toggle #1 of the composer UX pass: the Turn / Continuous / Work Session segmented toggle is now a body-portaled hierarchical picker (EnsembleModePicker), mirroring the Model/Reasoning + Permissions pickers — the trigger shows the active mode, the popover lists all three with descriptions + a checkmark on the active one. Fan-out stays a separate composable toggle beside it (per the product decision). Cloned structurally from ComposerProviderPicker; reuses the shared composer-combined-picker-popover CSS (shell-${style}), so per-shell theming applies with no per-shell branches. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
boggspa
added a commit
that referenced
this pull request
Jun 6, 2026
…kers (#1-5,#8) Final sign-off pill pass (remove side): the specified pickers read as floating labels (no outer pill) per shell — - Native (default): Permissions/Tool Grants, Turn, Provider, Model/Reasoning, Workspace - Codex / Grok: Turn - Claude / Cursor: Turn + Provider + Workspace - Satellite: Turn + Fan-out Gemini + Kimi keep their pills (restyle handled separately). Strips bg/border/shadow/blur on the trigger (+ nested picker-label/combined-picker -trigger) with !important to beat the base chrome. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
boggspa
added a commit
that referenced
this pull request
Jun 12, 2026
…eplaces segmented toggle #1 of the composer UX pass: the Turn / Continuous / Work Session segmented toggle is now a body-portaled hierarchical picker (EnsembleModePicker), mirroring the Model/Reasoning + Permissions pickers — the trigger shows the active mode, the popover lists all three with descriptions + a checkmark on the active one. Fan-out stays a separate composable toggle beside it (per the product decision). Cloned structurally from ComposerProviderPicker; reuses the shared composer-combined-picker-popover CSS (shell-${style}), so per-shell theming applies with no per-shell branches. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
boggspa
added a commit
that referenced
this pull request
Jun 12, 2026
…kers (#1-5,#8) Final sign-off pill pass (remove side): the specified pickers read as floating labels (no outer pill) per shell — - Native (default): Permissions/Tool Grants, Turn, Provider, Model/Reasoning, Workspace - Codex / Grok: Turn - Claude / Cursor: Turn + Provider + Workspace - Satellite: Turn + Fan-out Gemini + Kimi keep their pills (restyle handled separately). Strips bg/border/shadow/blur on the trigger (+ nested picker-label/combined-picker -trigger) with !important to beat the base chrome. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
boggspa
added a commit
that referenced
this pull request
Jun 22, 2026
…nt switch render handleSelectChat received a lightweight SUMMARY record from the sidebar and always rendered it (empty transcript) then re-fetched via getChat + re-rendered with messages — two full App+Composer reconciles per single-pane switch (the switch freeze). On re-visit we already hold a hydrated record (cached from a prior visit or a live run); when it is at least as fresh as the summary (updatedAt guard) we select it directly, so render #1 shows the full thread and hydrateSelectedChatAfterPaint's summary guard short-circuits — one reconcile instead of two, and no empty-then-full flash. First-visit (cache miss) still hydrates from disk as before. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
boggspa
added a commit
that referenced
this pull request
Jun 22, 2026
Implements the find verb: resolve a vague {provider, workspace, time, task}
reference to a ranked, bounded candidate set, scoped to a single workspace.
- RecallToolExecutors: createRecallToolExecutors now takes injected deps
(run-queue list, workspaces, caller-workspace resolver, chat-text loader,
forensics predicate) so it stays unit-testable with no Electron. find:
* scopes to the NAMED workspace, else the caller's own; refuses (none +
note) when there is no workspace to scope to — never enumerates
everything.
* flags crossWorkspace (named != caller) for the host gate; same-workspace
is auto-allowed, a different workspace is a cross-workspace read (the host
approval gate already runs before this executor; Slice 3 refines it into
the scope-conditional crossThreadRead service).
* optional remote-allowlist visibility gate (dormant in v1 — remote-issued
recall is blocked upstream).
* structural-only candidates (no prompt/transcript bytes); honours `limit`.
read / read_events still return not_implemented (Slice 4).
- AppStore.hasRunForensics: cheap existsSync + deletedRunIds check so a
deleted/tombstoned run is excluded rather than returned as a hollow shell
(the #1 confabulation trap). Correct across restarts.
The index.ts deps wiring lands in the working tree (deferred — that file
carries a concurrent feature). 30 recall tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
boggspa
added a commit
that referenced
this pull request
Jun 22, 2026
…o toolbar menus (build 39) #2 (diff-pill, 3-reviewer adversarial synthesis): near-edge drag wrapped the pill to multi-line and its hit-area sat inside the iPad screen-edge-swipe gutter, blocking sidebar expansion. pillBody now lineLimit(1)+fixedSize(horizontal)+layoutPriority(1) (incompressible single line; spacers yield, no wrap/latch); maxOffsetX keep-clear edgeMargin 4->28pt (clears the ~20pt edge-pan gutter) and fails CLOSED to 0 when unmeasured (was .greatestFiniteMagnitude = no clamp, letting a first-frame drag fling the pill to the edge); restingLeadingInset gains a hard ceiling so a stale measurement can't overflow the row. #1 (toolbar style): the New + More MENU pills inherited the accent (blue) over the pill chrome's black/white foreground — force .tint(textPrimary) so they match the Refresh/Settings button pills + the inspector toolbar. iOS build 38 -> 39. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
boggspa
added a commit
that referenced
this pull request
Jun 23, 2026
The headline streaming-smoothness fix: decouple the on-screen render cadence from the provider's wire cadence. Previously updateChatById called setChats + setCurrentChat synchronously on EVERY delta (5-60/sec), so React commit frequency tracked delta frequency. Now: - chatByIdRef stays the synchronous, byte-exact source of truth (the write on every delta is unchanged). - updateChatById gains options.coalesce. The streaming assistant_message_delta path defers its React commit to ONE requestAnimationFrame flush per frame (<=60 commits/sec); every other caller (complete/tool/error/media/hydration/ one-off) commits immediately and drains any pending deltas first, preserving order. - flushCoalescedChats commits all dirty chats by reading back from the ref, so a deferred commit can never write stale content. Two clobber vectors the coalescer widens are guarded (both surfaced by the gate + adversarial review): - the [currentChat] effect no longer seeds the ref for an actively-streaming chat (a lagging currentChat could otherwise overwrite fresh tokens); - handleSelectChat now prefers the live ref entry when selecting an actively- streaming chat instead of writing the now-laggier sidebar list record. Safety rests on the token-drop reconcile preserve set (committed earlier): the streaming chat's ref entry is preserved across the deferred window, so the reconcile cannot clobber it. The gate is extended with the coalescer contract, the [currentChat] guard, and the select-chat guard (each with negative controls). typecheck:web clean; 1916 renderer tests green; reviewed by two adversarial Opus agents (token-drop: SAFE-WITH-FIXES, fix applied; blast-radius: NO REGRESSIONS). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
boggspa
added a commit
that referenced
this pull request
Jun 23, 2026
Roadmap #5, compounds with #1. Wrap MarkdownMessage in React.memo with a comparator that re-renders only when the rendered output can change: the markdown content, the chat scope (appChatId), or the identity registry <AgentMention> reads (chat.providerMetadata.agentIdentities). The `chat` prop is the whole currentChat — a new object on every coalesced flush — so a reference compare would defeat the memo; comparing the identity-relevant slice instead means a per-frame transcript re-render only re-renders the ONE message that streamed, not every visible bubble. Also useMemo the block split so a re-render not caused by a content change doesn't re-run the O(n) string scan. renderToStaticMarkup output unchanged; markdown + transcript tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prompted by watching a new tester hit a Codex quota wall that read as "broken": the first-launch sheet had no way to show "signed in but out of usage", and gave little help installing a CLI.
typecheck clean; 3104 tests pass; lint clean.