claudedash 0.5.4

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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +207 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +247 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/core/contextHealth.d.ts +14 -0
  8. package/dist/core/contextHealth.d.ts.map +1 -0
  9. package/dist/core/contextHealth.js +46 -0
  10. package/dist/core/contextHealth.js.map +1 -0
  11. package/dist/core/insightsEngine.d.ts +4 -0
  12. package/dist/core/insightsEngine.d.ts.map +1 -0
  13. package/dist/core/insightsEngine.js +223 -0
  14. package/dist/core/insightsEngine.js.map +1 -0
  15. package/dist/core/logParser.d.ts +11 -0
  16. package/dist/core/logParser.d.ts.map +1 -0
  17. package/dist/core/logParser.js +127 -0
  18. package/dist/core/logParser.js.map +1 -0
  19. package/dist/core/qualityTimeline.d.ts +8 -0
  20. package/dist/core/qualityTimeline.d.ts.map +1 -0
  21. package/dist/core/qualityTimeline.js +40 -0
  22. package/dist/core/qualityTimeline.js.map +1 -0
  23. package/dist/core/queueParser.d.ts +25 -0
  24. package/dist/core/queueParser.d.ts.map +1 -0
  25. package/dist/core/queueParser.js +283 -0
  26. package/dist/core/queueParser.js.map +1 -0
  27. package/dist/core/stateEngine.d.ts +6 -0
  28. package/dist/core/stateEngine.d.ts.map +1 -0
  29. package/dist/core/stateEngine.js +154 -0
  30. package/dist/core/stateEngine.js.map +1 -0
  31. package/dist/core/todoReader.d.ts +12 -0
  32. package/dist/core/todoReader.d.ts.map +1 -0
  33. package/dist/core/todoReader.js +301 -0
  34. package/dist/core/todoReader.js.map +1 -0
  35. package/dist/core/types.d.ts +167 -0
  36. package/dist/core/types.d.ts.map +1 -0
  37. package/dist/core/types.js +2 -0
  38. package/dist/core/types.js.map +1 -0
  39. package/dist/core/worktreeDetector.d.ts +18 -0
  40. package/dist/core/worktreeDetector.d.ts.map +1 -0
  41. package/dist/core/worktreeDetector.js +99 -0
  42. package/dist/core/worktreeDetector.js.map +1 -0
  43. package/dist/core/worktreeMapper.d.ts +10 -0
  44. package/dist/core/worktreeMapper.d.ts.map +1 -0
  45. package/dist/core/worktreeMapper.js +38 -0
  46. package/dist/core/worktreeMapper.js.map +1 -0
  47. package/dist/public/404/index.html +1 -0
  48. package/dist/public/404.html +1 -0
  49. package/dist/public/__next.__PAGE__.txt +9 -0
  50. package/dist/public/__next._full.txt +17 -0
  51. package/dist/public/__next._head.txt +5 -0
  52. package/dist/public/__next._index.txt +5 -0
  53. package/dist/public/__next._tree.txt +2 -0
  54. package/dist/public/_next/static/36m05Da62vzqVee_ifGeq/_buildManifest.js +42 -0
  55. package/dist/public/_next/static/36m05Da62vzqVee_ifGeq/_clientMiddlewareManifest.json +1 -0
  56. package/dist/public/_next/static/36m05Da62vzqVee_ifGeq/_ssgManifest.js +1 -0
  57. package/dist/public/_next/static/chunks/02c545b35c5a7a0d.js +2 -0
  58. package/dist/public/_next/static/chunks/4611ba49fa18f0e2.js +1 -0
  59. package/dist/public/_next/static/chunks/64ee9622541d967c.js +1 -0
  60. package/dist/public/_next/static/chunks/66f59f4487e89157.js +1 -0
  61. package/dist/public/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  62. package/dist/public/_next/static/chunks/a6dad97d9634a72d.js.map +1 -0
  63. package/dist/public/_next/static/chunks/bfa1988f6340e536.css +2 -0
  64. package/dist/public/_next/static/chunks/d1f8ac52f80f9493.js +5 -0
  65. package/dist/public/_next/static/chunks/turbopack-87039ecabc6befeb.js +4 -0
  66. package/dist/public/_not-found/__next._full.txt +13 -0
  67. package/dist/public/_not-found/__next._head.txt +5 -0
  68. package/dist/public/_not-found/__next._index.txt +5 -0
  69. package/dist/public/_not-found/__next._not-found.__PAGE__.txt +5 -0
  70. package/dist/public/_not-found/__next._not-found.txt +4 -0
  71. package/dist/public/_not-found/__next._tree.txt +2 -0
  72. package/dist/public/_not-found/index.html +1 -0
  73. package/dist/public/_not-found/index.txt +13 -0
  74. package/dist/public/index.html +1 -0
  75. package/dist/public/index.txt +17 -0
  76. package/dist/server/routes/live.d.ts +9 -0
  77. package/dist/server/routes/live.d.ts.map +1 -0
  78. package/dist/server/routes/live.js +53 -0
  79. package/dist/server/routes/live.js.map +1 -0
  80. package/dist/server/routes/observability.d.ts +6 -0
  81. package/dist/server/routes/observability.d.ts.map +1 -0
  82. package/dist/server/routes/observability.js +18 -0
  83. package/dist/server/routes/observability.js.map +1 -0
  84. package/dist/server/routes/plan.d.ts +7 -0
  85. package/dist/server/routes/plan.d.ts.map +1 -0
  86. package/dist/server/routes/plan.js +134 -0
  87. package/dist/server/routes/plan.js.map +1 -0
  88. package/dist/server/server.d.ts +7 -0
  89. package/dist/server/server.d.ts.map +1 -0
  90. package/dist/server/server.js +42 -0
  91. package/dist/server/server.js.map +1 -0
  92. package/dist/server/watcher.d.ts +20 -0
  93. package/dist/server/watcher.d.ts.map +1 -0
  94. package/dist/server/watcher.js +97 -0
  95. package/dist/server/watcher.js.map +1 -0
  96. package/package.json +58 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 agent-scope contributors
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,207 @@
1
+ # claudedash
2
+
3
+ See what your AI agent is actually doing.
4
+
5
+ [![npm](https://img.shields.io/npm/v/claudedash)](https://www.npmjs.com/package/claudedash)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![CI](https://github.com/yunusemrgrl/claudedash/actions/workflows/ci.yml/badge.svg)](https://github.com/yunusemrgrl/claudedash/actions/workflows/ci.yml)
8
+
9
+ ---
10
+
11
+ ## The problem
12
+
13
+ You tell Claude Code to refactor your auth system. It says "on it." You wait. Terminal scrolls. Minutes pass. You have no idea if it's on task 2 of 12 or stuck in a loop. You're flying blind.
14
+
15
+ claudedash fixes that. One command, zero config. It reads Claude Code's own task files and gives you a live Kanban board.
16
+
17
+ ```bash
18
+ npx -y claudedash@latest start
19
+ ```
20
+
21
+ That's it. Open `localhost:4317`. Watch your agent work.
22
+
23
+ ![claudedash demo](docs/screenrecord.gif)
24
+
25
+ ## How it works
26
+
27
+ Claude Code writes task state to `~/.claude/tasks/` when it uses the TodoWrite tool. claudedash reads those files, watches for changes, and streams updates to your browser via SSE. No database. No auth. No cloud. Just files.
28
+
29
+ **Important:** Claude Code only writes task files when TodoWrite is actively used. To ensure your sessions always appear on the dashboard, add this to your project's `CLAUDE.md`:
30
+
31
+ ```markdown
32
+ You MUST use the TodoWrite tool to track your work.
33
+ At the START of any multi-step task, create a todo list with all steps.
34
+ Mark each task in_progress before starting, completed after finishing.
35
+ ```
36
+
37
+ Or run `claudedash init` — it generates a ready-to-use `CLAUDE.md` snippet.
38
+
39
+ ## Two modes
40
+
41
+ | | Live | Plan |
42
+ |---|---|---|
43
+ | **What** | Watch Claude Code work | Structured project planning |
44
+ | **Source** | `~/.claude/tasks/` | `.claudedash/queue.md` |
45
+ | **Setup** | None | `npx claudedash init` |
46
+ | **Use when** | You want visibility | You want control |
47
+
48
+ Live mode is the default. Plan mode adds dependencies, acceptance criteria, and execution tracking on top.
49
+
50
+ | Live mode | Plan mode |
51
+ |---|---|
52
+ | ![Live](docs/screenshot-1.png) | ![Plan](docs/screenshot-2.png) |
53
+
54
+ ## Install
55
+
56
+ ```bash
57
+ # Zero-install, always latest
58
+ npx -y claudedash@latest start
59
+
60
+ # Or install globally
61
+ npm i -g claudedash
62
+ claudedash start
63
+ ```
64
+
65
+ ### Plan mode
66
+
67
+ For structured project execution with task dependencies and acceptance criteria.
68
+
69
+ ```bash
70
+ claudedash init
71
+ ```
72
+
73
+ This creates `.claudedash/` with:
74
+
75
+ | File | Purpose |
76
+ |---|---|
77
+ | `queue.md` | Your task list — slices, dependencies, AC |
78
+ | `workflow.md` | Execution protocol your agent follows |
79
+ | `execution.log` | Agent logs DONE/FAILED/BLOCKED here |
80
+ | `config.json` | Heading patterns, port, field definitions |
81
+ | `CLAUDE.md` | Paste into your project's CLAUDE.md |
82
+
83
+ Then:
84
+
85
+ 1. Edit `queue.md` with your actual tasks
86
+ 2. Copy `CLAUDE.md` contents into your project's CLAUDE.md
87
+ 3. Tell your agent: *"follow .claudedash/workflow.md, start with S1-T1"*
88
+ 4. Run `claudedash start` and watch the dashboard
89
+
90
+ ## CLI
91
+
92
+ ```bash
93
+ claudedash start # Auto-detect modes, open dashboard
94
+ claudedash start --claude-dir /path # Custom Claude directory
95
+ claudedash start -p 3000 # Custom port
96
+ claudedash init # Init plan mode in current dir
97
+ ```
98
+
99
+ ## Queue format (Plan mode)
100
+
101
+ ```markdown
102
+ # Slice S1
103
+
104
+ ## S1-T1
105
+ Area: Backend
106
+ Depends: -
107
+ Description: Setup database schema
108
+ AC: Tables created and migrations run
109
+
110
+ ## S1-T2
111
+ Area: Backend
112
+ Depends: S1-T1
113
+ Description: Implement user authentication
114
+ AC: Login and registration endpoints working
115
+ ```
116
+
117
+ Validates: required fields, duplicate IDs, unknown deps, circular deps.
118
+
119
+ ## Execution log (Plan mode)
120
+
121
+ Append-only JSONL:
122
+
123
+ ```json
124
+ {"task_id":"S1-T1","status":"DONE","timestamp":"2026-02-16T14:31:22Z","agent":"claude"}
125
+ {"task_id":"S1-T2","status":"FAILED","timestamp":"2026-02-16T14:33:10Z","agent":"claude","meta":{"reason":"timeout"}}
126
+ {"task_id":"S1-T3","status":"BLOCKED","reason":"API key missing","timestamp":"2026-02-16T14:35:00Z","agent":"claude"}
127
+ ```
128
+
129
+ ## Observability Features
130
+
131
+ ### Quality Gates
132
+
133
+ Track lint, typecheck, and test results per task and view them as a timeline in the Plan mode dashboard.
134
+
135
+ Log quality results in `execution.log`:
136
+
137
+ ```json
138
+ {
139
+ "task_id": "F1-2",
140
+ "status": "DONE",
141
+ "timestamp": "2026-02-18T12:05:00Z",
142
+ "agent": "claude",
143
+ "meta": {
144
+ "file": "src/core/logParser.ts",
145
+ "quality": { "lint": true, "typecheck": true, "test": false }
146
+ }
147
+ }
148
+ ```
149
+
150
+ Select any task in Plan mode to see its quality check history with pass/fail badges. → [Quality Gates docs](docs/quality-gates.md)
151
+
152
+ ### Context Health
153
+
154
+ See how much of Claude's context window each session is using, with color-coded warnings at 65% (warn) and 75% (critical).
155
+
156
+ - Session cards show a compact `72%` indicator
157
+ - Selected session shows a full progress bar in the token header
158
+ - A header banner appears when any session crosses warn/critical level
159
+
160
+ → [Context Health docs](docs/context-health.md) | [Estimation methodology](docs/context-estimation.md)
161
+
162
+ ### Worktree Observability
163
+
164
+ When running agents across multiple git worktrees in parallel, the new **Worktrees** tab shows:
165
+
166
+ - Branch name and HEAD commit per worktree
167
+ - Dirty/clean status (uncommitted changes)
168
+ - Ahead/behind commits relative to upstream
169
+ - Which agent tasks are running in each worktree
170
+
171
+ → [Worktree docs](docs/worktrees.md)
172
+
173
+ ## API
174
+
175
+ | Endpoint | Description |
176
+ |---|---|
177
+ | `GET /health` | Status + available modes |
178
+ | `GET /sessions` | All Claude Code sessions (includes `contextHealth`) |
179
+ | `GET /sessions/:id` | Tasks for a session |
180
+ | `GET /events` | SSE stream |
181
+ | `GET /snapshot` | Plan mode state |
182
+ | `GET /quality-timeline` | Quality check events (filter with `?taskId=`) |
183
+ | `GET /worktrees` | Git worktrees with task associations |
184
+
185
+ ## Development
186
+
187
+ ```bash
188
+ git clone https://github.com/yunusemrgrl/claudedash.git
189
+ cd claudedash && npm install
190
+ cd dashboard && npm install && cd ..
191
+
192
+ npm run build # Build core + dashboard
193
+ npm test # 163 tests
194
+ npm run dev # Dev server with watch
195
+ ```
196
+
197
+ ## Stack
198
+
199
+ TypeScript, Fastify, chokidar, SSE, Next.js, Tailwind, Vitest.
200
+
201
+ ## Contributing
202
+
203
+ PRs welcome. Open an issue first for anything beyond small fixes. See [CHANGELOG.md](CHANGELOG.md) for release history.
204
+
205
+ ## License
206
+
207
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { mkdirSync, writeFileSync, existsSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { exec } from 'child_process';
6
+ import { startServer } from './server/server.js';
7
+ const program = new Command();
8
+ program
9
+ .name('claudedash')
10
+ .description('Live Kanban, quality gates and context health monitoring for Claude Code agents')
11
+ .version('0.5.4');
12
+ program
13
+ .command('init')
14
+ .description('Initialize claudedash in current directory')
15
+ .action(() => {
16
+ const claudeWatchDir = join(process.cwd(), '.claudedash');
17
+ // Create .claudedash/ directory
18
+ if (existsSync(claudeWatchDir)) {
19
+ console.log('⚠️ .claudedash/ already exists');
20
+ process.exit(1);
21
+ }
22
+ try {
23
+ mkdirSync(claudeWatchDir);
24
+ console.log('✓ Created .claudedash/');
25
+ // Create queue.md with realistic example
26
+ const queueTemplate = `# Slice S1
27
+
28
+ ## S1-T1
29
+ Area: Setup
30
+ Depends: -
31
+ Description: Initialize project structure and install dependencies
32
+ AC: Project builds and all linters pass
33
+
34
+ ## S1-T2
35
+ Area: Core
36
+ Depends: S1-T1
37
+ Description: Implement core feature
38
+ AC: Feature works end-to-end with happy path
39
+
40
+ ## S1-T3
41
+ Area: Test
42
+ Depends: S1-T1, S1-T2
43
+ Description: Add integration tests for core feature
44
+ AC: All tests pass, edge cases covered
45
+ `;
46
+ writeFileSync(join(claudeWatchDir, 'queue.md'), queueTemplate);
47
+ console.log('✓ Created queue.md');
48
+ // Create empty execution.log
49
+ writeFileSync(join(claudeWatchDir, 'execution.log'), '');
50
+ console.log('✓ Created execution.log');
51
+ // Create config.json
52
+ const config = {
53
+ queueFile: 'queue.md',
54
+ logFile: 'execution.log',
55
+ port: 4317,
56
+ taskModel: {
57
+ fields: [
58
+ { name: 'Area', type: 'enum', required: true, values: ['Setup', 'Core', 'Test'] },
59
+ { name: 'Depends', type: 'refs', required: false },
60
+ { name: 'Description', type: 'text', required: true },
61
+ { name: 'AC', type: 'text', required: true }
62
+ ],
63
+ id: '{slice}-T{n}',
64
+ headings: {
65
+ slice: '# Slice {name}',
66
+ task: '## {id}'
67
+ }
68
+ }
69
+ };
70
+ writeFileSync(join(claudeWatchDir, 'config.json'), JSON.stringify(config, null, 2));
71
+ console.log('✓ Created config.json');
72
+ // Create workflow.md — autonomous execution protocol
73
+ const workflowTemplate = `# Agent Workflow
74
+
75
+ Autonomous execution protocol for claudedash Plan mode.
76
+ Each task from \`queue.md\` is processed through these phases.
77
+
78
+ ---
79
+
80
+ ## Phase 1 — INTAKE
81
+
82
+ Read the next READY task from \`.claudedash/queue.md\`.
83
+
84
+ 1. Parse the task: ID, Area, Description, AC, Dependencies.
85
+ 2. Verify all dependencies have status DONE in \`execution.log\`.
86
+ 3. If dependencies are not met, log BLOCKED and move to next task.
87
+
88
+ ---
89
+
90
+ ## Phase 2 — EXECUTE
91
+
92
+ Implement the task.
93
+
94
+ 1. Read the task description and acceptance criteria.
95
+ 2. Identify affected files using the codebase.
96
+ 3. Implement the change. Follow existing conventions.
97
+ 4. Run relevant tests/linters to verify.
98
+
99
+ ---
100
+
101
+ ## Phase 3 — LOG
102
+
103
+ Append result to \`.claudedash/execution.log\` (one JSON line):
104
+
105
+ Success:
106
+ \`\`\`json
107
+ {"task_id":"S1-T1","status":"DONE","timestamp":"2026-01-15T10:30:00Z","agent":"claude"}
108
+ \`\`\`
109
+
110
+ Failure:
111
+ \`\`\`json
112
+ {"task_id":"S1-T1","status":"FAILED","timestamp":"2026-01-15T10:30:00Z","agent":"claude","meta":{"reason":"tests failing"}}
113
+ \`\`\`
114
+
115
+ Blocked:
116
+ \`\`\`json
117
+ {"task_id":"S1-T1","status":"BLOCKED","reason":"missing API key","timestamp":"2026-01-15T10:30:00Z","agent":"claude"}
118
+ \`\`\`
119
+
120
+ ---
121
+
122
+ ## Phase 4 — NEXT
123
+
124
+ Pick the next READY task and return to Phase 1.
125
+ If no READY tasks remain, stop and report summary.
126
+
127
+ ---
128
+
129
+ ## Rules
130
+
131
+ 1. One task at a time. Finish before starting next.
132
+ 2. Always log to execution.log — never skip Phase 3.
133
+ 3. If stuck after 2 attempts, log FAILED and move on.
134
+ 4. Do not modify queue.md — it is read-only for the agent.
135
+ 5. Use \`new Date().toISOString()\` for timestamps.
136
+ `;
137
+ writeFileSync(join(claudeWatchDir, 'workflow.md'), workflowTemplate);
138
+ console.log('✓ Created workflow.md');
139
+ // Create CLAUDE.md snippet file
140
+ const claudeMdContent = `# claudedash Integration
141
+
142
+ ## Task Tracking (MANDATORY)
143
+
144
+ You MUST use the TodoWrite tool to track your work. This is not optional.
145
+ The user monitors your progress via a live dashboard that reads TodoWrite output.
146
+
147
+ Rules:
148
+ - At the START of any multi-step task, create a todo list with all steps.
149
+ - Mark each task as \`in_progress\` BEFORE you start working on it.
150
+ - Mark each task as \`completed\` IMMEDIATELY after finishing it.
151
+ - Keep exactly ONE task as \`in_progress\` at any time.
152
+ - Update the todo list as you discover new subtasks.
153
+
154
+ If you skip TodoWrite, the user cannot see what you are doing.
155
+
156
+ ## Plan Mode (if .claudedash/queue.md exists)
157
+
158
+ Follow \`.claudedash/workflow.md\` for structured task execution.
159
+ Tasks are defined in \`.claudedash/queue.md\`.
160
+ Log progress to \`.claudedash/execution.log\`.
161
+
162
+ Log format (append one JSON line per task):
163
+ \`\`\`json
164
+ {"task_id":"S1-T1","status":"DONE","timestamp":"2026-01-15T10:30:00Z","agent":"claude"}
165
+ \`\`\`
166
+
167
+ Status values: \`DONE\`, \`FAILED\`, \`BLOCKED\` (requires \`reason\` field)
168
+
169
+ ## Dashboard
170
+
171
+ Run \`npx -y claudedash@latest start\` to view progress.
172
+ `;
173
+ writeFileSync(join(claudeWatchDir, 'CLAUDE.md'), claudeMdContent);
174
+ console.log('✓ Created CLAUDE.md');
175
+ console.log('\n✓ Ready! Next steps:');
176
+ console.log(' 1. Edit .claudedash/queue.md with your tasks');
177
+ console.log(' 2. Copy .claudedash/CLAUDE.md contents into your project CLAUDE.md');
178
+ console.log(' 3. Tell your agent: "follow .claudedash/workflow.md, start with S1-T1"');
179
+ console.log(' 4. Run: npx -y claudedash@latest start');
180
+ }
181
+ catch (error) {
182
+ console.error('❌ Failed to initialize:', error);
183
+ process.exit(1);
184
+ }
185
+ });
186
+ program
187
+ .command('start')
188
+ .description('Start the claudedash server and dashboard')
189
+ .option('--claude-dir <path>', 'Path to Claude directory', join(process.env.HOME || '~', '.claude'))
190
+ .option('-p, --port <number>', 'Port number', '4317')
191
+ .action(async (opts) => {
192
+ const claudeDir = opts.claudeDir;
193
+ const claudeWatchDir = join(process.cwd(), '.claudedash');
194
+ // Detect available modes
195
+ const hasLive = existsSync(join(claudeDir, 'tasks'));
196
+ const hasPlan = existsSync(claudeWatchDir);
197
+ if (!hasLive && !hasPlan) {
198
+ console.error('❌ No data sources found.');
199
+ console.error(` Live mode: ${claudeDir}/tasks/ not found`);
200
+ console.error(' Plan mode: .claudedash/ not found (run "claudedash init")');
201
+ process.exit(1);
202
+ }
203
+ // Read port from config if plan mode available, otherwise use CLI option
204
+ let port = parseInt(opts.port, 10);
205
+ if (hasPlan) {
206
+ const configPath = join(claudeWatchDir, 'config.json');
207
+ if (existsSync(configPath)) {
208
+ try {
209
+ const configContent = await import('fs').then(fs => fs.promises.readFile(configPath, 'utf-8'));
210
+ const config = JSON.parse(configContent);
211
+ if (config.port && opts.port === '4317') {
212
+ port = config.port;
213
+ }
214
+ }
215
+ catch { /* use default port */ }
216
+ }
217
+ }
218
+ const url = `http://localhost:${port}`;
219
+ try {
220
+ await startServer({
221
+ claudeDir,
222
+ port,
223
+ agentScopeDir: hasPlan ? claudeWatchDir : undefined
224
+ });
225
+ console.log(`✓ Server running on ${url}`);
226
+ if (hasLive)
227
+ console.log(` Live mode: watching ${claudeDir}/tasks/`);
228
+ if (hasPlan)
229
+ console.log(' Plan mode: reading .claudedash/');
230
+ console.log('✓ Opening browser...');
231
+ const platform = process.platform;
232
+ const openCommand = platform === 'darwin' ? 'open' :
233
+ platform === 'win32' ? 'start' :
234
+ 'xdg-open';
235
+ exec(`${openCommand} ${url}`, (error) => {
236
+ if (error) {
237
+ console.log('Could not auto-open browser. Please visit:', url);
238
+ }
239
+ });
240
+ }
241
+ catch (error) {
242
+ console.error('❌ Failed to start server:', error);
243
+ process.exit(1);
244
+ }
245
+ });
246
+ program.parse();
247
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ClaudeSession, ContextHealth } from './types.js';
2
+ /**
3
+ * Estimates context window usage percentage for a Claude session.
4
+ *
5
+ * Uses inputTokens as the primary proxy for context occupancy (see docs/context-estimation.md).
6
+ * Returns null when token data is unavailable or empty.
7
+ */
8
+ export declare function estimateContextPercentage(session: ClaudeSession): number | null;
9
+ /**
10
+ * Builds a full ContextHealth object for a session.
11
+ * Returns null when estimation is impossible.
12
+ */
13
+ export declare function buildContextHealth(session: ClaudeSession): ContextHealth | null;
14
+ //# sourceMappingURL=contextHealth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextHealth.d.ts","sourceRoot":"","sources":["../../src/core/contextHealth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAuB,MAAM,YAAY,CAAC;AAgBpF;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAQ/E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,GAAG,IAAI,CAa/E"}
@@ -0,0 +1,46 @@
1
+ const DEFAULT_MAX_TOKENS = 200_000;
2
+ const WARN_THRESHOLD = 65;
3
+ const CRITICAL_THRESHOLD = 75;
4
+ /**
5
+ * Derives warning level from a 0-100 percentage.
6
+ */
7
+ function deriveWarningLevel(percentage) {
8
+ if (percentage >= CRITICAL_THRESHOLD)
9
+ return 'critical';
10
+ if (percentage >= WARN_THRESHOLD)
11
+ return 'warn';
12
+ return 'safe';
13
+ }
14
+ /**
15
+ * Estimates context window usage percentage for a Claude session.
16
+ *
17
+ * Uses inputTokens as the primary proxy for context occupancy (see docs/context-estimation.md).
18
+ * Returns null when token data is unavailable or empty.
19
+ */
20
+ export function estimateContextPercentage(session) {
21
+ if (!session.tokenUsage)
22
+ return null;
23
+ const { inputTokens } = session.tokenUsage;
24
+ if (inputTokens <= 0)
25
+ return null;
26
+ const percentage = Math.min(100, (inputTokens / DEFAULT_MAX_TOKENS) * 100);
27
+ return Math.round(percentage * 10) / 10; // 1 decimal place
28
+ }
29
+ /**
30
+ * Builds a full ContextHealth object for a session.
31
+ * Returns null when estimation is impossible.
32
+ */
33
+ export function buildContextHealth(session) {
34
+ const percentage = estimateContextPercentage(session);
35
+ if (percentage === null)
36
+ return null;
37
+ const tokensUsed = session.tokenUsage.inputTokens;
38
+ return {
39
+ percentage,
40
+ warningLevel: deriveWarningLevel(percentage),
41
+ tokensUsed,
42
+ maxTokens: DEFAULT_MAX_TOKENS,
43
+ estimationMethod: 'token-based',
44
+ };
45
+ }
46
+ //# sourceMappingURL=contextHealth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextHealth.js","sourceRoot":"","sources":["../../src/core/contextHealth.ts"],"names":[],"mappings":"AAEA,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAEnC,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAE9B;;GAEG;AACH,SAAS,kBAAkB,CAAC,UAAkB;IAC5C,IAAI,UAAU,IAAI,kBAAkB;QAAE,OAAO,UAAU,CAAC;IACxD,IAAI,UAAU,IAAI,cAAc;QAAE,OAAO,MAAM,CAAC;IAChD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAsB;IAC9D,IAAI,CAAC,OAAO,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAC3C,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAElC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,GAAG,kBAAkB,CAAC,GAAG,GAAG,CAAC,CAAC;IAC3E,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,kBAAkB;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAsB;IACvD,MAAM,UAAU,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAW,CAAC,WAAW,CAAC;IAEnD,OAAO;QACL,UAAU;QACV,YAAY,EAAE,kBAAkB,CAAC,UAAU,CAAC;QAC5C,UAAU;QACV,SAAS,EAAE,kBAAkB;QAC7B,gBAAgB,EAAE,aAAa;KAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ComputedTask, LogEvent, ClaudeSession, PlanInsights, LiveInsights } from './types.js';
2
+ export declare function computePlanInsights(tasks: ComputedTask[], events: LogEvent[]): PlanInsights;
3
+ export declare function computeLiveInsights(sessions: ClaudeSession[]): LiveInsights;
4
+ //# sourceMappingURL=insightsEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insightsEngine.d.ts","sourceRoot":"","sources":["../../src/core/insightsEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EAAE,EACrB,MAAM,EAAE,QAAQ,EAAE,GACjB,YAAY,CA8Dd;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,YAAY,CAgE3E"}