local-kanban 1.6.3

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.
Files changed (64) hide show
  1. package/CHANGELOG.md +381 -0
  2. package/LICENSE +21 -0
  3. package/README.md +144 -0
  4. package/README.ru.md +144 -0
  5. package/bin/kb +306 -0
  6. package/bin/local-kanban +217 -0
  7. package/ecosystem.example.cjs +25 -0
  8. package/package.json +52 -0
  9. package/public/app.js +18 -0
  10. package/public/boot-fallback.js +3 -0
  11. package/public/drawer-sync.js +14 -0
  12. package/public/favicon-180.png +0 -0
  13. package/public/favicon-32.png +0 -0
  14. package/public/favicon-64.png +0 -0
  15. package/public/favicon.ico +0 -0
  16. package/public/favicon.svg +6 -0
  17. package/public/icon-192.png +0 -0
  18. package/public/icon-512.png +0 -0
  19. package/public/icon-maskable-192.png +0 -0
  20. package/public/icon-maskable-512.png +0 -0
  21. package/public/index.html +138 -0
  22. package/public/js/board.js +698 -0
  23. package/public/js/chaos.js +247 -0
  24. package/public/js/core.js +821 -0
  25. package/public/js/dash.js +114 -0
  26. package/public/js/drawer.js +919 -0
  27. package/public/js/horizon.js +140 -0
  28. package/public/js/init.js +208 -0
  29. package/public/js/project.js +338 -0
  30. package/public/js/settings.js +905 -0
  31. package/public/js/sidebar.js +640 -0
  32. package/public/js/sse.js +386 -0
  33. package/public/manifest.webmanifest +32 -0
  34. package/public/offline.html +39 -0
  35. package/public/style.css +1247 -0
  36. package/public/sw.js +31 -0
  37. package/scripts/raycast/open-kanban.sh +18 -0
  38. package/scripts/update.js +43 -0
  39. package/skills/deploy/SKILL.md +70 -0
  40. package/skills/kanban/SKILL.md +217 -0
  41. package/src/backup.js +111 -0
  42. package/src/bus.js +10 -0
  43. package/src/config.js +40 -0
  44. package/src/db.js +321 -0
  45. package/src/error-handler.js +11 -0
  46. package/src/file-snapshot.js +22 -0
  47. package/src/origin-guard.js +32 -0
  48. package/src/pm2-services.js +31 -0
  49. package/src/query-params.js +17 -0
  50. package/src/repo-base.js +23 -0
  51. package/src/restore.js +153 -0
  52. package/src/routes/dashboard.js +132 -0
  53. package/src/routes/events.js +30 -0
  54. package/src/routes/horizons.js +66 -0
  55. package/src/routes/projects.js +532 -0
  56. package/src/routes/skills.js +116 -0
  57. package/src/routes/system.js +285 -0
  58. package/src/routes/tasks.js +477 -0
  59. package/src/schema.sql +135 -0
  60. package/src/server.js +100 -0
  61. package/src/skills.js +119 -0
  62. package/src/sync/github.js +265 -0
  63. package/src/sync/worker.js +136 -0
  64. package/src/task-shape.js +29 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,381 @@
