kandown 0.34.2 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -2
- package/README.md +215 -185
- package/bin/kandown.js +14 -23
- package/bin/tui.js +1 -1
- package/dist/index.html +182 -182
- package/package.json +6 -2
- package/templates/AGENT_KANDOWN.md +13 -2
- package/templates/kandown.json +16 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.35.0 — 2026-07-25 — "House Green"
|
|
4
|
+
|
|
5
|
+
- **Added**: **Kandown finally has its own theme, and it is the default** — a `kandown` preset built from the brand palette registered on the website: `#88E138` brand lime (the logo arrow) as the dark-mode primary, `#7AD12A` as its light-background variant, `#0CE931` (the hero shader green) reused as the `success` token, `#F1FFB8` for accent surfaces and `#EBEBEB` for neutral borders, on 4px radius to match the website. Because lime cannot carry white text at any usable contrast, `primary-foreground` is a near-black green in both modes (7.9:1 light, 11.2:1 dark) rather than the usual white. Every other foreground/background pair passes WCAG AA in both modes.
|
|
6
|
+
- **Fixed**: **The default skin silently resolved to Vercel** — `DEFAULT_CONFIG.ui.skin` already read `'kandown'`, but `LEGACY_SKIN_MAP` still aliased `kandown` to `vercel` from before the FABLE_UI theme system, so every fresh project opened in monochrome instead of the brand colors. The alias is gone, the preset now sits first in `THEME_PRESETS` (and is therefore the `[0]` fallback for an unknown id), and `normalizeSkinId` falls back to `kandown` instead of `vercel`.
|
|
7
|
+
- **Changed**: **Website hero rewritten** — the technical breadcrumb (Local-first / MIT / Node / npm) is replaced by a short free, open-source, local promise, and the headline is reframed around Markdown tasks built for AI agents, long-running work, and the web/TUI/CLI trio. The shared tagline and description used for SEO and machine-readable docs were aligned with it.
|
|
8
|
+
- **Added**: **Demo mode** — a third backend for the web UI that answers the Kandown REST API from an in-memory `Map` instead of a disk, so the whole application can run in a browser tab with no CLI, no server and no storage. It plugs in at `apiFetch` (`src/lib/filesystem.ts`) via `registerDemoApi()`, which is why the board, drawer, editor, search, archive and drag-and-drop all work without knowing anything changed — nothing is mocked. Built with `pnpm build:demo`, which also drops `vite-plugin-singlefile` in favour of a normal chunked build. The entire feature is compiled out of the bundle `npx kandown` ships, behind the `__KANDOWN_DEMO_BUILD__` define.
|
|
9
|
+
- **Fixed**: **Header task counter rendered `[object Object] tasks`** — `useAnimatedNumber` returns a Motion `MotionValue`, which has to be rendered by a `motion.*` component that subscribes to it; wrapping it in `String()` stringified the object itself. Every user of the web board saw this on every screen.
|
|
10
|
+
- **Fixed**: **Repository root could open as a project named `templates`** — implicit project resolution now checks the current directory and walks upward for the nearest valid `.kandown/kandown.json` instead of recursively scanning child directories. This keeps the live board anchored to the canonical root `.kandown/` + `tasks/` layout, works from nested paths such as `src/`, and prevents packaged init assets under `templates/` from being mistaken for a project.
|
|
11
|
+
- **Changed**: **Removed downward child-project auto-discovery** — launching Kandown from a directory above a project no longer guesses which descendant board to open. Run it inside the intended project (or one of its subdirectories), or pass an explicit `--path`, for deterministic selection.
|
|
12
|
+
- **Cleaned**: Removed accidentally committed `templates/daemon.json` runtime state and `templates/kandown.html` generated output. The configuration, documentation, and welcome-task seeds required by `kandown init` remain in `templates/`.
|
|
13
|
+
|
|
14
|
+
## 0.34.3 — 2026-07-24 — "Motion Polish — Drag Fix"
|
|
15
|
+
|
|
16
|
+
- **Fixed**: **Cards could not be dragged between columns after the v0.34.2 motion polish** — the `motion.div` → plain `<div>` replacement in `Card.tsx` accidentally dropped the `draggable` HTML5 attribute and the `{...dragHandlers}` spread that wire `onDragStart` / `onDragEnd` on each card. Without `draggable` the native HTML5 drag event never fired, so the board could not move tasks between columns even though the click-to-open drawer still worked. Restores `draggable` and `dragHandlers` on the card container; no other behavior changes.
|
|
17
|
+
|
|
3
18
|
## 0.34.2 — 2026-07-24 — "Motion Polish"
|
|
4
19
|
|
|
5
20
|
- **Fixed**: **0.5s pop on card hover, click, and rearrange** — `Card`, `Column`, and `CardStack` were animating through Framer Motion springs (`whileHover={{ y: -1 }}`, `whileTap={{ scale: 0.99 }}` with stiffness 500) AND Tailwind `transition-all duration-150` at the same time, on the same `transform` property. The result was the half-second scale snap the user reported on every interaction. Replaced with a hybrid system:
|
|
@@ -352,8 +367,8 @@
|
|
|
352
367
|
|
|
353
368
|
## 0.15.0 — 2026-07-07 — "Boot Splash"
|
|
354
369
|
|
|
355
|
-
- **Added**: **Boot splash** —
|
|
356
|
-
- **Added**: **
|
|
370
|
+
- **Added**: **Boot splash** — on project launch, the `kandown` title and a `v<version>` badge stay on screen for 5 seconds, then fade out to leave only the logo. The name of the open project then takes its place as the header's page title, with a soft transition.
|
|
371
|
+
- **Added**: **Dynamic document title** — the browser tab now reflects the current project (`<Project> · Kandown`) instead of a static title.
|
|
357
372
|
|
|
358
373
|
## 0.14.1 — 2026-07-07 — "Resilience Pass"
|
|
359
374
|
|
package/README.md
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<strong>Too Many Ideas, Not Enough Agents.</strong><br>
|
|
9
|
-
|
|
10
|
-
Zero backend · Zero database · No account · AI
|
|
9
|
+
A local-first Kanban board where every task is a Markdown file you own forever.<br>
|
|
10
|
+
Zero backend · Zero database · No account · Built for working alongside AI agents
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
13
|
<p align="center">
|
|
@@ -17,230 +17,224 @@
|
|
|
17
17
|
<img src="https://img.shields.io/badge/local--first-100%25-orange" alt="100% local-first">
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- **AI-agent friendly** — Claude, Codex, Gemini, Goose, Aider, and OpenCode can read and update tasks directly
|
|
28
|
-
- **Dual interface** — a polished web UI + a full terminal TUI, both running entirely offline
|
|
29
|
-
- **Single-file deployment** — `kandown.html` is a self-contained app you can open in any browser
|
|
20
|
+
<p align="center">
|
|
21
|
+
<a href="#quick-start">Quick start</a> ·
|
|
22
|
+
<a href="#for-ai-agents">For AI agents</a> ·
|
|
23
|
+
<a href="#cli-reference">CLI</a> ·
|
|
24
|
+
<a href="#features">Features</a> ·
|
|
25
|
+
<a href="#contributing">Contributing</a>
|
|
26
|
+
</p>
|
|
30
27
|
|
|
31
28
|
---
|
|
32
29
|
|
|
33
|
-
##
|
|
30
|
+
## What it is
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
Kandown drops a `tasks/` folder into your project and gives you three ways to work
|
|
33
|
+
with it: a polished web board, a full terminal UI, and a scriptable CLI. All three
|
|
34
|
+
read and write the same plain Markdown files.
|
|
38
35
|
|
|
39
|
-
**
|
|
36
|
+
- **Your data is just files.** One `.md` per task, versioned in git, readable by any
|
|
37
|
+
editor, any script, any AI agent. Nothing to export, nothing to lose.
|
|
38
|
+
- **Agents are first-class users**, not an integration. Claude Code, Codex, Gemini
|
|
39
|
+
CLI, Goose, Aider and OpenCode all drive the board directly.
|
|
40
|
+
- **Fully offline.** No account, no cloud, no telemetry. The web UI is one
|
|
41
|
+
self-contained HTML file you can open anywhere.
|
|
40
42
|
|
|
41
43
|
---
|
|
42
44
|
|
|
43
|
-
##
|
|
44
|
-
|
|
45
|
-
### Initialize in any project
|
|
45
|
+
## Quick start
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
+
npm install -g kandown # Node.js 18+
|
|
48
49
|
cd my-project
|
|
49
50
|
kandown init
|
|
51
|
+
kandown
|
|
50
52
|
```
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
`kandown init` creates two folders at your project root:
|
|
53
55
|
|
|
54
56
|
```
|
|
57
|
+
tasks/ # your tasks — the source of truth
|
|
58
|
+
├── t1.md # one Markdown file per task
|
|
59
|
+
└── archive/ # archived tasks live here
|
|
60
|
+
|
|
55
61
|
.kandown/ # config + web UI + agent docs
|
|
56
|
-
├── kandown.
|
|
57
|
-
├── kandown.
|
|
58
|
-
├──
|
|
59
|
-
└──
|
|
60
|
-
|
|
61
|
-
tasks/ # Task files (source of truth)
|
|
62
|
-
├── t1.md # One .md file per task
|
|
63
|
-
└── archive/ # Archived tasks live here
|
|
62
|
+
├── kandown.json # columns, theme, notifications, agents
|
|
63
|
+
├── kandown.html # the web app, one self-contained file
|
|
64
|
+
├── instructions.md # optional: your project's agent instructions
|
|
65
|
+
└── AGENT*.md # agent reference, kept in sync with the CLI
|
|
64
66
|
```
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
`kandown` then starts a small local daemon and opens both a **web board** in your
|
|
69
|
+
browser and a **terminal UI** in your shell. The daemon outlives the TUI, so the
|
|
70
|
+
browser keeps working after you quit — stop it with `d` in the TUI or
|
|
71
|
+
`kandown daemon stop`.
|
|
70
72
|
|
|
71
|
-
|
|
73
|
+
Tasks live at your project root rather than inside `.kandown/` so that config and
|
|
74
|
+
data stay cleanly separated. Upgrading from an older layout? The CLI moves them for
|
|
75
|
+
you on first run.
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
kandown
|
|
75
|
-
```
|
|
77
|
+
---
|
|
76
78
|
|
|
77
|
-
|
|
78
|
-
- A **web UI** in your browser (board view, list view, task editor)
|
|
79
|
-
- A **terminal TUI** for keyboard-driven workflow (works over SSH, no browser needed)
|
|
79
|
+
## For AI agents
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
This is the part that makes kandown different, so it is worth two minutes.
|
|
82
82
|
|
|
83
|
-
###
|
|
83
|
+
### One command for context
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
| `kandown init` | Initialize in current project |
|
|
89
|
-
| `kandown board` | TUI only (no browser) |
|
|
90
|
-
| `kandown settings` | Terminal settings editor |
|
|
91
|
-
| `kandown daemon status` | Show this project's web daemon status |
|
|
92
|
-
| `kandown daemon start` | Start/reconnect this project's web daemon |
|
|
93
|
-
| `kandown daemon stop` | Stop this project's web daemon |
|
|
94
|
-
| `kandown daemon refresh-all` | Refresh open projects and restart outdated daemons with the current CLI version |
|
|
95
|
-
| `kandown update` | Update `kandown.html` to latest |
|
|
96
|
-
| `kandown list` \| `show` \| `create` \| `move` \| `assign` \| `commit` | One-shot task commands (see below) |
|
|
97
|
-
| `kandown tasks` | Full help for the one-shot task commands |
|
|
98
|
-
| `kandown work` | **For AI agents:** print the agent rules + a live board digest (see below) |
|
|
99
|
-
| `kandown help` | CLI help |
|
|
85
|
+
```bash
|
|
86
|
+
kandown work
|
|
87
|
+
```
|
|
100
88
|
|
|
101
|
-
|
|
89
|
+
That prints, as plain Markdown on stdout:
|
|
102
90
|
|
|
103
|
-
|
|
91
|
+
1. **The agent rules** — served from the installed CLI, so they are never a stale
|
|
92
|
+
copy frozen into your repo at init time.
|
|
93
|
+
2. **Your project instructions** — optional, from `.kandown/instructions.md`. Stack
|
|
94
|
+
quirks, "always use pnpm", commit-message language, token-efficiency
|
|
95
|
+
preferences.
|
|
96
|
+
3. **A live board digest** — column counts, tasks per column with blocked-by
|
|
97
|
+
annotations, and a computed **next actionable task** (unblocked, closest to done,
|
|
98
|
+
highest priority).
|
|
104
99
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
One call, full context. `kandown init` adds a single line to your `AGENTS.md` /
|
|
101
|
+
`CLAUDE.md` pointing at it — no block of rules copied in to go stale.
|
|
102
|
+
|
|
103
|
+
The Settings page has an **Agent → `kandown work` output** configurator: toggle each
|
|
104
|
+
block, switch to a concise token-efficient mode, hide digest fields, see an
|
|
105
|
+
estimated token count, or take full control with a raw template using
|
|
106
|
+
`{{baseRules}}`, `{{projectInstructions}}` and `{{boardDigest}}`.
|
|
107
|
+
|
|
108
|
+
### Scriptable, composable, offline
|
|
113
109
|
|
|
114
110
|
```bash
|
|
115
111
|
kandown list --json | jq '.[] | select(.priority=="P1")'
|
|
116
|
-
kandown create "Refactor auth middleware" -p P1 -t backend
|
|
117
|
-
kandown move
|
|
118
|
-
kandown assign t42 alice
|
|
112
|
+
ID=$(kandown create "Refactor auth middleware" -p P1 -t backend)
|
|
113
|
+
kandown move "$ID" Done
|
|
119
114
|
kandown commit -m "tasks: add auth refactor"
|
|
120
115
|
```
|
|
121
116
|
|
|
122
|
-
**Output contract:** stdout carries data only
|
|
117
|
+
**Output contract:** stdout carries data only — ids, JSON, tables. Everything
|
|
118
|
+
decorative (`✓ Created…`, warnings, errors) goes to stderr. So `$(kandown create
|
|
119
|
+
…)` captures exactly one id, and `--json | jq` never chokes on a checkmark. Exit
|
|
120
|
+
code `0` on success, non-zero on failure.
|
|
123
121
|
|
|
124
|
-
**No
|
|
122
|
+
**No network, ever.** The task commands and `kandown daemon` never contact the npm
|
|
123
|
+
registry, so they stay instant and work offline — ideal for CI and for agents in a
|
|
124
|
+
loop.
|
|
125
125
|
|
|
126
|
-
###
|
|
126
|
+
### MCP
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
```bash
|
|
129
|
+
kandown mcp # stdio MCP server
|
|
130
|
+
claude mcp add kandown -- kandown mcp
|
|
131
|
+
```
|
|
129
132
|
|
|
130
|
-
|
|
133
|
+
### Launching agents from the board
|
|
131
134
|
|
|
132
|
-
|
|
135
|
+
Press `a` on any task in the terminal UI to hand it to an agent:
|
|
133
136
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
| Agent | Binary | Launch mode |
|
|
138
|
+
|---|---|---|
|
|
139
|
+
| Claude Code | `claude` | interactive session |
|
|
140
|
+
| OpenAI Codex | `codex` | interactive session |
|
|
141
|
+
| Gemini CLI | `gemini` | `-p` initial prompt |
|
|
142
|
+
| Goose | `goose` | `run --text`, non-interactive |
|
|
143
|
+
| Aider | `aider` | `--message` initial prompt |
|
|
144
|
+
| OpenCode | `opencode` | TUI, context written to `/tmp` |
|
|
137
145
|
|
|
138
|
-
|
|
146
|
+
Or point kandown at your own tooling with `KANDOWN_AGENT_HOOK_URL` and let any
|
|
147
|
+
IDE, bot or webhook receive tasks.
|
|
139
148
|
|
|
140
|
-
|
|
149
|
+
---
|
|
141
150
|
|
|
142
|
-
|
|
151
|
+
## CLI reference
|
|
143
152
|
|
|
144
|
-
|
|
153
|
+
### Interactive
|
|
145
154
|
|
|
146
|
-
|
|
155
|
+
| Command | Description |
|
|
156
|
+
|---|---|
|
|
157
|
+
| `kandown` | Web UI + terminal board |
|
|
158
|
+
| `kandown init` | Initialize in the current project |
|
|
159
|
+
| `kandown board` | Terminal UI only, no browser |
|
|
160
|
+
| `kandown settings` | Terminal settings editor |
|
|
161
|
+
| `kandown doctor` | Diagnose config, daemon, ports, task frontmatter |
|
|
162
|
+
| `kandown help` | Full help |
|
|
147
163
|
|
|
148
|
-
|
|
164
|
+
### Tasks — non-interactive, agent- and CI-friendly
|
|
149
165
|
|
|
150
|
-
|
|
|
166
|
+
| Command | Description |
|
|
151
167
|
|---|---|
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
168
|
+
| `kandown list` | List tasks — `[-s status] [-a assignee] [-t tag] [-p priority] [--archived] [--json]` |
|
|
169
|
+
| `kandown show <id>` | Print a task file's raw content |
|
|
170
|
+
| `kandown create "title"` | Create — `[-p priority] [-a assignee] [-t tag …] [--to status] [--id custom-id] [--json]` |
|
|
171
|
+
| `kandown move <id> <status>` | Move to a column, or to `archived` |
|
|
172
|
+
| `kandown assign <id> [name]` | Assign, or unassign by omitting the name |
|
|
173
|
+
| `kandown commit [-m msg]` | `git add tasks/ .kandown/kandown.json` + commit |
|
|
174
|
+
| `kandown export` / `import` | JSON / CSV out, Trello JSON or Markdown in |
|
|
157
175
|
|
|
158
|
-
|
|
176
|
+
### Daemon & maintenance
|
|
177
|
+
|
|
178
|
+
| Command | Description |
|
|
179
|
+
|---|---|
|
|
180
|
+
| `kandown daemon status\|start\|stop` | Manage this project's web daemon |
|
|
181
|
+
| `kandown daemon refresh-all` | Restart outdated daemons on the current CLI version |
|
|
182
|
+
| `kandown projects` | List every open kandown project on this machine |
|
|
183
|
+
| `kandown update` | Update the CLI and the project's `kandown.html` |
|
|
159
184
|
|
|
160
185
|
---
|
|
161
186
|
|
|
162
|
-
##
|
|
187
|
+
## Features
|
|
163
188
|
|
|
164
|
-
|
|
165
|
-
- `.kandown/daemon.json` and `.kandown/daemon.lock` are runtime-only files; `kandown init` adds them to `.kandown/.gitignore` automatically.
|
|
189
|
+
### Board & views
|
|
166
190
|
|
|
167
|
-
|
|
191
|
+
Horizontal kanban with drag-and-drop · sectioned list view with filters and search ·
|
|
192
|
+
full-text search across titles, bodies, subtasks, tags, assignee and priority ·
|
|
193
|
+
command palette (`⌘K`) · freely editable columns · group-by
|
|
194
|
+
(priority / assignee / epic) · due-date banner · guarded double-click deletion ·
|
|
195
|
+
bulk archive or delete of a whole column.
|
|
168
196
|
|
|
169
|
-
|
|
197
|
+
### Tasks
|
|
170
198
|
|
|
171
|
-
|
|
199
|
+
WYSIWYG Markdown editor · subtask checklists with per-step descriptions, reports and
|
|
200
|
+
keyboard reordering · priority, assignee, tags, due date, epic, owner type ·
|
|
201
|
+
`depends_on` dependencies with a gate that refuses to close a blocked task ·
|
|
202
|
+
human/agent owner filtering · quick-add syntax
|
|
203
|
+
(`Fix login p1 #backend @chacha due:friday`) · task templates ·
|
|
204
|
+
external-change detection.
|
|
172
205
|
|
|
173
|
-
|
|
174
|
-
|---|---|
|
|
175
|
-
| Board view | Horizontal kanban with drag-and-drop |
|
|
176
|
-
| List view | Sectioned vertical list with filters, search, and drag-and-drop between statuses |
|
|
177
|
-
| Content search | Search titles, body, subtasks, tags, assignee, priority |
|
|
178
|
-
| Command palette | `⌘K` / `Ctrl+K` for quick actions |
|
|
179
|
-
| Custom columns | Add, rename, delete columns freely |
|
|
180
|
-
| Guarded deletion | Double-click to delete — no accidents |
|
|
181
|
-
| Terminal bulk actions | Archive or permanently delete every task in the terminal column with confirmation |
|
|
206
|
+
### Appearance
|
|
182
207
|
|
|
183
|
-
|
|
208
|
+
**38 built-in themes** (Vercel, Linear, Claude, Apple, Stripe, Catppuccin, Dracula,
|
|
209
|
+
Nord, Terminal, Synthwave and more) plus custom themes defined in JSON · light /
|
|
210
|
+
dark / auto · tokenised radius, shadows, density and motion · 5 font stacks ·
|
|
211
|
+
animated WebGL background · **48 languages** · browser and sound notifications.
|
|
184
212
|
|
|
185
|
-
|
|
186
|
-
|---|---|
|
|
187
|
-
| Rich task drawer | WYSIWYG markdown editor for title, metadata, subtasks, body |
|
|
188
|
-
| Subtasks | Full checklist with progress tracking on cards |
|
|
189
|
-
| Subtask editor | Add, reorder-by-keyboard, check off, remove, and edit per-step descriptions and reports |
|
|
190
|
-
| Metadata fields | Priority, assignee, tags, due date, owner type |
|
|
191
|
-
| Owner filtering | Filter human vs AI-agent tasks separately |
|
|
192
|
-
| External-change detection | Warns when files are modified outside the app |
|
|
213
|
+
### Terminal UI
|
|
193
214
|
|
|
194
|
-
|
|
215
|
+
Keyboard-driven and mouse-aware, works over SSH with no browser.
|
|
195
216
|
|
|
196
|
-
|
|
|
217
|
+
| Key | Action |
|
|
197
218
|
|---|---|
|
|
198
|
-
|
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
|
|
|
203
|
-
|
|
|
219
|
+
| `j`/`k`, `h`/`l` | Navigate tasks / columns |
|
|
220
|
+
| `n` · `e` · `m` | New task · edit in `$EDITOR` · move |
|
|
221
|
+
| `/` · `f` | Fuzzy search · cycle filters |
|
|
222
|
+
| `a` · `g` | Launch an agent · send to agent hook |
|
|
223
|
+
| `x` · `D` | Archive · delete |
|
|
224
|
+
| `d` · `r` · `?` | Toggle daemon · reload · cheatsheet |
|
|
204
225
|
|
|
205
|
-
|
|
226
|
+
Drag a task with the mouse to move it between columns.
|
|
206
227
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
| Agent | Binary | Launch mode |
|
|
210
|
-
|---|---|---|
|
|
211
|
-
| Claude Code | `claude` | Interactive session |
|
|
212
|
-
| OpenAI Codex | `codex` | Interactive session |
|
|
213
|
-
| Gemini CLI | `gemini` | `-p` flag for initial prompt |
|
|
214
|
-
| Goose | `goose` | `run --text` for non-interactive |
|
|
215
|
-
| Aider | `aider` | `--message` for initial prompt |
|
|
216
|
-
| OpenCode | `opencode` | TUI, context written to `/tmp` |
|
|
228
|
+
### Web shortcuts
|
|
217
229
|
|
|
218
|
-
|
|
230
|
+
`⌘K` palette · `⌘1`/`⌘2` board/list · `N` new · `R` reload · `/` search ·
|
|
231
|
+
`⌘S` save · `⌘⌫` delete · `Esc` close.
|
|
219
232
|
|
|
220
|
-
|
|
221
|
-
|---|---|
|
|
222
|
-
| `⌘K` / `Ctrl+K` | Command palette |
|
|
223
|
-
| `⌘1` / `Ctrl+1` | Board view |
|
|
224
|
-
| `⌘2` / `Ctrl+2` | List view |
|
|
225
|
-
| `N` | New task |
|
|
226
|
-
| `R` | Reload from disk |
|
|
227
|
-
| `/` | Focus search |
|
|
228
|
-
| `Esc` | Close drawer / palette |
|
|
229
|
-
| `⌘S` / `Ctrl+S` | Save task |
|
|
230
|
-
| `⌘⌫` / `Ctrl+Backspace` | Delete task (with confirmation) |
|
|
231
|
-
|
|
232
|
-
### TUI extras
|
|
233
|
-
|
|
234
|
-
| Shortcut / gesture | Action |
|
|
235
|
-
|---|---|
|
|
236
|
-
| `d` | Start/stop the per-project web daemon |
|
|
237
|
-
| Mouse drag task | Move a task between columns in the terminal |
|
|
238
|
-
| `m` | Open the focused task context menu |
|
|
239
|
-
| `r` | Reload board from disk |
|
|
233
|
+
---
|
|
240
234
|
|
|
241
|
-
|
|
235
|
+
## The data model
|
|
242
236
|
|
|
243
|
-
|
|
237
|
+
One task, one file, no index:
|
|
244
238
|
|
|
245
239
|
```markdown
|
|
246
240
|
---
|
|
@@ -250,6 +244,7 @@ status: Todo
|
|
|
250
244
|
priority: P1
|
|
251
245
|
tags: [backend, security]
|
|
252
246
|
assignee: chacha
|
|
247
|
+
depends_on: [t7]
|
|
253
248
|
created: 2026-04-10
|
|
254
249
|
---
|
|
255
250
|
|
|
@@ -259,50 +254,85 @@ created: 2026-04-10
|
|
|
259
254
|
Why this task exists.
|
|
260
255
|
|
|
261
256
|
## Subtasks
|
|
262
|
-
- [ ] Set up OAuth provider
|
|
263
257
|
- [x] Create user model
|
|
264
|
-
|
|
258
|
+
report: Added src/models/user.ts with the schema and migrations.
|
|
259
|
+
- [ ] Set up OAuth provider
|
|
265
260
|
```
|
|
266
261
|
|
|
262
|
+
| Field | Meaning |
|
|
263
|
+
|---|---|
|
|
264
|
+
| `status` | Board column, from `board.columns` in `kandown.json` |
|
|
265
|
+
| `order` | Sort position within the column |
|
|
266
|
+
| `priority` | `P1`–`P4` |
|
|
267
|
+
| `tags`, `assignee` | Free-form labels, username or agent name |
|
|
268
|
+
| `ownerType` | `human` or `ai` — drives owner filtering |
|
|
269
|
+
| `depends_on` | Task ids blocking this one; moving to the terminal column is refused while any is unresolved |
|
|
270
|
+
| `report` | Completion summary in Markdown, shown prominently in the UI |
|
|
271
|
+
|
|
267
272
|
---
|
|
268
273
|
|
|
269
|
-
##
|
|
274
|
+
## Configuration
|
|
270
275
|
|
|
271
|
-
|
|
276
|
+
### Environment variables
|
|
272
277
|
|
|
273
|
-
|
|
278
|
+
| Variable | Effect |
|
|
279
|
+
|---|---|
|
|
280
|
+
| `KANDOWN_NO_UPDATE=1` | Disable the background update check (recommended in CI) |
|
|
281
|
+
| `KANDOWN_DEBUG=1` | Print full stack traces instead of a one-line summary |
|
|
282
|
+
| `KANDOWN_AGENT_HOOK_URL` | Endpoint that receives tasks from "Send to Agent" / TUI `g` |
|
|
283
|
+
| `KANDOWN_AGENT_HOOK_LABEL` | Custom label for the agent hook button |
|
|
284
|
+
| `KANDOWN_AGENT_HOOK_HEADERS` | JSON object of extra headers for the hook request |
|
|
285
|
+
|
|
286
|
+
Interactive runs check npm for updates at most once every 24 hours — never for the
|
|
287
|
+
task commands, never for `daemon`, never when stdout is not a terminal — and install
|
|
288
|
+
silently when one is found.
|
|
289
|
+
|
|
290
|
+
### Security
|
|
291
|
+
|
|
292
|
+
The local daemon binds to `127.0.0.1` only and mints a random per-project API token
|
|
293
|
+
at startup, stored in the gitignored `.kandown/daemon.json` and injected into the
|
|
294
|
+
page it serves. Every route except the read-only `GET /api/daemon` identity check
|
|
295
|
+
requires it, so an unrelated browser tab cannot reach your tasks by scanning
|
|
296
|
+
localhost ports. Task ids are validated before they touch the filesystem.
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Contributing
|
|
301
|
+
|
|
302
|
+
Contributions are welcome.
|
|
274
303
|
|
|
275
304
|
```bash
|
|
276
305
|
git clone https://github.com/vava-nessa/kandown.git
|
|
277
306
|
cd kandown
|
|
278
|
-
pnpm install
|
|
279
|
-
pnpm dev
|
|
307
|
+
pnpm install # also installs the git hooks
|
|
308
|
+
pnpm dev # web UI at localhost:5176
|
|
280
309
|
```
|
|
281
310
|
|
|
282
|
-
|
|
311
|
+
Before your first change, read — in this order:
|
|
283
312
|
|
|
284
|
-
|
|
|
313
|
+
| Document | What it gives you |
|
|
285
314
|
|---|---|
|
|
286
|
-
| `
|
|
287
|
-
| `
|
|
288
|
-
| `
|
|
289
|
-
| `
|
|
290
|
-
| `pnpm preview` | Preview production build |
|
|
291
|
-
| `pnpm typecheck` | TypeScript check |
|
|
292
|
-
|
|
293
|
-
---
|
|
315
|
+
| [`AGENTS.md`](AGENTS.md) | The project's rules, including which files are generated |
|
|
316
|
+
| [`CODEMAP.md`](CODEMAP.md) | Every source file with a one-line summary — generated from JSDoc |
|
|
317
|
+
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | How the pieces fit and which invariants not to break |
|
|
318
|
+
| [`docs/RELEASE.md`](docs/RELEASE.md) | The release runbook |
|
|
294
319
|
|
|
295
|
-
|
|
320
|
+
The short version: **`bin/*.js` are build output, not source** — edit `src/cli/`
|
|
321
|
+
instead. Every source file carries a JSDoc `@file` / `@description` header, `CODEMAP.md`
|
|
322
|
+
is generated from them on every commit, and CI fails if either drifts.
|
|
296
323
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
324
|
+
| Script | Description |
|
|
325
|
+
|---|---|
|
|
326
|
+
| `pnpm dev` | Vite dev server for the web UI |
|
|
327
|
+
| `pnpm dev:app` | Full build, then launch the CLI |
|
|
328
|
+
| `pnpm dev:cli` | Watch-mode build of the CLI bundles |
|
|
329
|
+
| `pnpm build` | Version inject → agent-doc sync → typecheck → web → CLI |
|
|
330
|
+
| `pnpm typecheck` | TypeScript, no emit |
|
|
331
|
+
| `pnpm codemap` | Regenerate `CODEMAP.md` / `CODEMAP.json` |
|
|
300
332
|
|
|
301
333
|
---
|
|
302
334
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
<a href="#-ai-agent-integration">AI Agents</a>
|
|
308
|
-
</p>
|
|
335
|
+
## License
|
|
336
|
+
|
|
337
|
+
[MIT](LICENSE) © 2026 [Vanessa Depraute](https://vanessadepraute.dev) —
|
|
338
|
+
GitHub: [vava-nessa](https://github.com/vava-nessa)
|
package/bin/kandown.js
CHANGED
|
@@ -15,7 +15,7 @@ import { spawn, execSync } from "child_process";
|
|
|
15
15
|
import { homedir } from "os";
|
|
16
16
|
|
|
17
17
|
// src/lib/version.ts
|
|
18
|
-
var KANDOWN_VERSION = "0.
|
|
18
|
+
var KANDOWN_VERSION = "0.35.0";
|
|
19
19
|
|
|
20
20
|
// src/cli/lib/updater.ts
|
|
21
21
|
import { fileURLToPath } from "url";
|
|
@@ -1206,8 +1206,8 @@ function openBrowser(target) {
|
|
|
1206
1206
|
}
|
|
1207
1207
|
|
|
1208
1208
|
// src/cli/lib/cli-shared.ts
|
|
1209
|
-
import { existsSync as existsSync7, readFileSync as readFileSync7, readdirSync as readdirSync4
|
|
1210
|
-
import { join as join7, resolve as resolve2, basename } from "path";
|
|
1209
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, readdirSync as readdirSync4 } from "fs";
|
|
1210
|
+
import { join as join7, resolve as resolve2, basename, dirname as dirname4 } from "path";
|
|
1211
1211
|
import { spawn as spawn4 } from "child_process";
|
|
1212
1212
|
|
|
1213
1213
|
// src/cli/lib/init.ts
|
|
@@ -1383,30 +1383,21 @@ function stripFirstPositional(args, value) {
|
|
|
1383
1383
|
return result;
|
|
1384
1384
|
}
|
|
1385
1385
|
function resolveKandownDir(pathArg = ".kandown", cwd = process.cwd()) {
|
|
1386
|
-
if (basename(cwd) === ".kandown" || existsSync7(join7(cwd, "kandown.json"))) {
|
|
1387
|
-
return cwd;
|
|
1388
|
-
}
|
|
1389
1386
|
if (pathArg !== ".kandown") {
|
|
1390
1387
|
return resolve2(cwd, pathArg);
|
|
1391
1388
|
}
|
|
1392
|
-
let
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
const subPath = join7(cwd, name);
|
|
1401
|
-
let stat;
|
|
1402
|
-
try {
|
|
1403
|
-
stat = statSync4(subPath);
|
|
1404
|
-
} catch {
|
|
1405
|
-
continue;
|
|
1389
|
+
let currentDir = resolve2(cwd);
|
|
1390
|
+
while (true) {
|
|
1391
|
+
if (basename(currentDir) === ".kandown" && existsSync7(join7(currentDir, "kandown.json"))) {
|
|
1392
|
+
return currentDir;
|
|
1393
|
+
}
|
|
1394
|
+
const candidate = join7(currentDir, ".kandown");
|
|
1395
|
+
if (existsSync7(join7(candidate, "kandown.json"))) {
|
|
1396
|
+
return candidate;
|
|
1406
1397
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1398
|
+
const parentDir = dirname4(currentDir);
|
|
1399
|
+
if (parentDir === currentDir) break;
|
|
1400
|
+
currentDir = parentDir;
|
|
1410
1401
|
}
|
|
1411
1402
|
return resolve2(cwd, pathArg);
|
|
1412
1403
|
}
|
package/bin/tui.js
CHANGED
|
@@ -54963,7 +54963,7 @@ import { spawn, execSync } from "child_process";
|
|
|
54963
54963
|
import { homedir as homedir2 } from "os";
|
|
54964
54964
|
|
|
54965
54965
|
// src/lib/version.ts
|
|
54966
|
-
var KANDOWN_VERSION = "0.
|
|
54966
|
+
var KANDOWN_VERSION = "0.35.0";
|
|
54967
54967
|
|
|
54968
54968
|
// src/cli/lib/updater.ts
|
|
54969
54969
|
import { fileURLToPath as fileURLToPath2 } from "url";
|