Skip to content

Native iOS companion app (Liquid Glass) — read-only usage mirror over LAN + iCloud#1979

Draft
brahimhamichan wants to merge 4 commits into
steipete:mainfrom
brahimhamichan:feat/ios-companion-app
Draft

Native iOS companion app (Liquid Glass) — read-only usage mirror over LAN + iCloud#1979
brahimhamichan wants to merge 4 commits into
steipete:mainfrom
brahimhamichan:feat/ios-companion-app

Conversation

@brahimhamichan

@brahimhamichan brahimhamichan commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Screenshots

Lock Screen widget — Usage Codex detail — usage, cost & daily activity
Settings — Paired Macs & sync Choose Widget picker

What

A native iOS 26 Liquid Glass companion that mirrors the usage the Mac already aggregates —
provider windows, credits, token cost — on the Home Screen, Lock Screen, and (optional) Live
Activity
. It is a read-only mirror: the Mac ships the same WidgetSnapshot; no provider
credentials on the phone
. Opposite approach to the earlier POC in #439.

Closes #1976. Relates to #439, #319.

Transport (serverless, user-managed)

  • LAN fast path — the Mac advertises _codexbar-sync._tcp (Bonjour) and streams a
    length-prefixed JSON SyncEnvelope. Instant on the same Wi-Fi.
  • iCloud backbone — the Mac writes to the user's private CloudKit DB; keeps widgets / Lock
    Screen / Live Activities fresh in the background, anywhere. No server, no CF Worker.
  • Newest generatedAt wins.

Live Activities are off by default (opt-in; no APNs server, so they refresh locally).

Layout

  • ios/ — XcodeGen project (xcodegen generate). Shared/ (Foundation-only WidgetSnapshot
    mirror + transport), CodexBarMobile/ (SwiftUI app + Live Activity), CodexBarMobileWidget/
    (Home + Lock Screen widgets + Live Activity widget). Reuses the CodexBar icon + provider SVGs.
  • Sources/CodexBar/MobileSync/ — macOS publisher (Bonjour listener + CloudKit push), opt-in:
    a no-op unless UserDefaults.standard.bool(forKey: "mobileSyncEnabled"). Hooked into
    UsageStore.persistWidgetSnapshot (one line).
  • Tests/CodexBarTests/MobileSyncEnvelopeTests.swift — wire-contract guard for the JSON the phone decodes.

Testing

  • swift build (macOS) — Build complete.
  • swift test --filter MobileSyncEnvelopeTests — passes.
  • iOS app + widget extension build for the iOS 26 simulator; app + all three screens verified
    full-screen on iPhone 17 Pro Max (iOS 26.5).
  • LAN end-to-end verified: a Mac publisher advertising _codexbar-sync._tcp → the app
    discovered it and live-replaced its data over the network.
  • Installed and launched on a physical iPhone via a dev-signed build.

Notes for reviewers / follow-ups

  • Draft. A Preferences toggle for mobileSyncEnabled still needs wiring into SettingsStore
    (currently a bare UserDefaults key).
  • Checked-in .entitlements are empty so unsigned simulator builds stay green. Real device/signed
    builds need App Group + iCloud/CloudKit + Push + Background-remote-notification (+ macOS
    network.server) — documented in ios/README.md. CloudKit self-gates at runtime by reading the
    embedded provisioning profile, so an un-entitled build runs (LAN only) without crashing.
  • No manual pairing yet: LAN discovery is open on the local network. A pairing code / device
    allowlist is a sensible follow-up before wider release.

…+ iCloud

A read-only iPhone companion (iOS 26) that mirrors the WidgetSnapshot the Mac
already aggregates — provider windows, credits, token cost — on the Home Screen,
Lock Screen, and (optional, off by default) as a Live Activity.

Transport is serverless and user-managed: a LAN fast path (Bonjour +
Network.framework) plus a CloudKit private-database backbone that keeps widgets
and the Lock Screen fresh in the background. Newest generatedAt wins. No
credentials are stored on the phone.

macOS side (Sources/CodexBar/MobileSync) is opt-in and a no-op unless
`mobileSyncEnabled` is set, so existing users are unaffected. A wire-contract
test guards the JSON the phone decodes.

Closes steipete#1976. Relates to steipete#439, steipete#319.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed July 8, 2026, 3:00 AM ET / 07:00 UTC.

Summary
The branch adds a native iOS app, widgets, Live Activity support, shared iOS sync/model code, and an opt-in macOS MobileSync publisher over Bonjour LAN and private CloudKit.

Reproducibility: yes. for the review findings via source inspection: the Mac publisher sends frames to any ready connection, the iOS provider decoder maps unknown values to Codex, and the Mac CloudKit path checks only ubiquity identity before creating the container. I did not run builds or live provider checks because this is a read-only review.

