kandown 0.3.3 → 0.3.5
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 +324 -427
- package/bin/kandown.js +18 -6
- package/dist/index.html +332 -332
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,226 +1,257 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="logo.svg" width="
|
|
2
|
+
<img src="logo.svg" width="140" height="140" alt="Kandown logo">
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<h1 align="center">Kandown</h1>
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>File-based Kanban board backed by plain Markdown.</strong><br>
|
|
9
|
+
Zero backend · Zero database · No account · AI-agent friendly
|
|
10
|
+
</p>
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
<p align="center">
|
|
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
|
+
<a href="https://www.npmjs.com/package/kandown"><img src="https://img.shields.io/npm/dm/kandown?color=blue" alt="npm downloads"></a>
|
|
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
|
+
<img src="https://img.shields.io/badge/local--first-100%25-orange" alt="100% local-first">
|
|
18
|
+
</p>
|
|
12
19
|
|
|
13
|
-
|
|
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>
|
|
14
29
|
|
|
15
|
-
|
|
30
|
+
---
|
|
16
31
|
|
|
17
|
-
|
|
18
|
-
- `kandown.json` stores project preferences such as board columns, theme mode, skin, font, agent behavior, notifications, and enabled fields.
|
|
32
|
+
## 🚀 Quick Start
|
|
19
33
|
|
|
20
|
-
|
|
34
|
+
### 1. Install globally
|
|
21
35
|
|
|
22
|
-
|
|
36
|
+
```bash
|
|
37
|
+
npm i -g kandown
|
|
38
|
+
```
|
|
23
39
|
|
|
24
|
-
|
|
40
|
+
### 2. Initialize in any project
|
|
25
41
|
|
|
26
42
|
```bash
|
|
27
43
|
cd my-project
|
|
28
|
-
|
|
44
|
+
kandown init
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. Launch your board
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
kandown
|
|
29
51
|
```
|
|
30
52
|
|
|
31
|
-
|
|
53
|
+
> That's it. A local web UI opens in your browser, and an interactive board TUI appears in your terminal. All your data stays in `.kandown/` as plain markdown — versioned with git, readable by humans and AI agents alike.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 💡 Why Kandown?
|
|
58
|
+
|
|
59
|
+
Most kanban tools trap your data in their cloud. Kandown does the opposite.
|
|
32
60
|
|
|
33
|
-
|
|
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 |
|
|
69
|
+
|
|
70
|
+
**Your tasks are just `.md` files.** Move them, `grep` them, edit them in Vim, let an AI agent process them — they're yours.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 📦 What Gets Installed
|
|
75
|
+
|
|
76
|
+
Running `kandown init` creates a `.kandown/` folder in your project:
|
|
77
|
+
|
|
78
|
+
```
|
|
34
79
|
.kandown/
|
|
35
|
-
├── kandown.html
|
|
36
|
-
├── kandown.json
|
|
37
|
-
├── tasks/
|
|
38
|
-
├── AGENT.md
|
|
39
|
-
└── README.md
|
|
80
|
+
├── kandown.html ← Single-file web app (opens in any browser)
|
|
81
|
+
├── kandown.json ← Project preferences, columns, appearance
|
|
82
|
+
├── tasks/ ← One markdown file per task (source of truth)
|
|
83
|
+
├── AGENT.md ← AI-agent quick reference
|
|
84
|
+
└── README.md ← Project-local user guide
|
|
40
85
|
```
|
|
41
86
|
|
|
42
|
-
It also copies `AGENT_KANDOWN.md` to the project root and
|
|
43
|
-
|
|
44
|
-
To use the board:
|
|
45
|
-
|
|
46
|
-
1. Open `.kandown/kandown.html` in Chrome, Edge, Brave, or Opera.
|
|
47
|
-
2. Select the project folder when prompted.
|
|
48
|
-
3. Grant read/write permission.
|
|
49
|
-
|
|
50
|
-
Firefox and Safari do not currently support the required File System Access API.
|
|
51
|
-
|
|
52
|
-
## Features
|
|
53
|
-
|
|
54
|
-
- **File-over-app**: Markdown and JSON are the source of truth.
|
|
55
|
-
- **Zero backend**: No server, database, login, or sync vendor.
|
|
56
|
-
- **AI-agent optimized**: Task files are the single source of truth.
|
|
57
|
-
- **Board and list views**: Toggle with `⌘1` / `⌘2`.
|
|
58
|
-
- **Column status icons**: Board columns use Tabler icons beside titles so states like Backlog, In Progress, Review, and Done are easier to scan.
|
|
59
|
-
- **Column color accents**: Columns can use expanded translucent background colors, including black variants.
|
|
60
|
-
- **Custom columns**: Add, rename, and delete columns from the board; unknown task statuses appear as temporary columns until added to settings.
|
|
61
|
-
- **Drag and drop**: Move cards between columns with optimistic file writes.
|
|
62
|
-
- **Guarded card deletion**: Hover a card and click the trash icon twice to delete a task without opening the drawer.
|
|
63
|
-
- **Task drawer**: Edit title, enabled metadata fields, subtasks, and body content via a WYSIWYG markdown editor (Wysimark).
|
|
64
|
-
- **Content search**: Search titles, ids, task body, subtasks, tags, assignee, and priority with highlighted previews.
|
|
65
|
-
- **Command palette**: `⌘K` / `Ctrl+K` for task search and quick actions.
|
|
66
|
-
- **Owner type filtering**: Separate human tasks from AI-agent tasks.
|
|
67
|
-
- **Dense settings**: Sidebar search, compact setting controls, and hover help explain project options.
|
|
68
|
-
- **Configurable notifications**: Chrome permission, status-change alerts, debounced task-edit alerts, subtask-completion alerts, and in-page sound cues.
|
|
69
|
-
- **External-change detection**: Warns when a task file is modified outside the app and offers Reload / Overwrite / Cancel choices via ConflictModal.
|
|
70
|
-
- **Appearance system**: Project-level `auto` / `light` / `dark`, built-in skins, fonts, animated WebGL backgrounds (LiquidEther fluid simulation), and local font presets.
|
|
71
|
-
- **Recent projects**: Stored in IndexedDB so local handles can be reopened quickly.
|
|
72
|
-
- **i18n**: 48 languages supported.
|
|
73
|
-
- **Single-file publish artifact**: Vite bundles the web UI into `dist/index.html`.
|
|
74
|
-
|
|
75
|
-
## Keyboard Shortcuts
|
|
87
|
+
It also copies `AGENT_KANDOWN.md` to the project root and wires it into your `AGENTS.md` / `CLAUDE.md` so AI agents know how to manage your board automatically.
|
|
76
88
|
|
|
77
|
-
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## ✨ Features
|
|
92
|
+
|
|
93
|
+
### Board & Views
|
|
94
|
+
|
|
95
|
+
| Feature | Description |
|
|
78
96
|
|---|---|
|
|
79
|
-
|
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
| `
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
| `Esc` | Cancel the drawer or close the command palette |
|
|
86
|
-
| `⌘S` / `Ctrl+S` | Save current task in the drawer |
|
|
87
|
-
| `⌘⌫` / `Ctrl+Backspace` | Delete current task in the drawer after confirmation |
|
|
97
|
+
| 🗂️ Board view | Horizontal kanban with drag-and-drop between columns |
|
|
98
|
+
| 📋 List view | Dense table-like view with the same filters & search |
|
|
99
|
+
| 🔍 Content search | Search titles, body, subtasks, tags, assignee, priority — with highlighted previews |
|
|
100
|
+
| ⌨️ Command palette | `⌘K` / `Ctrl+K` for quick actions and task lookup |
|
|
101
|
+
| 🏷️ Custom columns | Add, rename, delete columns — unknown statuses appear as temp columns |
|
|
102
|
+
| 🗑️ Guarded deletion | Double-click the trash icon to delete — no accidental losses |
|
|
88
103
|
|
|
89
|
-
|
|
104
|
+
### Task Management
|
|
105
|
+
|
|
106
|
+
| Feature | Description |
|
|
107
|
+
|---|---|
|
|
108
|
+
| ✏️ Rich task drawer | Edit title, metadata, subtasks, and body via WYSIWYG markdown editor |
|
|
109
|
+
| ☑️ Subtasks | Full checklist support with progress tracking on cards |
|
|
110
|
+
| 📊 Metadata fields | Priority, assignee, tags, due date, owner type — toggle each on/off |
|
|
111
|
+
| 👤 Owner filtering | Separate human tasks from AI-agent tasks |
|
|
112
|
+
| ⚡ External-change detection | Warns when a file was modified outside the app (Reload / Overwrite / Cancel) |
|
|
113
|
+
|
|
114
|
+
### Appearance & UX
|
|
115
|
+
|
|
116
|
+
| Feature | Description |
|
|
117
|
+
|---|---|
|
|
118
|
+
| 🎨 5 built-in skins | Kandown, Graphite, Sage, Cobalt, Rose |
|
|
119
|
+
| 🌗 Theme modes | Auto, Light, Dark |
|
|
120
|
+
| 🔤 5 font stacks | Inter, System, Serif, Mono, Rounded |
|
|
121
|
+
| 🌊 Animated backgrounds | WebGL fluid simulation (LiquidEther) |
|
|
122
|
+
| 🔔 Notifications | Browser + in-page sound alerts for status changes, edits, subtask completions |
|
|
123
|
+
| 🌍 48 languages | Full i18n support |
|
|
124
|
+
| 📌 Recent projects | Stored in IndexedDB for quick reopening |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 🖥️ CLI Commands
|
|
129
|
+
|
|
130
|
+
### Installation
|
|
131
|
+
|
|
132
|
+
**Always install globally first:**
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npm install -g kandown
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Then run from any project directory. Upgrades are automatic — just run `kandown` again.
|
|
139
|
+
|
|
140
|
+
### Usage
|
|
90
141
|
|
|
91
142
|
```bash
|
|
92
|
-
|
|
93
|
-
npx kandown
|
|
94
|
-
npx kandown --port 3000
|
|
95
|
-
|
|
96
|
-
# Board TUI only (no browser)
|
|
97
|
-
npx kandown board
|
|
98
|
-
|
|
99
|
-
# Initialize kandown in the current project
|
|
100
|
-
npx kandown init
|
|
101
|
-
npx kandown init --path docs/tasks
|
|
102
|
-
npx kandown init --no-agents
|
|
103
|
-
npx kandown init --force
|
|
104
|
-
|
|
105
|
-
# Other commands
|
|
106
|
-
npx kandown update
|
|
107
|
-
npx kandown settings
|
|
143
|
+
kandown [command] [options]
|
|
108
144
|
```
|
|
109
145
|
|
|
110
146
|
### Commands
|
|
111
147
|
|
|
112
|
-
| Command |
|
|
148
|
+
| Command | Description |
|
|
113
149
|
|---|---|
|
|
114
|
-
|
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `help` | Print CLI help
|
|
150
|
+
| `kandown` | Launch web UI + board TUI (recommended daily workflow) |
|
|
151
|
+
| `kandown init` | Initialize Kandown in the current project |
|
|
152
|
+
| `kandown board` | Open the board TUI only (no browser) |
|
|
153
|
+
| `kandown settings` | Open the terminal settings editor |
|
|
154
|
+
| `kandown update` | Update `kandown.html` to the latest version |
|
|
155
|
+
| `kandown help` | Print CLI help |
|
|
120
156
|
|
|
121
|
-
|
|
157
|
+
### Init Options
|
|
122
158
|
|
|
123
|
-
|
|
159
|
+
| Flag | Description |
|
|
160
|
+
|---|---|
|
|
161
|
+
| `--path <dir>` | Install `.kandown` at a custom location |
|
|
162
|
+
| `--force` | Overwrite existing installation |
|
|
163
|
+
| `--no-agents` | Skip AI agent docs setup |
|
|
124
164
|
|
|
125
|
-
|
|
165
|
+
### Serve Options
|
|
166
|
+
|
|
167
|
+
| Flag | Description |
|
|
168
|
+
|---|---|
|
|
169
|
+
| `--port <number>` | Use a specific port (default: auto-scan 2048–2060) |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 📟 Board TUI
|
|
174
|
+
|
|
175
|
+
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.
|
|
126
176
|
|
|
127
177
|
```
|
|
128
178
|
KANDOWN tmux My Project
|
|
129
|
-
|
|
179
|
+
──────────────────────────────────────────────────────────────
|
|
130
180
|
Backlog (3) │ Todo (2) │ In Progress │ Review (1) │ Done
|
|
131
181
|
──────────────│──────────────│──────────────│────────────│──────
|
|
132
182
|
▸ t9 │ t16 │ (empty) │ t18 │ ...
|
|
133
|
-
t10 │ t7
|
|
183
|
+
t10 │ t7 │ │
|
|
134
184
|
t11 │ │
|
|
135
185
|
```
|
|
136
186
|
|
|
137
|
-
|
|
187
|
+
### TUI Navigation
|
|
138
188
|
|
|
139
189
|
| Key | Action |
|
|
140
190
|
|---|---|
|
|
141
191
|
| `h` / `l` or `←` / `→` | Move between columns |
|
|
142
|
-
| `j` / `k` or `↑` / `↓` | Move between tasks
|
|
143
|
-
| `Enter` | Open task detail
|
|
144
|
-
| `a` |
|
|
145
|
-
| `r` | Reload
|
|
146
|
-
| `q` / `Esc` | Quit
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
| Agent | Binary | Notes |
|
|
192
|
+
| `j` / `k` or `↑` / `↓` | Move between tasks |
|
|
193
|
+
| `Enter` | Open task detail (scrollable) |
|
|
194
|
+
| `a` | Launch AI agent picker |
|
|
195
|
+
| `r` | Reload files from disk |
|
|
196
|
+
| `q` / `Esc` | Quit or go back |
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 🤖 AI Agent Integration
|
|
201
|
+
|
|
202
|
+
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.
|
|
203
|
+
|
|
204
|
+
### Supported Agents
|
|
205
|
+
|
|
206
|
+
| Agent | Binary | Launch mode |
|
|
158
207
|
|---|---|---|
|
|
159
|
-
| Claude Code | `claude` | Interactive session with initial prompt |
|
|
160
|
-
| OpenAI Codex | `codex` | Interactive session |
|
|
161
|
-
| Gemini CLI | `gemini` | `-p` flag for initial prompt |
|
|
162
|
-
| Goose | `goose` | `run --text` for non-interactive |
|
|
163
|
-
| Aider | `aider` | `--message` for initial prompt |
|
|
164
|
-
| OpenCode | `opencode` | TUI, context written to `/tmp` |
|
|
208
|
+
| **Claude Code** | `claude` | Interactive session with initial prompt |
|
|
209
|
+
| **OpenAI Codex** | `codex` | Interactive session |
|
|
210
|
+
| **Gemini CLI** | `gemini` | `-p` flag for initial prompt |
|
|
211
|
+
| **Goose** | `goose` | `run --text` for non-interactive |
|
|
212
|
+
| **Aider** | `aider` | `--message` for initial prompt |
|
|
213
|
+
| **OpenCode** | `opencode` | TUI, context written to `/tmp` |
|
|
165
214
|
|
|
166
|
-
|
|
215
|
+
### How it works
|
|
167
216
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
├── src/
|
|
174
|
-
│ ├── App.tsx # web app shell and global shortcuts
|
|
175
|
-
│ ├── main.tsx # React/Vite browser entrypoint
|
|
176
|
-
│ ├── cli/ # Ink terminal UI source
|
|
177
|
-
│ │ ├── tui.tsx # Ink entrypoint — alternate screen buffer
|
|
178
|
-
│ │ ├── app.tsx # TUI screen router (board, settings)
|
|
179
|
-
│ │ ├── lib/
|
|
180
|
-
│ │ │ ├── config.ts # kandown.json reader/writer
|
|
181
|
-
│ │ │ ├── board-reader.ts # Node fs task scanner + moveTaskToColumn
|
|
182
|
-
│ │ │ ├── agents.ts # AI agent registry, detection, prompt builder
|
|
183
|
-
│ │ │ └── launcher.ts # Process spawning (tmux / direct exec)
|
|
184
|
-
│ │ └── screens/
|
|
185
|
-
│ │ ├── board.tsx # Interactive kanban board TUI
|
|
186
|
-
│ │ ├── agent-picker.tsx # Agent selection overlay
|
|
187
|
-
│ │ └── settings.tsx # Settings editor TUI
|
|
188
|
-
│ ├── components/ # React UI components (web only)
|
|
189
|
-
│ ├── hooks/ # small React hooks
|
|
190
|
-
│ ├── lib/ # domain model, parser, serializer, store, theme, filesystem
|
|
191
|
-
│ ├── logo.svg
|
|
192
|
-
│ └── styles/ # Tailwind layers and CSS tokens
|
|
193
|
-
├── templates/ # files copied by `kandown init`
|
|
194
|
-
│ ├── AGENT_KANDOWN.md # full agent instructions (copied to project root)
|
|
195
|
-
│ └── AGENT_KANDOWN.md # agent instructions (single source of truth)
|
|
196
|
-
├── dist/index.html # generated single-file web app
|
|
197
|
-
├── tailwind.config.js
|
|
198
|
-
├── vite.config.ts
|
|
199
|
-
├── tsup.config.ts
|
|
200
|
-
└── package.json
|
|
201
|
-
```
|
|
217
|
+
1. Selecting an agent sets the task status to **In Progress**
|
|
218
|
+
2. A system prompt is built from `AGENT_KANDOWN.md` + the task file
|
|
219
|
+
3. Context is written to `/tmp/kandown-<id>-context.md`
|
|
220
|
+
4. **In tmux**: opens in a 50%-wide split pane (TUI stays visible)
|
|
221
|
+
5. **Without tmux**: exits TUI and hands the terminal to the agent
|
|
202
222
|
|
|
203
|
-
|
|
223
|
+
> **Tip:** AI agents can also edit task files directly — Kandown detects external changes and syncs automatically.
|
|
204
224
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## ⌨️ Keyboard Shortcuts
|
|
228
|
+
|
|
229
|
+
### Web UI
|
|
230
|
+
|
|
231
|
+
| Shortcut | Action |
|
|
232
|
+
|---|---|
|
|
233
|
+
| `⌘K` / `Ctrl+K` | Command palette |
|
|
234
|
+
| `⌘1` / `Ctrl+1` | Board view |
|
|
235
|
+
| `⌘2` / `Ctrl+2` | List view |
|
|
236
|
+
| `N` | New task |
|
|
237
|
+
| `R` | Reload from disk |
|
|
238
|
+
| `/` | Focus search |
|
|
239
|
+
| `Esc` | Close drawer / palette |
|
|
240
|
+
| `⌘S` / `Ctrl+S` | Save task in drawer |
|
|
241
|
+
| `⌘⌫` / `Ctrl+Backspace` | Delete task (with confirmation) |
|
|
242
|
+
|
|
243
|
+
---
|
|
213
244
|
|
|
214
|
-
## Data Model
|
|
245
|
+
## 📄 Data Model
|
|
215
246
|
|
|
216
|
-
### `tasks/<id>.md`
|
|
247
|
+
### Task files — `tasks/<id>.md`
|
|
217
248
|
|
|
218
|
-
|
|
249
|
+
Each task is a standalone markdown file with YAML frontmatter:
|
|
219
250
|
|
|
220
251
|
```markdown
|
|
221
252
|
---
|
|
222
253
|
id: t1
|
|
223
|
-
title:
|
|
254
|
+
title: Implement user auth
|
|
224
255
|
status: Todo
|
|
225
256
|
order: 0
|
|
226
257
|
priority: P1
|
|
@@ -230,25 +261,24 @@ created: 2026-04-10
|
|
|
230
261
|
ownerType: human
|
|
231
262
|
---
|
|
232
263
|
|
|
233
|
-
#
|
|
264
|
+
# Implement user auth
|
|
234
265
|
|
|
235
266
|
## Context
|
|
236
|
-
|
|
237
|
-
Why this task exists.
|
|
267
|
+
Why this task exists and what it solves.
|
|
238
268
|
|
|
239
269
|
## Subtasks
|
|
240
|
-
|
|
241
|
-
- [
|
|
242
|
-
- [
|
|
270
|
+
- [ ] Set up OAuth provider
|
|
271
|
+
- [x] Create user model
|
|
272
|
+
- [ ] Add session middleware
|
|
243
273
|
|
|
244
274
|
## Notes
|
|
245
|
-
|
|
246
|
-
Extra details.
|
|
275
|
+
Extra details, links, decisions.
|
|
247
276
|
```
|
|
248
277
|
|
|
249
|
-
### `kandown.json`
|
|
278
|
+
### Configuration — `kandown.json`
|
|
250
279
|
|
|
251
|
-
|
|
280
|
+
<details>
|
|
281
|
+
<summary>Full default configuration</summary>
|
|
252
282
|
|
|
253
283
|
```json
|
|
254
284
|
{
|
|
@@ -287,315 +317,182 @@ Project-level preferences:
|
|
|
287
317
|
}
|
|
288
318
|
```
|
|
289
319
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
Notifications are driven by a 500ms polling file watcher that computes SHA-256 hashes of task file content to detect external changes. Status changes fire when task frontmatter `status` changes, task edit notifications fire after `notifications.editDebounceMs` with a minimum 2 second delay, and subtask completion notifications fire when a checklist item flips from open to done. Browser notifications require Chrome permission; sound notifications play inside the open board tab.
|
|
293
|
-
|
|
294
|
-
## Appearance Architecture
|
|
295
|
-
|
|
296
|
-
Kandown uses shadcn-compatible CSS variables without depending on shadcn components. The app keeps its own source components, while Tailwind aliases point at token variables.
|
|
297
|
-
|
|
298
|
-
Important pieces:
|
|
299
|
-
|
|
300
|
-
- `src/lib/theme.ts` defines skin ids, font ids, token maps, validators, and `applyProjectTheme`.
|
|
301
|
-
- `tailwind.config.js` maps `background`, `foreground`, `card`, `primary`, `secondary`, `muted`, `accent`, `destructive`, plus legacy aliases like `bg`, `fg`, and `border`.
|
|
302
|
-
- `src/styles/globals.css` provides default CSS variables and shared component classes.
|
|
303
|
-
- `src/components/SettingsPage.tsx` exposes mode, skin, and font controls per project.
|
|
304
|
-
- `src/components/LiquidEther.tsx` provides an animated WebGL fluid simulation background (GPU-accelerated, available as a background option in appearance settings).
|
|
320
|
+
</details>
|
|
305
321
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
| Value | Behavior |
|
|
322
|
+
| Section | Key options |
|
|
309
323
|
|---|---|
|
|
310
|
-
| `
|
|
311
|
-
| `
|
|
312
|
-
| `
|
|
313
|
-
|
|
314
|
-
Built-in skins:
|
|
324
|
+
| `ui` | Language (48 locales), theme mode, skin, font |
|
|
325
|
+
| `board` | Task ID prefix, default priority/owner |
|
|
326
|
+
| `fields` | Toggle visibility of priority, assignee, tags, due date, owner type |
|
|
327
|
+
| `notifications` | Browser alerts, sound cues, debounce timing |
|
|
315
328
|
|
|
316
|
-
|
|
317
|
-
|---|---|
|
|
318
|
-
| `kandown` | Crisp neutral default, close to the original UI. |
|
|
319
|
-
| `graphite` | Soft gray surfaces. |
|
|
320
|
-
| `sage` | Calm green-gray planning palette. |
|
|
321
|
-
| `cobalt` | Cool blue accent, restrained surfaces. |
|
|
322
|
-
| `rose` | Warm ink with a restrained rose accent. |
|
|
329
|
+
Disabled fields are hidden from cards, list view, the task drawer, and metadata filters.
|
|
323
330
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
| Font | Stack |
|
|
327
|
-
|---|---|
|
|
328
|
-
| `inter` | Inter-first sans stack. |
|
|
329
|
-
| `system` | Native platform sans stack. |
|
|
330
|
-
| `serif` | Editorial serif stack. |
|
|
331
|
-
| `mono` | Monospace stack. |
|
|
332
|
-
| `rounded` | Rounded system stack. |
|
|
333
|
-
|
|
334
|
-
## Web Modules
|
|
331
|
+
---
|
|
335
332
|
|
|
336
|
-
|
|
333
|
+
## 🌐 Browser Support
|
|
337
334
|
|
|
338
|
-
|
|
|
335
|
+
| Browser | Supported |
|
|
339
336
|
|---|---|
|
|
340
|
-
|
|
|
341
|
-
|
|
|
337
|
+
| Chrome | ✅ |
|
|
338
|
+
| Edge | ✅ |
|
|
339
|
+
| Brave | ✅ |
|
|
340
|
+
| Opera | ✅ |
|
|
341
|
+
| Firefox | ❌ (no File System Access API) |
|
|
342
|
+
| Safari | ❌ (no File System Access API) |
|
|
342
343
|
|
|
343
|
-
|
|
344
|
+
> **Server mode** (run `kandown` from the CLI, no browser install needed) works in all browsers — it proxies file operations through a local REST API, bypassing the File System Access API requirement.
|
|
344
345
|
|
|
345
|
-
|
|
346
|
-
|---|---|---|
|
|
347
|
-
| `Board.tsx` | `Board` | Horizontal kanban view, filtering, drag state, search-match forwarding. |
|
|
348
|
-
| `Column.tsx` | `Column` | One kanban column, Tabler status icon, drop target, create-task button, empty state. |
|
|
349
|
-
| `Card.tsx` | `Card` | Task card with progress, metadata, guarded hover deletion, drag handlers, and search previews. |
|
|
350
|
-
| `ListView.tsx` | `ListView` | Dense table-like view sharing the same filters/search cache as board view. |
|
|
351
|
-
| `Drawer.tsx` | `Drawer` | Task detail editor for title, enabled frontmatter metadata, subtasks, and body content. |
|
|
352
|
-
| `MarkdownEditor.tsx` | `MarkdownEditor` | WYSIWYG markdown body editor (Wysimark) for task body content. |
|
|
353
|
-
| `SubtaskItem.tsx` | `SubtaskItem` | Editable markdown checklist row. |
|
|
354
|
-
| `FilterBar.tsx` | `FilterBar` | Search input, owner filter, active chips, clear action. |
|
|
355
|
-
| `CommandPalette.tsx` | `CommandPalette` | Quick actions, task lookup, content search, keyboard navigation. |
|
|
356
|
-
| `SettingsPage.tsx` | `SettingsPage` | Dense project settings with sidebar search, compact controls, and contextual hover help. |
|
|
357
|
-
| `Header.tsx` | `Header` | Project switcher, view controls, settings link, reload, new task. |
|
|
358
|
-
| `EmptyState.tsx` | `EmptyState` | First-run folder picker and recent projects. |
|
|
359
|
-
| `Toaster.tsx` | `Toaster` | Animated notification stack. |
|
|
360
|
-
| `Icons.tsx` | `Icon` | Local SVG icon set for app chrome; board column status glyphs use `@tabler/icons-react`. |
|
|
361
|
-
| `ConflictModal.tsx` | `ConflictModal` | Warns when a task file was modified externally; offers Reload / Overwrite / Cancel. |
|
|
362
|
-
| `LiquidEther.tsx` | `LiquidEther` | WebGL fluid simulation background (animated, GPU-accelerated). |
|
|
363
|
-
|
|
364
|
-
### Store And Domain Logic
|
|
365
|
-
|
|
366
|
-
| File | Main exports | Description |
|
|
367
|
-
|---|---|---|
|
|
368
|
-
| `src/lib/types.ts` | `DEFAULT_CONFIG`, domain types | Shared TypeScript contracts for board, tasks, config, filters, search, and appearance. |
|
|
369
|
-
| `src/lib/store.ts` | `useStore` | Zustand state machine for project loading, board mutations, drawer editing, search cache, config, and toasts. |
|
|
370
|
-
| `src/lib/filesystem.ts` | File and IndexedDB helpers | Browser File System Access API and recent-project persistence. |
|
|
371
|
-
| `src/lib/parser.ts` | Markdown parsers/search | Parses board/task markdown, extracts/reinjects subtasks, and searches cached task content. |
|
|
372
|
-
| `src/lib/serializer.ts` | Markdown writers | Serializes board and task data back to markdown. |
|
|
373
|
-
| `src/lib/theme.ts` | Theme engine | Applies project-level light/dark tokens, skins, and font stacks. |
|
|
374
|
-
| `src/lib/i18n/index.ts` | i18n setup | 48-locale translation system with per-project language preference. |
|
|
375
|
-
| `src/lib/watcher.ts` | File watcher | 500ms polling watcher with SHA-256 content hashing to detect external file changes and drive reloads/notifications. |
|
|
376
|
-
| `src/hooks/useAnimatedNumber.ts` | `useAnimatedNumber` | Spring-animated numeric display for task counts. |
|
|
346
|
+
---
|
|
377
347
|
|
|
378
|
-
##
|
|
348
|
+
## 🎨 Appearance
|
|
379
349
|
|
|
380
|
-
###
|
|
350
|
+
### Skins
|
|
381
351
|
|
|
382
|
-
|
|
|
383
|
-
|---|---|
|
|
384
|
-
| `openFolder` | Prompts for a project folder, resolves `.kandown`, saves recent project, loads config and board. |
|
|
385
|
-
| `openRecentProject` | Reopens an IndexedDB-stored project handle after permission verification. |
|
|
386
|
-
| `loadConfig` | Reads `kandown.json`, merges defaults, applies theme tokens. |
|
|
387
|
-
| `updateConfig` | Optimistically updates config, applies appearance immediately, writes `kandown.json`. |
|
|
388
|
-
| `reloadBoard` | Scans task files, derives columns from task statuses, and eagerly loads task content for small boards. |
|
|
389
|
-
| `moveTask` | Optimistically moves a task between columns and writes task frontmatter `status` / `order`, rolling back on failure. |
|
|
390
|
-
| `reorderInColumn` | Reorders tasks within one column by writing task frontmatter `order`. |
|
|
391
|
-
| `addColumn` / `renameColumn` / `deleteColumn` | Manage `board.columns` in config and update affected task files. |
|
|
392
|
-
| `createTask` | Creates a task markdown file with initial frontmatter. |
|
|
393
|
-
| `deleteTask` | Deletes the task file and clears cached content/search matches. |
|
|
394
|
-
| `openDrawer` | Reads one task detail file and prepares editable drawer state. |
|
|
395
|
-
| `saveDrawer` | Writes full task detail content and closes the drawer. |
|
|
396
|
-
| `saveDrawerMetadata` | Autosaves task detail content and reloads derived board metadata/progress. |
|
|
397
|
-
| `setFilter` | Updates filters and lazily loads task contents for search queries. |
|
|
398
|
-
| `loadTaskContents` | Reads task files into the content-search cache. |
|
|
399
|
-
| `computeSearchMatches` | Produces per-task search matches for board/list previews. |
|
|
400
|
-
| `toast` | Adds transient UI messages. |
|
|
401
|
-
|
|
402
|
-
### `src/lib/notifications.ts`
|
|
403
|
-
|
|
404
|
-
| Function | Description |
|
|
352
|
+
| Skin | Description |
|
|
405
353
|
|---|---|
|
|
406
|
-
| `
|
|
407
|
-
| `
|
|
408
|
-
| `
|
|
409
|
-
| `
|
|
354
|
+
| `kandown` | Crisp neutral default |
|
|
355
|
+
| `graphite` | Soft gray surfaces |
|
|
356
|
+
| `sage` | Calm green-gray planning palette |
|
|
357
|
+
| `cobalt` | Cool blue accent, restrained surfaces |
|
|
358
|
+
| `rose` | Warm ink with rose accent |
|
|
410
359
|
|
|
411
|
-
###
|
|
360
|
+
### Theme Modes
|
|
412
361
|
|
|
413
|
-
|
|
|
362
|
+
| Mode | Behavior |
|
|
414
363
|
|---|---|
|
|
415
|
-
| `
|
|
416
|
-
| `
|
|
417
|
-
| `
|
|
418
|
-
| `buildColumnsFromTasks` | Groups parsed task files into configured and temporary columns. |
|
|
419
|
-
| `extractSubtasks` | Pulls markdown checklist lines out of a subtask section. |
|
|
420
|
-
| `injectSubtasks` | Writes edited subtasks back into a task body. |
|
|
421
|
-
| `searchTaskContent` | Searches title, subtasks, body, tags, assignee, and priority with contextual snippets. |
|
|
364
|
+
| `auto` | Follows system `prefers-color-scheme` |
|
|
365
|
+
| `light` | Force light theme |
|
|
366
|
+
| `dark` | Force dark theme |
|
|
422
367
|
|
|
423
|
-
###
|
|
368
|
+
### Fonts
|
|
424
369
|
|
|
425
|
-
|
|
|
426
|
-
|---|---|
|
|
427
|
-
| `supportsFileSystemAccess` | Detects required browser API support. |
|
|
428
|
-
| `pickProjectDirectory` | Prompts for a project folder and opens or creates `.kandown`. |
|
|
429
|
-
| `getKandownHandle` | Resolves `.kandown` from a remembered project directory handle. |
|
|
430
|
-
| `ensureTasksDir` | Ensures `.kandown/tasks` exists. |
|
|
431
|
-
| `readConfigFile` / `writeConfigFile` | Load and save `kandown.json`. |
|
|
432
|
-
| `listTaskIds` | Scans `.kandown/tasks/*.md` and returns task IDs. |
|
|
433
|
-
| `readTaskFile` / `writeTaskFile` / `deleteTaskFile` | Manage per-task markdown files. |
|
|
434
|
-
| `saveRecentProject` / `listRecentProjects` / `removeRecentProject` | Manage recent project handles in IndexedDB. |
|
|
435
|
-
| `verifyPermission` | Requests read/write permission for a stored handle. |
|
|
436
|
-
|
|
437
|
-
### `src/lib/theme.ts`
|
|
438
|
-
|
|
439
|
-
| Function | Description |
|
|
370
|
+
| Font | Stack |
|
|
440
371
|
|---|---|
|
|
441
|
-
| `
|
|
442
|
-
| `
|
|
443
|
-
| `
|
|
444
|
-
| `
|
|
372
|
+
| `inter` | Inter-first sans stack |
|
|
373
|
+
| `system` | Native platform sans stack |
|
|
374
|
+
| `serif` | Editorial serif stack |
|
|
375
|
+
| `mono` | Monospace stack |
|
|
376
|
+
| `rounded` | Rounded system stack |
|
|
445
377
|
|
|
446
|
-
|
|
378
|
+
---
|
|
447
379
|
|
|
448
|
-
|
|
380
|
+
## 🛠️ Development
|
|
449
381
|
|
|
450
|
-
|
|
451
|
-
|---|---|
|
|
452
|
-
| `help` | Prints usage and commands. |
|
|
453
|
-
| `openInBrowser` | Opens `kandown.html` non-blocking in the system default browser. |
|
|
454
|
-
| `findKandownDir` | Locates `.kandown/` walking up from cwd. |
|
|
455
|
-
| `copyRecursive` | Copies template directories into `.kandown`. |
|
|
456
|
-
| `findAgentsFile` | Detects existing AI-agent instruction files. |
|
|
457
|
-
| `appendAgentReference` | Adds a Kandown task-management section to an existing agent file. |
|
|
458
|
-
| `createAgentsFileIfMissing` | Creates `AGENTS.md` when no agent instructions exist. |
|
|
459
|
-
| `parseArgs` | Parses shared CLI flags such as `--path`, `--force`, and `--port`. |
|
|
460
|
-
| `cmdInit` | Installs `.kandown`, templates, config, web app, and agent docs. |
|
|
461
|
-
| `cmdUpdate` | Updates `kandown.html` from `dist/index.html`. |
|
|
462
|
-
| `createServeServer` | Creates the local HTTP server for the web UI, including placeholder `/api/*` routing. |
|
|
463
|
-
| `cmdServe` | Serves `kandown.html` over localhost, injects `window.__KANDOWN_ROOT__`, opens the browser, and launches the board TUI. |
|
|
464
|
-
| `cmdTui` | Launches a named TUI screen (`board`, `settings`). |
|
|
465
|
-
|
|
466
|
-
The terminal UI source lives under `src/cli/` and is bundled into `bin/tui.js` by `tsup`.
|
|
467
|
-
|
|
468
|
-
| File | Description |
|
|
469
|
-
|---|---|
|
|
470
|
-
| `src/cli/tui.tsx` | Ink entrypoint — alternate screen buffer, renders the `App` shell. |
|
|
471
|
-
| `src/cli/app.tsx` | TUI screen router (`board`, `settings`). |
|
|
472
|
-
| `src/cli/lib/config.ts` | Node-side `kandown.json` reader/writer with dot-path accessors. |
|
|
473
|
-
| `src/cli/lib/board-reader.ts` | Node fs wrapper around task scanning: `readBoard`, `readTask`, `readAgentDoc`, `moveTaskToColumn`. |
|
|
474
|
-
| `src/cli/lib/agents.ts` | Agent registry (claude, codex, gemini, goose, aider, opencode), detection via `which`, `buildPrompt`. |
|
|
475
|
-
| `src/cli/lib/launcher.ts` | Process spawning: tmux split-pane or direct exec, auto-moves task to In Progress. |
|
|
476
|
-
| `src/cli/screens/board.tsx` | Interactive kanban board TUI — column navigation, task detail, agent picker integration. |
|
|
477
|
-
| `src/cli/screens/agent-picker.tsx` | Agent selection overlay component. |
|
|
478
|
-
| `src/cli/screens/settings.tsx` | Terminal settings editor for `kandown.json`. |
|
|
479
|
-
|
|
480
|
-
## Development
|
|
382
|
+
### Setup
|
|
481
383
|
|
|
482
384
|
```bash
|
|
385
|
+
git clone https://github.com/vava-nessa/kandown.git
|
|
386
|
+
cd kandown
|
|
483
387
|
pnpm install
|
|
484
|
-
pnpm dev
|
|
485
|
-
pnpm build # full build: web + CLI
|
|
388
|
+
pnpm dev # Web UI at localhost:5173
|
|
486
389
|
```
|
|
487
390
|
|
|
488
391
|
### Scripts
|
|
489
392
|
|
|
490
393
|
| Script | Description |
|
|
491
394
|
|---|---|
|
|
492
|
-
| `pnpm dev` |
|
|
493
|
-
| `pnpm dev:cli` | Watch-mode build for the CLI TUI
|
|
494
|
-
| `pnpm build` | Full build: typecheck →
|
|
495
|
-
| `pnpm build:cli` |
|
|
496
|
-
| `pnpm preview` | Preview the Vite production build
|
|
497
|
-
| `pnpm typecheck` |
|
|
395
|
+
| `pnpm dev` | Vite dev server for the web UI |
|
|
396
|
+
| `pnpm dev:cli` | Watch-mode build for the CLI TUI |
|
|
397
|
+
| `pnpm build` | Full build: typecheck → web app → CLI TUI |
|
|
398
|
+
| `pnpm build:cli` | One-shot CLI TUI build |
|
|
399
|
+
| `pnpm preview` | Preview the Vite production build |
|
|
400
|
+
| `pnpm typecheck` | TypeScript check without emitting |
|
|
498
401
|
|
|
499
|
-
###
|
|
402
|
+
### Dev Workflow (CLI / TUI)
|
|
500
403
|
|
|
501
404
|
```bash
|
|
502
|
-
|
|
503
|
-
# → open http://localhost:5173
|
|
504
|
-
# → select any folder that has a .kandown/ directory when prompted
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
Hot-reload is fully supported. Changes to `src/` reflect immediately in the browser.
|
|
508
|
-
|
|
509
|
-
### Developing the CLI / Board TUI
|
|
510
|
-
|
|
511
|
-
The CLI TUI is built with [Ink](https://github.com/vadimdemedes/ink) (React for terminals) and bundled by `tsup`.
|
|
512
|
-
|
|
513
|
-
**Recommended dev workflow** — two terminals:
|
|
514
|
-
|
|
515
|
-
```bash
|
|
516
|
-
# Terminal 1: watch-rebuild on every save
|
|
405
|
+
# Terminal 1 — watch and rebuild on save
|
|
517
406
|
pnpm dev:cli
|
|
518
407
|
|
|
519
|
-
# Terminal 2
|
|
408
|
+
# Terminal 2 — test the board TUI
|
|
520
409
|
node bin/kandown.js board
|
|
521
410
|
|
|
522
|
-
# Or
|
|
523
|
-
node bin/kandown.js
|
|
524
|
-
|
|
525
|
-
# Use a fixed local web UI port:
|
|
411
|
+
# Or full experience (web server + browser + TUI):
|
|
526
412
|
node bin/kandown.js --port 3000
|
|
527
413
|
```
|
|
528
414
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
**Testing a specific screen:**
|
|
532
|
-
|
|
533
|
-
```bash
|
|
534
|
-
# Board TUI (new)
|
|
535
|
-
node bin/kandown.js board
|
|
536
|
-
|
|
537
|
-
# Settings TUI
|
|
538
|
-
node bin/kandown.js settings
|
|
415
|
+
### Build Output
|
|
539
416
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
```
|
|
417
|
+
| File | Purpose |
|
|
418
|
+
|---|---|
|
|
419
|
+
| `dist/index.html` | Single-file web app → copied as `kandown.html` |
|
|
420
|
+
| `bin/tui.js` | Bundled Ink TUI → used by `kandown board` and `kandown settings` |
|
|
545
421
|
|
|
546
|
-
|
|
422
|
+
---
|
|
547
423
|
|
|
548
|
-
|
|
424
|
+
## 🏗️ Architecture
|
|
549
425
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
tmux new-session -s dev
|
|
426
|
+
<details>
|
|
427
|
+
<summary>Project structure</summary>
|
|
553
428
|
|
|
554
|
-
|
|
555
|
-
|
|
429
|
+
```
|
|
430
|
+
kandown/
|
|
431
|
+
├── bin/
|
|
432
|
+
│ ├── kandown.js # CLI entrypoint (hand-rolled, no deps)
|
|
433
|
+
│ └── tui.js # Generated TUI bundle (tsup)
|
|
434
|
+
├── src/
|
|
435
|
+
│ ├── App.tsx # Web app shell + global shortcuts
|
|
436
|
+
│ ├── main.tsx # React/Vite browser entrypoint
|
|
437
|
+
│ ├── cli/ # Ink terminal UI source
|
|
438
|
+
│ │ ├── tui.tsx # Ink entrypoint (alternate screen buffer)
|
|
439
|
+
│ │ ├── app.tsx # TUI screen router
|
|
440
|
+
│ │ ├── lib/ # Node-side helpers (config, board, agents, launcher)
|
|
441
|
+
│ │ └── screens/ # board.tsx, agent-picker.tsx, settings.tsx
|
|
442
|
+
│ ├── components/ # React UI components (web)
|
|
443
|
+
│ ├── hooks/ # React hooks
|
|
444
|
+
│ ├── lib/ # Domain model, parser, serializer, store, theme, i18n
|
|
445
|
+
│ └── styles/ # Tailwind layers + CSS tokens
|
|
446
|
+
├── templates/ # Files copied by `kandown init`
|
|
447
|
+
├── dist/index.html # Generated single-file web app
|
|
448
|
+
├── vite.config.ts
|
|
449
|
+
├── tsup.config.ts
|
|
450
|
+
└── package.json
|
|
556
451
|
```
|
|
557
452
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
`pnpm build` regenerates:
|
|
561
|
-
|
|
562
|
-
- `dist/index.html` — single-file web app, copied into target projects as `kandown.html`.
|
|
563
|
-
- `bin/tui.js` — bundled Ink TUI, used by `kandown board` and `kandown settings`.
|
|
453
|
+
</details>
|
|
564
454
|
|
|
565
|
-
|
|
455
|
+
<details>
|
|
456
|
+
<summary>Runtime flow</summary>
|
|
566
457
|
|
|
567
|
-
|
|
458
|
+
1. `main.tsx` mounts the React app
|
|
459
|
+
2. `App` renders header + board / list / settings / empty state
|
|
460
|
+
3. User selects a folder → File System Access API (or server mode)
|
|
461
|
+
4. `filesystem.ts` resolves `.kandown/`, `tasks/`, `kandown.json`
|
|
462
|
+
5. `store.ts` loads config, applies theme, scans tasks, saves recent project handles
|
|
463
|
+
6. `parser.ts` converts task markdown into typed data
|
|
464
|
+
7. Mutations flow back through store → `serializer.ts` → `filesystem.ts`
|
|
568
465
|
|
|
569
|
-
|
|
466
|
+
</details>
|
|
570
467
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
- Brave
|
|
574
|
-
- Opera
|
|
468
|
+
<details>
|
|
469
|
+
<summary>Key modules</summary>
|
|
575
470
|
|
|
576
|
-
|
|
471
|
+
| Module | Role |
|
|
472
|
+
|---|---|
|
|
473
|
+
| `src/lib/store.ts` | Zustand state machine — project loading, board mutations, drawer, search, config |
|
|
474
|
+
| `src/lib/filesystem.ts` | File System Access API + IndexedDB helpers |
|
|
475
|
+
| `src/lib/parser.ts` | Markdown parsing, subtask extraction, content search |
|
|
476
|
+
| `src/lib/serializer.ts` | Markdown serialization |
|
|
477
|
+
| `src/lib/theme.ts` | Theme engine — skins, fonts, CSS variables |
|
|
478
|
+
| `src/lib/watcher.ts` | 500ms polling watcher with SHA-256 hashing for external change detection |
|
|
479
|
+
| `src/lib/i18n/index.ts` | 48-locale translation system |
|
|
577
480
|
|
|
578
|
-
|
|
579
|
-
- Safari
|
|
481
|
+
</details>
|
|
580
482
|
|
|
581
|
-
|
|
483
|
+
---
|
|
582
484
|
|
|
583
|
-
|
|
584
|
-
- Markdown stays the canonical data format.
|
|
585
|
-
- Task files are the canonical source of truth.
|
|
586
|
-
- Board columns belong in `kandown.json`.
|
|
587
|
-
- UI state that is project-specific belongs in `kandown.json`.
|
|
588
|
-
- Browser-only convenience state, such as recent handles, can live in IndexedDB.
|
|
589
|
-
- The installed web app should remain a single file.
|
|
485
|
+
## 📐 Design Constraints
|
|
590
486
|
|
|
591
|
-
|
|
487
|
+
- **Local-first, backend-free** — no servers, no sync vendors
|
|
488
|
+
- **Markdown is the canonical data format** — always human-readable
|
|
489
|
+
- **Task files are the single source of truth** — no index files to sync
|
|
490
|
+
- **Single-file web app** — `kandown.html` bundles everything
|
|
491
|
+
- **Project config in `kandown.json`** — columns, appearance, fields, notifications
|
|
492
|
+
- **Browser state in IndexedDB** — only for convenience (recent project handles)
|
|
592
493
|
|
|
593
|
-
|
|
594
|
-
pnpm build
|
|
595
|
-
npm login
|
|
596
|
-
npm publish --access public
|
|
597
|
-
```
|
|
494
|
+
---
|
|
598
495
|
|
|
599
|
-
## License
|
|
496
|
+
## 📜 License
|
|
600
497
|
|
|
601
|
-
MIT
|
|
498
|
+
[MIT](LICENSE) — use it, fork it, ship it.
|