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.
- package/LICENSE +21 -0
- package/README.md +207 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +247 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/contextHealth.d.ts +14 -0
- package/dist/core/contextHealth.d.ts.map +1 -0
- package/dist/core/contextHealth.js +46 -0
- package/dist/core/contextHealth.js.map +1 -0
- package/dist/core/insightsEngine.d.ts +4 -0
- package/dist/core/insightsEngine.d.ts.map +1 -0
- package/dist/core/insightsEngine.js +223 -0
- package/dist/core/insightsEngine.js.map +1 -0
- package/dist/core/logParser.d.ts +11 -0
- package/dist/core/logParser.d.ts.map +1 -0
- package/dist/core/logParser.js +127 -0
- package/dist/core/logParser.js.map +1 -0
- package/dist/core/qualityTimeline.d.ts +8 -0
- package/dist/core/qualityTimeline.d.ts.map +1 -0
- package/dist/core/qualityTimeline.js +40 -0
- package/dist/core/qualityTimeline.js.map +1 -0
- package/dist/core/queueParser.d.ts +25 -0
- package/dist/core/queueParser.d.ts.map +1 -0
- package/dist/core/queueParser.js +283 -0
- package/dist/core/queueParser.js.map +1 -0
- package/dist/core/stateEngine.d.ts +6 -0
- package/dist/core/stateEngine.d.ts.map +1 -0
- package/dist/core/stateEngine.js +154 -0
- package/dist/core/stateEngine.js.map +1 -0
- package/dist/core/todoReader.d.ts +12 -0
- package/dist/core/todoReader.d.ts.map +1 -0
- package/dist/core/todoReader.js +301 -0
- package/dist/core/todoReader.js.map +1 -0
- package/dist/core/types.d.ts +167 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/worktreeDetector.d.ts +18 -0
- package/dist/core/worktreeDetector.d.ts.map +1 -0
- package/dist/core/worktreeDetector.js +99 -0
- package/dist/core/worktreeDetector.js.map +1 -0
- package/dist/core/worktreeMapper.d.ts +10 -0
- package/dist/core/worktreeMapper.d.ts.map +1 -0
- package/dist/core/worktreeMapper.js +38 -0
- package/dist/core/worktreeMapper.js.map +1 -0
- package/dist/public/404/index.html +1 -0
- package/dist/public/404.html +1 -0
- package/dist/public/__next.__PAGE__.txt +9 -0
- package/dist/public/__next._full.txt +17 -0
- package/dist/public/__next._head.txt +5 -0
- package/dist/public/__next._index.txt +5 -0
- package/dist/public/__next._tree.txt +2 -0
- package/dist/public/_next/static/36m05Da62vzqVee_ifGeq/_buildManifest.js +42 -0
- package/dist/public/_next/static/36m05Da62vzqVee_ifGeq/_clientMiddlewareManifest.json +1 -0
- package/dist/public/_next/static/36m05Da62vzqVee_ifGeq/_ssgManifest.js +1 -0
- package/dist/public/_next/static/chunks/02c545b35c5a7a0d.js +2 -0
- package/dist/public/_next/static/chunks/4611ba49fa18f0e2.js +1 -0
- package/dist/public/_next/static/chunks/64ee9622541d967c.js +1 -0
- package/dist/public/_next/static/chunks/66f59f4487e89157.js +1 -0
- package/dist/public/_next/static/chunks/a6dad97d9634a72d.js +1 -0
- package/dist/public/_next/static/chunks/a6dad97d9634a72d.js.map +1 -0
- package/dist/public/_next/static/chunks/bfa1988f6340e536.css +2 -0
- package/dist/public/_next/static/chunks/d1f8ac52f80f9493.js +5 -0
- package/dist/public/_next/static/chunks/turbopack-87039ecabc6befeb.js +4 -0
- package/dist/public/_not-found/__next._full.txt +13 -0
- package/dist/public/_not-found/__next._head.txt +5 -0
- package/dist/public/_not-found/__next._index.txt +5 -0
- package/dist/public/_not-found/__next._not-found.__PAGE__.txt +5 -0
- package/dist/public/_not-found/__next._not-found.txt +4 -0
- package/dist/public/_not-found/__next._tree.txt +2 -0
- package/dist/public/_not-found/index.html +1 -0
- package/dist/public/_not-found/index.txt +13 -0
- package/dist/public/index.html +1 -0
- package/dist/public/index.txt +17 -0
- package/dist/server/routes/live.d.ts +9 -0
- package/dist/server/routes/live.d.ts.map +1 -0
- package/dist/server/routes/live.js +53 -0
- package/dist/server/routes/live.js.map +1 -0
- package/dist/server/routes/observability.d.ts +6 -0
- package/dist/server/routes/observability.d.ts.map +1 -0
- package/dist/server/routes/observability.js +18 -0
- package/dist/server/routes/observability.js.map +1 -0
- package/dist/server/routes/plan.d.ts +7 -0
- package/dist/server/routes/plan.d.ts.map +1 -0
- package/dist/server/routes/plan.js +134 -0
- package/dist/server/routes/plan.js.map +1 -0
- package/dist/server/server.d.ts +7 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +42 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/watcher.d.ts +20 -0
- package/dist/server/watcher.d.ts.map +1 -0
- package/dist/server/watcher.js +97 -0
- package/dist/server/watcher.js.map +1 -0
- 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"}
|