Files
Screens/docs/HANDOFF.md
Claude 99a9a7ae55 Export plan + handoff into repo
- docs/PLAN.md: full implementation plan (copied from ~/.claude/plans/)
- docs/HANDOFF.md: machine-portable status, resume steps, architectural
  notes, phase status, open decisions

Lets the repo stand alone for a fresh checkout on another computer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:36:00 -05:00

4.4 KiB

Handoff — Screens VNC app

A snapshot of project state so another machine (or another Claude Code session) can pick up without any out-of-band context.

Resume on a new machine

# 1. Clone
git clone git@gitea.treytartt.com:admin/Screens.git
cd Screens

# 2. Prerequisites (macOS host)
brew install xcodegen            # reproducible .xcodeproj generation
# Xcode 16+ required (Xcode 26 tested)

# 3. Generate the Xcode project (not committed)
xcodegen generate

# 4. Open in Xcode (or build from CLI)
open Screens.xcodeproj
# - or -
xcodebuild -scheme Screens -destination 'platform=iOS Simulator,name=iPhone 17' build

# 5. Fast unit tests (no simulator)
cd Packages/VNCCore && swift test    # ~0.4s, 3 tests
cd ../VNCUI && swift test            # ~3s, 1 test

Git layout

  • main — cumulative integrated history. Default branch.
  • phase-N-<topic> — per-phase branches; open a PR into main and merge.
  • Current branch in progress: phase-1-vnc-wiring (branched from main @ Phase 0 scaffold).

Phase status

Phase Scope Status
0 — Scaffold Packages, app target, xcodegen, RoyalVNCKit dep, CI-compilable merged to main (commit 2cff17f)
1 — MVP connect/view/tap Wire VNCConnectionDelegate, render framebuffer, touch input, Keychain auth 🔄 in progress on phase-1-vnc-wiring
2 — Input parity Trackpad mode, hardware keyboard, pointer, adaptive quality, reconnect not started
3 — Productivity Clipboard sync, multi-monitor, Apple Pencil, screenshots, view-only, curtain mode not started
4 — Polish & ship iPad multi-window, CloudKit sync, a11y, privacy manifest, TestFlight prep not started

Full plan: docs/PLAN.md.

Critical architectural notes

  1. RoyalVNCKit owns its own networking. It constructs its own NWConnection internally from VNCConnection.Settings. Our Transport protocol in VNCCore is not on the RFB path — it's kept as the extension point for future SSH tunneling. Don't try to pipe bytes from DirectTransport into VNCConnection.

  2. Delegate model. SessionController should conform to VNCConnectionDelegate and bridge delegate callbacks (which arrive on internal RoyalVNCKit queues) to @MainActor state. Password supplied via credentialFor:completion: callback.

  3. iOS framebuffer rendering is on us. RoyalVNCKit ships macOS-only VNCFramebufferView (NSView). We render by grabbing framebuffer.cgImage and setting FramebufferUIView.contentLayer.contents on each didUpdateFramebuffer callback. IOSurface-backed path available for zero-copy later.

  4. Swift 6 strict concurrency is on. Cross-actor hops need care. Use @MainActor on everything UI-adjacent; mark Transport-style types as actors.

  5. Name "Screens" is owned by Edovia. Pick a different App Store title before any public artifact.

Dependencies

Package Purpose Version License
royalvnc RFB protocol, encodings, auth branch: main (tagged releases blocked by transitive CryptoSwift unstable-version constraint) MIT
Apple first-party Network, SwiftData, Security, UIKit, SwiftUI, Observation iOS 18 SDK

Build artifacts

  • Screens.xcodeproj/git-ignored. Regenerate with xcodegen generate.
  • Packages/*/.build/ — git-ignored. swift build or Xcode resolves.
  • Packages/*/Package.resolved — git-ignored; change if you want reproducible dep versions across machines (recommended for an app target — consider flipping later).

Files to look at first

  • docs/PLAN.md — full plan
  • Project.yml — xcodegen project definition
  • Screens/App/AppStateController.swift — app-level state machine
  • Packages/VNCCore/Sources/VNCCore/Session/SessionController.swift — the stub that Phase 1 will replace with a real VNCConnectionDelegate integration
  • Packages/VNCUI/Sources/VNCUI/Session/FramebufferUIView.swift — where incoming framebuffer CGImages land

Open decisions

  • App Store name — not "Screens" (trademarked).
  • Bundle identifier — currently com.example.screens placeholder; set to your real prefix.
  • Team ID / signing — currently CODE_SIGN_STYLE: Automatic; point at your team for device builds.
  • Privacy manifest — scheduled for Phase 4; will enumerate UIPasteboard, UserDefaults, NSPrivacyAccessedAPICategoryFileTimestamp reasons.