Commit Graph
328 Commits
Author SHA1 Message Date
Nucleic c79d1767bc Resync dev into nucleic/trunk after promotion
# Conflicts:
#	cloud/nucleic-edge/wrangler.jsonc
#	ios/NucleicRemote/NucleicRemote.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
2026-06-27 13:44:15 -07:00
NucleicandClaude Opus 4.8 ab17d9d229 Promote nvrsion trunk → dev
Squash-merge nucleic/trunk into dev (234 commits of accumulated nvrsion work).

Resolved two auto-generated-file conflicts:
- cloud/nucleic-edge/wrangler.jsonc: kept dev's real KV namespace ids and the
  xyz.blakeslee.nucleic.remote APNS topic, with binding names corrected to
  RELAY_TOKENS/PUSH_TOKENS to match the worker code on both branches.
- Package.resolved: took trunk's newer dependency pins.

Nucleic-Promote: 1
Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-27 13:43:32 -07:00
Nucleic d78f7ccef1 ios changes 2026-06-26 21:11:28 -07:00
Nucleic 7f452e5664 nvrsion: recovered uncommitted work after restart
Nucleic-Recovery: 1
2026-06-26 20:58:18 -07:00
Nucleic f1e18477a7 Tool Call Semantics Alignment
Nucleic-Session: B5E370C3-4764-47E1-95D3-A36B4AAB8AC6
2026-06-26 20:26:34 -07:00
Nucleic e674508e59 Tool Call Semantics Alignment
Nucleic-Session: B5E370C3-4764-47E1-95D3-A36B4AAB8AC6
2026-06-26 20:25:24 -07:00
Nucleic 8d8be78a6a Tool Call Semantics Alignment
Nucleic-Session: B5E370C3-4764-47E1-95D3-A36B4AAB8AC6
2026-06-26 20:25:15 -07:00
Nucleic e9256d8a6d Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:23:14 -07:00
Nucleic 87ed8f2bda Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:23:09 -07:00
Nucleic e22b63da4c Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:22:59 -07:00
Nucleic 5c3c0d82c8 Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:22:54 -07:00
Nucleic 1e6e1d4ba3 Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:22:49 -07:00
Nucleic dac5b158cc Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:22:42 -07:00
Nucleic bf3da86252 Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:22:36 -07:00
Nucleic 6634734e0f Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:22:30 -07:00
Nucleic 5a43718fd4 Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:22:24 -07:00
Nucleic 0f1c1e8ffd Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:22:19 -07:00
Nucleic 4b6e51ab03 Release Keyboard Release
Nucleic-Session: FD190A87-E8F7-4C72-A15E-E35B88EF5921
2026-06-26 20:22:11 -07:00
NucleicandClaude Opus 4.8 cc97c26256 Signing: rebrand bundle IDs to xyz.blakeslee.* and correct the Team ID
Desktop channels → xyz.blakeslee.nucleic.desktop.{dev,beta,rc,release} (the stable channel keyword is unchanged; only its bundle-id suffix is "release"). iOS remote → xyz.blakeslee.nucleic.remote, including its Keychain account namespaces, the scanner log subsystem, and the coupled APNS topic.

