Space in Finder opens the board — a Quick Look preview extension that outlines a .kanban package
A board is a folder, and a folder previews as a folder. `KanbanQuickLook.appex` gives it a document's preview instead: the board's name, its tint and its symbol, then its lanes in display order with each one's card count and its first few card titles. The reading is `BoardOutline` (Kanban/Storage), deliberately not `BoardLoader.load`. The loader throws on a half-broken board — right for opening one, wrong for pressing Space, where the honest answer is the part that reads; it visits every card and lists `attachments/` and counts `comments/` inside each; and it carries trash, tombstone migration and the defect stream, none of which renders. This walk never throws and is capped at every level (`BoardOutlineLimits`): 12 lanes shown of at most 100 considered, 6 card titles per lane of at most 200 parsed, counts by readdir-plus-stat up to 2000 per lane and never a parse. It re-derives nothing that decides *what* the answer is — `FrontmatterDocument` parses, `IntegrityRules.isIdentityShaped` says what a lane or a card is, `BoardLoader.directoryCandidates` supplies the stray tolerance, `Ranks` supplies display order, `Palette` resolves colours — only *how far to look*. The reply is HTML, the one data-based reply that reflows: a Quick Look panel is resized by the user and a board outline is a wrapping row of columns, so a drawing block baked at a fixed `contentSize` would be the wrong size a moment later. It gets vector text, its own scrolling and light/dark for free. The board tint is a wash under the title and a lane's edge accent — never under text, because a preview has none of `ContrastMath`'s ink-picking machinery and should not grow one. The extension compiles `Kanban/Storage` whole, the `KanbanMobile` arrangement — the directory is one unit in practice, so a narrower list is not on offer. `STORAGE_ONLY` is new: EchoLedger's consumer sections speak the live store's vocabulary, and the phone's `#if os(macOS)` cannot exclude them from a target that *is* macOS. Platform, and layer. Nothing else defines it. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
+66
@@ -73,6 +73,10 @@ targets:
|
||||
- package: swift-markdown
|
||||
product: Markdown
|
||||
- package: IndieAbout
|
||||
# The Quick Look preview extension, embedded into `Contents/PlugIns/` — an appex is only ever
|
||||
# found through the app that carries it, so this line is what makes pressing Space on a
|
||||
# `.kanban` package in Finder reach `BoardPreviewProvider` at all.
|
||||
- target: KanbanQuickLook
|
||||
postBuildScripts:
|
||||
- script: '"${SRCROOT}/../indie-skills/skills/app-versioning/scripts/update_build_info.sh"'
|
||||
name: Update Build Info
|
||||
@@ -106,6 +110,68 @@ targets:
|
||||
SWIFT_STRICT_CONCURRENCY: complete
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
|
||||
|
||||
# MARK: - Quick Look preview extension
|
||||
#
|
||||
# **Space on a `.kanban` package in Finder** shows the board rather than a folder icon: its name,
|
||||
# its tint, its lanes in order with each one's card count and first few card titles. A classic
|
||||
# NSExtension appex (`com.apple.quicklook.preview`), embedded into the app above — the same
|
||||
# arrangement Xcode's own "Quick Look Preview Extension" template produces, since Quick Look's
|
||||
# preview point has no ExtensionKit spelling.
|
||||
#
|
||||
# **It compiles the shared storage engine verbatim, exactly as `KanbanMobile` does below** — the
|
||||
# same source paths, not a copy and not a package — and for the same reason: a preview that read
|
||||
# the format through its own parser would be a second reading of the storage contract, free to
|
||||
# drift. `Kanban/Storage` is one compilation unit in practice (`FrontmatterDocument` reaches
|
||||
# `IntegrityRules`, which reaches `BoardLoader` and `BoardWriter`), so it is listed whole; the
|
||||
# paired `LiveStore/EchoLedger.swift` is `BoardWriter`'s one upward dependency, riding along here
|
||||
# for the phone target's own stated reason. The write half is dead weight in a preview and stays
|
||||
# dead: the entitlements are read-only, so nothing in here *could* write even if something called
|
||||
# it.
|
||||
#
|
||||
# `STORAGE_ONLY` is what stops that one file dragging the whole live store in behind it. Its
|
||||
# consumer-side sections speak `BoardDiff`/`ItemPath`/`CommentPath`, which reach `BoardStore` and
|
||||
# everything under it; the phone excludes them with `#if os(macOS)` and cannot help here, because
|
||||
# this target *is* macOS. So EchoLedger.swift carries the same gate on a second axis — platform,
|
||||
# and layer — and this is the one target that sets it. See that file's "The reload's verdicts"
|
||||
# comment for the full statement.
|
||||
#
|
||||
# `Kanban/UI/Palette.swift` is the one UI file it takes: the twelve-and-twelve name→hex table, so a
|
||||
# board tinted `smokey-ocean` is the same colour in the preview as in the app. It is self-contained
|
||||
# — AppKit, SwiftUI and `FieldValue`, nothing else in `Kanban/UI` — which is what makes a single
|
||||
# file listable here at all. Nothing else from `Kanban/UI` compiles in: the preview is HTML, not a
|
||||
# view hierarchy, and every other file up there reaches the store.
|
||||
#
|
||||
# The walk itself is `Kanban/Storage/BoardOutline.swift` — capped at every level, read-only, and
|
||||
# unit-tested in `KanbanTests` where it can be, which is the whole reason it lives in the shared
|
||||
# directory rather than in `KanbanQuickLook/`.
|
||||
|
||||
KanbanQuickLook:
|
||||
type: app-extension
|
||||
platform: macOS
|
||||
sources:
|
||||
- KanbanQuickLook
|
||||
- path: Kanban/Storage
|
||||
- path: Kanban/LiveStore/EchoLedger.swift
|
||||
- path: Kanban/UI/Palette.swift
|
||||
dependencies:
|
||||
- package: Yams
|
||||
- package: swift-markdown
|
||||
product: Markdown
|
||||
settings:
|
||||
base:
|
||||
# Prefixed by the host app's identifier, as the sandbox requires of an embedded extension.
|
||||
PRODUCT_BUNDLE_IDENTIFIER: dev.rzen.indie.Kanban.QuickLook
|
||||
MARKETING_VERSION: "2.0"
|
||||
INFOPLIST_FILE: KanbanQuickLook/Info.plist
|
||||
CODE_SIGN_ENTITLEMENTS: KanbanQuickLook/KanbanQuickLook.entitlements
|
||||
GENERATE_INFOPLIST_FILE: false
|
||||
SWIFT_STRICT_CONCURRENCY: complete
|
||||
# The Info.plist's `NSExtensionPrincipalClass` is `$(PRODUCT_MODULE_NAME).BoardPreviewProvider`
|
||||
# — stated here so the two can never drift apart silently.
|
||||
PRODUCT_MODULE_NAME: KanbanQuickLook
|
||||
# `$(inherited)` keeps the configuration's own `DEBUG` — this only *adds* the layer gate.
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS: $(inherited) STORAGE_ONLY
|
||||
|
||||
# MARK: - Lanework for iPhone
|
||||
#
|
||||
# **The mobile app is a second product, not a second edition** (distinct bundle id, ruled
|
||||
|
||||
Reference in New Issue
Block a user