Skip to content

feat(kanban): Markdown Kanban board per project, with live tasks and GitHub issues - #317

Merged
johannesjo merged 7 commits into
mainfrom
claude/kanban-markdown-planning-ojl536
Oct 16, 2026
Merged

johannesjo merged 7 commits into
mainfrom
claude/kanban-markdown-planning-ojl536

Conversation

@johannesjo

@johannesjo johannesjo commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds a Kanban board to every code project. It opens from a new board icon on the project row in the sidebar, next to the GitHub icon. The board is plain Markdown in KANBAN.md at the project root. You can edit it on the board, in any editor, or let an agent write it. The board picks up changes on disk within a couple of seconds. Every card can start a Parallel Code task. Full documentation is in docs/kanban.md.

Board and file format

  • ## headings are columns, list items are cards, and indented lines are the card's description.
  • - [ ] items in a description form a checklist. The card shows its progress, and the task treats the items as acceptance criteria.
  • depends: <card> lines block a card until the named card is done.
  • issue: <url> links a GitHub issue or PR.
  • branch: `…` is written by the app when a task is started from the card.
  • The parser follows CommonMark for code fences, HTML comments and list items. Notes, sub-headings, Obsidian Kanban front matter and settings, line endings and the BOM all survive a round trip. A fuzz run over ~100k random boards showed no content loss.

Cards follow their tasks

  • Start task opens the new-task form prefilled from the card. When the task is created, its branch is recorded on the card and the card moves to In progress.
  • The card shows the task's live state (working, needs input, failed, ready for review), one line of agent activity, and PR checks. Only "needs input" and "failed" are coloured. Answer jumps to the waiting agent pane.
  • Cards move forward on their own and never backwards: to Review when the task signals done or opens a PR, and to Done when the branch merges (from the app, by landing, or on GitHub).
  • Plan with agent opens a separate hidden agent session in the project checkout with a planning prompt. The agent edits KANBAN.md directly, and the board highlights the cards that changed.

GitHub issues

  • Add from GitHub on the board adds open issues and PRs as cards.
  • Add to board on the GitHub page adds the current issue or a batch selection. An issue that is already on the board shows its column instead.
  • A task started from an issue card is linked to the issue and asked to use "Fixes #N" in its commits and PR.
  • Only titles are copied; nothing is written to GitHub.

Safety

  • The main process reads and writes only KANBAN.md, through one no-follow descriptor. It refuses symlinks, FIFOs, files over 1 MB and files that are not valid UTF-8. Writes are atomic, and both IPC channels are kept out of IPC traces.
  • Every write names the text it expects to replace. If another writer changed the file first (an editor, the agent, or the automation), the board re-applies the user's change to the current file instead of dropping it.
  • Card references carry a fingerprint, so two cards with the same title are not confused.
  • Merges: unstaged KANBAN.md edits are set aside before the merge and written back after it, including when a failed squash merge is recovered with reset --hard. Staged board changes still block a merge. Real-git integration tests cover these cases.
  • Card text is stripped of terminal controls and invisible characters before it goes into a prompt. Prompts are always prefilled for the user to send, never sent automatically.

UI and accessibility

  • Full keyboard support:
    • arrows or hjkl to move between cards
    • Shift to move a card
    • < and > to move a column
    • e, s, x, a and r
    • 1–9 for checklist items
    • Delete, and u to undo
    • n, / and ?
    • ⌘ labels on macOS
  • Screen readers get the card state and announcements of changes.
  • Layout does not shift when things change.
  • Colours come from each look's own tokens.
  • Undo replaces confirm dialogs.

Review process

Two rounds of parallel review agents went over the branch: parser and data safety (with fuzzing), component logic, UI and accessibility, security, and integration. Their confirmed findings are fixed in the last two commits. The UI was checked in the running Electron app under xvfb, including starting a real task from a card and seeing the card show "Working" and then "Needs input".

