Build the template engine — board-as-template instantiation

A template is a board folder the ordinary loader reads — no second
schema, no Swift catalog. BoardTemplate became exactly that: a loaded
BoardModel with chooser-facing derivations, the lane-title stub gone.
TemplateEngine instantiates by the copy-remint-restamp walk: .git and
.trash excluded at top level only — both names mean something at a
board root and nowhere else, and .gitignore must survive — every
materialized folder reminted, created/modified stamped fresh (born
today, not forked), modified-by cleared, the template: key carried
inert, the blurb and style inherited, and loose card files normalized
at this import boundary per the paste precedent so a new board never
opens with a notice about a mess its own birth made. Legacy deleted:
keys copy through verbatim to the one migrator — stripping would
resurrect, skipping would destroy. Atomicity is construct-then-clean:
a sibling temp can be sandbox-refused and a cross-volume rename is
just a second copy, so the call removes what it created on every
non-board exit and never touches an occupied destination. The
cancellable per-item walk extracted into BoardTreeCopy serves
Duplicate and instantiation with two parameters — top-level exclusions
and folder-attribute carriage, the only axes they differ on.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-28 18:46:23 -04:00
parent 797d020d01
commit b6f559375b
13 changed files with 1446 additions and 316 deletions
+11
View File
@@ -43,6 +43,13 @@ targets:
platform: macOS
sources:
- Kanban
# The bundled template store (09-templates.md ▸ Definition format): real board folders,
# copied into `Contents/Resources/Templates/` verbatim as a folder reference — the same
# arrangement `Fixtures/` uses below, and for the same reason. A template is a board, so it
# must reach the bundle as directories on disk, not as flattened resource files.
- path: Templates
type: folder
buildPhase: resources
dependencies: &appDependencies
- package: Yams
- package: swift-markdown
@@ -88,6 +95,10 @@ targets:
excludes:
- Info.plist
- KanbanPro.entitlements
# The same bundled template store — the inventory is the app's, not an edition's.
- path: Templates
type: folder
buildPhase: resources
dependencies: *appDependencies
postBuildScripts: *updateBuildInfo
settings: