kandown 0.3.4 → 0.4.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/README.md +89 -371
- package/bin/kandown.js +23 -4
- package/dist/index.html +559 -4225
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -13,214 +13,122 @@
|
|
|
13
13
|
<a href="https://www.npmjs.com/package/kandown"><img src="https://img.shields.io/npm/v/kandown?color=cb3837&label=npm" alt="npm version"></a>
|
|
14
14
|
<a href="https://www.npmjs.com/package/kandown"><img src="https://img.shields.io/npm/dm/kandown?color=blue" alt="npm downloads"></a>
|
|
15
15
|
<img src="https://img.shields.io/badge/license-MIT-green" alt="MIT License">
|
|
16
|
-
<img src="https://img.shields.io/badge/languages-48-purple" alt="48 languages">
|
|
17
16
|
<img src="https://img.shields.io/badge/local--first-100%25-orange" alt="100% local-first">
|
|
18
17
|
</p>
|
|
19
18
|
|
|
20
|
-
<p align="center">
|
|
21
|
-
<a href="#-quick-start">Quick Start</a> ·
|
|
22
|
-
<a href="#-features">Features</a> ·
|
|
23
|
-
<a href="#-cli-commands">CLI</a> ·
|
|
24
|
-
<a href="#-board-tui">Board TUI</a> ·
|
|
25
|
-
<a href="#-ai-agent-integration">AI Agents</a> ·
|
|
26
|
-
<a href="#-keyboard-shortcuts">Shortcuts</a> ·
|
|
27
|
-
<a href="#-development">Development</a>
|
|
28
|
-
</p>
|
|
29
|
-
|
|
30
19
|
---
|
|
31
20
|
|
|
32
|
-
##
|
|
33
|
-
|
|
34
|
-
### 1. Install globally
|
|
21
|
+
## Description
|
|
35
22
|
|
|
36
|
-
|
|
37
|
-
npm i -g kandown
|
|
38
|
-
```
|
|
23
|
+
Kandown is a **local-first Kanban board** where your tasks live as plain Markdown files. No cloud, no account, no vendor lock-in — just a `.kandown/` folder in your project that you own forever.
|
|
39
24
|
|
|
40
|
-
|
|
25
|
+
- **Your data is portable** — tasks are `.md` files versioned with git, readable by any text editor or AI agent
|
|
26
|
+
- **AI-agent friendly** — Claude, Codex, Gemini, Goose, Aider, and OpenCode can read and update tasks directly
|
|
27
|
+
- **Dual interface** — a polished web UI + a full terminal TUI, both running entirely offline
|
|
28
|
+
- **Single-file deployment** — `kandown.html` is a self-contained app you can open in any browser
|
|
41
29
|
|
|
42
|
-
|
|
43
|
-
cd my-project
|
|
44
|
-
kandown init
|
|
45
|
-
```
|
|
30
|
+
---
|
|
46
31
|
|
|
47
|
-
|
|
32
|
+
## Installation
|
|
48
33
|
|
|
49
34
|
```bash
|
|
50
|
-
kandown
|
|
35
|
+
npm install -g kandown
|
|
51
36
|
```
|
|
52
37
|
|
|
53
|
-
|
|
38
|
+
**Requirements:** Node.js 18+
|
|
54
39
|
|
|
55
40
|
---
|
|
56
41
|
|
|
57
|
-
##
|
|
42
|
+
## Usage
|
|
58
43
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
| Traditional Kanban | Kandown |
|
|
62
|
-
|---|---|
|
|
63
|
-
| ☁️ Cloud-hosted, needs an account | 📁 100% local, no account |
|
|
64
|
-
| 🔒 Proprietary data format | 📝 Plain Markdown + JSON |
|
|
65
|
-
| 💰 Paid plans for teams | 🆓 Free & open-source (MIT) |
|
|
66
|
-
| 🤖 No AI integration | 🤖 AI-agent native (Claude, Codex, Gemini…) |
|
|
67
|
-
| 🔄 Requires sync/internet | 📂 Git-diffable, offline-first |
|
|
68
|
-
| 🏗️ Backend, database, infra | 🚫 Zero backend, zero dependencies |
|
|
44
|
+
### Initialize in any project
|
|
69
45
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
## 📦 What Gets Installed
|
|
46
|
+
```bash
|
|
47
|
+
cd my-project
|
|
48
|
+
kandown init
|
|
49
|
+
```
|
|
75
50
|
|
|
76
|
-
|
|
51
|
+
This creates a `.kandown/` folder with:
|
|
77
52
|
|
|
78
53
|
```
|
|
79
54
|
.kandown/
|
|
80
|
-
├── kandown.html
|
|
81
|
-
├── kandown.json
|
|
82
|
-
├── tasks/
|
|
83
|
-
|
|
84
|
-
|
|
55
|
+
├── kandown.html # Single-file web app
|
|
56
|
+
├── kandown.json # Project config (columns, appearance)
|
|
57
|
+
├── tasks/ # One .md file per task
|
|
58
|
+
└── AGENT.md # AI-agent quick reference
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Launch the board
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
kandown
|
|
85
65
|
```
|
|
86
66
|
|
|
87
|
-
|
|
67
|
+
This opens:
|
|
68
|
+
- A **web UI** in your browser (board view, list view, task editor)
|
|
69
|
+
- A **terminal TUI** for keyboard-driven workflow (works over SSH, no browser needed)
|
|
70
|
+
|
|
71
|
+
### CLI Commands
|
|
72
|
+
|
|
73
|
+
| Command | Description |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `kandown` | Launch web UI + board TUI |
|
|
76
|
+
| `kandown init` | Initialize in current project |
|
|
77
|
+
| `kandown board` | TUI only (no browser) |
|
|
78
|
+
| `kandown settings` | Terminal settings editor |
|
|
79
|
+
| `kandown update` | Update `kandown.html` to latest |
|
|
80
|
+
| `kandown help` | CLI help |
|
|
88
81
|
|
|
89
82
|
---
|
|
90
83
|
|
|
91
|
-
##
|
|
84
|
+
## Features
|
|
92
85
|
|
|
93
86
|
### Board & Views
|
|
94
87
|
|
|
95
88
|
| Feature | Description |
|
|
96
89
|
|---|---|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
|
|
|
100
|
-
|
|
|
101
|
-
|
|
|
102
|
-
|
|
|
90
|
+
| Board view | Horizontal kanban with drag-and-drop |
|
|
91
|
+
| List view | Dense table with filters & search |
|
|
92
|
+
| Content search | Search titles, body, subtasks, tags, assignee, priority |
|
|
93
|
+
| Command palette | `⌘K` / `Ctrl+K` for quick actions |
|
|
94
|
+
| Custom columns | Add, rename, delete columns freely |
|
|
95
|
+
| Guarded deletion | Double-click to delete — no accidents |
|
|
103
96
|
|
|
104
97
|
### Task Management
|
|
105
98
|
|
|
106
99
|
| Feature | Description |
|
|
107
100
|
|---|---|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
101
|
+
| Rich task drawer | WYSIWYG markdown editor for title, metadata, subtasks, body |
|
|
102
|
+
| Subtasks | Full checklist with progress tracking on cards |
|
|
103
|
+
| Metadata fields | Priority, assignee, tags, due date, owner type |
|
|
104
|
+
| Owner filtering | Filter human vs AI-agent tasks separately |
|
|
105
|
+
| External-change detection | Warns when files are modified outside the app |
|
|
113
106
|
|
|
114
107
|
### Appearance & UX
|
|
115
108
|
|
|
116
109
|
| Feature | Description |
|
|
117
110
|
|---|---|
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
| 📌 Recent projects | Stored in IndexedDB for quick reopening |
|
|
111
|
+
| 5 built-in skins | Kandown, Graphite, Sage, Cobalt, Rose |
|
|
112
|
+
| Theme modes | Auto (system), Light, Dark |
|
|
113
|
+
| 5 font stacks | Inter, System, Serif, Mono, Rounded |
|
|
114
|
+
| Animated backgrounds | WebGL fluid simulation (LiquidEther) |
|
|
115
|
+
| 48 languages | Full i18n support |
|
|
116
|
+
| Notifications | Browser + sound alerts for status changes, edits, completions |
|
|
125
117
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
## 🖥️ CLI Commands
|
|
129
|
-
|
|
130
|
-
### Usage
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
# If installed globally (recommended):
|
|
134
|
-
kandown [command] [options]
|
|
135
|
-
|
|
136
|
-
# Or with npx (no install needed):
|
|
137
|
-
npx kandown [command] [options]
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### Commands
|
|
141
|
-
|
|
142
|
-
| Command | Description |
|
|
143
|
-
|---|---|
|
|
144
|
-
| `kandown` | Launch web UI + board TUI (recommended daily workflow) |
|
|
145
|
-
| `kandown init` | Initialize Kandown in the current project |
|
|
146
|
-
| `kandown board` | Open the board TUI only (no browser) |
|
|
147
|
-
| `kandown settings` | Open the terminal settings editor |
|
|
148
|
-
| `kandown update` | Update `kandown.html` to the latest version |
|
|
149
|
-
| `kandown help` | Print CLI help |
|
|
150
|
-
|
|
151
|
-
### Init Options
|
|
152
|
-
|
|
153
|
-
| Flag | Description |
|
|
154
|
-
|---|---|
|
|
155
|
-
| `--path <dir>` | Install `.kandown` at a custom location |
|
|
156
|
-
| `--force` | Overwrite existing installation |
|
|
157
|
-
| `--no-agents` | Skip AI agent docs setup |
|
|
158
|
-
|
|
159
|
-
### Serve Options
|
|
160
|
-
|
|
161
|
-
| Flag | Description |
|
|
162
|
-
|---|---|
|
|
163
|
-
| `--port <number>` | Use a specific port (default: auto-scan 2048–2060) |
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
## 📟 Board TUI
|
|
168
|
-
|
|
169
|
-
The board TUI is a full-screen terminal kanban built with [Ink](https://github.com/vadimdemedes/ink). Same columns and tasks as the web UI — plus the ability to launch AI agents on any task.
|
|
170
|
-
|
|
171
|
-
```
|
|
172
|
-
KANDOWN tmux My Project
|
|
173
|
-
──────────────────────────────────────────────────────────────
|
|
174
|
-
Backlog (3) │ Todo (2) │ In Progress │ Review (1) │ Done
|
|
175
|
-
──────────────│──────────────│──────────────│────────────│──────
|
|
176
|
-
▸ t9 │ t16 │ (empty) │ t18 │ ...
|
|
177
|
-
t10 │ t7 │ │
|
|
178
|
-
t11 │ │
|
|
179
|
-
```
|
|
118
|
+
### AI Agent Integration
|
|
180
119
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
| Key | Action |
|
|
184
|
-
|---|---|
|
|
185
|
-
| `h` / `l` or `←` / `→` | Move between columns |
|
|
186
|
-
| `j` / `k` or `↑` / `↓` | Move between tasks |
|
|
187
|
-
| `Enter` | Open task detail (scrollable) |
|
|
188
|
-
| `a` | Launch AI agent picker |
|
|
189
|
-
| `r` | Reload files from disk |
|
|
190
|
-
| `q` / `Esc` | Quit or go back |
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## 🤖 AI Agent Integration
|
|
195
|
-
|
|
196
|
-
Press `a` in the board TUI to launch an AI agent on the selected task. Kandown auto-detects installed agents and builds a context-rich prompt from `AGENT_KANDOWN.md` + the task file.
|
|
197
|
-
|
|
198
|
-
### Supported Agents
|
|
120
|
+
Press `a` in the board TUI to launch an AI agent on any task. Supported agents:
|
|
199
121
|
|
|
200
122
|
| Agent | Binary | Launch mode |
|
|
201
123
|
|---|---|---|
|
|
202
|
-
|
|
|
203
|
-
|
|
|
204
|
-
|
|
|
205
|
-
|
|
|
206
|
-
|
|
|
207
|
-
|
|
|
208
|
-
|
|
209
|
-
### How it works
|
|
124
|
+
| Claude Code | `claude` | Interactive session |
|
|
125
|
+
| OpenAI Codex | `codex` | Interactive session |
|
|
126
|
+
| Gemini CLI | `gemini` | `-p` flag for initial prompt |
|
|
127
|
+
| Goose | `goose` | `run --text` for non-interactive |
|
|
128
|
+
| Aider | `aider` | `--message` for initial prompt |
|
|
129
|
+
| OpenCode | `opencode` | TUI, context written to `/tmp` |
|
|
210
130
|
|
|
211
|
-
|
|
212
|
-
2. A system prompt is built from `AGENT_KANDOWN.md` + the task file
|
|
213
|
-
3. Context is written to `/tmp/kandown-<id>-context.md`
|
|
214
|
-
4. **In tmux**: opens in a 50%-wide split pane (TUI stays visible)
|
|
215
|
-
5. **Without tmux**: exits TUI and hands the terminal to the agent
|
|
216
|
-
|
|
217
|
-
> **Tip:** AI agents can also edit task files directly — Kandown detects external changes and syncs automatically.
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## ⌨️ Keyboard Shortcuts
|
|
222
|
-
|
|
223
|
-
### Web UI
|
|
131
|
+
### Keyboard Shortcuts
|
|
224
132
|
|
|
225
133
|
| Shortcut | Action |
|
|
226
134
|
|---|---|
|
|
@@ -231,149 +139,42 @@ Press `a` in the board TUI to launch an AI agent on the selected task. Kandown a
|
|
|
231
139
|
| `R` | Reload from disk |
|
|
232
140
|
| `/` | Focus search |
|
|
233
141
|
| `Esc` | Close drawer / palette |
|
|
234
|
-
| `⌘S` / `Ctrl+S` | Save task
|
|
142
|
+
| `⌘S` / `Ctrl+S` | Save task |
|
|
235
143
|
| `⌘⌫` / `Ctrl+Backspace` | Delete task (with confirmation) |
|
|
236
144
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
## 📄 Data Model
|
|
240
|
-
|
|
241
|
-
### Task files — `tasks/<id>.md`
|
|
145
|
+
### Data Model
|
|
242
146
|
|
|
243
|
-
Each task is a standalone
|
|
147
|
+
Each task is a standalone Markdown file:
|
|
244
148
|
|
|
245
149
|
```markdown
|
|
246
150
|
---
|
|
247
151
|
id: t1
|
|
248
152
|
title: Implement user auth
|
|
249
153
|
status: Todo
|
|
250
|
-
order: 0
|
|
251
154
|
priority: P1
|
|
252
155
|
tags: [backend, security]
|
|
253
156
|
assignee: chacha
|
|
254
157
|
created: 2026-04-10
|
|
255
|
-
ownerType: human
|
|
256
158
|
---
|
|
257
159
|
|
|
258
160
|
# Implement user auth
|
|
259
161
|
|
|
260
162
|
## Context
|
|
261
|
-
Why this task exists
|
|
163
|
+
Why this task exists.
|
|
262
164
|
|
|
263
165
|
## Subtasks
|
|
264
166
|
- [ ] Set up OAuth provider
|
|
265
167
|
- [x] Create user model
|
|
266
168
|
- [ ] Add session middleware
|
|
267
|
-
|
|
268
|
-
## Notes
|
|
269
|
-
Extra details, links, decisions.
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Configuration — `kandown.json`
|
|
273
|
-
|
|
274
|
-
<details>
|
|
275
|
-
<summary>Full default configuration</summary>
|
|
276
|
-
|
|
277
|
-
```json
|
|
278
|
-
{
|
|
279
|
-
"ui": {
|
|
280
|
-
"language": "en",
|
|
281
|
-
"theme": "auto",
|
|
282
|
-
"skin": "kandown",
|
|
283
|
-
"font": "inter"
|
|
284
|
-
},
|
|
285
|
-
"agent": {
|
|
286
|
-
"suggestFollowUp": false,
|
|
287
|
-
"maxSuggestions": 3
|
|
288
|
-
},
|
|
289
|
-
"board": {
|
|
290
|
-
"taskPrefix": "t",
|
|
291
|
-
"defaultPriority": "P3",
|
|
292
|
-
"defaultOwnerType": "human"
|
|
293
|
-
},
|
|
294
|
-
"fields": {
|
|
295
|
-
"priority": false,
|
|
296
|
-
"assignee": false,
|
|
297
|
-
"tags": false,
|
|
298
|
-
"dueDate": false,
|
|
299
|
-
"ownerType": false,
|
|
300
|
-
"tools": false
|
|
301
|
-
},
|
|
302
|
-
"notifications": {
|
|
303
|
-
"browser": false,
|
|
304
|
-
"sound": false,
|
|
305
|
-
"soundId": "soft",
|
|
306
|
-
"statusChanges": true,
|
|
307
|
-
"taskEdits": true,
|
|
308
|
-
"subtaskCompletions": true,
|
|
309
|
-
"editDebounceMs": 2000
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
169
|
```
|
|
313
170
|
|
|
314
|
-
</details>
|
|
315
|
-
|
|
316
|
-
| Section | Key options |
|
|
317
|
-
|---|---|
|
|
318
|
-
| `ui` | Language (48 locales), theme mode, skin, font |
|
|
319
|
-
| `board` | Task ID prefix, default priority/owner |
|
|
320
|
-
| `fields` | Toggle visibility of priority, assignee, tags, due date, owner type |
|
|
321
|
-
| `notifications` | Browser alerts, sound cues, debounce timing |
|
|
322
|
-
|
|
323
|
-
Disabled fields are hidden from cards, list view, the task drawer, and metadata filters.
|
|
324
|
-
|
|
325
|
-
---
|
|
326
|
-
|
|
327
|
-
## 🌐 Browser Support
|
|
328
|
-
|
|
329
|
-
| Browser | Supported |
|
|
330
|
-
|---|---|
|
|
331
|
-
| Chrome | ✅ |
|
|
332
|
-
| Edge | ✅ |
|
|
333
|
-
| Brave | ✅ |
|
|
334
|
-
| Opera | ✅ |
|
|
335
|
-
| Firefox | ❌ (no File System Access API) |
|
|
336
|
-
| Safari | ❌ (no File System Access API) |
|
|
337
|
-
|
|
338
|
-
> **Server mode** (`kandown` CLI command) works in all browsers — it proxies file operations through a local REST API, bypassing the File System Access API requirement.
|
|
339
|
-
|
|
340
171
|
---
|
|
341
172
|
|
|
342
|
-
##
|
|
343
|
-
|
|
344
|
-
### Skins
|
|
345
|
-
|
|
346
|
-
| Skin | Description |
|
|
347
|
-
|---|---|
|
|
348
|
-
| `kandown` | Crisp neutral default |
|
|
349
|
-
| `graphite` | Soft gray surfaces |
|
|
350
|
-
| `sage` | Calm green-gray planning palette |
|
|
351
|
-
| `cobalt` | Cool blue accent, restrained surfaces |
|
|
352
|
-
| `rose` | Warm ink with rose accent |
|
|
353
|
-
|
|
354
|
-
### Theme Modes
|
|
355
|
-
|
|
356
|
-
| Mode | Behavior |
|
|
357
|
-
|---|---|
|
|
358
|
-
| `auto` | Follows system `prefers-color-scheme` |
|
|
359
|
-
| `light` | Force light theme |
|
|
360
|
-
| `dark` | Force dark theme |
|
|
361
|
-
|
|
362
|
-
### Fonts
|
|
363
|
-
|
|
364
|
-
| Font | Stack |
|
|
365
|
-
|---|---|
|
|
366
|
-
| `inter` | Inter-first sans stack |
|
|
367
|
-
| `system` | Native platform sans stack |
|
|
368
|
-
| `serif` | Editorial serif stack |
|
|
369
|
-
| `mono` | Monospace stack |
|
|
370
|
-
| `rounded` | Rounded system stack |
|
|
371
|
-
|
|
372
|
-
---
|
|
173
|
+
## Contributing
|
|
373
174
|
|
|
374
|
-
|
|
175
|
+
Contributions are welcome! Please read the existing code style and conventions before submitting PRs.
|
|
375
176
|
|
|
376
|
-
### Setup
|
|
177
|
+
### Development Setup
|
|
377
178
|
|
|
378
179
|
```bash
|
|
379
180
|
git clone https://github.com/vava-nessa/kandown.git
|
|
@@ -386,107 +187,24 @@ pnpm dev # Web UI at localhost:5173
|
|
|
386
187
|
|
|
387
188
|
| Script | Description |
|
|
388
189
|
|---|---|
|
|
389
|
-
| `pnpm dev` | Vite dev server for
|
|
390
|
-
| `pnpm dev:cli` | Watch-mode build for
|
|
391
|
-
| `pnpm build` | Full build: typecheck → web app → CLI
|
|
392
|
-
| `pnpm build:cli` |
|
|
393
|
-
| `pnpm preview` | Preview
|
|
394
|
-
| `pnpm typecheck` | TypeScript check
|
|
395
|
-
|
|
396
|
-
### Dev Workflow (CLI / TUI)
|
|
397
|
-
|
|
398
|
-
```bash
|
|
399
|
-
# Terminal 1 — watch and rebuild on save
|
|
400
|
-
pnpm dev:cli
|
|
401
|
-
|
|
402
|
-
# Terminal 2 — test the board TUI
|
|
403
|
-
node bin/kandown.js board
|
|
404
|
-
|
|
405
|
-
# Or full experience (web server + browser + TUI):
|
|
406
|
-
node bin/kandown.js --port 3000
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
### Build Output
|
|
410
|
-
|
|
411
|
-
| File | Purpose |
|
|
412
|
-
|---|---|
|
|
413
|
-
| `dist/index.html` | Single-file web app → copied as `kandown.html` |
|
|
414
|
-
| `bin/tui.js` | Bundled Ink TUI → used by `kandown board` and `kandown settings` |
|
|
415
|
-
|
|
416
|
-
---
|
|
417
|
-
|
|
418
|
-
## 🏗️ Architecture
|
|
419
|
-
|
|
420
|
-
<details>
|
|
421
|
-
<summary>Project structure</summary>
|
|
422
|
-
|
|
423
|
-
```
|
|
424
|
-
kandown/
|
|
425
|
-
├── bin/
|
|
426
|
-
│ ├── kandown.js # CLI entrypoint (hand-rolled, no deps)
|
|
427
|
-
│ └── tui.js # Generated TUI bundle (tsup)
|
|
428
|
-
├── src/
|
|
429
|
-
│ ├── App.tsx # Web app shell + global shortcuts
|
|
430
|
-
│ ├── main.tsx # React/Vite browser entrypoint
|
|
431
|
-
│ ├── cli/ # Ink terminal UI source
|
|
432
|
-
│ │ ├── tui.tsx # Ink entrypoint (alternate screen buffer)
|
|
433
|
-
│ │ ├── app.tsx # TUI screen router
|
|
434
|
-
│ │ ├── lib/ # Node-side helpers (config, board, agents, launcher)
|
|
435
|
-
│ │ └── screens/ # board.tsx, agent-picker.tsx, settings.tsx
|
|
436
|
-
│ ├── components/ # React UI components (web)
|
|
437
|
-
│ ├── hooks/ # React hooks
|
|
438
|
-
│ ├── lib/ # Domain model, parser, serializer, store, theme, i18n
|
|
439
|
-
│ └── styles/ # Tailwind layers + CSS tokens
|
|
440
|
-
├── templates/ # Files copied by `kandown init`
|
|
441
|
-
├── dist/index.html # Generated single-file web app
|
|
442
|
-
├── vite.config.ts
|
|
443
|
-
├── tsup.config.ts
|
|
444
|
-
└── package.json
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
</details>
|
|
448
|
-
|
|
449
|
-
<details>
|
|
450
|
-
<summary>Runtime flow</summary>
|
|
451
|
-
|
|
452
|
-
1. `main.tsx` mounts the React app
|
|
453
|
-
2. `App` renders header + board / list / settings / empty state
|
|
454
|
-
3. User selects a folder → File System Access API (or server mode)
|
|
455
|
-
4. `filesystem.ts` resolves `.kandown/`, `tasks/`, `kandown.json`
|
|
456
|
-
5. `store.ts` loads config, applies theme, scans tasks, saves recent project handles
|
|
457
|
-
6. `parser.ts` converts task markdown into typed data
|
|
458
|
-
7. Mutations flow back through store → `serializer.ts` → `filesystem.ts`
|
|
459
|
-
|
|
460
|
-
</details>
|
|
461
|
-
|
|
462
|
-
<details>
|
|
463
|
-
<summary>Key modules</summary>
|
|
464
|
-
|
|
465
|
-
| Module | Role |
|
|
466
|
-
|---|---|
|
|
467
|
-
| `src/lib/store.ts` | Zustand state machine — project loading, board mutations, drawer, search, config |
|
|
468
|
-
| `src/lib/filesystem.ts` | File System Access API + IndexedDB helpers |
|
|
469
|
-
| `src/lib/parser.ts` | Markdown parsing, subtask extraction, content search |
|
|
470
|
-
| `src/lib/serializer.ts` | Markdown serialization |
|
|
471
|
-
| `src/lib/theme.ts` | Theme engine — skins, fonts, CSS variables |
|
|
472
|
-
| `src/lib/watcher.ts` | 500ms polling watcher with SHA-256 hashing for external change detection |
|
|
473
|
-
| `src/lib/i18n/index.ts` | 48-locale translation system |
|
|
474
|
-
|
|
475
|
-
</details>
|
|
190
|
+
| `pnpm dev` | Vite dev server for web UI |
|
|
191
|
+
| `pnpm dev:cli` | Watch-mode build for CLI TUI |
|
|
192
|
+
| `pnpm build` | Full build: typecheck → web app → CLI |
|
|
193
|
+
| `pnpm build:cli` | CLI TUI build only |
|
|
194
|
+
| `pnpm preview` | Preview production build |
|
|
195
|
+
| `pnpm typecheck` | TypeScript check |
|
|
476
196
|
|
|
477
197
|
---
|
|
478
198
|
|
|
479
|
-
##
|
|
199
|
+
## License
|
|
480
200
|
|
|
481
|
-
|
|
482
|
-
- **Markdown is the canonical data format** — always human-readable
|
|
483
|
-
- **Task files are the single source of truth** — no index files to sync
|
|
484
|
-
- **Single-file web app** — `kandown.html` bundles everything
|
|
485
|
-
- **Project config in `kandown.json`** — columns, appearance, fields, notifications
|
|
486
|
-
- **Browser state in IndexedDB** — only for convenience (recent project handles)
|
|
201
|
+
[MIT](LICENSE) — use it, fork it, ship it.
|
|
487
202
|
|
|
488
203
|
---
|
|
489
204
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
205
|
+
<p align="center">
|
|
206
|
+
<a href="#-quick-start">Quick Start</a> ·
|
|
207
|
+
<a href="#-features">Features</a> ·
|
|
208
|
+
<a href="#-cli-commands">CLI</a> ·
|
|
209
|
+
<a href="#-ai-agent-integration">AI Agents</a>
|
|
210
|
+
</p>
|
package/bin/kandown.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* → parseArgs — parses shared CLI flags
|
|
19
19
|
* → cmdInit — installs `.kandown`
|
|
20
20
|
* → cmdUpdate — refreshes installed kandown.html
|
|
21
|
+
* → injectServerRoot — injects the CLI server root into single-file HTML
|
|
21
22
|
* → createServeServer — creates the local zero-dependency HTTP server
|
|
22
23
|
* → cmdServe — opens the web UI over localhost and launches the board TUI
|
|
23
24
|
* → main — dispatches CLI commands
|
|
@@ -333,6 +334,11 @@ function cmdInit(rawArgs) {
|
|
|
333
334
|
const kandownPath = args.path;
|
|
334
335
|
const kandownDir = resolve(cwd, kandownPath);
|
|
335
336
|
|
|
337
|
+
if (existsSync(join(cwd, '.kandown', 'board.md'))) {
|
|
338
|
+
err(`Kandown already initialized in this directory. To reinitialize, remove the .kandown folder first.`);
|
|
339
|
+
process.exit(1);
|
|
340
|
+
}
|
|
341
|
+
|
|
336
342
|
log('');
|
|
337
343
|
info(`Installing kandown in ${c.bold}${kandownPath}/${c.reset}`);
|
|
338
344
|
log('');
|
|
@@ -549,6 +555,22 @@ function deleteTask(res, kandownDir, id) {
|
|
|
549
555
|
}
|
|
550
556
|
}
|
|
551
557
|
|
|
558
|
+
/**
|
|
559
|
+
* 📖 The single-file Vite bundle can contain literal strings such as
|
|
560
|
+
* `</head>` from HTML parser libraries. Use the last closing head tag so the
|
|
561
|
+
* CLI does not inject server-mode globals into bundled JavaScript text.
|
|
562
|
+
*/
|
|
563
|
+
function injectServerRoot(html, kandownDir) {
|
|
564
|
+
const marker = '</head>';
|
|
565
|
+
const markerIndex = html.toLowerCase().lastIndexOf(marker);
|
|
566
|
+
const safeRoot = JSON.stringify(kandownDir).replace(/</g, '\\u003c');
|
|
567
|
+
const script = `<script>window.__KANDOWN_ROOT__ = ${safeRoot};</script>\n`;
|
|
568
|
+
|
|
569
|
+
if (markerIndex === -1) return script + html;
|
|
570
|
+
|
|
571
|
+
return html.slice(0, markerIndex) + script + html.slice(markerIndex);
|
|
572
|
+
}
|
|
573
|
+
|
|
552
574
|
function handleApi(req, res, url, kandownDir) {
|
|
553
575
|
const parts = url.pathname.replace('/api/', '').split('/');
|
|
554
576
|
const resource = parts[0];
|
|
@@ -583,10 +605,7 @@ function serveApp(res, kandownDir) {
|
|
|
583
605
|
|
|
584
606
|
try {
|
|
585
607
|
const html = readFileSync(htmlPath, 'utf8');
|
|
586
|
-
const injected = html
|
|
587
|
-
'</head>',
|
|
588
|
-
`<script>window.__KANDOWN_ROOT__ = ${JSON.stringify(kandownDir)};</script>\n</head>`,
|
|
589
|
-
);
|
|
608
|
+
const injected = injectServerRoot(html, kandownDir);
|
|
590
609
|
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
591
610
|
res.end(injected);
|
|
592
611
|
} catch (e) {
|