# Kanban Go — CLI Skills By [Colin Knapp](https://colinknapp.com). Create, read, edit, and export kanban boards from the command line using `curl`. Every operation a human can do in the web UI has a JSON/Markdown equivalent here, so an agent can manage a board start-to-finish without touching the browser. ## Markdown Format Boards are expressed in Markdown with a simple, human-editable hierarchy: - `#` — board title (one per file) - `##` — column name - `-` — card under the most recent column - ` > ` — card description (multiple `>` lines stack into a multi-line description) - ` - [ ]` / ` - [x]` — task under the most recent card; `[x]` means done Cards can have **either or both** of: a description (free-form prose) and a task list. They're independent. A card with no tasks is fine, and so is a card with no description. ### HTML-comment metadata `/board//export` emits `` and `` comments under the board title. They're informational; on import the server ignores them (timestamps are server-managed). They render as nothing in standard Markdown viewers. ### Minimal skeleton ``` # Board Title ## Column Name - Card name > Optional description. - [x] Completed task - [ ] Open task ## Another Column - Another card ``` ### Realistic example ``` # Sprint 12 — Auth Rewrite ## Backlog - Migrate session store to Redis > Cookies-only currently; we want it cluster-safe before the > multi-node rollout. Redis already runs for rate-limit. - [ ] Pick TTL policy - [ ] Decide on key namespace (`sess::`) - Document refresh-token rotation flow ## In Progress - Replace JWT signing key > Compromise drill from last quarter exposed how clunky the > rotation path is. Aim: zero-downtime rollover. - [x] Generate new ed25519 keypair in vault - [ ] Roll public key to verifiers - [ ] Cut over signing on prod - Delete legacy /v1/login endpoint - [ ] Confirm zero traffic for 7 days - [ ] Remove handler + tests ## Review - Audit log: capture user-agent - [x] Backend wired - [x] Migration shipped - [ ] Dashboard panel ## Done - Add password rate-limit > Per-IP + per-account, alerts on breach. Done. - [x] Limiter middleware - [x] Per-IP + per-account counters - [x] Alert on threshold breach ``` This is the same shape `/board//export` produces, so the round-trip below is loss-free. ## Create a board from Markdown (one step) Post raw Markdown to the import endpoint. A new board is created automatically from the `# Title` heading and populated with the columns, cards, and tasks found in the body. ```bash curl -X POST https:///api/board-import \ -H "Content-Type: text/markdown" \ --data-binary @board.md ``` The response is JSON: ```json { "id": 42, "key": "aB3kZ9xQ", "name": "Board Title", "url": "https:///board/aB3kZ9xQ" } ``` ## Create an empty board ```bash curl -X POST https:///api/boards \ -H "Content-Type: application/json" \ -d '{"name": "Sprint 12"}' ``` ## Replace a board's content (round-trip editing) To edit a board, export it, modify the Markdown, then `PUT` it back: ```bash # 1. Pull the current state curl -s https:///board/aB3kZ9xQ/export -o board.md # 2. Edit board.md however you like # 3. Replace the board's content with the edited Markdown curl -X PUT https:///api/boards/aB3kZ9xQ \ -H "Content-Type: text/markdown" \ --data-binary @board.md ``` `PUT` is a full replace: the board's existing columns, cards, and tasks are dropped and rebuilt from the Markdown. The board's name is updated from the `# Title` heading. Idempotent — running the same `PUT` twice yields the same board. ## Append Markdown to an existing board If you want to *add* content to a board instead of replacing it (e.g. dump a new column at the end without touching what's there), use `POST /import` instead: ```bash curl -X POST https:///api/boards/aB3kZ9xQ/import \ -H "Content-Type: text/markdown" \ --data-binary @additions.md ``` Existing columns with the same name are reused; everything else is added. ## Export a board to Markdown ```bash curl -s https:///board/aB3kZ9xQ/export -o board.md ``` ## Get a board as JSON ```bash curl -s https:///api/boards/aB3kZ9xQ ``` Returns: ```json { "id": 42, "key": "aB3kZ9xQ", "name": "Board Title", "url": "https:///board/aB3kZ9xQ" } ``` ## Pipe a board directly ```bash cat <<'MD' | curl -X POST https:///api/board-import \ -H "Content-Type: text/markdown" --data-binary @- # Weekend Project ## To Do - Design landing page - [ ] Pick color palette - [ ] Sketch wireframe ## In Progress - Write backend - [x] Set up database - [ ] Add auth ## Done - Buy domain MD ```