Review metrics: 3 noteworthy metrics.

  • Diff size: 146 files, +4,999/-0. This is a new platform and sync subsystem, so maintainers need broad product, signing, privacy, and release review before merge.
  • Runtime surfaces added: 2 iOS targets plus 1 macOS publisher hook. The patch touches the phone app/widget runtime and the existing Mac snapshot persistence path.
  • Prior blockers rechecked: 3 still present. The latest commit did not change the files containing the previous P1 security, provider-parity, and entitlement findings.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #1976
Summary: This PR is the implementation candidate for the open native iOS companion proposal; older remote-access and iOS companion items are related history but do not supersede the current PR.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🦪 silver shellfish
Patch quality: 🧂 unranked krab
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Fix the Mac publisher so paired identity, hello nonce handling, HKDF/AES-GCM sealing, and rejection of unpaired clients are enforced on the Mac side.
  • [P1] Add ClawRouter or a non-mislabeling unknown-provider path to the iOS mirror, with a wire-contract test using current-main providers.
  • Attach redacted proof from a real signed or simulator setup showing Mac-to-iOS sync, widget refresh, and CloudKit/LAN behavior after the fixes.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR includes UI screenshots and test claims, but no screenshot, recording, terminal output, live logs, or linked artifact proving the signed Mac-to-iOS LAN/CloudKit path after the security-sensitive changes; add redacted proof and update the PR body for a fresh review.

Risk before merge

  • [P1] The Mac publisher still exposes usage snapshots to any local TCP client once mobile sync is enabled; iOS-side pairing does not protect the Mac export surface.
  • [P1] The iOS provider mirror already drifts from current main and can display a ClawRouter snapshot as Codex, mixing provider data in a user-visible surface.
  • [P1] CloudKit, App Group, LAN server entitlements, signing, and release packaging are not fully wired for the macOS app, so enabling sync can crash, fail closed, or ship an unsupported path.
  • [P1] This PR turns CodexBar into a second-platform iOS and CloudKit product surface, which VISION.md and prior iOS discussion both put behind explicit product, privacy, and release sign-off.
  • [P1] The screenshots show UI surfaces, but they do not prove the signed Mac-to-iOS LAN, pairing, widget refresh, or CloudKit path after the security-sensitive changes.

Maintainer options:

  1. Pause for scope and security sign-off (recommended)
    Do not merge until maintainers approve the iOS product direction and the contributor fixes the LAN pairing, provider parity, CloudKit entitlement, and proof gaps.
  2. Repair the sponsored beta path
    If maintainers sponsor the feature, require a paired encrypted Mac publisher, explicit SettingsStore and entitlement wiring, provider mirror coverage, and signed end-to-end proof.
  3. Close as out of scope
    If maintainers do not want to own iOS release and CloudKit support in this repository, close this PR and preserve the discussion through the linked proposal issue.

Next step before merge

  • [P1] Manual review is needed because this draft adds a new iOS/CloudKit/LAN product surface with security and availability blockers plus insufficient proof; automation should not choose the product direction.

Maintainer decision needed

  • Question: Should this repository accept and release a native iOS companion with Bonjour LAN plus private CloudKit sync, or should that product surface stay outside CodexBar core?
  • Rationale: This PR adds a new platform, storage and network privacy boundary, signing and entitlement requirements, and release support burden, so code review cannot decide the product direction alone.
  • Likely owner: steipete — This decision spans product scope, signing/release support, provider privacy, and current widget/provider architecture.
  • Options:
    • Pause for sponsored iOS scope (recommended): Keep the draft open as a proposal until a maintainer approves the iOS product, privacy, signing, and release plan, then require the blocking fixes and proof before merge.
    • Approve a narrow beta path: Sponsor the direction but require paired encrypted LAN, entitlement-gated CloudKit, provider parity, SettingsStore wiring, and signed proof before any release path.
    • Decline in-repo companion: Close this PR and direct native iOS companion work to a separate project, consistent with the earlier scope decision.

Security
Needs attention: The diff introduces a concrete security-boundary issue because the macOS LAN publisher still serves usage snapshots before pairing or encryption is enforced.

Review findings

  • [P1] Enforce pairing before sending LAN snapshots — Sources/CodexBar/MobileSync/MobileSyncPublisher.swift:99
  • [P1] Preserve unknown providers instead of showing Codex — ios/Shared/Model/UsageProvider.swift:66
  • [P1] Gate the Mac CloudKit publisher on entitlements — Sources/CodexBar/MobileSync/MobileSyncPublisher.swift:132
Review details

Best possible solution:

Keep this draft paused until a maintainer sponsors the iOS scope; then land a narrower implementation with paired encrypted Mac publishing, SettingsStore-backed toggles and entitlements, provider parity tests, and redacted signed end-to-end proof.

