Skip to content

Swift Package Plan - #11

Merged
leogdion merged 6 commits into
v0.1.xfrom
feature/swift-package
Jul 29, 2026
Merged

Swift Package Plan#11
leogdion merged 6 commits into
v0.1.xfrom
feature/swift-package

Conversation

@leogdion

Copy link
Copy Markdown
Member

No description provided.

leogdion and others added 2 commits July 28, 2026 16:39
Sketch how the v0.1.x prototype research becomes a shippable Swift
package. The prototype answered the format questions (transitions,
builds, magic-id, the two document invariants); this plans the port.

Goal: a self-contained Swift package that authors .key files — no
Python, keynote-parser, mise, or AppleScript at runtime. Native
Swift IWA/protobuf backend.

PLAN.md lays out 7 steps, each ending in a runnable gate, plus a
decision log recording why each choice was made.

Two risks are called out explicitly:

- The IWA container (Step 2). Apple frames .iwa in a NON-STANDARD
  Snappy stream — no sNaPpY identifier, custom chunk headers, no
  CRC-32C — so stock Snappy libraries reject it outright. The Python
  path got this free from keynote-parser; we reimplement it.

- Slide/text-item supply (Step 4b). The bundled template has a fixed
  slide count but users author arbitrarily many, so the writer must
  duplicate slides and mint ids — maintaining objectUuidMapEntries
  and lastObjectIdentifier by hand. That is the same class of
  invariant behind the SIGTRAP crash, on a path the Python backend
  never exercised (it only mutated decks whose slides existed).

Scope decisions recorded in .claude/agent-notes.md:

- Swift 6.4 (dev)+ only; build via Xcode-beta DEVELOPER_DIR or a
  swiftly 6.4.x snapshot, never the default 6.3.2.
- The goal is authoring; reading is NOT a v0.1.0 feature (#6).
- Surgery on a bundled template, not synthesis from nothing (#2).
  "Self-contained" = no runtime Python/mise/AppleScript, not zero
  dependencies.
- ScriptingBridge is a developer escape hatch (#10), never a backend.
- Gates are structural, not byte-identical: Keynote requires the file
  be accepted, not byte-equal.

Follow-ups filed as #2-#10.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Nothing about the Swift package's direction lived where a fresh
session would find it: CLAUDE.md/AGENTS.md described only the
research lab, HANDOFF.md ended at the Python backend, and the
Swift 6.4 toolchain memory existed only in global ~/.claude.

- AGENTS.md (CLAUDE.md symlinks to it) now opens with what the
  project is and a reading order: PLAN.md, then agent-notes, then
  the scope memory.
- HANDOFF.md gets a banner marking the research phase complete and
  pointing at PLAN.md. Its content stays accurate as the format
  spec and Python reference.
- New memory keynotekit-v010-scope.md records the decisions a fresh
  session is most likely to get wrong by inference: that reading a
  .key is in scope (it is not — #6), that "from scratch" means no
  template (it does not — #2), that "self-contained" means zero
  dependencies (it does not — swift-protobuf plus a bundled
  template), and that gates are byte-identical (they are
  structural).
- Mirror keynotekit-swift-64-only.md into the repo per the repo's
  own memories-live-in-repo convention.

Also corrects pack-option-a-viable.md, which warned that the hybrid
parser depended on ephemeral scratchpad artifacts. That was resolved
when the schema was vendored: verified this session from a clean
worktree with no scratchpad present — prepare-keynote-parser rebuilt
it (631 registry entries, 0 missing) and verify-pack passed on
build_in_B / build_action_B / direction_B. The fresh-worktree setup
steps are recorded there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ad7c9b7-76f8-4502-92b0-5bae51315317

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/swift-package

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

leogdion and others added 4 commits July 28, 2026 21:18
Record SlideContent/product splits in PLAN, add twelve scratch tickets plus a worktree lane guide so substrate work can fan out after scaffolding.

Co-authored-by: Cursor <cursoragent@cursor.com>
Tickets now live under map #12 (#13#24); keep parallel-worktree guidance in
.claude and point PLAN/HANDOFF at the GitHub tracker.

Co-authored-by: Cursor <cursoragent@cursor.com>
Rewrite the README for KeynoteKit, remap worktree lanes to #13#24, and drop stale research-lab paths from agent and handoff notes.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the v0.1.0 plan with the other agent guidance and update repo, handoff, and map #12 pointers.

Co-authored-by: Cursor <cursoragent@cursor.com>
@leogdion
leogdion marked this pull request as ready for review July 29, 2026 14:46
@leogdion
leogdion merged commit 62a68f3 into v0.1.x Jul 29, 2026
1 check passed
@leogdion
leogdion deleted the feature/swift-package branch July 29, 2026 14:46
@leogdion
leogdion restored the feature/swift-package branch July 29, 2026 15:13
@leogdion
leogdion deleted the feature/swift-package branch July 29, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant