Commit Graph
15 Commits
Author SHA1 Message Date
abkslmandnucleic 3187a0f3d0 Settings Feature Enhancement
Nucleic-Session: 89BFAB13-D559-43FC-BE28-0B2639BECF0F
Co-authored-by: Nucleic <[email protected]>
2026-07-05 22:17:43 -07:00
abkslmandnucleic 7048786f10 Settings Feature Enhancement
Nucleic-Session: 89BFAB13-D559-43FC-BE28-0B2639BECF0F
Co-authored-by: Nucleic <[email protected]>
2026-07-05 22:05:54 -07:00
abkslmandnucleic 0f710582bf nvrsion: Add: Reconnect Icon Update, fix mesh iPhone discovery for new Macs, fix session order adjustment to pin sidebar sessions for remote projects, fix session status synchronization for remote viewer Macs, fix session order adjustment for iOS app session list, fix session status synchronization for remote sessions, fix iOS app live activity height by removing the “<n> files changed” line, fix Tool Call Card Mesh so AI bash summaries transit the mesh layer to other Macs, replace “Resolved by mac-ui” in transcripts with device ID, fix Chat: Print Wait Message, fix Chat: Reconnect Icon Update, fix Chat: Activity Theme Adjustment for “attention needed” live activity theme.
Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
2026-07-05 04:24:25 -07:00
abkslmandnucleic 7d7a7c457d nvrsion: Add: Global Icon For Remote Projects to display globe icon next to remote projects in sidebar, matching local projects in appearance, Fix: Chat: Remove Face ID Permission Text, Refactor: Chat: Live Activity Content Density to open app directly into waiting sessions when tapped, Refactor: Chat: Live Activity Content Density to refresh live activity info significantly faster, Refactor: Chat: Live Activity Content Density to refresh live activity info significantly faster, Fix: Chat: Live Activity Content Density to refresh live activity info significantly faster, Fix: Chat: Network Type Transition Optimization to reduce delay during network type switches, Feature Enhancement Planning: All devices in a mesh group should see and be aware of each other; “pair” reframed into “join”; scanning
Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
2026-07-05 00:28:21 -07:00
abkslmandClaude Opus 4.8 1786fba01f Mesh P5: finish transfer feature set — moved/arrived visibility, recovery, bulk hand-off
Completes Phase 5 of the multi-device mesh / session-transfer program (docs/MESH_TRANSFER.md)
except the two-Mac memory-carry spike. All additive + capability-gated; SyncProtocol stays v1.

- Moved-session visibility: additive SessionSummary.movedTo (MovedDestination), decode-defaulted.
  A moved session no longer silently vanishes — the source keeps a read-only "Moved to <Mac>"
  tombstone under Archived (name resolved live from paired Macs), surfaced on relaunch without
  rebuilding a runnable controller, and sent on the wire so phones see it too.

- Relaunch recovery driven from launch (+ on every peer reconnect, single-flight):
  AppStore.recoverInterruptedTransfers clears abandoned pre-tombstone locks, discards orphaned
  inbound staging, and re-drives a tombstoned commit via SessionTransferCoordinator.recoverTombstoned
  (bounded, idempotent; a dest that lost staging leaves the lock, never revives the source).

- Bulk "Hand off active sessions…": transferableSessions + moveSessionsToPeer (sequential, rollup
  error) behind a "Hand off…" button → HandoffSheet checklist in RemoteAccessView.

- Arrived-from provenance (mirror of moved-to): GRDB v24 arrived_from_device_id/arrived_at; the
  importer stamps them at staging; additive SessionSummary.arrivedFrom (ArrivedFrom); a subtle
  "Arrived from <Mac>" marker on the sidebar (live name) + iOS row (host-baked name).

- Stranded-arrival "Activate anyway": the importer persists the staged Session to the staging dir
  at .ready, so a destination that relaunches before commit can recoverableInboundTransfers() and
  activateRecoveredTransfer()/clearInboundStaging(). AppStore surfaces pendingArrivedTransfers with
  activate/discard, shown in a new "Interrupted arrivals" section. (A .ready lock with no manifest
  is now cleared as unrecoverable.)

