Files
lanework/WISHLIST.md
T
rzen c87616f3fb Comments join attachments on the card face — a quiet bubble-and-count chip, present-only
A card whose thread holds one comment or more now draws a second trailing chip beside the
paperclip: a secondary-tinted bubble glyph plus its count, shown only when the count is above
zero (design ruling 2026-08-09, card e729e30a). Same styling family as the attachments chip —
caption size, secondary tint, decorative and hidden outright from the accessibility tree — but
this one carries a visible count rather than staying icon-only, per the ruling's own "bubble-style
SF Symbol + count." It sits after the attachments chip at the row's trailing edge, in both the
live title row and the drag replica.

The count is a new `Card.commentCount` field the loader fills with a readdir over `comments/`'s
identity-shaped children that carry their own `index.md` — `BoardLoader.commentCount(in:)`, built
on the same `identityShapedChildren` predicate a trash entry's held-card count already uses. Never
a parse: `.draft` and `.trash/` are excluded for free, the same dot-prefixed hidden-entry skip
`CommentThread.load` documents for both, so the walk stays exactly the O(cards) shape
01-storage-format.md § Enhanced schema already commits to. Because the count rides inside the
`card: Card` parameter `CardFaceView` already takes — not a new parameter of its own — drawing the
chip costs nothing beyond a field read on an already-compared value: no new Observable read joins
the body, and the equatable gate already covers it via `Card`'s synthesized `Equatable`.

The one divergence from the comments pane's parsed count is documented rather than hidden: a
comment folder whose `index.md` exists but fails to parse is a `Stray` the thread read excludes by
opening and rejecting it, a cost this readdir does not pay. The face may then read one comment
high until that folder is fixed or removed — the trade the ruling's "cheap directory-entry count…
not a parse" asks for, over paying full parse cost on every card of every load. Every well-formed
comment, and every card with no malformed one, agrees with the pane exactly.

VoiceOver: `AccessibilityPhrases.cardValue` gains a `comments: Int` parameter, appended after
attachments and before the cut-pending phrase — the same left-to-right order the two chips draw
in, so a sighted read and a VoiceOver read never disagree about which comes first. The trashed
lane row's own call site (an opaque unit with no comments to speak of) passes `comments: 0`.

Docs: DESIGN/03-board-ui.md's card-face section describes both chips and retires the stale "closed
with no growth" sentence, honestly recording the 2026-08-09 growth (the hero banner landed hours
earlier, this chip after it) as exposure of facts the card already carries rather than a body
excerpt. DESIGN/10-accessibility.md's flattened-element sentence gains the comment count.
DESIGN/01-storage-format.md's Enhanced schema paragraph records the chip as shipped. WISHLIST #9
is marked shipped in place — not renumbered, since #10 and #11 are cross-referenced elsewhere.

Tests: CardCommentCountListingTests (BoardLoaderTests.swift) pins the readdir against a synthetic
tree — no comments/ folder, an empty one, non-identity-shaped and index-less strays excluded,
.draft/.trash/ excluded for free, agreement with CommentThread.load's parsed count in the
well-formed case, and the one documented divergence on a malformed index.md.
AccessibilityPhrasesTests covers cardValue's new parameter alone, alongside attachments, and
all three fragments together. ViewEquatableTests pins that a comment landing on a card is a gate
difference. BoardRenderPerformanceTests adds a render-cost guard: one comment added to one card
on a hosted 180-card board re-renders a handful of bodies, not the board.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-09 01:21:33 -04:00

9.7 KiB

Lanework — Feature Wishlist

Ideas worth developing further, deliberately outside the current design scope. Items get recorded as they come; grooming happens later. The DESIGN/ documents hold the committed design — nothing here is committed.

Items

1. "While you were away" digest

A human-facing digest of what changed on a board since the user last looked, derived from the git trail (commit messages already describe every settled change, agent and human alike). The read-ritual half of the masterplan pattern (DESIGN/08-agent-integration.md): agents file cards at near-zero friction all week; the digest is how the human catches up and stays honest about the plan. Sketch: on opening a board (or in the board popover), "since you last opened: 4 cards added by claude-code, 2 moved to Done" — clicking through highlights the affected cards. Requires git-enabled boards; another reason the git trail is the substrate of record.

