Round out the Mac-parity keyboard/pointer affordances on the iPad split view.
Keyboard shortcuts (hidden buttons in SplitRootView carry them):
- ⌘N — start a new chat: select Home and focus the composer (also defaults the
project). A one-shot Bool binding threads Home→StartChatComposer and is
consumed on use, so it grabs focus on ⌘N but never on a later Home appearance
(handles both "already on Home" via onChange and "switched from a session"
via onAppear).
- ⌘1–4 — jump to Home / Projects / To-dos / Settings.
- ⌘R — refresh sessions.
- ⌘. — interrupt a running session (Mac's "stop"; otherwise only in the ⋯ menu).
UI:
- A visible "New chat" (compose) button in the sidebar toolbar runs the same
action, so touch users get the affordance too (gated on control scope).
Hover (pointer):
- .hoverEffect on the transcript tool-call / tool-block rows and the Home
in-progress session rows (native List rows already hover).
Verified in the iPad simulator: the New-chat action scrolls to + focuses the
composer with the project defaulted. Builds clean.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Make the remote feel native with a Magic Keyboard / trackpad, and give iPad a
pairing path that survives a blocked camera.
Keyboard shortcuts (mirroring the Mac's .commands):
- Cmd+Return sends in the session follow-up composer and the start-chat composer
(plain Return stays a newline in the multiline fields).
- On the approval card, Return allows and Esc denies -- the approval bar replaces
the composer, so Return is unclaimed there. Allow stays gated on the biometric.
Pointer:
- .hoverEffect on the diff file-list rows (native List rows already hover).
Camera-free pairing (ManualPairingView):
- "Enter code manually" in both the pairing intro and Settings opens a sheet to
paste the Mac's nucleic://pair?d=... code, parsed with the same
PairingPayload(qrString:) the scanner uses (+ a Paste-from-clipboard button).
The iPad scanner can't run while mirrored to an external display or in some
Stage Manager states; this always works.
Note: the Mac's RemoteAccessView currently shows only the QR, so a follow-up host
change is needed to surface a copyable pairing link for this to be end-to-end.
Builds clean.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Four Mac surfaces the iOS remote couldn't render now ride the wire,
forward-compatibly (decodeIfPresent defaults; unknown HostMsg tags
already decode to .unknown):
- DashboardSnapshot gains `usage` (WireSubscriptionUsage — the Mac's
5-hour/weekly quota gauges) and `statusFeeds` (WireStatusFeed —
active provider incidents); the host re-pushes the dashboard when a
poll changes either.
- WireTodo gains `triage` (raw TriageLevel name); the phone renders
the Mac's TriageBadge honoring the encouraging/classic label
setting.
- ClientMsg.fetchDiff / HostMsg.sessionDiff deliver the full worktree
patch on demand (capped at 512 KB with a truncated flag), gated on
the new WireCapabilities.canFetchDiff so a new phone never sends it
to an old host. iOS renders a file list + colored unified patch,
falling back to the diffstat summary against older hosts.
Round-trip and legacy-decode tests cover the new fields; the full
suite passes apart from the pre-existing fake-backend fixture gaps
and the flaky nvrsion lock-domain test (same failure rate on the
base commit).
Co-Authored-By: Claude Fable 5 <[email protected]>
Port the Mac's MarkdownText renderer, AppPalette (color-vision modes +
night-softening), appearance settings (theme/text size/color vision),
and BuildBanner channel strip to the iPhone remote. Add session-row
attention/unseen-completion washes and marker icons, Discard action,
branch/worktree options in the new-chat composer, and a transient
error bubble for host wire errors. Stamp the build channel via
NucleicChannel in Info.plist (ios-release.sh passes NUCLEIC_CHANNEL,
default beta). Demo mode gains NUCLEIC_DEMO_SESSION and skips the
notifications prompt so UI previews are scriptable.
Co-Authored-By: Claude Fable 5 <[email protected]>
Bring NucleicRemote closer to desktop parity in two areas (the core
sync loop was already at parity — shared protocol, control scope).
Transcript fidelity (iOS): a client-side TranscriptProjection coalesces
streaming text by messageID and folds each tool call's lifecycle
(start/deltas/complete/result/fileChange) into one expandable card —
fixing the duplicate started+completed rows. Adds Markdown bubbles, the
gold Orchestra card for Task/Agent spawns, and the previously-dropped
usage/cost, rate-limit, file-change, turn-boundary and session-started
rows, plus a context-window % header badge.
Mid-session controls + model catalog (protocol/host/iOS): project the
host ModelCatalog over the wire as WireModelCatalog (in Welcome); add 5
control-scope setters (setSessionModel/Effort/Auto/AutoShip/ShipBranch)
backed by the existing AppStore.mutateSession + SessionController hooks;
enrich WireSessionSummary with model/effort/auto/autoShip/shipBranch/
contextInputTokens (all forward-compatible). The composer gains a model
picker and a catalog-driven effort menu (per-backend caps: Codex→xhigh,
Grok→auto), and the session header gains a model/effort/auto/autoship
control bar.
Tests: CBOR round-trips for the new messages, Welcome.modelCatalog, the
new summary fields, forward-compat decode of old bytes, and the setters
reaching the host. Verified in the Simulator (NUCLEIC_DEMO=1).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Orchestra is a Nucleic Control capability now:
- Core: SessionController withholds the fan-out consent unless the session's project
is under Control (resolvedEffort still maps the sentinel to xhigh, so a stray
selection never reaches a backend verbatim). Covered by a new SessionController test.
- macOS: the effort menu shows Orchestra disabled with a 'Requires Nucleic Control'
note + tooltip off-control; effectiveEffort demotes a carried-over selection so the
label/glow never show it active where it can't run.
- Home composer themes lavender (the Control accent) for a Control project — the
Auto/Merge accents and a persistent ring on the field, tracking the project picker.
- Remote: WireProject carries isNucleicControlled (decode-tolerant) so the iOS effort
picker gates Orchestra the same way.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Renames the orchestration mode's user-facing brand and all code identifiers
(UltracodeStyle→OrchestraStyle, isUltracode→isOrchestra, AppTheme.ultracode→
.orchestra, etc.). The canonical effort sentinel becomes "orchestra"; the legacy
"ultracode" token is still recognized so a persisted/in-flight session keeps
working. Comment referencing Claude Code's own ultracode mode kept accurate.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Design system: Palette (teal accent + the Mac's categorical status colors, status→color
refined by turn disposition), StatusStyle glyphs/labels, a card surface modifier, app-wide
teal tint.
Fixes the reported bug: Sessions now hides archived chats and uses disposition to split
NEEDS YOU from DONE (a finished-the-work turn no longer shows as needing you). Rows gain
status dots, favorite star, approval-count badge, diffstat; swipe to favorite/archive/delete.
New surfaces, full control-scope parity with the Mac:
- Home: greeting + day-streak flame, GitHub-style activity grid, stat cards, quick to-dos,
and a start-chat composer (project picker + Auto).
- Projects: per-project session counts → project detail with a scoped composer.
- To-dos: capture, group by project, complete/dispatch/delete.
- Session detail: a control menu (rename, favorite, interrupt, integrate merge/squash/rebase,
archive, delete).
RemoteStore handles the dashboard event + exposes all control intents; claims control scope.
A NUCLEIC_DEMO/NUCLEIC_TAB env seam seeds mock state for offline UI preview.
iOS app builds for the iOS 27 simulator; Home + Sessions verified rendering via screenshots.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>