claude-code-kanban 7.4.0 → 7.6.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.
Files changed (48) hide show
  1. package/README.md +5 -3
  2. package/cli.js +95 -29
  3. package/hub-app.json +5 -0
  4. package/lib/panes.js +41 -6
  5. package/lib/parsers.js +42 -3
  6. package/lib/retention.js +54 -6
  7. package/lib/scratchpad-dir.js +19 -2
  8. package/lib/session-cache.js +1 -1
  9. package/lib/session-events.js +174 -47
  10. package/lib/show.js +385 -0
  11. package/lib/task-dir.js +26 -0
  12. package/lib/terminal-client.js +14 -1
  13. package/lib/terminal-host.js +2 -1
  14. package/lib/terminal.js +28 -8
  15. package/package.json +1 -1
  16. package/plugin/plugins/claude-code-kanban/.claude-plugin/plugin.json +2 -5
  17. package/plugin/plugins/claude-code-kanban/hooks/doorbell.ts +136 -0
  18. package/plugin/plugins/claude-code-kanban/hooks/index.ts +4 -0
  19. package/plugin/plugins/claude-code-kanban/hooks/show.ts +120 -0
  20. package/plugin/plugins/claude-code-kanban/skills/dispatch/SKILL.md +2 -0
  21. package/plugin/plugins/claude-code-kanban/skills/kanban/SKILL.md +3 -3
  22. package/plugin/plugins/claude-code-kanban/skills/show/SKILL.md +45 -0
  23. package/plugin/plugins/claude-code-kanban/skills/show/references/NOTICE.md +27 -0
  24. package/plugin/plugins/claude-code-kanban/skills/show/references/chart.md +58 -0
  25. package/plugin/plugins/claude-code-kanban/skills/show/references/diagram/architecture.md +18 -0
  26. package/plugin/plugins/claude-code-kanban/skills/show/references/diagram/er.md +10 -0
  27. package/plugin/plugins/claude-code-kanban/skills/show/references/diagram/flow.md +13 -0
  28. package/plugin/plugins/claude-code-kanban/skills/show/references/diagram/layers.md +10 -0
  29. package/plugin/plugins/claude-code-kanban/skills/show/references/diagram/sequence.md +19 -0
  30. package/plugin/plugins/claude-code-kanban/skills/show/references/diagram/state.md +12 -0
  31. package/plugin/plugins/claude-code-kanban/skills/show/references/diagram/swimlane.md +10 -0
  32. package/plugin/plugins/claude-code-kanban/skills/show/references/diagram/timeline.md +9 -0
  33. package/plugin/plugins/claude-code-kanban/skills/show/references/diagram/tree.md +10 -0
  34. package/plugin/plugins/claude-code-kanban/skills/show/references/diagram.md +87 -0
  35. package/plugin/plugins/claude-code-kanban/skills/show/references/explain.md +98 -0
  36. package/plugin/plugins/claude-code-kanban/skills/show/references/mockup.md +30 -0
  37. package/plugin/plugins/claude-code-kanban/tests/doorbell.test.ts +133 -0
  38. package/plugin/plugins/claude-code-kanban/tests/show.test.ts +137 -0
  39. package/public/app.js +2151 -1108
  40. package/public/index.html +19 -36
  41. package/public/style.css +1047 -125
  42. package/public/terminal-frame.js +0 -2
  43. package/public/tree-highlight.js +137 -15
  44. package/server.js +237 -178
  45. package/lib/dispatch.js +0 -32
  46. package/plugin/plugins/claude-code-kanban/monitors.json +0 -8
  47. package/plugin/plugins/claude-code-kanban/scripts/postman.js +0 -82
  48. package/plugin/plugins/claude-code-kanban/skills/follow/SKILL.md +0 -47
package/lib/dispatch.js DELETED
@@ -1,32 +0,0 @@
1
- // Dispatch: a Claude Code session one session started in cck's terminal. In memory on
2
- // purpose: an entry lives as long as its PTY, which dies with the server.
3
-
4
- function createDispatchRegistry({ now = Date.now } = {}) {
5
- const entries = new Map();
6
-
7
- function add({ session, parent, cwd, name, group, worktree }) {
8
- entries.set(session, {
9
- session,
10
- parent: parent || null,
11
- cwd,
12
- name: name || null,
13
- group: group || null,
14
- worktree: worktree || null,
15
- startedAt: now(),
16
- });
17
- }
18
-
19
- function list({ parent } = {}) {
20
- const out = [...entries.values()];
21
- return parent ? out.filter((e) => e.parent === parent) : out;
22
- }
23
-
24
- return {
25
- add,
26
- list,
27
- has: (session) => entries.has(session),
28
- remove: (session) => entries.delete(session),
29
- };
30
- }
31
-
32
- module.exports = { createDispatchRegistry };
@@ -1,8 +0,0 @@
1
- [
2
- {
3
- "name": "kanban-doorbell",
4
- "description": "Notifies this session when its tasks are moved on the kanban board or the user sends it review comments.",
5
- "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/postman.js\"",
6
- "when": "on-skill-invoke:claude-code-kanban:follow"
7
- }
8
- ]
@@ -1,82 +0,0 @@
1
- #!/usr/bin/env node
2
- // Kanban -> session doorbell.
3
- //
4
- // Claude Code delivers every line a monitor prints to the owning session as a task
5
- // notification, so this process is the only way board activity can reach a session that
6
- // is sitting idle. It long-polls the kanban server for events addressed to this session
7
- // and prints them one per line.
8
- //
9
- // Pairing is free: CLAUDE_CODE_SESSION_ID is inherited from the session that spawned us,
10
- // so the id we poll with is the same id the hooks report. No cwd or pid guessing.
11
- //
12
- // The lines we print carry board text (the card subject and description), which the
13
- // session is told to read as the user's own brief. That is only safe because we are armed
14
- // by an explicit `follow` invocation: the user asked to follow the board before anything the
15
- // board says can reach the model.
16
-
17
- const fs = require('fs');
18
- const os = require('os');
19
- const path = require('path');
20
-
21
- const SESSION_ID = process.env.CLAUDE_CODE_SESSION_ID;
22
- const CLAUDE_DIR = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
23
- const SERVER_INFO = path.join(CLAUDE_DIR, '.cck', 'server.json');
24
- // The server caps its own wait at 120s. Sitting at the ceiling halves every recurring
25
- // cost -- handshake, route walk, timer, empty response -- and costs no event latency,
26
- // because an enqueue wakes the poll immediately.
27
- const WAIT_SEC = 120;
28
- const RETRY_MS = 15000;
29
- // Windows sometimes fails a loopback connect with ETIMEDOUT, or resets it once open, while the
30
- // board is up, so those errors get a few short waits before the normal one.
31
- const CONNECT_RETRY_MS = [250, 500, 1000, 2000];
32
-
33
- if (!SESSION_ID) process.exit(0);
34
-
35
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
36
-
37
- // Re-read every cycle rather than caching: it is how we follow the board across a
38
- // restart onto a different port. A file left behind by a crashed server names a port
39
- // something else may now hold, so trust it only while its pid is alive.
40
- // CCK_URL comes from the board whose terminal started this session. That board owns the
41
- // session's queue, and server.json may name another board on the same config dir.
42
- function serverUrl() {
43
- if (process.env.CCK_URL) return process.env.CCK_URL.replace(/\/+$/, '');
44
- const { port, pid } = JSON.parse(fs.readFileSync(SERVER_INFO, 'utf8'));
45
- if (pid) process.kill(pid, 0);
46
- return `http://127.0.0.1:${port}`;
47
- }
48
-
49
- // Once per process, not once per poll: the grant means "follow the board from here on", so
50
- // the first attach throws away whatever queued up before it. A later reconnect must not
51
- // discard again -- by then the queue holds events the user is owed.
52
- let firstAttach = true;
53
-
54
- async function poll(base) {
55
- const first = firstAttach ? '&first=1' : '';
56
- const url = `${base}/api/sessions/${encodeURIComponent(SESSION_ID)}/events?wait=${WAIT_SEC}${first}`;
57
- const res = await fetch(url, { signal: AbortSignal.timeout((WAIT_SEC + 15) * 1000) });
58
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
59
- firstAttach = false;
60
- const { events } = await res.json();
61
- return Array.isArray(events) ? events : [];
62
- }
63
-
64
- (async () => {
65
- let connectRetries = 0;
66
- for (;;) {
67
- try {
68
- for (const line of await poll(serverUrl())) console.log(line);
69
- connectRetries = 0;
70
- } catch (e) {
71
- // No board yet, or it went away. It may come back later in the session, so keep
72
- // waiting quietly -- a missing server is the normal case, not an error.
73
- const blip = (e.cause?.code === 'ETIMEDOUT' && e.cause?.syscall === 'connect') || e.cause?.code === 'ECONNRESET';
74
- if (blip && connectRetries < CONNECT_RETRY_MS.length) {
75
- await sleep(CONNECT_RETRY_MS[connectRetries++]);
76
- } else {
77
- connectRetries = 0;
78
- await sleep(RETRY_MS);
79
- }
80
- }
81
- }
82
- })();
@@ -1,47 +0,0 @@
1
- ---
2
- name: follow
3
- description: Let kanban card moves drive this session.
4
- disable-model-invocation: true
5
- ---
6
-
7
- # Follow the kanban board
8
-
9
- The user typing this skill is the whole grant: it armed the doorbell — a monitor watching the board for moves of *this session's* tasks, live for the rest of the session. Confirm in one line and run no command. Moves made before it attached are discarded, so every line you get is current.
10
-
11
- ```
12
- [kanban board] The user moved task <taskId> "<subject>" from <from> to <to>. Description: <description>
13
- ```
14
-
15
- `Description:` is omitted when the card has none. Everything after it is the description verbatim to end of line, truncated if long — read the task with `TaskGet` for the full text or for `activeForm` and `blockedBy`. Moves and review comments (below) are the only lines announced.
16
-
17
- **A move is an instruction, not an FYI** — the user dragging a card is the user telling you something, and the subject and description are their brief for the work:
18
-
19
- | Transition | What the user means |
20
- |---|---|
21
- | To `in_progress` | Start this task now. |
22
- | From `in_progress` to `pending` or `todo` | Stop working on it and park it. |
23
- | To `completed` | The user considers it done — do not keep working on it. |
24
- | To `cancelled` | Abandon it. Undo nothing unless asked. |
25
-
26
- Act on the newest line per task; a card dragged twice means only its final position. When a move contradicts your current work, the board wins.
27
-
28
- Delivery is best-effort and the task file is the authority, so a missed line only delays you to your next turn.
29
-
30
- ## Review comments
31
-
32
- ```
33
- [kanban board] The user left <n> review comments on <source>. Address them: <review file>
34
- ```
35
-
36
- The review file holds the comments and how to read them.
37
-
38
- ## Finish the task on the board
39
-
40
- A move hands you work; the task file is where you hand it back. When the work a move to `in_progress` asked for is done, set that task to `completed` with `TaskUpdate` before you reply — the card moves itself, and the board is where the user is watching. A card left in In Progress reads as work still running.
41
-
42
- Your own `TaskUpdate` writes the task file rather than going through the board, so it rings no doorbell: there is no echo to guard against.
43
-
44
- ## Troubleshooting
45
-
46
- - **No lines arrive** → the doorbell arms once per session, on the namespaced dispatch: `/claude-code-kanban:follow`. A session that never got it never hears the board.
47
- - **"Cannot reach cck server…"** → the error names the port it tried. Ask the user to start the server with `claude-code-kanban`.