specsmd 0.0.0-dev.85 → 0.0.0-dev.87
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/README.md +15 -0
- package/bin/cli.js +15 -1
- package/flows/fire/agents/builder/agent.md +2 -2
- package/flows/fire/agents/builder/skills/code-review/SKILL.md +1 -1
- package/flows/fire/agents/builder/skills/run-execute/SKILL.md +16 -7
- package/flows/fire/agents/builder/skills/run-execute/scripts/complete-run.cjs +22 -3
- package/flows/fire/agents/builder/skills/run-execute/scripts/init-run.cjs +63 -20
- package/flows/fire/agents/builder/skills/run-execute/scripts/update-checkpoint.cjs +254 -0
- package/flows/fire/agents/builder/skills/run-execute/scripts/update-phase.cjs +17 -6
- package/flows/fire/agents/builder/skills/run-status/SKILL.md +1 -1
- package/flows/fire/agents/builder/skills/walkthrough-generate/SKILL.md +30 -27
- package/flows/fire/agents/orchestrator/agent.md +1 -1
- package/flows/fire/agents/orchestrator/skills/status/SKILL.md +2 -2
- package/flows/fire/memory-bank.yaml +4 -4
- package/flows/ideation/agents/orchestrator/agent.md +8 -7
- package/flows/ideation/agents/orchestrator/skills/flame/SKILL.md +1 -0
- package/flows/ideation/agents/orchestrator/skills/flame/references/evaluation-criteria.md +4 -0
- package/flows/ideation/agents/orchestrator/skills/flame/references/six-hats-method.md +12 -0
- package/flows/ideation/agents/orchestrator/skills/forge/SKILL.md +1 -0
- package/flows/ideation/agents/orchestrator/skills/forge/references/disney-method.md +8 -0
- package/flows/ideation/agents/orchestrator/skills/forge/references/pitch-framework.md +15 -0
- package/flows/ideation/agents/orchestrator/skills/spark/SKILL.md +1 -0
- package/flows/ideation/agents/orchestrator/skills/spark/references/techniques/analogy.md +7 -0
- package/flows/ideation/agents/orchestrator/skills/spark/references/techniques/first-principles.md +5 -0
- package/flows/ideation/agents/orchestrator/skills/spark/references/techniques/inversion.md +6 -0
- package/flows/ideation/agents/orchestrator/skills/spark/references/techniques/questorming.md +6 -0
- package/flows/ideation/agents/orchestrator/skills/spark/references/techniques/random-word.md +1 -0
- package/flows/ideation/agents/orchestrator/skills/spark/references/techniques/scamper.md +15 -0
- package/flows/ideation/agents/orchestrator/skills/spark/references/techniques/what-if.md +6 -0
- package/flows/ideation/shared/protocols/anti-bias.md +7 -4
- package/flows/ideation/shared/protocols/deep-thinking.md +7 -0
- package/flows/ideation/shared/protocols/diverge-converge.md +2 -0
- package/flows/ideation/shared/protocols/interaction-adaptation.md +7 -0
- package/lib/dashboard/aidlc/parser.js +581 -0
- package/lib/dashboard/fire/model.js +382 -0
- package/lib/dashboard/fire/parser.js +470 -0
- package/lib/dashboard/flow-detect.js +86 -0
- package/lib/dashboard/git/changes.js +362 -0
- package/lib/dashboard/git/worktrees.js +248 -0
- package/lib/dashboard/index.js +709 -0
- package/lib/dashboard/runtime/watch-runtime.js +122 -0
- package/lib/dashboard/simple/parser.js +293 -0
- package/lib/dashboard/tui/app.js +1675 -0
- package/lib/dashboard/tui/components/error-banner.js +35 -0
- package/lib/dashboard/tui/components/header.js +60 -0
- package/lib/dashboard/tui/components/help-footer.js +15 -0
- package/lib/dashboard/tui/components/stats-strip.js +35 -0
- package/lib/dashboard/tui/file-entries.js +383 -0
- package/lib/dashboard/tui/flow-builders.js +991 -0
- package/lib/dashboard/tui/git-builders.js +218 -0
- package/lib/dashboard/tui/helpers.js +236 -0
- package/lib/dashboard/tui/overlays.js +242 -0
- package/lib/dashboard/tui/preview.js +220 -0
- package/lib/dashboard/tui/renderer.js +76 -0
- package/lib/dashboard/tui/row-builders.js +797 -0
- package/lib/dashboard/tui/sections.js +45 -0
- package/lib/dashboard/tui/store.js +44 -0
- package/lib/dashboard/tui/views/overview-view.js +61 -0
- package/lib/dashboard/tui/views/runs-view.js +93 -0
- package/lib/dashboard/tui/worktree-builders.js +229 -0
- package/lib/installers/CodexInstaller.js +72 -1
- package/package.json +7 -3
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
function normalizeStatus(status) {
|
|
2
|
+
if (typeof status !== 'string') {
|
|
3
|
+
return undefined;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const normalized = status.toLowerCase().trim().replace(/[-\s]+/g, '_');
|
|
7
|
+
const map = {
|
|
8
|
+
pending: 'pending',
|
|
9
|
+
todo: 'pending',
|
|
10
|
+
in_progress: 'in_progress',
|
|
11
|
+
inprogress: 'in_progress',
|
|
12
|
+
active: 'in_progress',
|
|
13
|
+
completed: 'completed',
|
|
14
|
+
complete: 'completed',
|
|
15
|
+
done: 'completed',
|
|
16
|
+
blocked: 'blocked'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
return map[normalized];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function normalizeMode(mode) {
|
|
23
|
+
if (typeof mode !== 'string') {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const normalized = mode.toLowerCase().trim();
|
|
28
|
+
if (normalized === 'autopilot' || normalized === 'confirm' || normalized === 'validate') {
|
|
29
|
+
return normalized;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function normalizeScope(scope) {
|
|
36
|
+
if (typeof scope !== 'string') {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const normalized = scope.toLowerCase().trim();
|
|
41
|
+
if (normalized === 'single' || normalized === 'batch' || normalized === 'wide') {
|
|
42
|
+
return normalized;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function normalizeComplexity(complexity) {
|
|
49
|
+
if (typeof complexity !== 'string') {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const normalized = complexity.toLowerCase().trim();
|
|
54
|
+
if (normalized === 'low' || normalized === 'medium' || normalized === 'high') {
|
|
55
|
+
return normalized;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function normalizeArray(value) {
|
|
62
|
+
return Array.isArray(value) ? value : [];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function normalizeTimestamp(value) {
|
|
66
|
+
if (value == null) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (value instanceof Date) {
|
|
71
|
+
return value.toISOString();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (typeof value === 'string') {
|
|
75
|
+
return value.trim() === '' ? undefined : value;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return String(value);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function normalizeCheckpointState(value) {
|
|
82
|
+
if (typeof value !== 'string') {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const normalized = value.toLowerCase().trim().replace(/[\s-]+/g, '_');
|
|
87
|
+
return normalized === '' ? undefined : normalized;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function parseDependencies(raw) {
|
|
91
|
+
if (Array.isArray(raw)) {
|
|
92
|
+
return raw.filter((item) => typeof item === 'string' && item.trim() !== '');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (typeof raw === 'string' && raw.trim() !== '') {
|
|
96
|
+
return [raw.trim()];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function normalizeRunWorkItem(raw, fallbackIntentId = '') {
|
|
103
|
+
if (typeof raw === 'string') {
|
|
104
|
+
return {
|
|
105
|
+
id: raw,
|
|
106
|
+
intentId: fallbackIntentId,
|
|
107
|
+
mode: 'confirm',
|
|
108
|
+
status: 'pending',
|
|
109
|
+
currentPhase: undefined,
|
|
110
|
+
checkpointState: undefined,
|
|
111
|
+
currentCheckpoint: undefined
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!raw || typeof raw !== 'object') {
|
|
116
|
+
return {
|
|
117
|
+
id: '',
|
|
118
|
+
intentId: fallbackIntentId,
|
|
119
|
+
mode: 'confirm',
|
|
120
|
+
status: 'pending',
|
|
121
|
+
currentPhase: undefined,
|
|
122
|
+
checkpointState: undefined,
|
|
123
|
+
currentCheckpoint: undefined
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const id = typeof raw.id === 'string' ? raw.id : '';
|
|
128
|
+
const intentId = typeof raw.intent === 'string'
|
|
129
|
+
? raw.intent
|
|
130
|
+
: (typeof raw.intentId === 'string' ? raw.intentId : fallbackIntentId);
|
|
131
|
+
|
|
132
|
+
const status = normalizeStatus(raw.status) || 'pending';
|
|
133
|
+
const mode = normalizeMode(raw.mode) || 'confirm';
|
|
134
|
+
const currentPhase = typeof raw.current_phase === 'string'
|
|
135
|
+
? raw.current_phase
|
|
136
|
+
: (typeof raw.currentPhase === 'string' ? raw.currentPhase : undefined);
|
|
137
|
+
const checkpointState = typeof raw.checkpoint_state === 'string'
|
|
138
|
+
? raw.checkpoint_state
|
|
139
|
+
: (typeof raw.checkpointState === 'string'
|
|
140
|
+
? raw.checkpointState
|
|
141
|
+
: (typeof raw.approval_state === 'string'
|
|
142
|
+
? raw.approval_state
|
|
143
|
+
: (typeof raw.approvalState === 'string' ? raw.approvalState : undefined)));
|
|
144
|
+
const currentCheckpoint = typeof raw.current_checkpoint === 'string'
|
|
145
|
+
? raw.current_checkpoint
|
|
146
|
+
: (typeof raw.currentCheckpoint === 'string'
|
|
147
|
+
? raw.currentCheckpoint
|
|
148
|
+
: (typeof raw.checkpoint === 'string' ? raw.checkpoint : undefined));
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
id,
|
|
152
|
+
intentId,
|
|
153
|
+
mode,
|
|
154
|
+
status,
|
|
155
|
+
currentPhase,
|
|
156
|
+
checkpointState,
|
|
157
|
+
currentCheckpoint
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function normalizeState(rawState) {
|
|
162
|
+
const raw = rawState && typeof rawState === 'object' ? rawState : {};
|
|
163
|
+
|
|
164
|
+
const project = raw.project && typeof raw.project === 'object'
|
|
165
|
+
? {
|
|
166
|
+
name: typeof raw.project.name === 'string' ? raw.project.name : 'Unknown',
|
|
167
|
+
description: typeof raw.project.description === 'string' ? raw.project.description : undefined,
|
|
168
|
+
created: normalizeTimestamp(raw.project.created) || new Date().toISOString(),
|
|
169
|
+
fireVersion: typeof raw.project.fire_version === 'string'
|
|
170
|
+
? raw.project.fire_version
|
|
171
|
+
: (typeof raw.project.fireVersion === 'string'
|
|
172
|
+
? raw.project.fireVersion
|
|
173
|
+
: '0.0.0')
|
|
174
|
+
}
|
|
175
|
+
: null;
|
|
176
|
+
|
|
177
|
+
const workspace = raw.workspace && typeof raw.workspace === 'object'
|
|
178
|
+
? {
|
|
179
|
+
type: typeof raw.workspace.type === 'string' ? raw.workspace.type : 'greenfield',
|
|
180
|
+
structure: typeof raw.workspace.structure === 'string' ? raw.workspace.structure : 'monolith',
|
|
181
|
+
autonomyBias: typeof raw.workspace.autonomy_bias === 'string'
|
|
182
|
+
? raw.workspace.autonomy_bias
|
|
183
|
+
: (typeof raw.workspace.autonomyBias === 'string' ? raw.workspace.autonomyBias : 'balanced'),
|
|
184
|
+
runScopePreference: normalizeScope(raw.workspace.run_scope_preference)
|
|
185
|
+
|| normalizeScope(raw.workspace.runScopePreference)
|
|
186
|
+
|| 'single',
|
|
187
|
+
scannedAt: normalizeTimestamp(raw.workspace.scanned_at)
|
|
188
|
+
|| normalizeTimestamp(raw.workspace.scannedAt),
|
|
189
|
+
parts: normalizeArray(raw.workspace.parts)
|
|
190
|
+
}
|
|
191
|
+
: null;
|
|
192
|
+
|
|
193
|
+
const intents = normalizeArray(raw.intents).map((intent) => {
|
|
194
|
+
if (!intent || typeof intent !== 'object') {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const workItemsRaw = normalizeArray(intent.work_items).concat(normalizeArray(intent.workItems));
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
id: typeof intent.id === 'string' ? intent.id : '',
|
|
202
|
+
title: typeof intent.title === 'string' ? intent.title : '',
|
|
203
|
+
status: normalizeStatus(intent.status),
|
|
204
|
+
workItems: workItemsRaw
|
|
205
|
+
.map((item) => {
|
|
206
|
+
if (!item || typeof item !== 'object') {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
id: typeof item.id === 'string' ? item.id : '',
|
|
212
|
+
status: normalizeStatus(item.status) || 'pending',
|
|
213
|
+
mode: normalizeMode(item.mode)
|
|
214
|
+
};
|
|
215
|
+
})
|
|
216
|
+
.filter(Boolean)
|
|
217
|
+
};
|
|
218
|
+
}).filter(Boolean);
|
|
219
|
+
|
|
220
|
+
const rawRuns = raw.runs && typeof raw.runs === 'object' ? raw.runs : {};
|
|
221
|
+
|
|
222
|
+
const activeRuns = normalizeArray(rawRuns.active).map((run) => {
|
|
223
|
+
if (!run || typeof run !== 'object') {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const workItemsRaw = normalizeArray(run.work_items).concat(normalizeArray(run.workItems));
|
|
228
|
+
|
|
229
|
+
return {
|
|
230
|
+
id: typeof run.id === 'string' ? run.id : '',
|
|
231
|
+
scope: normalizeScope(run.scope) || 'single',
|
|
232
|
+
workItems: workItemsRaw.map((item) => normalizeRunWorkItem(item)).filter((item) => item.id !== ''),
|
|
233
|
+
currentItem: typeof run.current_item === 'string'
|
|
234
|
+
? run.current_item
|
|
235
|
+
: (typeof run.currentItem === 'string' ? run.currentItem : ''),
|
|
236
|
+
started: normalizeTimestamp(run.started) || '',
|
|
237
|
+
checkpointState: normalizeCheckpointState(
|
|
238
|
+
run.checkpoint_state
|
|
239
|
+
|| run.checkpointState
|
|
240
|
+
|| run.approval_state
|
|
241
|
+
|| run.approvalState
|
|
242
|
+
),
|
|
243
|
+
currentCheckpoint: typeof run.current_checkpoint === 'string'
|
|
244
|
+
? run.current_checkpoint
|
|
245
|
+
: (typeof run.currentCheckpoint === 'string'
|
|
246
|
+
? run.currentCheckpoint
|
|
247
|
+
: (typeof run.checkpoint === 'string' ? run.checkpoint : undefined))
|
|
248
|
+
};
|
|
249
|
+
}).filter(Boolean);
|
|
250
|
+
|
|
251
|
+
const completedRuns = normalizeArray(rawRuns.completed).map((run) => {
|
|
252
|
+
if (!run || typeof run !== 'object') {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const fallbackIntentId = typeof run.intent === 'string' ? run.intent : '';
|
|
257
|
+
const workItemsRaw = normalizeArray(run.work_items).concat(normalizeArray(run.workItems));
|
|
258
|
+
|
|
259
|
+
return {
|
|
260
|
+
id: typeof run.id === 'string' ? run.id : '',
|
|
261
|
+
workItems: workItemsRaw.map((item) => normalizeRunWorkItem(item, fallbackIntentId)).filter((item) => item.id !== ''),
|
|
262
|
+
checkpointState: normalizeCheckpointState(
|
|
263
|
+
run.checkpoint_state
|
|
264
|
+
|| run.checkpointState
|
|
265
|
+
|| run.approval_state
|
|
266
|
+
|| run.approvalState
|
|
267
|
+
),
|
|
268
|
+
currentCheckpoint: typeof run.current_checkpoint === 'string'
|
|
269
|
+
? run.current_checkpoint
|
|
270
|
+
: (typeof run.currentCheckpoint === 'string'
|
|
271
|
+
? run.currentCheckpoint
|
|
272
|
+
: (typeof run.checkpoint === 'string' ? run.checkpoint : undefined)),
|
|
273
|
+
completed: normalizeTimestamp(run.completed) || ''
|
|
274
|
+
};
|
|
275
|
+
}).filter(Boolean);
|
|
276
|
+
|
|
277
|
+
return {
|
|
278
|
+
project,
|
|
279
|
+
workspace,
|
|
280
|
+
intents,
|
|
281
|
+
runs: {
|
|
282
|
+
active: activeRuns,
|
|
283
|
+
completed: completedRuns
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function deriveIntentStatus(stateStatus, workItems) {
|
|
289
|
+
const normalizedState = normalizeStatus(stateStatus);
|
|
290
|
+
if (normalizedState) {
|
|
291
|
+
return normalizedState;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (!Array.isArray(workItems) || workItems.length === 0) {
|
|
295
|
+
return 'pending';
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (workItems.every((item) => item.status === 'completed')) {
|
|
299
|
+
return 'completed';
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (workItems.some((item) => item.status === 'in_progress')) {
|
|
303
|
+
return 'in_progress';
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (workItems.some((item) => item.status === 'blocked')) {
|
|
307
|
+
return 'blocked';
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return 'pending';
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function calculateStats(intents, runs, activeRuns) {
|
|
314
|
+
const safeIntents = Array.isArray(intents) ? intents : [];
|
|
315
|
+
const safeRuns = Array.isArray(runs) ? runs : [];
|
|
316
|
+
const safeActiveRuns = Array.isArray(activeRuns) ? activeRuns : [];
|
|
317
|
+
const workItems = safeIntents.flatMap((intent) => intent.workItems || []);
|
|
318
|
+
|
|
319
|
+
return {
|
|
320
|
+
totalIntents: safeIntents.length,
|
|
321
|
+
completedIntents: safeIntents.filter((intent) => intent.status === 'completed').length,
|
|
322
|
+
inProgressIntents: safeIntents.filter((intent) => intent.status === 'in_progress').length,
|
|
323
|
+
pendingIntents: safeIntents.filter((intent) => intent.status === 'pending').length,
|
|
324
|
+
blockedIntents: safeIntents.filter((intent) => intent.status === 'blocked').length,
|
|
325
|
+
totalWorkItems: workItems.length,
|
|
326
|
+
completedWorkItems: workItems.filter((item) => item.status === 'completed').length,
|
|
327
|
+
inProgressWorkItems: workItems.filter((item) => item.status === 'in_progress').length,
|
|
328
|
+
pendingWorkItems: workItems.filter((item) => item.status === 'pending').length,
|
|
329
|
+
blockedWorkItems: workItems.filter((item) => item.status === 'blocked').length,
|
|
330
|
+
totalRuns: safeRuns.length,
|
|
331
|
+
completedRuns: safeRuns.filter((run) => run.completedAt != null).length,
|
|
332
|
+
activeRunsCount: safeActiveRuns.length
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function buildPendingItems(intents) {
|
|
337
|
+
const pendingItems = [];
|
|
338
|
+
|
|
339
|
+
for (const intent of intents || []) {
|
|
340
|
+
for (const item of intent.workItems || []) {
|
|
341
|
+
if (item.status !== 'pending') {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
pendingItems.push({
|
|
346
|
+
id: item.id,
|
|
347
|
+
title: item.title,
|
|
348
|
+
intentId: intent.id,
|
|
349
|
+
intentTitle: intent.title,
|
|
350
|
+
mode: item.mode,
|
|
351
|
+
complexity: item.complexity,
|
|
352
|
+
dependencies: item.dependencies || [],
|
|
353
|
+
filePath: item.filePath
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
pendingItems.sort((a, b) => {
|
|
359
|
+
const depDiff = (a.dependencies?.length || 0) - (b.dependencies?.length || 0);
|
|
360
|
+
if (depDiff !== 0) {
|
|
361
|
+
return depDiff;
|
|
362
|
+
}
|
|
363
|
+
return a.id.localeCompare(b.id);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
return pendingItems;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
module.exports = {
|
|
370
|
+
normalizeStatus,
|
|
371
|
+
normalizeMode,
|
|
372
|
+
normalizeScope,
|
|
373
|
+
normalizeComplexity,
|
|
374
|
+
normalizeArray,
|
|
375
|
+
normalizeTimestamp,
|
|
376
|
+
parseDependencies,
|
|
377
|
+
normalizeRunWorkItem,
|
|
378
|
+
normalizeState,
|
|
379
|
+
deriveIntentStatus,
|
|
380
|
+
calculateStats,
|
|
381
|
+
buildPendingItems
|
|
382
|
+
};
|