Tests: +6 core, +2 protocol across WireMessageTests, SessionTransferTests, AppStoreTests,
AppStoreSyncBridgeTests. Full package builds; Swift suites green. iOS NucleicRemote edits reviewed
but not compiled here (separate Xcode target).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-04 17:02:15 -07:00
abkslmandClaude Fable 5 6bd439dd66 Mesh P5 (engine): session-transfer wire, schema, git bundle, coordinator/importer
Builds the tested foundation for session transfer Mac→Mac (docs/MESH_TRANSFER.md
Phase 5) — a 2-phase commit that moves an idle session's git branch, transcript,
row projection, and best-effort agent memory to another Mac. This commit is the
transfer *engine*; the live AppStore/PeerClient/UI wiring is the next layer.

Wire (NucleicProtocol): TransferMessages.swift — TransferOffer / TransferAccept /
TransferReject / TransferChunk / TransferChunkAck payloads, SessionTransferRecord,
ProjectDescriptor (matches by UUID / root commit / normalized remote),
TransferRejectReason (raw-string, forward-compatible). ClientMsg source→dest verbs
(transferOffer/Chunk/Commit/Cancel) + HostMsg dest→source replies; the replies ALSO
map to SyncClient.Event + messageLoop so the source, receiving them as a client,
doesn't drop them. WireCapabilities.canReceiveSessionTransfer (decodeIfPresent).

Persistence (v23): moved_to_device_id/moved_at tombstone columns (archived path,
NOT a new SessionStatus case) + session_transfer table with a UNIQUE-while-active
index; store methods beginTransfer/updateTransferState/activeTransfer/
allActiveTransfers/tombstoneSession/activateTransferredSession (atomic + idempotent).

Git (WorktreeManager): createTransferBundle (prereq-based with prereq-free fallback),
createFromTransfer (bundle verify + fetch + worktree add), discardAfterTransfer,
presentSHAs/branchExists; TransferGitProbe for repo shape (shallow/partial/LFS/
submodule) + identity (root commit + normalized remote). git-bundle round-trip
verified against real temp repos.

Transcript: SessionHeader.maxSupported + TranscriptHeaderRewriter (repoint paths /
drop backendSessionID for the fresh-context fallback) — first consumer of versioning.

Engine: SessionTransferPackage (stage items + per-item sha256, bundle built post-
accept vs haveSHAs), SessionTransferCoordinator (source 2-phase commit, tombstone-
before-commit, windowed chunk acks, typed errors), SessionTransferImporter (dest
stage-non-runnable → activate-on-commit, best-effort native memory carry with fresh-
context fallback). ConnectionHandler dispatches the verbs gated on .control + mac
peer (peerKind now persisted); SyncHostBridge importer surface with reject-defaults.

Tests: 763 core + 105 protocol green (+~28). Wire codec/backcompat; GRDB v23 schema
+ lock lifecycle + UNIQUE-while-active (disk path) + atomic idempotent activate;
git bundle round-trip (prereq/prereq-free) + shape/identity probes; transcript
rewrite/versioning; full loopback transfer (real repos + GRDB + in-memory channel):
happy path w/ tombstone ordering + worktree discard + activation, project-not-found
/version-mismatch rejects, commit idempotency, double-transfer lock, native memory carry.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-04 03:06:38 -07:00
abkslmandClaude Fable 5 8776c9f333 Mesh P4 remainder: PeerClient, Mac↔Mac pairing, addresses, dedup
Completes Phase 4 of the multi-device mesh program (docs/MESH_TRANSFER.md):
a Mac now dials paired sibling Macs with the same platform-neutral SyncClient
the iPhone uses, so it is both a host to its phones and a .control-scope client
of its peers — the dependency session transfer (P5) was waiting on.

Wire (NucleicProtocol, version stays 1, additive + capability-gated):
- PeerAddresses {lanHint, tailnet, relayRoomID, updatedAt}; optional
  Hello.addresses / Welcome.addresses; ClientMsg.addressUpdate gated on new
  WireCapabilities.canUpdateAddresses; PairedDevice.addresses — all
  decode-defaulted so shipped iPhones and pre-mesh stores load unchanged.