2. In-app shortcut recorder pane

A Settings ▸ Shortcuts pane with a per-command recorder, writing the same NSUserKeyEquivalents mechanism the committed system-native remapping uses (DESIGN/04-interactions.md ▸ Configurable bindings) — so menus would keep showing effective bindings either way. Set aside as ceremony: System Settings ▸ App Shortcuts already covers remapping completely because every command is a menu item. Revisit only if users demonstrably don't find the system path.

3. Move cards to another lane before deleting a lane

An explicit "Move cards to…" action (context menu on a lane) that relocates a lane's cards to a chosen lane in one gesture. The old lane-delete confirmation dialog offered this as a delete intercept; the trash design replaced the dialog with a recoverable move into .trash/ (DESIGN/04-interactions.md — lanes joined the materialized trash 2026-07-29), so the relocation convenience — if ever wanted — should return as a deliberate standalone action, not a prompt.

4. Restore a card version from its History section

The card window's History section (DESIGN/05-card-window.md) is read-only in v1. A per-row "Restore this version" would forward-restore the card folder at that commit (a new commit — "Restore card 'X'" — never a rewrite, per DESIGN/06-history-undo.md). Needs design: attachments at the old version, versions that lived in another lane, interaction with the trash and the undo stack.

5. Lane history

Per-lane commit trail, the lane sibling of the card History section. Undecided whether it's wanted at all (a lane's own commits — rename, restyle, resize, reorder — are sparse; most of what changes "in" a lane belongs to its cards) and where it would surface, since lanes have no window.

6. EchoLedger-synthesized foreign undo (free tier)

Narrow base Lanework's honest gap vs Pro — foreign/agent edits aren't ⌘Z-able without git (DESIGN/13-native-undo.md ▸ Out of scope). The EchoLedger already classifies every foreign diff for announcements; it could synthesize inverse operations and push foreign steps onto the native stack, making an agent's edit undoable in base too. Real design needed: ordering against app steps, attribution in menu titles, user expectations when undoing work they didn't do, interaction with the staleness rules.

7. Custom fly-to-slot drop animation

Drags run as system NSItemProvider sessions (cross-board transfer, the copy badge), so a successful drop's replica gets AppKit's brief fade — not the fly-to-slot settle DESIGN/03 originally imagined; 03 resettled the drop as the board's (the held overlay renders the arrangement instantly at release). Reclaiming the literal fly-to-slot needs an NSDraggingSession bridge: mask the system fade, fly a shadow-window replica to the slot frame, hide the landed item during flight — a compositing dance that must stay correct across masonry reflows and multi-item drags. Fund only if the system fade ever reads as cheap in practice.

8. Archive lane (.archive — the second materialized reserved lane)