Testing

  • npm run check, npm run lint:dead and npm run lint:arch pass.
  • npm run test:client: 1928 passed.
  • npm run test:unit: 5114 passed, 1 failed. The failure is electron/documents/quick-edit.test.ts ("reports a failing sync once…"). It also fails without this branch when run as root, because it relies on chmod making a file unreadable.
  • New tests:
    • parser, round trips and fuzz findings: src/lib/kanban.test.ts
    • main-process file access: electron/ipc/kanban.test.ts
    • merge guard: electron/ipc/git-merge-guard.test.ts and electron/ipc/git-merge-kanban.integration.test.ts
    • store and automation: src/store/kanban.client.test.tsx
    • board page: src/components/KanbanPage.client.test.tsx
  • Not verified: the GitHub picker against a real remote (the container has none), screen reader output, and the light looks in the running app.

🤖 Generated with Claude Code

https://claude.ai/code/session_019LnrB4p2yrMynkvZo7ayVk

Behind Settings → Experimental → Kanban board. Each code project gets a
board button in the sidebar that opens a board page in the task area,
like the GitHub issues page.

The board is plain Markdown in KANBAN.md at the project root: `##`
headings are columns, list items are cards, indented lines are the
card's description. Edits made in an editor or by an agent show up on
the board (polled while it is open), and a write is refused when the
file changed since it was last read, so nothing is overwritten.

Start task on a card opens the new-task form prefilled from the card.
Once the task exists, its branch is recorded under the card
(`branch: ...`) and the card moves to the "In progress" column; the
card then links to the open task.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LnrB4p2yrMynkvZo7ayVk
Drop the experimental switch: like the GitHub issues view, the board is
reached from the project row in the sidebar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LnrB4p2yrMynkvZo7ayVk
…olish

Cards now show how their tasks are doing and move with them:

- Each linked task shows its state (working, needs input, failed, ready
  for review, idle) with a one-line activity preview and PR checks.
  Only needs-input and failures get colour; Answer jumps to the waiting
  agent pane. The header sums it up ("2 need you · 3 running").
- A card moves to Review when its task signals done or opens a PR, and
  to Done when the branch is merged from the app, lands, or its PR merges
  on GitHub. Cards never move backwards.
- "Plan with agent" opens the project's agent (the one behind the GitHub
  page) with a planning prompt. It edits KANBAN.md in the checkout and
  the board follows, highlighting cards that changed.
- `- [ ]` items in a description are a checklist with progress on the
  card and are passed to the task as acceptance criteria; `depends:`
  lines mark a card blocked until the named card is done.
- Archive column (collapsed by default), collapsible columns, Obsidian
  Kanban front matter and settings kept intact.

Polish: keyboard navigation and shortcuts (arrows/hjkl, Shift to move,
E, S, X, A, Delete, N, /, ?), text and state filters, undo instead of
confirm dialogs, paste a list to add many cards, drop position from the
pointer, auto-scroll while dragging, a save indicator, loading skeleton,
an empty state that shows the format, reserved space for everything that
comes and goes, and reduced-motion support.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LnrB4p2yrMynkvZo7ayVk
Focus the board when it opens so the shortcuts work at once; draw the
card's done mark as a circle on a span (some looks force a radius on all
inputs), distinct from checklist boxes; make Start a quiet text action
that gains a border on hover and drop it from done cards; let columns
shrink so a normal window fits the board without sideways scrolling;
turn Add column into a compact strip and keep collapsed columns short.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LnrB4p2yrMynkvZo7ayVk
Seen with a real task started from a card: the task button repeated the
card title and the activity line echoed the prompt. The button now says
Open, Answer or Show, the activity falls back to the agent's name, and
questions use the app's warning colour (as in the attention tray) while
failures keep the error colour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LnrB4p2yrMynkvZo7ayVk
Five review agents (logic, UI logic, design/a11y, security, integration)
went over the board. Fixes for what they confirmed:

Data safety
- Parser follows CommonMark for code fences, HTML comments, list items,
  thematic breaks and lazy continuation lines, so an unbalanced fence,
  a commented-out card or `## C#` no longer swallow or alter the board.
  Notes between cards keep their place; BOM, CRLF, tabs, empty titles
  and indented code survive a round trip. Only the exact `branch:` /
  `depends:` lines the app writes are metadata; prose stays prose.