Core (NucleicCore):
- PeerClient: serial LAN→tailnet dial over an injectable PeerDialer, capped
  backoff, live presence stream, listPeers only when advertised. MacPeerDialer
  + LANDialChannel add the outbound dial-side FrameChannel that didn't exist.
- Symmetric pairing into one PairedDeviceStore (one pasted link makes both Macs
  dialable); accepting-Mac confirm (locked decision #4); SyncHost per-deviceID
  connection dedup (keep-newest, 2s grace); AppStore lifecycle + meshPeers.

UI: "Paired Macs" section (presence/transport/revoke), paste-link pairing sheet,
QR sheet doubles as copy-link + confirm dialog.

Hardening (adversarial review, 11 defects fixed incl. two security holes):
- Mac-pairing confirm enforced on the reconnect promotion path (a phone can't
  reconnect claiming deviceKind=mac to skip the confirm).
- Existing-device hello branch requires the authenticated static key to match
  the pin (a pairing party can't claim another device's deviceID).
- startPeerClient guarded against a racing stopSyncServer; confirm timer stored
  and cancelled on resolve; pair() treats pre-welcome wireError as terminal and
  classifies decline vs unreachable; handshake deadlines; setPresence won't
  resurrect an unpaired peer; meshPeersChanged no-ops once the server is down;
  pairing UI cancels in-flight pair() on dismiss; LANDialChannel cancels on
  .failed + TCP keepalive.

Tests: 871 green (742 core + 98 protocol + 31 new) — wire codec/backcompat,
dedup, address exchange, addressUpdate, mac-confirm decline/phone-skip,
key-mismatch + promotion rejects, PeerClient pair-via-link/reconnect/listPeers
gating/unpair loopback.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-04 02:19:23 -07:00
abkslmandClaude Fable 5 7e80a45ddc Mesh + session transfer: P1 done, P2 core, P4 foundation
Multi-device mesh + session-transfer program (docs/MESH_TRANSFER.md).

P1 (multi-select connection methods, Mac): SyncTransportSet with legacy
migration; CompositeSyncListener partial-failure tolerant + per-method health;
AppStore listens on all enabled methods; HostInfo.hostID = DeviceIdentity.hostID
(key hash, not display name); Settings 3 method toggles + LAN-only recommendation
banner.

P2 core (relay hardening, security-critical, tested): nucleic-edge relayEnroll.ts
X25519 proof-of-possession enroll + server-side roomId derivation; room.ts
role-routed per-peer forwarding with deviceId-tag envelope + frame cap +
one-host-per-room eviction; host-bearer minting bound to the PoP room. Swift
cross-stack contracts pinned to test vectors: RelayEnrollment (PoP proof),
RelayEnvelope (routing tag), PairingPayload relay fields. Socket transport +
iOS un-gating remain deploy-gated.

P4 foundation (peer model + listPeers, tested): PeerTypes (PeerKind/
PeerCapabilities/PeerSummary); Hello.deviceKind+clientCaps;
WireCapabilities.canListPeers; ClientMsg.listPeers -> HostMsg.peerList;
PairedDevice.kind+capabilities (decode-defaulted); ConnectionHandler records
kind at pairing; SyncHost.connectedDeviceIDs(); AppStore.peerSummaries();
SyncClient .peerList event; iOS RemoteStore.meshPeers. PeerClient + Mac<->Mac
pairing UI remain.

All additive + capability-gated; SyncProtocol.version stays 1; pre-mesh stores
and clients unaffected. Swift 724 core + 91 protocol tests green; edge 50 green.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-04 00:39:30 -07:00
abkslmandnucleic 98f84d21a1 nvrsion: Add: Adjust Canary Build Auto-Update to run every hour, fix Keychain permission audit by updating files: ControlAuth.swift, GitHubCredentials.swift, HeartbeatReporter.swift, KeychainOwnedAccess.swift, HostIdentityStore.swift, PushRelayClient.swift, refactor Remote Build Icon to use “bell.and.waves.left.and.right.fill” in ios/NucleicRemote/NucleicRemote/Views/BuildBanner.swift, add a Remote Release Channel Check in AppStore.swift, Sync/ConnectionHandler.swift, Sync/SyncHostBridge.swift, Sync/ReleaseChannel.swift, Sync/SyncClient.swift, Sync/WireMessages.swift, tests/SyncHostTests.swift, tests/SyncTestSupport.swift, and align build number hash in ios/NucleicRemote/NucleicRemote.xcodeproj/project.pbxproj, ios/NucleicRemote/NucleicRemote/Info.plist, ios/NucleicRemote/NucleicRemote/Views/BuildBanner.swift.
Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
2026-07-02 21:54:40 -07:00
abkslmandClaude Fable 5 2b7290b73e sync: project quota, provider status, todo triage, and full diffs to the phone
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]>
2026-07-02 16:06:32 -07:00
abkslmandnucleic 0404147164 nvrsion: Add: Fix truncation of “Run now” button text in New idea composer, add model selector support for Claude Fable 5, refactor Project Workflow Enhancement, add Wait Button Logic, update iOS remote to match Chat Message Queue Display, block sandboxed/controlled agents from running git commands via mcp__nucleic__host_exec using container-level shims, add chat icon animation to bounce when chat is blocked for >60 seconds, add “Cmd+Shift+N” shortcut to open a floating chat composer over the window, remove “Run now” button from “New idea” composer, and shield Git command execution by scanning inside ‘-c’ strings.
Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
2026-07-01 19:01:20 -07:00
abkslmandnucleic ae488f1332 Activity Chart Intensity Logic
Nucleic-Session: 76D64900-B16F-45BE-A6CB-E3D2EBC7C73A
Co-authored-by: Nucleic <[email protected]>
2026-06-27 19:17:17 -07:00
NucleicandClaude Opus 4.8 277a76b85c iOS remote: transcript fidelity + mid-session controls & model catalog
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]>
2026-06-21 04:03:53 -07:00
abkslmandClaude Opus 4.8 a0bbbe34e9 M4+: control-scope protocol + host bridge (session metadata, dashboard, actions)
Protocol: SessionSummary gains projectID/disposition/pendingApprovalCount/favorite/
archived (fixes the archived-chats-in-Needs-You bug + done-vs-needs-you). New
DashboardSnapshot (counts + activity grid + projects + todos), WireProject/WireTodo,
StartChatRequest/CaptureTodoRequest. ClientMsg gains listDashboard + the control set
(startChat, captureTodo, dispatchTodo, setTodoStatus, deleteTodo, renameSession,
setFavorite, setArchived, deleteSession, integrate, discard); HostMsg gains dashboard.
Moved ProjectID/TodoID/TodoStatus/TurnDisposition into NucleicProtocol. SyncClient
claims control by default + surfaces a .dashboard event.

Host: phone is granted control scope (parity). AppStore implements dashboardSnapshot()
+ all control actions (mapping to startChat/addTodo/dispatchTodo/todo CRUD/deleteSession/
integrate/discard/favorite/archive/rename) and broadcasts dashboard refreshes on turn
end + after each action. ConnectionHandler dispatches the new cases, control-gated.

178 tests green (protocol round-trips for all new messages; host control actions reach
the bridge end-to-end + grant control scope).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-13 02:10:24 -07:00
abkslmandClaude Opus 4.8 daeaa13d3d M4: CBOR codec, length-prefixed framing, and the sync wire message set
NucleicProtocol/CBOR: a deterministic Codable CBOR encoder/decoder (value-tree
parse/serialize + Encoder/Decoder adapters) with type-flexible numeric decoding
(so JSONValue's int/double probing round-trips) and sorted map keys. Plus
length-prefixed framing (4-byte BE) with a FrameAccumulator that reassembles
across arbitrary stream chunks and caps frame size.

NucleicProtocol/Sync: the SYNC_PROTOCOL §5 message set — ClientMsg/HostMsg with
tagged Codable, Hello/Welcome handshake, Subscribe/Verbosity, SessionSummary,
SessionSnapshot, EventBatch, WireError, DeviceScope. HostMsg decodes unknown
tags to .unknown for forward compatibility.

15 NucleicProtocol tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-13 00:34:52 -07:00