Correct the Apple Developer Team ID to L7UDTQ6F5W across the Xcode project, ExportOptions, the APNS config + tests, and the signing/cloud docs.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-26 16:52:14 -07:00
Nucleic d97c9397a0 Merge branch 'dev' into nucleic/trunk 2026-06-26 16:18:02 -07:00
Nucleic 16c7b2cc7e nvrsion: promote trunk to dev
Nucleic-Promote: 1
2026-06-26 16:18:02 -07:00
Nucleic f83e73eb80 Cloud Infrastructure Setup
Nucleic-Session: 5AC77C62-A729-42E5-A368-1142C3B9E695
2026-06-26 15:35:09 -07:00
Nucleic e9c65725ae Cloud Infrastructure Setup
Nucleic-Session: 5AC77C62-A729-42E5-A368-1142C3B9E695
2026-06-26 15:35:07 -07:00
Nucleic a2ab883035 Cloud Infrastructure Setup
Nucleic-Session: 5AC77C62-A729-42E5-A368-1142C3B9E695
2026-06-26 15:35:04 -07:00
Nucleic d0e50f896e Cloud Infrastructure Setup
Nucleic-Session: 5AC77C62-A729-42E5-A368-1142C3B9E695
2026-06-26 15:35:01 -07:00
Nucleic 878ffd9eab Cloud Infrastructure Setup
Nucleic-Session: 5AC77C62-A729-42E5-A368-1142C3B9E695
2026-06-26 15:34:58 -07:00
Nucleic e71aac7056 Cloud Infrastructure Setup
Nucleic-Session: 5AC77C62-A729-42E5-A368-1142C3B9E695
2026-06-26 15:34:51 -07:00
Nucleic c33002ca45 Cloud Infrastructure Setup
Nucleic-Session: 5AC77C62-A729-42E5-A368-1142C3B9E695
2026-06-26 15:08:00 -07:00
Nucleic 1e8816907e Cloud Infrastructure Setup
Nucleic-Session: 5AC77C62-A729-42E5-A368-1142C3B9E695
2026-06-26 15:07:58 -07:00
Nucleic ac01589dbf Cloud Infrastructure Setup
Nucleic-Session: 5AC77C62-A729-42E5-A368-1142C3B9E695
2026-06-26 15:07:54 -07:00
Nucleic 7eb60fe672 Cloud Infrastructure Setup
Nucleic-Session: 5AC77C62-A729-42E5-A368-1142C3B9E695
2026-06-26 15:07:50 -07:00
Nucleic 1fdb89e6c1 nvrsion: promote trunk to dev
Nucleic-Promote: 1
2026-06-26 14:28:43 -07:00
Nucleic e618ceb0a9 Merge branch 'dev' into nucleic/trunk 2026-06-26 14:28:43 -07:00
Nucleic b3693f7ce3 Signing Process Optimization
Nucleic-Session: 673CC74C-CCCA-4025-A961-87CC35C28327
2026-06-26 14:17:52 -07:00
Nucleic 24b0b4e8c4 Signing Process Optimization
Nucleic-Session: 673CC74C-CCCA-4025-A961-87CC35C28327
2026-06-26 14:17:18 -07:00
Nucleic 8db01ac703 nvrsion: promote trunk to dev
Nucleic-Promote: 1
2026-06-26 01:29:27 -07:00
Nucleic 4093b3568c Merge branch 'dev' into nucleic/trunk 2026-06-26 01:29:27 -07:00
Nucleic 0847d8fbff Streak Freeze Feature Implementation
Nucleic-Session: 89DB7BC1-F74C-4768-BC7B-25F898265E0E
2026-06-26 01:18:41 -07:00
Nucleic 705d997b78 Streak Freeze Feature Implementation
Nucleic-Session: 89DB7BC1-F74C-4768-BC7B-25F898265E0E
2026-06-26 01:18:36 -07:00
Nucleic cf1176fe96 Streak Freeze Feature Implementation
Nucleic-Session: 89DB7BC1-F74C-4768-BC7B-25F898265E0E
2026-06-26 01:18:29 -07:00
Nucleic e11fda7fa2 Streak Freeze Feature Implementation
Nucleic-Session: 89DB7BC1-F74C-4768-BC7B-25F898265E0E
2026-06-26 01:18:24 -07:00
Nucleic 09d4c80edf Streak Freeze Feature Implementation
Nucleic-Session: 89DB7BC1-F74C-4768-BC7B-25F898265E0E
2026-06-26 01:18:11 -07:00
Nucleic f96e2948ab Streak Freeze Feature Implementation
Nucleic-Session: 89DB7BC1-F74C-4768-BC7B-25F898265E0E
2026-06-26 01:18:03 -07:00
NucleicandClaude Opus 4.8 cfa823bc13 iOS pairing scanner: surface "could not start" + Try Again
On-device logs proved the camera is being blocked by device state, not
the app: every retry showed window=true app=active scene=foregroundActive
yet reason-1 (videoDeviceNotAvailableInBackground) persisted for 6s — the
signature of iPhone Mirroring / a locked tethered device, where iOS
disables the camera (the recurring com.apple.PointerUI log is the Mac
pointer driving the phone).