Do we have a high-confidence way to reproduce the issue?

Yes for the review findings via source inspection: the Mac publisher sends frames to any ready connection, the iOS provider decoder maps unknown values to Codex, and the Mac CloudKit path checks only ubiquity identity before creating the container. I did not run builds or live provider checks because this is a read-only review.

Is this the best way to solve the issue?

No; the read-only mirror direction may be safer than phone-side provider credentials, but this implementation is not the best merge path until maintainer sponsorship, paired Mac publishing, provider parity, entitlement gating, and real behavior proof are in place.

Full review comments:

  • [P1] Enforce pairing before sending LAN snapshots — Sources/CodexBar/MobileSync/MobileSyncPublisher.swift:99
    This remains unfixed from the prior review. The Mac side still accepts every NWConnection and sends latestFramed as soon as it becomes ready, so iOS-side pairing only protects the official app; any LAN client can connect to the advertised service and read the snapshot. Make the Mac advertise a paired identity, consume the hello nonce, derive the session key, and send only AES-GCM sealed frames.
    Confidence: 0.95
  • [P1] Preserve unknown providers instead of showing Codex — ios/Shared/Model/UsageProvider.swift:66
    This remains unfixed from the prior review. Current main already has .clawrouter, but the iOS mirror omits it and then decodes any unknown raw value as .codex, so a ClawRouter snapshot will be displayed as Codex. Add the missing provider or introduce an explicit unknown/skip path instead of reusing Codex.
    Confidence: 0.93
  • [P1] Gate the Mac CloudKit publisher on entitlements — Sources/CodexBar/MobileSync/MobileSyncPublisher.swift:132
    This remains unfixed from the prior review for the Mac publisher. The code checks only ubiquityIdentityToken before constructing CKContainer(identifier:), while the package entitlements currently generated for the Mac app do not include CloudKit; enabling sync on a non-entitled build can crash instead of falling back to LAN. Gate on actual entitlements or keep CloudKit disabled until signed support is wired.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.89

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against aa401f1d8b74.

Label changes

Label justifications:

  • P2: This is a normal-priority feature PR with serious pre-merge blockers, but it is unmerged, draft, and default-off rather than a current-main regression.
  • merge-risk: 🚨 compatibility: The PR adds a parallel iOS provider model that already omits a current-main provider and changes the release/signing surface.
  • merge-risk: 🚨 security-boundary: The macOS LAN publisher can expose usage snapshots to any local TCP client before pairing or encryption is enforced.
  • merge-risk: 🚨 availability: The macOS CloudKit path constructs CKContainer without checking actual entitlements, creating a plausible crash or fail-closed runtime path when sync is enabled.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦪 silver shellfish and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR includes UI screenshots and test claims, but no screenshot, recording, terminal output, live logs, or linked artifact proving the signed Mac-to-iOS LAN/CloudKit path after the security-sensitive changes; add redacted proof and update the PR body for a fresh review.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The PR includes UI screenshots and test claims, but no screenshot, recording, terminal output, live logs, or linked artifact proving the signed Mac-to-iOS LAN/CloudKit path after the security-sensitive changes; add redacted proof and update the PR body for a fresh review.
Evidence reviewed

Security concerns:

  • [high] LAN snapshots are sent before authentication — Sources/CodexBar/MobileSync/MobileSyncPublisher.swift:99
    The Mac publisher sends the latest framed snapshot to any ready TCP connection on the advertised Bonjour service, so a local-network client can read usage data without the new pairing secret or AES-GCM handshake.
    Confidence: 0.95

What I checked:

  • Repository policy read: AGENTS.md was read fully; its guidance on scoped SwiftPM changes, provider-data separation, focused validation, and release/signing paths affected this review. (AGENTS.md:1, aa401f1d8b74)
  • Vision requires sign-off: VISION.md says new features and behavior affecting data storage, releases, or user privacy need sign-off, which applies to an iOS, LAN, and CloudKit product surface. (VISION.md:13, aa401f1d8b74)
  • Live PR metadata: The live PR is a draft with 146 changed files and +4,999/-0 lines, with screenshots attached but no inspectable runtime proof for the signed LAN or CloudKit path. (fc3c82e5c821)
  • Prior blockers still apply: The previous review raised three P1 findings; comparing the previous reviewed SHA to the latest head shows the new commit only touched widget/project files and did not repair the macOS publisher, provider mirror, or Mac CloudKit path. (fc3c82e5c821)
  • LAN publisher sends unauthenticated frames: The macOS publisher accepts any ready NWConnection and immediately sends the latest framed snapshot without checking a paired device ID, consuming a hello nonce, or sealing the payload. (Sources/CodexBar/MobileSync/MobileSyncPublisher.swift:99, fc3c82e5c821)
  • iOS subscriber expects paired encrypted LAN: The iOS subscriber only connects to paired Macs identified through Bonjour and expects AES-GCM sealed frames after a hello nonce, but the Mac publisher does not implement the matching protocol. (ios/Shared/Transport/LANSubscriber.swift:118, fc3c82e5c821)

