Skip to content

A2: board card markdown round-trip + directory sync#46

Merged
hartsock merged 1 commit into
mainfrom
feat/board-markdown-roundtrip
Jun 9, 2026
Merged

A2: board card markdown round-trip + directory sync#46
hartsock merged 1 commit into
mainfrom
feat/board-markdown-roundtrip

Conversation

@hartsock

@hartsock hartsock commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Summary

Supersedes #43 (auto-closed when its stacked base branch was deleted on #42's merge). Same content, now targeting main.

Adds the portable-export layer for board cards: SQLite ↔ markdown round-trip and directory sync.

  • board_md: card_to_markdown / card_from_markdown (tolerant of free-text status, trailing # comments, blocked_by alias, refs map). lane/context are directory facts.
  • Store::import_dir / export_dir: walk/emit <root>/[<context>/]<lane>/*.md; import dedups by card_id (source + symlink import once).
  • Config: BoardConfig gains sync_dir / default_lane / default_context.
  • New dep: serde_yaml_ng.

Fidelity boundary: card-content level (frontmatter + body); does not reconstruct numbered-symlink lane views.

Disclosure tier: internal capability + one dependency.

Test plan

just check green; board_md round-trip + dir_sync_round_trips tests.

🤖 Generated with Claude Code

WHAT: Add board_md (card_to_markdown / card_from_markdown) and the
Store::import_dir / export_dir directory sync, so the operational SQLite
cards round-trip to/from the portable markdown+frontmatter form.

- board_md.rs: emits the canonical frontmatter field order (id, project,
  created, updated, summary, size, status, recurs, expires, blocked_on,
  refs, author/source) + body; parses tolerantly (free-text status,
  trailing `# comments` on list items, a `blocked_by` alias for
  blocked_on, refs label:url map). lane/context are directory facts, left
  empty by the parser and filled by the walker.
- Store::import_dir walks <root>/[<context>/]<lane>/*.md (lanes
  p0|p1|p2|done|dropped), follows symlinks (the lane-view convention) but
  dedups by card_id so a source file and its lane symlink import once;
  returns {added, updated, skipped}.
- Store::export_dir writes flat <context>/<lane>/<card_id>.md real files
  (non-destructive; never deletes files it didn't write).
- BoardConfig gains sync_dir / default_lane / default_context (all
  #[serde(default)], existing configs parse unchanged).
- New dependency: serde_yaml_ng (maintained drop-in for the deprecated
  serde_yaml) — parses the frontmatter map + list cleanly.

WHY: Markdown stays the portable, sovereign artifact (no lock-in); SQLite
is the fast operational store. v1 round-trip is at the card-content level
(frontmatter + body survive SQLite -> md -> SQLite) — it does NOT
reconstruct the numbered relative-symlink lane views; that's a follow-up.

Disclosure tier: internal capability + one new dependency. No MCP surface
change, no listed step yet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hartsock hartsock added the risk:low Scoped, tested, no CI/build changes label Jun 9, 2026
@hartsock hartsock merged commit 20559a2 into main Jun 9, 2026
2 checks passed
@hartsock hartsock deleted the feat/board-markdown-roundtrip branch June 9, 2026 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:low Scoped, tested, no CI/build changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant