specsmd 0.1.62 → 0.1.63
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/flows/fire/agents/builder/skills/run-execute/scripts/complete-run.cjs +3 -3
- package/flows/fire/agents/builder/skills/run-execute/scripts/init-run.cjs +54 -19
- package/flows/fire/agents/builder/skills/run-execute/scripts/update-checkpoint.cjs +4 -4
- package/flows/fire/agents/builder/skills/run-execute/scripts/update-phase.cjs +6 -6
- package/package.json +1 -1
|
@@ -704,7 +704,7 @@ function printUsage() {
|
|
|
704
704
|
console.error('');
|
|
705
705
|
console.error('Arguments:');
|
|
706
706
|
console.error(' rootPath - Project root directory');
|
|
707
|
-
console.error(' runId - Run ID to complete (e.g., run-003)');
|
|
707
|
+
console.error(' runId - Run ID to complete (e.g., run-fabriqa-2026-003)');
|
|
708
708
|
console.error('');
|
|
709
709
|
console.error('Flags:');
|
|
710
710
|
console.error(' --complete-item - Complete only the current work item (batch/wide runs)');
|
|
@@ -718,8 +718,8 @@ function printUsage() {
|
|
|
718
718
|
console.error(' --coverage=N - Coverage percentage');
|
|
719
719
|
console.error('');
|
|
720
720
|
console.error('Examples:');
|
|
721
|
-
console.error(' node complete-run.cjs /project run-003 --complete-item');
|
|
722
|
-
console.error(' node complete-run.cjs /project run-003 --complete-run --tests=5 --coverage=85');
|
|
721
|
+
console.error(' node complete-run.cjs /project run-fabriqa-2026-003 --complete-item');
|
|
722
|
+
console.error(' node complete-run.cjs /project run-fabriqa-2026-003 --complete-run --tests=5 --coverage=85');
|
|
723
723
|
}
|
|
724
724
|
|
|
725
725
|
// =============================================================================
|
|
@@ -152,26 +152,61 @@ function writeState(statePath, state) {
|
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
// =============================================================================
|
|
155
|
-
// Run ID Generation (CRITICAL - checks
|
|
155
|
+
// Run ID Generation (CRITICAL - checks state and file system)
|
|
156
156
|
// =============================================================================
|
|
157
157
|
|
|
158
|
-
function
|
|
158
|
+
function sanitizeWorktreeToken(value) {
|
|
159
|
+
const normalized = String(value || '')
|
|
160
|
+
.toLowerCase()
|
|
161
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
162
|
+
.replace(/^-+|-+$/g, '');
|
|
163
|
+
return normalized || 'workspace';
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function resolveWorktreeToken(rootPath) {
|
|
167
|
+
const baseName = path.basename(path.resolve(String(rootPath || '')));
|
|
168
|
+
return sanitizeWorktreeToken(baseName);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function parseRunSequence(runId, worktreeToken) {
|
|
172
|
+
if (typeof runId !== 'string' || runId.trim() === '') {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const legacyMatch = runId.match(/^run-(\d+)$/);
|
|
177
|
+
if (legacyMatch) {
|
|
178
|
+
const parsed = parseInt(legacyMatch[1], 10);
|
|
179
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const worktreeMatch = runId.match(/^run-([a-z0-9][a-z0-9-]*)-(\d+)$/);
|
|
183
|
+
if (worktreeMatch && worktreeMatch[1] === worktreeToken) {
|
|
184
|
+
const parsed = parseInt(worktreeMatch[2], 10);
|
|
185
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function generateRunId(rootPath, runsPath, state) {
|
|
159
192
|
// Ensure runs directory exists
|
|
160
193
|
if (!fs.existsSync(runsPath)) {
|
|
161
194
|
fs.mkdirSync(runsPath, { recursive: true });
|
|
162
195
|
}
|
|
163
196
|
|
|
164
|
-
|
|
165
|
-
let
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
197
|
+
const worktreeToken = resolveWorktreeToken(rootPath);
|
|
198
|
+
let maxFromState = 0;
|
|
199
|
+
|
|
200
|
+
// Source 1: Get max from state.yaml run history (active + completed)
|
|
201
|
+
const stateRuns = state?.runs || {};
|
|
202
|
+
const stateRunRecords = [
|
|
203
|
+
...(Array.isArray(stateRuns.active) ? stateRuns.active : []),
|
|
204
|
+
...(Array.isArray(stateRuns.completed) ? stateRuns.completed : [])
|
|
205
|
+
];
|
|
206
|
+
for (const run of stateRunRecords) {
|
|
207
|
+
const num = parseRunSequence(run?.id, worktreeToken);
|
|
208
|
+
if (num != null && num > maxFromState) {
|
|
209
|
+
maxFromState = num;
|
|
175
210
|
}
|
|
176
211
|
}
|
|
177
212
|
|
|
@@ -180,9 +215,9 @@ function generateRunId(runsPath, state) {
|
|
|
180
215
|
try {
|
|
181
216
|
const entries = fs.readdirSync(runsPath);
|
|
182
217
|
for (const entry of entries) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
218
|
+
const num = parseRunSequence(entry, worktreeToken);
|
|
219
|
+
if (num != null && num > maxFromFileSystem) {
|
|
220
|
+
maxFromFileSystem = num;
|
|
186
221
|
}
|
|
187
222
|
}
|
|
188
223
|
} catch (err) {
|
|
@@ -194,10 +229,10 @@ function generateRunId(runsPath, state) {
|
|
|
194
229
|
}
|
|
195
230
|
|
|
196
231
|
// Use MAX of both to ensure no duplicates
|
|
197
|
-
const maxNum = Math.max(
|
|
232
|
+
const maxNum = Math.max(maxFromState, maxFromFileSystem);
|
|
198
233
|
const nextNum = maxNum + 1;
|
|
199
234
|
|
|
200
|
-
return `run-${String(nextNum).padStart(3, '0')}`;
|
|
235
|
+
return `run-${worktreeToken}-${String(nextNum).padStart(3, '0')}`;
|
|
201
236
|
}
|
|
202
237
|
|
|
203
238
|
// =============================================================================
|
|
@@ -333,7 +368,7 @@ function initRun(rootPath, workItems, scope) {
|
|
|
333
368
|
}
|
|
334
369
|
|
|
335
370
|
// Generate run ID (checks both history AND file system)
|
|
336
|
-
const runId = generateRunId(runsPath, state);
|
|
371
|
+
const runId = generateRunId(rootPath, runsPath, state);
|
|
337
372
|
const runPath = path.join(runsPath, runId);
|
|
338
373
|
|
|
339
374
|
// Create run folder
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* node update-checkpoint.cjs <rootPath> <runId> <checkpointState> [--item=<workItemId>] [--checkpoint=<name>]
|
|
10
10
|
*
|
|
11
11
|
* Examples:
|
|
12
|
-
* node update-checkpoint.cjs /project run-001 awaiting_approval --checkpoint=plan
|
|
13
|
-
* node update-checkpoint.cjs /project run-001 approved
|
|
12
|
+
* node update-checkpoint.cjs /project run-fabriqa-2026-001 awaiting_approval --checkpoint=plan
|
|
13
|
+
* node update-checkpoint.cjs /project run-fabriqa-2026-001 approved
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
const fs = require('fs');
|
|
@@ -223,8 +223,8 @@ function printUsage() {
|
|
|
223
223
|
console.error(` ${VALID_STATES.join(', ')}`);
|
|
224
224
|
console.error('');
|
|
225
225
|
console.error('Examples:');
|
|
226
|
-
console.error(' node update-checkpoint.cjs /project run-001 awaiting_approval --checkpoint=plan');
|
|
227
|
-
console.error(' node update-checkpoint.cjs /project run-001 approved');
|
|
226
|
+
console.error(' node update-checkpoint.cjs /project run-fabriqa-2026-001 awaiting_approval --checkpoint=plan');
|
|
227
|
+
console.error(' node update-checkpoint.cjs /project run-fabriqa-2026-001 approved');
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
if (require.main === module) {
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* node update-phase.cjs <rootPath> <runId> <phase>
|
|
11
11
|
*
|
|
12
12
|
* Examples:
|
|
13
|
-
* node update-phase.cjs /project run-001 execute
|
|
14
|
-
* node update-phase.cjs /project run-001 test
|
|
15
|
-
* node update-phase.cjs /project run-001 review
|
|
13
|
+
* node update-phase.cjs /project run-fabriqa-2026-001 execute
|
|
14
|
+
* node update-phase.cjs /project run-fabriqa-2026-001 test
|
|
15
|
+
* node update-phase.cjs /project run-fabriqa-2026-001 review
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
const fs = require('fs');
|
|
@@ -219,12 +219,12 @@ function printUsage() {
|
|
|
219
219
|
console.error('');
|
|
220
220
|
console.error('Arguments:');
|
|
221
221
|
console.error(' rootPath - Project root directory');
|
|
222
|
-
console.error(' runId - Run ID (e.g., run-001)');
|
|
222
|
+
console.error(' runId - Run ID (e.g., run-fabriqa-2026-001)');
|
|
223
223
|
console.error(' phase - New phase: plan, execute, test, review');
|
|
224
224
|
console.error('');
|
|
225
225
|
console.error('Examples:');
|
|
226
|
-
console.error(' node update-phase.cjs /project run-001 execute');
|
|
227
|
-
console.error(' node update-phase.cjs /project run-001 test');
|
|
226
|
+
console.error(' node update-phase.cjs /project run-fabriqa-2026-001 execute');
|
|
227
|
+
console.error(' node update-phase.cjs /project run-fabriqa-2026-001 test');
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
if (require.main === module) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specsmd",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.63",
|
|
4
4
|
"description": "Multi-agent orchestration system for AI-native software development. Delivers AI-DLC, Agile, and custom SDLC flows as markdown-based agent systems.",
|
|
5
5
|
"main": "lib/installer.js",
|
|
6
6
|
"bin": {
|