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
@@ -0,0 +1,283 @@
1
+ // Placeholder → regex mapping
2
+ const PLACEHOLDER_PATTERNS = {
3
+ '{id}': '(\\S+)',
4
+ '{name}': '(\\S+)',
5
+ '{slice}': '(\\S+?)',
6
+ '{n}': '(\\d+)'
7
+ };
8
+ /**
9
+ * Converts a user-friendly template into a regex string.
10
+ * "## {id}" → "^##\\s+(\S+)$"
11
+ * "# Slice {name}" → "^#\\s+Slice\\s+(\S+)$"
12
+ */
13
+ function templateToRegex(template) {
14
+ let regex = template;
15
+ // Escape regex special chars except our placeholders
16
+ regex = regex.replace(/([.+?^${}()|[\]\\])/g, (match) => {
17
+ // Don't escape if it's part of a placeholder like {id}
18
+ if (match === '{' || match === '}')
19
+ return match;
20
+ return '\\' + match;
21
+ });
22
+ // Replace placeholders with capture groups
23
+ for (const [placeholder, pattern] of Object.entries(PLACEHOLDER_PATTERNS)) {
24
+ regex = regex.replaceAll(placeholder, pattern);
25
+ }
26
+ // Replace spaces with \s+
27
+ regex = regex.replace(/\s+/g, '\\s+');
28
+ return '^' + regex + '$';
29
+ }
30
+ /**
31
+ * Builds a slice extractor regex from the id template.
32
+ * "{slice}-T{n}" → "^(\S+?)-T" (everything before the last known literal)
33
+ */
34
+ function idTemplateToSliceRegex(idTemplate) {
35
+ const sliceIdx = idTemplate.indexOf('{slice}');
36
+ if (sliceIdx === -1)
37
+ return /^(.+)$/; // No slice in template, use full ID
38
+ // Get the literal text right after {slice}
39
+ const afterSlice = idTemplate.substring(sliceIdx + '{slice}'.length);
40
+ // Take the first literal character(s) before the next placeholder
41
+ const nextPlaceholder = afterSlice.search(/\{/);
42
+ const separator = nextPlaceholder === -1 ? afterSlice : afterSlice.substring(0, nextPlaceholder);
43
+ if (!separator)
44
+ return /^(.+)$/;
45
+ const escapedSep = separator.replace(/([.+?^${}()|[\]\\])/g, '\\$1');
46
+ return new RegExp('^(\\S+?)' + escapedSep);
47
+ }
48
+ const DEFAULT_TEMPLATES = {
49
+ id: '{slice}-T{n}',
50
+ headings: {
51
+ slice: '# Slice {name}',
52
+ task: '## {id}'
53
+ }
54
+ };
55
+ const DEFAULT_FIELDS = [
56
+ { name: 'Area', type: 'enum', required: true },
57
+ { name: 'Depends', type: 'refs', required: false },
58
+ { name: 'Description', type: 'text', required: true },
59
+ { name: 'AC', type: 'text', required: true },
60
+ ];
61
+ // Maps config field names to Task property names
62
+ const FIELD_TO_PROP = {
63
+ 'area': 'area',
64
+ 'depends': 'dependsOn',
65
+ 'description': 'description',
66
+ 'ac': 'acceptanceCriteria',
67
+ };
68
+ /**
69
+ * Builds regex matchers for each field definition.
70
+ * Returns an array of { field, regex } pairs.
71
+ */
72
+ function buildFieldMatchers(fields) {
73
+ return fields.map(field => ({
74
+ field,
75
+ regex: new RegExp(`^${field.name}:\\s*(.+)$`)
76
+ }));
77
+ }
78
+ /**
79
+ * Parses a markdown queue file into structured tasks.
80
+ * Returns both tasks and any validation errors encountered.
81
+ */
82
+ export function parseQueue(content, config) {
83
+ const tasks = [];
84
+ const errors = [];
85
+ const lines = content.split('\n');
86
+ const sliceTemplate = config?.headings?.slice ?? DEFAULT_TEMPLATES.headings.slice;
87
+ const taskTemplate = config?.headings?.task ?? DEFAULT_TEMPLATES.headings.task;
88
+ const idTemplate = config?.id ?? DEFAULT_TEMPLATES.id;
89
+ const fields = config?.fields ?? DEFAULT_FIELDS;
90
+ const fieldMatchers = buildFieldMatchers(fields);
91
+ const sliceRegex = new RegExp(templateToRegex(sliceTemplate));
92
+ const taskRegex = new RegExp(templateToRegex(taskTemplate));
93
+ const sliceFromIdRegex = idTemplateToSliceRegex(idTemplate);
94
+ let currentTask = null;
95
+ let lineNumber = 0;
96
+ for (const line of lines) {
97
+ lineNumber++;
98
+ const trimmed = line.trim();
99
+ // Match slice header
100
+ const sliceMatch = trimmed.match(sliceRegex);
101
+ if (sliceMatch) {
102
+ // Slice headers are informational only; task IDs contain slice info
103
+ continue;
104
+ }
105
+ // Match task header
106
+ const taskMatch = trimmed.match(taskRegex);
107
+ if (taskMatch) {
108
+ // Save previous task if exists
109
+ if (currentTask) {
110
+ const validated = validateTask(currentTask, lineNumber - 1, fields);
111
+ if (validated.errors.length > 0) {
112
+ errors.push(...validated.errors);
113
+ }
114
+ if (validated.task) {
115
+ tasks.push(validated.task);
116
+ }
117
+ }
118
+ // Start new task
119
+ const taskId = taskMatch[1];
120
+ const sliceMatch2 = taskId.match(sliceFromIdRegex);
121
+ const sliceId = sliceMatch2 ? sliceMatch2[1] : taskId;
122
+ currentTask = {
123
+ id: taskId,
124
+ slice: sliceId,
125
+ area: '',
126
+ description: '',
127
+ acceptanceCriteria: ''
128
+ };
129
+ continue;
130
+ }
131
+ // Parse task fields dynamically from config
132
+ if (currentTask && trimmed) {
133
+ let matched = false;
134
+ for (const { field, regex } of fieldMatchers) {
135
+ const m = trimmed.match(regex);
136
+ if (!m)
137
+ continue;
138
+ matched = true;
139
+ const value = m[1].trim();
140
+ const propKey = FIELD_TO_PROP[field.name.toLowerCase()];
141
+ if (field.type === 'refs') {
142
+ // refs type: comma-separated task IDs, "-" means empty
143
+ if (propKey === 'dependsOn') {
144
+ currentTask.dependsOn = value === '-' ? [] : value.split(',').map(d => d.trim()).filter(d => d);
145
+ }
146
+ }
147
+ else if (propKey) {
148
+ // Known Task property
149
+ currentTask[propKey] = value;
150
+ }
151
+ else {
152
+ // Extra field not in Task interface — store in extra
153
+ if (!currentTask.extra)
154
+ currentTask.extra = {};
155
+ currentTask.extra[field.name] = value;
156
+ }
157
+ break;
158
+ }
159
+ if (matched)
160
+ continue;
161
+ }
162
+ }
163
+ // Save last task
164
+ if (currentTask) {
165
+ const validated = validateTask(currentTask, lineNumber, fields);
166
+ if (validated.errors.length > 0) {
167
+ errors.push(...validated.errors);
168
+ }
169
+ if (validated.task) {
170
+ tasks.push(validated.task);
171
+ }
172
+ }
173
+ // Check for duplicate IDs
174
+ const idSet = new Set();
175
+ for (const task of tasks) {
176
+ if (idSet.has(task.id)) {
177
+ errors.push(`Duplicate task ID: ${task.id}`);
178
+ }
179
+ idSet.add(task.id);
180
+ }
181
+ // Check for unknown dependencies
182
+ const taskIds = new Set(tasks.map(t => t.id));
183
+ for (const task of tasks) {
184
+ for (const dep of task.dependsOn) {
185
+ if (!taskIds.has(dep)) {
186
+ errors.push(`Task ${task.id} depends on unknown task: ${dep}`);
187
+ }
188
+ }
189
+ }
190
+ // Check for circular dependencies
191
+ const circularErrors = detectCircularDependencies(tasks);
192
+ errors.push(...circularErrors);
193
+ return { tasks, errors };
194
+ }
195
+ /**
196
+ * Validates that a task has all required fields based on field definitions.
197
+ */
198
+ function validateTask(task, lineNumber, fields) {
199
+ const errors = [];
200
+ if (!task.id) {
201
+ errors.push(`Task at line ${lineNumber} missing ID`);
202
+ return { task: null, errors };
203
+ }
204
+ for (const field of fields) {
205
+ if (!field.required)
206
+ continue;
207
+ const propKey = FIELD_TO_PROP[field.name.toLowerCase()];
208
+ if (propKey) {
209
+ const value = task[propKey];
210
+ if (!value && value !== false && !(Array.isArray(value) && value.length >= 0)) {
211
+ errors.push(`Task ${task.id} missing ${field.name} field`);
212
+ }
213
+ }
214
+ else {
215
+ // Extra field — check in task.extra
216
+ if (!task.extra?.[field.name]) {
217
+ errors.push(`Task ${task.id} missing ${field.name} field`);
218
+ }
219
+ }
220
+ }
221
+ // Ensure dependsOn is at least an empty array if refs field exists
222
+ if (task.dependsOn === undefined) {
223
+ const hasRefsField = fields.some(f => f.type === 'refs');
224
+ if (hasRefsField) {
225
+ errors.push(`Task ${task.id} missing ${fields.find(f => f.type === 'refs').name} field`);
226
+ }
227
+ else {
228
+ task.dependsOn = [];
229
+ }
230
+ }
231
+ if (errors.length > 0) {
232
+ return { task: null, errors };
233
+ }
234
+ return {
235
+ task: task,
236
+ errors: []
237
+ };
238
+ }
239
+ /**
240
+ * Detects circular dependencies using DFS with recursion stack tracking.
241
+ */
242
+ function detectCircularDependencies(tasks) {
243
+ const errors = [];
244
+ const graph = new Map();
245
+ // Build adjacency list
246
+ for (const task of tasks) {
247
+ graph.set(task.id, task.dependsOn);
248
+ }
249
+ const visited = new Set();
250
+ const recursionStack = new Set();
251
+ const path = [];
252
+ function dfs(taskId) {
253
+ visited.add(taskId);
254
+ recursionStack.add(taskId);
255
+ path.push(taskId);
256
+ const dependencies = graph.get(taskId) || [];
257
+ for (const dep of dependencies) {
258
+ if (!visited.has(dep)) {
259
+ if (dfs(dep)) {
260
+ return true;
261
+ }
262
+ }
263
+ else if (recursionStack.has(dep)) {
264
+ // Found a cycle
265
+ const cycleStart = path.indexOf(dep);
266
+ const cycle = [...path.slice(cycleStart), dep];
267
+ errors.push(`Circular dependency: ${cycle.join(' → ')}`);
268
+ return true;
269
+ }
270
+ }
271
+ recursionStack.delete(taskId);
272
+ path.pop();
273
+ return false;
274
+ }
275
+ // Check each task for cycles
276
+ for (const task of tasks) {
277
+ if (!visited.has(task.id)) {
278
+ dfs(task.id);
279
+ }
280
+ }
281
+ return errors;
282
+ }
283
+ //# sourceMappingURL=queueParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queueParser.js","sourceRoot":"","sources":["../../src/core/queueParser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Task, LogEvent, Snapshot } from './types.js';
2
+ /**
3
+ * Computes a snapshot of the current system state from tasks and log events.
4
+ */
5
+ export declare function computeSnapshot(tasks: Task[], events: LogEvent[]): Snapshot;
6
+ //# sourceMappingURL=stateEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stateEngine.d.ts","sourceRoot":"","sources":["../../src/core/stateEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAgB,QAAQ,EAAc,MAAM,YAAY,CAAC;AAErF;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAwC3E"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Computes a snapshot of the current system state from tasks and log events.
3
+ */
4
+ export function computeSnapshot(tasks, events) {
5
+ // Create a map of events by task_id for quick lookup
6
+ const eventMap = new Map();
7
+ for (const event of events) {
8
+ eventMap.set(event.task_id, event);
9
+ }
10
+ // Create a map of tasks by id for dependency resolution
11
+ const taskMap = new Map();
12
+ for (const task of tasks) {
13
+ taskMap.set(task.id, task);
14
+ }
15
+ // Sort tasks by ID for deterministic ordering
16
+ const sortedTasks = [...tasks].sort((a, b) => a.id.localeCompare(b.id));
17
+ // Compute status for each task
18
+ const computedTasks = [];
19
+ const statusCache = new Map();
20
+ for (const task of sortedTasks) {
21
+ const status = computeTaskStatus(task, eventMap, taskMap, statusCache);
22
+ const lastEvent = eventMap.get(task.id);
23
+ computedTasks.push({
24
+ ...task,
25
+ status,
26
+ lastEvent
27
+ });
28
+ }
29
+ // Aggregate statistics
30
+ const slices = computeSliceStats(computedTasks);
31
+ const summary = computeSummary(computedTasks);
32
+ return {
33
+ tasks: computedTasks,
34
+ slices,
35
+ summary
36
+ };
37
+ }
38
+ /**
39
+ * Computes the status of a single task based on events and dependencies.
40
+ */
41
+ function computeTaskStatus(task, eventMap, taskMap, statusCache) {
42
+ // Check cache first
43
+ if (statusCache.has(task.id)) {
44
+ return statusCache.get(task.id);
45
+ }
46
+ const lastEvent = eventMap.get(task.id);
47
+ // Priority: FAILED > BLOCKED(explicit) > DONE > BLOCKED(computed) > READY
48
+ if (lastEvent?.status === 'FAILED') {
49
+ statusCache.set(task.id, 'FAILED');
50
+ return 'FAILED';
51
+ }
52
+ if (lastEvent?.status === 'BLOCKED') {
53
+ statusCache.set(task.id, 'BLOCKED');
54
+ return 'BLOCKED';
55
+ }
56
+ if (lastEvent?.status === 'DONE') {
57
+ statusCache.set(task.id, 'DONE');
58
+ return 'DONE';
59
+ }
60
+ // Check dependencies
61
+ for (const depId of task.dependsOn) {
62
+ const depTask = taskMap.get(depId);
63
+ if (!depTask) {
64
+ // Unknown dependency - treat as blocking
65
+ statusCache.set(task.id, 'BLOCKED');
66
+ return 'BLOCKED';
67
+ }
68
+ const depStatus = computeTaskStatus(depTask, eventMap, taskMap, statusCache);
69
+ if (depStatus !== 'DONE') {
70
+ statusCache.set(task.id, 'BLOCKED');
71
+ return 'BLOCKED';
72
+ }
73
+ }
74
+ // All dependencies are DONE (or no dependencies)
75
+ statusCache.set(task.id, 'READY');
76
+ return 'READY';
77
+ }
78
+ /**
79
+ * Computes statistics per slice.
80
+ */
81
+ function computeSliceStats(tasks) {
82
+ const slices = {};
83
+ for (const task of tasks) {
84
+ if (!slices[task.slice]) {
85
+ slices[task.slice] = {
86
+ total: 0,
87
+ done: 0,
88
+ failed: 0,
89
+ blocked: 0,
90
+ ready: 0,
91
+ progress: 0
92
+ };
93
+ }
94
+ const slice = slices[task.slice];
95
+ slice.total++;
96
+ switch (task.status) {
97
+ case 'DONE':
98
+ slice.done++;
99
+ break;
100
+ case 'FAILED':
101
+ slice.failed++;
102
+ break;
103
+ case 'BLOCKED':
104
+ slice.blocked++;
105
+ break;
106
+ case 'READY':
107
+ slice.ready++;
108
+ break;
109
+ }
110
+ }
111
+ // Calculate progress percentage for each slice
112
+ for (const slice of Object.values(slices)) {
113
+ if (slice.total > 0) {
114
+ slice.progress = Math.round((slice.done / slice.total) * 100);
115
+ }
116
+ }
117
+ return slices;
118
+ }
119
+ /**
120
+ * Computes global summary statistics.
121
+ */
122
+ function computeSummary(tasks) {
123
+ const summary = {
124
+ total: tasks.length,
125
+ done: 0,
126
+ failed: 0,
127
+ blocked: 0,
128
+ ready: 0,
129
+ successRate: 0
130
+ };
131
+ for (const task of tasks) {
132
+ switch (task.status) {
133
+ case 'DONE':
134
+ summary.done++;
135
+ break;
136
+ case 'FAILED':
137
+ summary.failed++;
138
+ break;
139
+ case 'BLOCKED':
140
+ summary.blocked++;
141
+ break;
142
+ case 'READY':
143
+ summary.ready++;
144
+ break;
145
+ }
146
+ }
147
+ // Calculate success rate: done / (done + failed) || 0
148
+ const completed = summary.done + summary.failed;
149
+ if (completed > 0) {
150
+ summary.successRate = Math.round((summary.done / completed) * 100) / 100;
151
+ }
152
+ return summary;
153
+ }
154
+ //# sourceMappingURL=stateEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stateEngine.js","sourceRoot":"","sources":["../../src/core/stateEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ClaudeSession } from './types.js';
2
+ /**
3
+ * Reads all sessions from ~/.claude/tasks/ and ~/.claude/todos/ directories.
4
+ * tasks/: legacy format — subdirectories with individual JSON task files.
5
+ * todos/: current format — single JSON array file per session.
6
+ */
7
+ export declare function readSessions(claudeDir: string): ClaudeSession[];
8
+ /**
9
+ * Reads tasks for a specific session.
10
+ */
11
+ export declare function readSession(tasksDir: string, sessionId: string): ClaudeSession | null;
12
+ //# sourceMappingURL=todoReader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todoReader.d.ts","sourceRoot":"","sources":["../../src/core/todoReader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAc,aAAa,EAAc,MAAM,YAAY,CAAC;AAIxE;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE,CAiD/D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAsCrF"}