The materialized .trash/ (DESIGN/03 ▸ Trash, the 2026-07-28 pivot) establishes the pattern: a reserved dot-named container at board root holding ordinary card folders, special only in how cards enter it. An archive lane — <root>/.archive, receiving cards that meet a criterion to be designed (age? a Done-lane dwell time? an explicit Archive command?) — is the anticipated second instance. Design open: intake criteria, visibility (a Show Archive toggle like the trash's?), search participation, whether archived cards count anywhere. Nothing committed; the trash proves the mechanism first.

9. Comment-count chip on card faces — shipped 2026-08-09

Comments are window-scoped by design (DESIGN/01 ▸ Enhanced schema — the board snapshot never loads comment content, keeping the walk O(cards)), so card faces couldn't show a live count. The shipped chip took this item's own anticipated shape — a cheap directory-entry count folded into the loader's card walk, a readdir rather than a parse — over the cached/stale-tolerant alternative. See DESIGN/03-board-ui.md § Card face and DESIGN/01 ▸ Enhanced schema for the design as built; number kept in place so #10 and #11 below stay addressable.

10. Search scope options

Board search covers all meaningful card content (DESIGN/04 ▸ Search, re-ruled 2026-07-29 — title + body, comment bodies when comments ship, attributes as they activate). An either/or scope control — content vs attributes, or per-field filters — was anticipated in the same ruling but not designed. Decide when a real query pattern demands narrowing; the transient search index is the natural host for field-aware matching.

11. Board diagnostics surface (coerce/tolerate report)

The loader's Defect stream carries coerce-tier fallbacks (field, path, raw text) and tolerate-tier warnings, consumed this version by the unified log alone (DESIGN/01 ▸ coercion, ruled 2026-07-30 — promotion to heuristics is manual, investigation-driven). An in-app surface — a popover line or a per-board report window listing what the last load coerced, tolerated, and healed — would serve the agents-edit-boards workflow without Console.app. The typed stream is already the right plumbing; design open: where it lives, when it refreshes, and how it words defect classes without inventing a second banner vocabulary.

12. AI-aided software design template set

The Lanework build itself ran on three board archetypes — design corpus (topic lanes, atomic decision cards, open/parked/deferred/tbd labels), findings tracker (Contradictions/Gaps/Minor/Issues to Resolve/Resolved/Mooted, one card per finding, Resolved as living precedent), implementation masterplan (Backlog/Active/Done, Design constraints / Depends on / Done when bodies, one commit per card). Distilling them into bundled templates — including a seeded CLAUDE.user.md teaching agents the workflow (DESIGN/09's stray-copy rule already carries it through instantiation) — was considered 2026-07-31 and set aside: these are working artifacts, not release content yet. Designing a reusable template set becomes its own project in due time; the raw conventions live in the retired Redesign-board card (951ed5f1) and the boards themselves.

13. Board/lane/card "nature" — schema plus presentation

A nature is a combination of an object's schema and its presentation, configurable at board/lane/card level: a storyboard board (sketches per card, image-forward faces) and an agile ticket board (story/task types, status attributes rendered on faces) bracket the range. Deliberately not MVP (user-filed 2026-07-29, wishlisted 2026-07-31); a future design session starts from the corpus hooks: kind is kin but orthogonal (structural role vs domain flavor); the agile example lands on the reserved enhanced-schema keys (labels, assignees, due, remote/remote-state) and the Teams tracker story probably wants to be a nature rather than a mode; image-forward faces would be a nature-scoped, per-board reopening of the one-presentation rule (composing, not conflicting — the carousel stays dead); templates are the delivery vehicle (a nature may be what a template declares — pairs with #12); nature must live in frontmatter (files-first, no sidecars), inert-but-preserved in apps that don't know it, no edition-specific keys; the agent guide / seeded CLAUDE.user.md would teach per-nature conventions.

14. Export and reporting — the board as a PDF-book or report

A board output as a PDF book or a report (user-filed 2026-07-29, wishlisted 2026-07-31; not MVP). Dovetails with #13: a nature plausibly implies its export shape — a storyboard board exports as a PDF book of sketches with captions, an agile-ticket board as a status report grouped by type/status; nature = how the board lives, export = how it leaves. Session orientation notes: scope (whole board / lane / selection / search subset; trash never exports; ranks vs nature-informed groupings); formats (PDF named; Markdown/HTML compilations near-free since bodies are Markdown and swift-markdown is in the tree; ⌘P → PDF as cheapest first door or red herring); export is a read (works under every read-only lock per the Save-as-Template precedent, never mutates, save-panel output outside the package — files-first stays absolute); attachments embedded vs referenced vs appendix (body-embedded relative image paths already resolve in Preview); long-running + cancellable copy-shaped work (in-progress row, Cancel, partial-output cleanup per the Duplicate precedent); on-screen styling vs print-first design language (the book case suggests print-first; nature parameterizes); edition placement undecided (a read feels base-worthy, report natures may tier); agents need no export but an agent-triggerable one may be worth a thought (pairs with #12).