Likely related people:

  • steipete: Recent current-main history owns release packaging/signing and provider/widget surfaces, and this PR changes product scope, privacy boundaries, and release support. (role: product and release-signing decision owner; confidence: high; commits: a83a83fa4131, c923e3e9fd8a; files: Package.swift, Scripts/package_app.sh, Sources/CodexBarCore/Providers/Providers.swift)
  • ngutman: Closed the earlier native iOS companion proposal as out of scope for the macOS menu-bar tracker unless pursued as its own product direction. (role: prior product-scope reviewer; confidence: medium)
  • ThiagoCAltoe: Introduced the existing localhost codexbar serve surface that resolved the older remote-access issue referenced by this PR. (role: adjacent remote-access contributor; confidence: medium; commits: 74a019c4aa65; files: Sources/CodexBarCLI/CLIServeCommand.swift, Sources/CodexBarCLI/CLILocalHTTPServer.swift, Tests/CodexBarTests/CLIServeRouterTests.swift)
  • enieuwy: Has recent current-main work maintaining and hardening the CLI serve/export surface related to remote usage access. (role: recent adjacent serve maintainer; confidence: medium; commits: 240f4293f637, 8c83f054ffbf, 894bbcb8c20b; files: Sources/CodexBarCLI/CLIServeCommand.swift, Sources/CodexBarCLI/CLILocalHTTPServer.swift, Tests/CodexBarTests/CLIServeRouterTests.swift)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (3 earlier review cycles)
  • reviewed 2026-07-08T02:15:49.661Z sha 9b2bc81 :: needs real behavior proof before merge. :: [P1] Require pairing before sending LAN snapshots | [P1] Do not decode unknown providers as Codex | [P1] Check CloudKit entitlement before creating the container
  • reviewed 2026-07-08T05:49:42.228Z sha e0c36df :: needs real behavior proof before merge. :: [P1] Require the Mac publisher to enforce pairing | [P1] Do not map unknown providers to Codex | [P1] Gate the Mac CloudKit container on entitlements
  • reviewed 2026-07-08T06:42:08.616Z sha e0c36df :: needs real behavior proof before merge. :: [P1] Require the Mac publisher to enforce pairing | [P1] Do not map unknown providers to Codex | [P1] Gate the Mac CloudKit container on entitlements

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. labels Jul 8, 2026
… sample data

- Refresh control next to Settings triggers a manual CloudKit/LAN pull with a
  rotating symbol while in flight.
- Gate the DEBUG sample seed behind the `-seed` launch arg (screenshots only), so
  the shipped app shows the honest "Waiting for CodexBar" state until a live
  snapshot arrives — never fabricated numbers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@clawsweeper clawsweeper Bot removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 8, 2026
…ed LAN

Adds a real pairing model so the phone only syncs with *your* Mac and the data is
private on shared networks:

- Each Mac has a device identity + 256-bit key; the phone enrolls via a QR code
  (`cbp1.` payload, pattern borrowed from agent-activity) or manual code entry.
- Discovery is filtered to paired Macs (device ID advertised in the Bonjour service
  name), so a stranger's Mac is ignored.
- The channel is authenticated + encrypted: the phone sends a nonce, both sides
  derive an HKDF session key from the shared key, and each snapshot frame is
  AES-GCM sealed — only the paired Mac can produce readable frames.
- Pairing UI (QR scanner + manual entry), Keychain-backed store with an App Group
  fallback for unsigned builds, and paired-Mac management in Settings.

Verified end-to-end: pairing code → filtered discovery → encrypted handshake →
decrypt → live usage on device.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. labels Jul 8, 2026
…Combined, Switcher)

Brings the macOS CodexBar home-screen widgets to iOS so the phone has the same
styles. Adds Usage History (Swift Charts), a compact single-metric widget with a
metric picker, a Burn Down widget (remaining budget vs ideal steady-burn pace with
a Canvas chart and run-out projection), a Combined session+weekly burn tile, and a
Switcher showing the most-constrained provider. Home Usage now also supports
systemLarge with credits + token costs. All reuse the shared iOS design system and
read the App Group snapshot.

Also stop tracking the generated ios/CodexBarMobile.xcodeproj (regenerate with
`xcodegen generate`) so per-developer signing/bundle-id/App-Group overrides don't
land in the repo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Native iOS companion app (Liquid Glass) — read-only usage mirror over LAN + iCloud

1 participant