1
+ # Changelog
2
+
3
+ Notable changes, newest first. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
4
+ and the project uses [semantic versioning](https://semver.org/).
5
+
6
+ ## [1.6.3]
7
+
8
+ ### Changed
9
+
10
+ - **A commercial invoice is asked for by email now, not through a public issue.** Wanting to pay
11
+ for something you use at work is not a thing anyone should have to announce in public, and the
12
+ first line of an invoice request is the company name. `docs/COMMERCIAL.md` names an address
13
+ instead, and asks for the two things an invoice needs: the country and how many people use the
14
+ board.
15
+
16
+ ### Fixed
17
+
18
+ - **The install section described a question the wizard never asks.** It said the wizard asks
19
+ *where* to put the Claude Code skills. There is no choice of place — the path is
20
+ `~/.claude/skills` — and the question is whether to install them at all; it installs two, the
21
+ board's own skill and the deploy one. Both READMEs now describe what the program actually does.
22
+
23
+ ## [1.6.2]
24
+
25
+ ### Added
26
+
27
+ - **A quiet ask for companies that use the board at work.** It stays MIT-licensed and free for
28
+ everyone — nothing is switched off, nothing to activate, and it still never contacts a server —
29
+ but if the board earns you money, $12 a year per person keeps it maintained. The ask is one line
30
+ in the README and one row in Settings → About, both pointing at `docs/COMMERCIAL.md`, which spells
31
+ out what this is and, just as plainly, what it is not: not a licence purchase, not a support
32
+ contract, and not a subscription that switches anything off when it lapses.
33
+
34
+ ### Fixed
35
+
36
+ - **The bulk-registration script sent you to a file that does not exist.** `contrib/bootstrap.js`
37
+ loads a registry of projects from `contrib/seed-projects.json`, and when that file was missing it
38
+ told you to run `contrib/seed-from-panel.js` first — a script that is git-ignored and has never
39
+ been in the repository, as `contrib/README.md` says a few lines below. The directory is not part
40
+ of the published package, but it is part of the repository, so the first thing a reader of a fresh
41
+ clone was told to do could not be done at all. The message now names
42
+ `contrib/seed-projects.example.json`, which sits right next to the script: copy it, edit it, run
43
+ the script. Only `slug` and `name` are required, and a test keeps the example in step with the
44
+ fields the script actually reads — an example promising fields that are silently ignored is the
45
+ same broken promise, only quieter.
46
+
47
+ ## [1.6.1]
48
+
49
+ ### Fixed
50
+
51
+ - **The buttons in the skills section could act on the previous skill instead of the one on
52
+ screen.** Creating a skill left two requests in flight — the section re-renders and opens its
53
+ first row, then the code opens the new skill — and whichever answered last owned the panel's
54
+ state. In that gap the page showed the new skill while "load the shared version" fetched the text
55
+ of another one and "delete" would have removed it: with the guard deliberately switched off, 19
56
+ frames out of 30 showed one skill's row above another skill's path. An answer that is no longer
57
+ the current one is now discarded, the section opens exactly one skill instead of two, and the
58
+ buttons stay disabled until its text has arrived.
59
+
60
+ ## [1.6.0]
61
+
62
+ ### Changed
63
+
64
+ - **The skills section lists only what the board is about.** A skills directory holds every skill
65
+ its owner uses in Claude Code — most of it has nothing to do with the board — and burying the rest
66
+ behind a "show the others" line was not enough: the section is about deploy instructions. It now
67
+ shows the board's own skill and deploy skills: the shared one, the ones registered projects use,
68
+ and the ones created here. The full list is still where it is needed — in the deploy-skill picker
69
+ on the project page.
70
+ - **A skill created from the board no longer disappears from the list.** Nothing on disk tells a
71
+ skill created here apart from the rest of the library, so the board now remembers its own.
72
+ Entering the name of a skill that already exists adopts it into the list instead of failing —
73
+ without that, a skill outside those groups could be neither opened nor deleted.
74
+
75
+ ### Added
76
+
77
+ - **A skill can be deleted from the settings**, with the resolved path in the confirmation and a
78
+ snapshot of the file kept beforehand. **A skill that is a symlink loses only the link** — the file
79
+ it points to usually lives in another repository and is left alone; the dialog says so before you
80
+ press the button, not after.
81
+
82
+ ### Fixed
83
+
84
+ - **"Load the shared version" no longer answers with a raw error on your own skill.** The board has
85
+ no shared version of a skill it does not ship, so the button is simply disabled there and says why.
86
+
87
+ ## [1.5.0]
88
+
89
+ ### Added
90
+
91
+ - **The deploy skill of a project is picked from a list instead of typed in.** The field took a
92
+ free-form name, so a typo left the project without a deploy and said nothing; now it offers the
93
+ skills the board actually found, plus "not set", plus a line explaining what the field is for. A
94
+ name that is stored but not installed stays in the list, marked as such, rather than quietly
95
+ disappearing on the next save.
96
+ - **A skill can be created from the settings.** "New skill" asks for a name and writes the file; if
97
+ this package ships a skill under that name, the file starts as that shared version — so taking the
98
+ ready-made one and starting your own are the same action with a different name. The new skill
99
+ shows up in the project's deploy-skill list immediately.
100
+ - **The project's own notes and its skill are editable where they are shown.** The viewer opened
101
+ from project settings was deliberately read-only, which was the wrong call: a rule is worked out
102
+ while doing a task, and writing it into `CLAUDE.md` belongs right there. Saving takes the same
103
+ lock as a skill — it confirms the resolved path, the server checks that path itself, and the
104
+ previous contents are snapshotted into the data directory first.
105
+
106
+ ### Changed
107
+
108
+ - **The skills list is grouped.** A skills directory holds everything its owner uses in Claude Code,
109
+ most of it unrelated to the board. The section now leads with the board's own skill and the deploy
110
+ skills of registered projects, and keeps the rest behind a "other Claude skills" line.
111
+
112
+ ## [1.4.1]
113
+
114
+ ### Fixed
115
+
116
+ - **A skill used by a dozen projects broke its own row in the new "Skills" section.** The label
117
+ listed every project by name, so it wrapped onto a second line and pushed the size and date off
118
+ the right edge of the list. Past two projects the label now counts them ("used by 12 projects")
119
+ and the names move into the tooltip.
120
+
121
+ ## [1.4.0]
122
+
123
+ ### Added
124
+
125
+ - **Project settings are a page inside the project instead of a popup at the cursor.** The popup
126
+ was 250 pixels wide with its own scrollbar and a collapsible "paths & deploy" block, and it had
127
+ long stopped fitting what belongs there — seven registry fields. The same places open it (the
128
+ `⋯` button in the topbar, a right-click on a board in the sidebar); clicking `⋯` again, or Esc,
129
+ goes back to the board.
130
+ - **The page shows what Claude reads before it starts working:** the project's own `CLAUDE.md`
131
+ (plus `README.md` and the like when they exist) and the deploy skill it uses — the shared one or
132
+ its own — with absolute paths, a copy button and a read-only viewer. A missing `CLAUDE.md` is
133
+ listed too: that absence is worth knowing, since the agent will start the task without those
134
+ notes.
135
+ - **A "Skills" section in the settings.** Skills are the instructions Claude actually reads, and
136
+ they live outside the board, in `~/.claude/skills`; until now the board only wrote them once, at
137
+ install time, and never mentioned them again. The section lists every skill it can find, says
138
+ which projects use which, and shows the text of the selected one.
139
+ - **Loading the shared version of a skill and writing it to disk are two separate buttons.** A
140
+ skill directory is often a symlink to a file in another repository — a customised copy somebody
141
+ keeps deliberately — so a single "update" button would silently overwrite it. Loading only fills
142
+ the editor and names the source (GitHub, or the copy that shipped with the package) and the
143
+ language; saving is a second, explicit step that asks about the resolved path it is about to
144
+ overwrite, and keeps a snapshot of the previous contents in the data directory first.
145
+
146
+ ## [1.3.2]
147
+
148
+ ### Fixed
149
+
150
+ - **The GitHub sync stopped as soon as a label differed only in capitalisation.** GitHub treats
151
+ label names as case-insensitive; the board compared them exactly. A board whose repository
152
+ already had, say, `NoClaude` while the palette asks for `noclaude` did not recognise it, tried to
153
+ create it, and GitHub answered "a label with that name already exists" — which brought down the
154
+ whole issue creation, so every task after that reported "the issue does not exist yet" and the
155
+ error log filled up. Dropping `--force` in 1.3.0 is what exposed it: `--force` never complained
156
+ about a label that was already there. A label that already exists is no longer treated as a
157
+ failure at all, and a repository whose labels could not be listed is retried on the next
158
+ operation instead of being written off until a restart.
159
+
160
+ ## [1.3.1]
161
+
162
+ Three fixes found by testing the previous release rather than by using it — each one a place where
163
+ the 1.3.0 change was right in intent and incomplete in reach.
164
+
165
+ ### Fixed
166
+
167
+ - **A board with its own data directory could not create a project folder.** Keeping an isolated
168
+ instance out of the owner's live `~/claude-projects` (1.3.0) moved project folders next to the
169
+ data directory — but nothing ever created that directory, so the first "create a folder" answered
170
+ with an error and the feature simply did not work for anyone who chose a custom data directory
171
+ during setup. The failure was also invisible: it never reached the error log.
172
+ - **The dashboard funnel still counted archived boards.** Archiving was made to remove a board from
173
+ every card and every total, and it does — except for the bar chart of how many tasks sit at each
174
+ stage, which was left counting the archived board's tasks. On one screen that put a set of
175
+ consistent numbers next to one inconsistent one.
176
+ - **A deleted issue was retried instead of failing.** The list of GitHub answers that mean "this
177
+ will never succeed" spelled the article one way, and GitHub writes it the other way for half the
178
+ entries — so an issue that no longer exists was treated as a passing network problem and retried
179
+ fifteen times before giving up.
180
+
181
+ ## [1.3.0]
182
+
183
+ A full audit of the board — stability, performance and error handling — went through every part of
184
+ it, and this release is the answer to it. The headline is the tab you leave open all day: it used
185
+ to go quiet without ever saying so.
186
+
187
+ ### Added
188
+
189
+ - **The board tells you when a change did not save.** With the server down, the board used to stay
190
+ silent: a dragged card slid into its new column and drifted back on its own two seconds later, a
191
+ description you typed went nowhere, and the title of a new task vanished without a trace — the
192
+ only record was a failed request in the console, because the error report itself goes to the
193
+ server that is down. A change that cannot reach the server now rolls back, lights up a "not
194
+ saved" badge in the header, and is sent again as soon as the connection returns.
195
+ - **Archived boards can be brought back.** Archiving hid a board from the sidebar and there was no
196
+ way back short of a raw HTTP request. Settings now has an Archive section listing what was
197
+ archived, with a button to restore it.
198
+ - **`local-kanban skills` refreshes the Claude Code skills.** Installed from npm they were copied
199
+ once and then never updated by anything, so the board moved forward while the instructions the
200
+ agent reads stayed on an older version.
201
+ - **Search covers the whole description.** It only ever looked at the first 180 characters, so a
202
+ word further in was simply not found — no result, no error, no hint that the search was partial.
203
+
204
+ ### Fixed
205
+
206
+ - **A tab that lost its event stream never noticed.** The check for a dead stream ran only when the
207
+ window was hidden or refocused — and the board is normally visible and focused all day, so
208
+ neither ever happened. After a laptop sleep or a network timeout the board froze: finished tasks
209
+ did not appear, and anything done from the frozen board overwrote what had happened meanwhile.
210
+ Liveness is now checked on a timer, and a stream that recovers on its own catches up on what it
211
+ missed.
212
+ - **A burst of events left only the last one.** Five tasks created in a row showed up as one; five
213
+ tasks moved in a row left four cards sitting in their old column — which is worse, because a
214
+ missing card is visible and a card in the wrong column is not. Every event in a burst is now
215
+ applied.
216
+ - **The task panel overwrote changes made elsewhere.** It sent every field it held on any edit,
217
+ while only refreshing the status, so setting a priority or a label from the CLI or another tab
218
+ was rolled back within half a second. It now sends only what actually changed, shows what came
219
+ from elsewhere, and closes itself if the task was deleted.
220
+ - **Every board render held on to the previous one.** Memory grew with each redraw for as long as
221
+ the tab stayed on one board — tens of megabytes over a day of activity.
222
+ - **A task forgotten in a working column counted the whole time as work.** One task left in
223
+ "doing" over a weekend turned the week's work time into fiction. A single stretch is now capped,
224
+ and a capped number is marked as approximate instead of pretending to be exact.
225
+ - **Two snapshots taken in the same second destroyed each other,** leaving a zero-byte file under
226
+ the final name that was listed, downloadable and counted as a backup.
227
+ - **A failing daily backup said nothing.** With the snapshot directory unwritable the board started
228
+ normally, took no snapshots, logged nothing, and tried again six hours later. The Backups section
229
+ now shows the last success and the last failure, and a failure is retried in minutes.
230
+ - **Attachments were in no backup at all.** Images are now mirrored alongside the snapshots and
231
+ restored into the preview board.
232
+ - **A board opened from a backup could outlive the one that started it,** holding a port and
233
+ serving a full copy of every task with nothing left to stop it.
234
+ - **Uploading a backup buffered the whole file in memory** and lifted the size limit from every
235
+ other route as a side effect. The body is now streamed to disk and the limit is scoped.
236
+ - **The error log washed itself out.** A few hundred identical broken requests erased the whole
237
+ ring, real failures included; repeats are now collapsed with a counter. A genuine server failure
238
+ also reaches the process log — previously its only copy was the table, and if that table was the
239
+ problem, the board pointed at a section that answered with the same failure.
240
+ - **Malformed input answered 500 instead of 400** on ten routes, and in one of them a request could
241
+ come back 200 while writing the wrong value into a project field.
242
+ - **`kb` could not tell a refusal from a failure.** A board erroring on a request exited with the
243
+ same code as a lawful refusal, and a reply that was not JSON — what you get when the address
244
+ points at something else — exited zero and reported a move that never happened.
245
+ - **GitHub sync could create a second issue for one task** if the process restarted at the wrong
246
+ moment, and an unparsed answer from `gh` started stamping out new ones. An ordinary network
247
+ failure was also filed as permanent and never retried, and labels recoloured by hand were reset
248
+ on every restart.
249
+ - **Archiving a project hid it from the sidebar only.** Its cards stayed on the combined board, its
250
+ tasks stayed in "waiting for you", and it was still named in the top projects.
251
+ - **Dashboard windows were cut in UTC but drawn in local days,** so the edge of the week fell in
252
+ the middle of a day that the calendar showed in full. The header and the dashboard also counted
253
+ the same week by different rules.
254
+ - **A board with its own data directory still used the live project folder of the account,** listed
255
+ it and created folders in it.
256
+ - **A relative or `~`-prefixed data directory** created a real directory named `~` and then died on
257
+ a raw stack trace.
258
+ - **The install check in CI passed on a package that installs but does not open,** and it was not
259
+ called on the publishing path at all.
260
+ - **A broken database died on a raw driver stack** instead of pointing at the snapshots next to it.
261
+ - **A group drag that was refused explained nothing** — the reason was computed, translated and
262
+ thrown away.
263
+ - **Deleting the demo project left its attachments on disk,** still served over a direct link.
264
+
265
+ ### Performance
266
+
267
+ Groundwork for larger boards; on a board of a couple of thousand tasks the difference today is a
268
+ few milliseconds. The task list no longer reads full descriptions off disk to return a 180-character
269
+ preview, the link map is built only for the tasks being shown, the dashboard stops scanning the whole
270
+ event log for one minimum, project counters got a covering index, and an edit that changes neither
271
+ the column nor the order redraws one card instead of the whole board. Search input is debounced.
272
+
273
+ ## [1.2.1]
274
+
275
+ ### Fixed
276
+
277
+ - **Creating a task threw an error every single time.** The board splits its frontend into ES
278
+ modules, and two of them wrote to a variable owned by another module. An import is a read-only
279
+ binding, so the assignment threw a `TypeError` and took the rest of the function with it. Three
280
+ things were broken by it at once: a freshly created card was never scrolled into view, the board
281
+ refresh that follows creation never ran, and the sync badge stopped updating — which also meant
282
+ a board with no GitHub sync configured still promised "creating issue…" on every new task. Each
283
+ creation also left an entry in the error log; on a board in daily use they were 82 of the last
284
+ 100 records.
285
+ - **A task deleted in another tab filled the error log.** The panel re-reads the task it shows on
286
+ every board refresh, so a task deleted elsewhere logged the same "task not found" line again and
287
+ again. Opening one now says so plainly, closes the panel and refreshes the board, and the
288
+ periodic re-read no longer treats an expected miss as a failure.
289
+
290
+ ## [1.2.0]
291
+
292
+ ### Added
293
+
294
+ - **A long status history no longer buries the rest of the task.** A task that has been moved
295
+ around for weeks collects a couple of dozen timeline rows, and they pushed everything else in
296
+ the panel out of view. Anything longer than six entries now shows the three most recent ones
297
+ with an arrow to expand the rest — and to fold them back.
298
+
299
+ ### Fixed
300
+
301
+ - **`kb info` crashed on a project whose pm2 services were stored as a plain string.** The field
302
+ is documented as "a comma-separated string or JSON" and both forms exist in real databases, but
303
+ every reader parsed it as JSON only: the command exited with an error instead of printing the
304
+ project, `GET /api/projects/:slug/status` answered 500, and the project settings showed an empty
305
+ pm2 field that the next save would have wiped. Both forms are now read, and new values are
306
+ stored in one canonical shape.
307
+
308
+ ### Changed
309
+
310
+ - `package.json` no longer declares a `test` script. The tests are not part of the published
311
+ package, so inside an installed one the command exited successfully having run nothing at all —
312
+ a green check for a check that never happened. Tests are run from a clone with `node --test`.
313
+
314
+ ## [1.1.0]
315
+
316
+ ### Changed
317
+
318
+ - **Node 22 is now the minimum, and installing on a current Node no longer builds from source.**
319
+ The database driver is a native module that ships prebuilt binaries per Node version. The
320
+ pinned version had them for Node 18 through 23 only, so anyone installing on Node 24 LTS or 26
321
+ — which is what you get if you install Node today — silently fell through to compiling the
322
+ driver locally: minutes of waiting, a C++ toolchain required, and an outright failure on a
323
+ machine that has none. The driver is updated to a release with binaries for Node 22, 24, 25 and
324
+ 26, `engines` states that range, and CI now tests both ends of it plus a real install on the
325
+ current LTS. Node 20 drops out of the range: the new driver has no binaries for it and Node 20
326
+ itself stopped receiving releases in March 2026.
327
+
328
+ ## [1.0.2]
329
+
330
+ ### Fixed
331
+
332
+ - **The bundled Raycast command did not work.** `scripts/raycast/open-kanban.sh` ships in the
333
+ package, and the export step removed its `@raycast.title` and `@raycast.description` lines as
334
+ if they were prose. They are not — Raycast parses them, and without a title it never registers
335
+ the command. The script is now written in English and the export refuses to drop a directive.
336
+
337
+ ### Changed
338
+
339
+ - `package.json` no longer advertises `bootstrap` and `seed:panel`. Neither could run from an
340
+ installed package: one points into a directory that is not shipped, the other at a file that
341
+ was never in the repository. The `contrib/` helpers are run directly from a clone.
342
+
343
+ ## [1.0.1]
344
+
345
+ ### Fixed
346
+
347
+ - **The board could not be stopped.** Neither `Ctrl+C` nor `SIGTERM` had any effect — only
348
+ `SIGKILL` did. A module-level signal listener was registered on import and did nothing, which
349
+ is enough to cancel Node's default terminate-on-signal. Handlers now live only for as long as
350
+ the thing they clean up, and they exit explicitly.
351
+ - **"Stop" on a restored backup lied.** The second board opened from an uploaded backup ignored
352
+ the stop button, the thirty-minute expiry and the next upload — same root cause — so preview
353
+ boards piled up, each still serving a copy of the data on an open port.
354
+ - **The wizard's manual instructions assumed a git clone.** Anyone who installed from npm was
355
+ told to run `npm link` and to symlink `skills/` from a directory they do not have; `kb` ships
356
+ with the package and the wizard already copies the skills. The final step now branches on how
357
+ the board was installed.
358
+ - Missing Russian translation for the dashboard "Streak" card, which never went through the
359
+ translation layer at all.
360
+ - `npm run update` printed git's raw `fatal: not a git repository` before its own explanation of
361
+ how to update an npm install.
362
+ - The release preflight reported "something was committed straight to main" when the real problem
363
+ was that no local `main` branch existed.
364
+
365
+ ### Changed
366
+
367
+ - The README no longer claims parts of the settings are Russian-first — English is the source
368
+ language of the interface and a string with no translation stays English.
369
+
370
+ ## [1.0.0]
371
+
372
+ First public release. A local kanban board built to work in tandem with Claude Code: the human
373
+ plans and accepts, Claude takes tasks from the queue through the `kb` CLI and stops at review.
374
+
375
+ - Board, dashboard, chaos capture, horizon and calendar views; drag and drop, task links,
376
+ checklists, attachments, comments with images.
377
+ - `kb` — a token-efficient CLI for the whole task loop (`take`, `show`, `mv`, `review`, `done`).
378
+ - Optional one-way GitHub mirror: every task becomes an issue, every project a Projects v2 board.
379
+ - SQLite with versioned migrations, a pre-migration snapshot and rotating backups.
380
+ - Local-first by design: binds to loopback, checks request origin, ships no external resources.
381
+ - English and Russian interface, installed and set up by `npx local-kanban`.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dannylamao
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # local-kanban
2
+
3
+ [![tests](https://github.com/lamaohub/local-kanban/actions/workflows/test.yml/badge.svg)](https://github.com/lamaohub/local-kanban/actions/workflows/test.yml)
4
+
5
+ A local kanban board built for working **in tandem with Claude Code**: the human plans and accepts tasks, Claude takes them from the queue, does the work and reports back — all through a token-efficient CLI called `kb`. Optionally mirrors everything to GitHub (issues + Projects v2).
6
+
7
+ Русская версия — [README.ru.md](README.ru.md).
8
+
9
+ ![Board](docs/screenshot-board.png)
10
+
11
+ ![Dashboard](docs/screenshot-dashboard.png)
12
+
13
+ ## Why
14
+
15
+ - **A queue for Claude, not just a board.** Statuses model the real loop: `backlog → todo → prep → doing → deploy → review → done`. Claude pulls the next task with `kb take`, works, and stops at *review* — accepting is always the human's call.
16
+ - **Local-first.** Everything lives in a single SQLite file on your machine. GitHub sync is optional and off until you configure it.
17
+ - **Honest metrics.** Work time is measured only while Claude actually works; the dashboard shows streaks, cycle time and what's waiting for you.
18
+
19
+ ## Security model — read this first
20
+
21
+ The server listens on **127.0.0.1 only** and has **no authentication**. The board is strictly local: your machine is the trust boundary. **Never expose the port to the network** (no reverse proxies, no `0.0.0.0`, no port forwarding). Third-party integrations should run on the same machine and talk to `127.0.0.1` (see [docs/API.md](docs/API.md)).
22
+
23
+ ## Requirements
24
+
25
+ - **Node.js ≥ 22** (macOS or Linux) — 24 LTS or newer is what most people have
26
+ - Optional, only for GitHub sync: [`gh` CLI](https://cli.github.com/) authenticated with the `project` scope:
27
+ `gh auth login && gh auth refresh -s project`
28
+
29
+ ## Install
30
+
31
+ ```bash
32
+ npm install -g local-kanban
33
+ local-kanban # setup wizard
34
+ local-kanban start # board at http://localhost:3100
35
+ ```
36
+
37
+ The wizard asks for the port, the data directory, whether you want GitHub sync, and whether to install the two Claude Code skills — the board's own and the deploy one — into `~/.claude/skills`. Every question has a default, so Enter-Enter-Enter is enough. It also writes `ecosystem.config.cjs` for autostart under [pm2](https://pm2.keymetrics.io/).
38
+
39
+ `local-kanban start` takes `--port <N>` and `--data <dir>`. Data lives in `~/.local-kanban` by default, outside the package directory, so updating the package never touches your board.
40
+
41
+ From source:
42
+
43
+ ```bash
44
+ git clone <repo-url> local-kanban && cd local-kanban
45
+ npm install
46
+ npx local-kanban # setup wizard (optional)
47
+ npm start # board at http://localhost:3100
48
+ ```
49
+
50
+ To get the `kb` command globally: `npm link` (or `npm install -g .`).
51
+
52
+ First launch shows an empty dashboard with an optional **demo project** — one click creates it, one click removes it.
53
+
54
+ ### Let Claude finish the setup
55
+
56
+ The last step of the first-run wizard shows a ready-made prompt (in the board's language). Paste it
57
+ into Claude Code and it will walk you through the rest — check that `kb` works, ask whether you want
58
+ the GitHub mirror, register your first projects with their paths and deploys, and verify the result.
59
+ The same prompt lives in **Settings → About**, so you can come back to it later.
60
+
61
+ ### Claude Code skills
62
+
63
+ The repo ships two skills for Claude Code in `skills/`:
64
+
65
+ - `skills/kanban` — teaches Claude the task workflow (`kb take` → work → `kb review`);
66
+ - `skills/deploy` — a generic deploy flow driven by the project registry (`kb info`).
67
+
68
+ Install by symlink or copy:
69
+
70
+ ```bash
71
+ ln -s "$(pwd)/skills/kanban" ~/.claude/skills/kanban
72
+ ln -s "$(pwd)/skills/deploy" ~/.claude/skills/deploy
73
+ ```
74
+
75
+ ## GitHub sync (optional)
76
+
77
+ Set the owner and issues repo in **Settings → Sync** on the board (or env `KB_GH_OWNER` / `KB_GH_REPO`). Without them the board runs in local-only mode: no queue, no warnings. With them, every task becomes an issue and every project gets a `kb: <slug>` GitHub Project with matching columns. Sync is one-way (board → GitHub) and runs in the background.
78
+
79
+ ## Updating
80
+
81
+ From npm:
82
+
83
+ ```bash
84
+ npm install -g local-kanban@latest
85
+ local-kanban skills # refresh the Claude Code skills — they are a copy, not a link
86
+ ```
87
+
88
+ From a clone:
89
+
90
+ ```bash
91
+ npm run update # git pull + npm install + pm2 restart (if applicable)
92
+ ```
93
+
94
+ Your data is never touched by updates: `data/` is gitignored and schema migrations run automatically on start — **with a pre-migration snapshot** saved to `data/backups/pre-migrate/` before anything changes.
95
+
96
+ **Rollback:** stop the server, restore the latest file from `data/backups/` (daily) or `data/backups/pre-migrate/` over `data/kanban.db`, then `git checkout <previous tag>` and start again.
97
+
98
+ Releases live in `main` (stable, tagged); day-to-day development happens in `dev`.
99
+
100
+ ## Environment variables
101
+
102
+ | Variable | Default | Meaning |
103
+ |---|---|---|
104
+ | `PORT` | `3100` | HTTP port (bound to 127.0.0.1) |
105
+ | `KB_DATA_DIR` | `./data` | data directory (SQLite, attachments, backups) |
106
+ | `KB_LOCAL_ROOT` | `~/claude-projects` | root folder scanned for local projects |
107
+ | `KB_URL` | `http://127.0.0.1:3100` | board URL for the `kb` CLI |
108
+ | `KB_GH_OWNER` / `KB_GH_REPO` | — | GitHub sync target; empty = sync off (can also be set in Settings) |
109
+ | `KB_PANEL_URL` | — | custom HTTP source of service statuses; empty = local `pm2 jlist` |
110
+ | `KB_PANEL_INFO` | — | optional path to an external panel's info.json for category sync |
111
+ | `KB_SSE_MAX` | `20` | cap on concurrent SSE connections |
112
+ | `KB_SKILLS_EXTRA` | — | extra skill root directories, `:`-separated |
113
+
114
+ The legacy names `PANEL_URL` and `PANEL_INFO` (without the prefix) still work as a fallback.
115
+
116
+ ## Metrics and the `noclaude` label
117
+
118
+ Tasks done **by hand** (without Claude) get the `noclaude` label — they are counted separately on the dashboard and excluded from Claude's metrics (work time, cycle, completion %), which would otherwise be skewed by their zero work time. The label is optional and can be added later. Manual tasks are also allowed to jump straight to *review*/*done*.
119
+
120
+ ## Extending
121
+
122
+ The full HTTP API and the SSE event stream are the official extension point — build bots, stats, integrations as separate programs, no plugins inside the page. See [docs/API.md](docs/API.md).
123
+
124
+ ## Development
125
+
126
+ ```bash
127
+ node --test # DB isolated via KB_DATA_DIR
128
+ ```
129
+
130
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup, branch flow and the schema-migration rule. The architecture is described in [ARCHITECTURE.md](ARCHITECTURE.md), and what changed between versions in [CHANGELOG.md](CHANGELOG.md).
131
+
132
+ ## UI language
133
+
134
+ English is the source language of the interface; Russian comes as a translation. The board follows your system language and can be switched in **Settings → General** — a string with no translation yet stays English rather than leaking into the wrong locale.
135
+
136
+ ## Using it at work
137
+
138
+ The board is MIT-licensed and free for everyone: nothing is switched off and there is nothing to
139
+ activate. If it earns you money — inside a company, or on paid client work — $12 a year per person
140
+ keeps it maintained. A request, not a rule: [docs/COMMERCIAL.md](docs/COMMERCIAL.md).
141
+
142
+ ## License
143
+
144
+ [MIT](LICENSE).