dev received an intermediate snapshot of this branch that had the accent
scoping machinery (AppPalette.make(controlled:), controlAccent, RootView's
contextProjectID gate) but NOT the reverts of the base accent back to teal.
Result: the standard palette's base accent AND controlAccent were both
lavender, so control and non-control projects rendered identically lavender.
Re-assert the defaults so the gate is actually visible:
- macOS AppTheme: standard base accent -> teal (0.04,0.52,0.50); controlAccent
stays lavender (0.45,0.32,0.82). Non-control/home now render teal; only
Nucleic Control projects get lavender.
- iOS NucleicRemote: Palette.accent + AccentColor.colorset back to flat teal
(remote has no Control concept).
Merges current dev first so this branch is strictly ahead of it — autoshipping
it back to dev will now override dev's lavender base with teal.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Make the lavender/purple accent a signal that you are operating inside a
Nucleic Control project; every other project keeps the standard teal tint.
- AppPalette.make gains a 'controlled' flag. When true (and in standard
color-vision mode) it swaps the teal accent for a cached, nightSoftened
lavender (controlAccent); otherwise it returns the unchanged palette.
- RootView derives 'controlled' from store.contextProjectID ->
Project.isNucleicControlled, so the tint follows the active project and
reverts to teal on the home dashboard / non-control projects. Tracked
through Observation, so it flips live as you navigate.
- Color-vision (deut/prot/trit) palettes keep their tuned accents; the
swap only applies in standard mode.
- iOS NucleicRemote reverts to the standard teal: the remote has no
Nucleic Control concept (the wire protocol doesn't carry it), so it
can't distinguish controlled projects and stays teal everywhere.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Switch the standard brand accent from deep teal to lavender/purple across
macOS and iOS, with a distinct shade per appearance:
- macOS (AppTheme standard palette): accent -> (0.45, 0.32, 0.82). ~5.4:1
with white labels in light; nightSoftened() derives the muted dark shade.
- iOS (Palette.accent): now an appearance-aware UIColor — deep violet in
light, brighter lavender (0.66, 0.55, 0.95) in dark so it lifts off the
near-black background.
- iOS AccentColor.colorset: add a dark luminosity variant to match.
Accessibility color-vision palettes (deuteranopia/protanopia/tritanopia)
are intentionally left tuned for distinguishability; tritanopia already
renders violet.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
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]>
Animate the Mac streak lightning bolt; intensity (speed, scale, brightness,
rotation jitter, glow) ramps up with streak length.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
# Conflicts:
# Sources/NucleicApp/HomeView.swift
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]>
iPhone client gains full control-scope parity with the Mac (start chats, manage
to-dos, manage/integrate sessions), the desktop design language (teal palette,
status colors, cards), and Home/Projects/To-Dos surfaces. Fixes archived chats
leaking into Needs You. See nucleic-m4-state.
# Conflicts:
# ios/NucleicRemote/NucleicRemote.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
Adds DEVELOPMENT_TEAM (3XPAYVD6BP) so the app signs to a physical iPhone, and
records the resolved SwiftTerm / swift-argument-parser package pins. Generated by
opening the project in Xcode.
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]>
- LANAddress.primaryIPv4() (getifaddrs, prefers en*) embedded in the pairing QR via
beginPairing, so the phone dials the Mac directly instead of relying on Bonjour
discovery (much more robust on real networks; Bonjour stays a fallback).
- iOS project switches from CODE_SIGNING_ALLOWED=NO to CODE_SIGN_STYLE=Automatic so
it signs to a physical device once a team is selected in Xcode (simulator still
builds without a team).
174 tests green; macOS + iOS-simulator builds clean.
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]>