Rather than sit on a black screen after retries are exhausted, report a
new .couldNotStart state explaining the likely cause (locked / mirrored)
with a "Try Again" button that rebuilds the capture session from scratch
(via .id(retryToken)). App-side capture code is correct; this is a
graceful fallback for an environment that withholds the camera.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-21 17:16:08 -07:00
NucleicandClaude Opus 4.8 765183d25b iOS pairing scanner: delayed bounded retry for reason-1 interruption
On device the camera still reported reason 1 (videoDeviceNotAvailable-
InBackground) even when started from viewDidAppear with the app
foreground-active: the camera assertion isn't granted until the sheet's
presentation transition fully settles (a few hundred ms), and the
back-to-back retries all fired inside that unsettled window.

Add a short delayed retry (0.5s, bounded to 12 attempts) driven by the
interruption notification, plus a proactive +0.6s retry after the view
appears, resetting the counter once the session actually starts. Also log
the window/app/scene activation state to confirm the foreground signals.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-21 17:09:14 -07:00
NucleicandClaude Opus 4.8 07b6769410 iOS pairing scanner: start camera only when foreground (fix black preview)
Root cause (from on-device logs): the session was started from
viewDidLoad while the pairing sheet was still presenting, so iOS
interrupted it with reason 1 (videoDeviceNotAvailableInBackground) and it
never ran (isRunning=false) — a black preview. The CMVideoFormatDescription
-12710 errors were unrelated noise.

Defer startRunning until the camera can actually run: configure the graph
up front, then start only once the view is on screen and the app is
foreground-active (viewDidAppear + a guarded startSessionIfReady). Recover
on AVCaptureSessionInterruptionEnded / didBecomeActive / runtimeError. All
start triggers funnel through the session queue and no-op if already
running, so it's idempotent.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-21 17:00:42 -07:00
NucleicandClaude Opus 4.8 783aac7683 iOS pairing scanner: add capture diagnostics (temporary)
Black preview persists on a real device though the session reports
running, so instrument the capture lifecycle to pinpoint it: logs the
authorization status, the selected device, isRunning/inputs/outputs after
startRunning, and on AVCaptureSessionDidStartRunning the preview layer's
connection (present/active/enabled) plus the view/layer bounds. Also
observes AVCaptureSessionRuntimeError and ...WasInterrupted.

Filterable via os.Logger subsystem com.nucleic.remote / category scanner
(marker "📷"). To be trimmed once the root cause is fixed. Also sets an
explicit .high preset and gates metadataObjectTypes on availability.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-21 16:53:31 -07:00
NucleicandClaude Opus 4.8 b5853eee67 iOS pairing scanner: fix black preview on device
The feed stayed black even when the session reported running: the preview
was a manually-framed sublayer (frame set in viewDidLoad/viewDidLayout,
which raced the async permission callback and could end up zero-sized),
and the session was configured across threads (addInput/Output on main,
startRunning on a queue).

Switch to the canonical AVFoundation pattern: the preview is now the
view's backing layer (CameraPreviewView via layerClass), so it always
fills the view with no frame bookkeeping, and all session configuration +
start/stop run on a dedicated serial queue with delegate/state callbacks
hopped to main.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-21 16:38:00 -07:00
NucleicandClaude Opus 4.8 d8fc4696a8 iOS pairing scanner: handle no-camera / denied gracefully
The QR scanner sat on a silent black screen when the camera couldn't
start: it called AVCaptureDevice.default(for: .video), got nil (e.g. on
the Simulator, which has no camera), and bailed via an early guard with
no UI feedback. It also never requested camera permission (a denied
device stayed black with no recovery) and sized the preview layer only
once in viewDidLoad.

Now it gates on AVCaptureDevice authorization (requesting access when
undetermined, surfacing a Settings link when denied), reports an
"unavailable" state when there's no camera so the UI explains the black
screen, and updates the preview frame in viewDidLayoutSubviews. Camera
runs work on a background queue.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-21 04:45:18 -07:00
NucleicandClaude Opus 4.8 e6ef59e830 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