The first pass put the detail in a ScrollView with fixedSize(horizontal:)
and a fixed maxHeight, so the command was forced onto one long line that
scrolled horizontally and the box always claimed full height — a tall box
with a lot of empty space.
Replace it with an ApprovalDetailBox (macOS + iOS) that wraps the text and
measures its content height via a PreferenceKey, sizing the box to fit and
only scrolling vertically once the content exceeds the max height. No more
horizontal scroll; short commands sit in a snug box.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Permission requests only ever displayed a summary that was hard-capped:
RiskClassifier.title() slices to 80 chars, and the iOS card used a lossy
compactSummary clipped to 8 lines. The full tool input was present on the
request but never shown, so a long Bash command, file path, or URL was cut
off with "…" and the user couldn't see what they were granting.
- Add RiskClassifier.detail(toolName:input:): the full, untruncated content
(full command/path/url/query), falling back to the pretty-printed input so
nothing about an unrecognized tool is hidden.
- Add JSONValue.prettyString() for indented, multi-line display.
- macOS ApprovalBar: render the detail in a bounded, scrollable, selectable
monospaced block (shown only when it adds beyond the already-shown title).
- iOS ApprovalCardView: replace lossy compactSummary/lineLimit(8) with the
full content in a bounded scroll view via JSONValue.approvalDetail.
- Tests: assert detail is full and untruncated, with pretty-input fallback.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Surface actively-running sessions on the phone home dashboard: a fourth
"In progress" stat card and a list pinned above the to-dos. Both share one
definition (live sessions with status .running), and list rows link into the
session transcript.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add a `.note` AgentEvent kind — a system-generated log line — and emit one
into the open session's transcript whenever a control in the header Git menu
is used (merge/squash/rebase outcome, open in Terminal, reveal in Finder,
copy branch/worktree path). Renders as a muted note on both macOS and iOS.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The macOS ApprovalBar put the title and action buttons on one row, so a
long file-path title got truncated. Stack title above the buttons so it
wraps to as many lines as needed. Bump the iOS card's input summary cap
from 3 to 8 lines. Both made text-selectable.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Adds a per-project "Allow host build/run" sandbox capability that lets a
containerized agent request to build and run executables on the host
machine, escaping the Linux sandbox — e.g. compiling and running a macOS
binary the container can't.
- New `host_exec` MCP tool on the approval server, advertised only when the
session opts in. Pre-allowed via --allowedTools so the call reaches our
handler directly rather than Claude's permission path: the handler is the
sole gate, so `auto` mode can never auto-approve it.
- Every host command surfaces an explicit approval (risk .hostExec) and runs
on the host via /bin/zsh -lc in the session worktree only after approval.
An explicit "Allow for Session" choice grants the rest of the session;
auto-approve never sets that — only a deliberate user choice does.
- ProjectSandbox.allowHostExec (off by default) with tolerant decoding so
rows persisted before the field default to false instead of dropping the
whole sandbox config.
- Threaded allowHostExec through RunSpec/ResumeSpec/SessionController; Mac
Project Settings toggle; Mac ApprovalBar "Allow for Session" button; iOS
risk styling/biometric gate for .hostExec.
- Tests: host_exec advertised/served only when registered + refused
otherwise; allowHostExec round-trip and legacy-JSON default-to-false.
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]>
A real iOS Xcode app (ios/NucleicRemote) linking the NucleicProtocol SwiftPM
library as a local package. Builds for the iOS 27 simulator and launches to the
pairing screen.
- Transport: NWFrameChannel (NWConnection) + LANDiscovery (Bonjour _nucleic._tcp).
- Engine: drives NucleicProtocol.SyncClient (Noise XXpsk0 pair / IK reconnect,
hello/welcome, HostMsg→Event stream).
- State: RemoteStore (ObservableObject) — the single on-device projection of host
state; IdentityStore persists the device identity (Keychain) + pinned host.
- UI (UX_IOS): attention-first SessionsView, SessionDetailView (transcript/diff +
status-driven action area / composer), ApprovalCardView with Face ID gate on
high-risk approvals + allow-always menu, PairingScannerView (AVFoundation QR),
SettingsView, connection chip. Same status glyphs/semantics as the Mac.
Add-iPhone QR display + server start live on the macOS side (follow-up); push /
Live Activity are M5 (needs the relay). gitignore keeps this .xcodeproj despite
the blanket *.xcodeproj rule.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>