- The page applies every change as an intent and re-applies it to the
  file on disk when another writer got in first, so an edit made while
  the planning agent or an editor changes the board is never dropped.
  Cards are found by identity, not position: editing one card while
  another moves can no longer overwrite the wrong card. Drags are off
  while editing; a reload in flight never reverts a local change.
- Merges are no longer blocked by KANBAN.md being modified.
- Direct-mode tasks are not linked (they share the base branch);
  "Not started" / "Definition of done" columns are not In progress /
  Done; archiving keeps a card's checkmark; automation moves each card
  at most once per stage.
- Board text in task prompts is stripped of terminal controls and
  invisible characters. The main process reads through one no-follow,
  non-blocking descriptor, refuses non-UTF-8 files, and the board's
  channels are kept out of IPC traces.

Integration
- The planner is its own hidden agent session, apart from the GitHub
  page's; an unsent draft in it is never replaced. Relinking a project
  closes its board; one helper closes every project page.

UI and accessibility
- Keyboard: checklist items (1-9), rename column (R), move column (< >),
  undo (U / Ctrl+Z), card keys only act from a card. No stuck states
  after an empty Enter, a collapsed column or a filter change.
- Screen readers: card state in its description, announcements for
  moves and deletes, aria-expanded on toggles, focus kept on collapse.
- No layout shift from pressed filters, done cards or live counts
  (moved to the toolbar); theme tokens instead of gradients and fixed
  shadows; obsidian look no longer breaks shapes; readable muted text;
  editor no longer overflows; popovers anchored and dismissable.

GitHub issues
- Cards can carry `issue: <url>`. "Add from GitHub" on the board, and
  "Add to board" on the GitHub page (single or batch), add issues as
  cards; the issue page shows the column an issue is in. A task started
  from an issue card is linked to the issue and asked to reference it.
  Only titles are copied; nothing is written to GitHub.

Docs: README entry and docs/kanban.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LnrB4p2yrMynkvZo7ayVk
Four more review agents (parser fuzzing, page logic, UI/a11y,
integration/security). Fixes for what they confirmed:

- Merges: unstaged KANBAN.md edits are set aside before a merge and
  written back afterwards, so a failed squash merge's `reset --hard`
  can no longer wipe them; staged or conflicted board changes block a
  merge again. Real-git integration tests cover the cases.
- Card identity: references carry a fingerprint, so of two cards with
  the same title the right one is edited, deleted or linked even after
  cards moved.
- Saves report a change whose card or column was removed elsewhere
  instead of claiming "Saved"; Undo is offered only once a delete is
  saved and never duplicates cards (column undo restores only the
  cards still waiting in the neighbour).
- The card editor keeps typed text across re-renders; collapsing a
  renamed column, or a column vanishing under an open field, can no
  longer leave the keyboard and live updates off. Drops and keyboard
  moves find their target column by name.
- Parser (from ~100k fuzzed boards): only a line starting with `<!--`
  opens a comment; fences or comments left open in notes are closed
  before cards that follow; free text keeps its indentation; text above
  a card stays in the column when the card is removed or moved; every
  `issue:` line is kept; columns without a title round-trip.
- A PR card no longer makes the new task treat that PR as its own; task
  names from cards are cleaned like prompts. Adding issues reports
  creating the board, and real failures, instead of "Added 0".
- UI/a11y: cards have a full border with markers drawn as shadows;
  columns stand off the page in every look; live counts sit inside the
  filters in reserved space; one popover at a time, Escape and focus
  handled; every card control follows the roving tab order and a
  visible edit button exists; list semantics and a keyboard hint for
  screen readers; light-look hover/pressed tokens; warning colour kept
  off small text; ⌘ labels on macOS; GitHub page buttons regrouped.
- docs: corrected format example and merge behaviour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LnrB4p2yrMynkvZo7ayVk
@johannesjo johannesjo changed the title feat(kanban): add a Markdown Kanban board per project feat(kanban): Markdown Kanban board per project, with live tasks and GitHub issues Oct 16, 2026
@johannesjo
johannesjo merged commit 717229e into main Oct 16, 2026
2 checks passed
@johannesjo
johannesjo deleted the claude/kanban-markdown-planning-ojl536 branch October 16, 2026 13:09
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.

2 participants