@zhuan-ai/zhuanspec 2.15.6 → 2.15.7
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/dist/cli/index.js
CHANGED
|
@@ -272,7 +272,7 @@ progressCmd
|
|
|
272
272
|
// Progress set-phase subcommand
|
|
273
273
|
progressCmd
|
|
274
274
|
.command('set-phase <change-id> <phase>')
|
|
275
|
-
.description('Set phase for a change (
|
|
275
|
+
.description('Set phase for a change (idle, techDesign, propose, apply, review, archive). Workflow-entry phases (idle/techDesign/propose) auto-create the change directory if missing.')
|
|
276
276
|
.action(async (changeId, phase) => {
|
|
277
277
|
try {
|
|
278
278
|
const progressCommand = new ProgressCommand();
|
|
@@ -32,6 +32,10 @@ export declare class ProgressCommand {
|
|
|
32
32
|
/**
|
|
33
33
|
* Set phase for a change
|
|
34
34
|
* Usage: zhuanspec progress set-phase <change-id> <phase>
|
|
35
|
+
*
|
|
36
|
+
* Workflow-entry phases (idle/techDesign/propose) auto-create the change
|
|
37
|
+
* directory if it does not exist; later phases (apply/review/archive)
|
|
38
|
+
* require the directory to already exist to avoid typo-creating ghost dirs.
|
|
35
39
|
*/
|
|
36
40
|
setPhase(changeId: string, phase: string): Promise<void>;
|
|
37
41
|
/**
|
|
@@ -350,19 +350,30 @@ export class ProgressCommand {
|
|
|
350
350
|
/**
|
|
351
351
|
* Set phase for a change
|
|
352
352
|
* Usage: zhuanspec progress set-phase <change-id> <phase>
|
|
353
|
+
*
|
|
354
|
+
* Workflow-entry phases (idle/techDesign/propose) auto-create the change
|
|
355
|
+
* directory if it does not exist; later phases (apply/review/archive)
|
|
356
|
+
* require the directory to already exist to avoid typo-creating ghost dirs.
|
|
353
357
|
*/
|
|
354
358
|
async setPhase(changeId, phase) {
|
|
359
|
+
// Validate phase first (fail fast on user typos so we don't surface
|
|
360
|
+
// misleading "Change not found" errors when the real issue is the phase name).
|
|
361
|
+
// Match case-insensitively but keep the canonical casing from PHASE_ORDER
|
|
362
|
+
// (e.g. user input 'techdesign' / 'TECHDESIGN' / 'techDesign' all map to 'techDesign').
|
|
363
|
+
const normalizedPhase = PHASE_ORDER.find(p => p.toLowerCase() === phase.toLowerCase());
|
|
364
|
+
if (!normalizedPhase) {
|
|
365
|
+
throw new Error(`Invalid phase: ${phase}. Valid phases: ${PHASE_ORDER.join(', ')}`);
|
|
366
|
+
}
|
|
355
367
|
const cwd = resolveZhuanSpecRoot();
|
|
356
368
|
const changeDir = path.join(cwd, 'zhuanspec', 'changes', changeId);
|
|
357
|
-
|
|
369
|
+
const dirExists = await FileSystemUtils.directoryExists(changeDir);
|
|
370
|
+
// Workflow-entry phases may create the change directory; later phases must not.
|
|
371
|
+
const ENTRY_PHASES = ['idle', 'techDesign', 'propose'];
|
|
372
|
+
if (!dirExists && !ENTRY_PHASES.includes(normalizedPhase)) {
|
|
358
373
|
throw new Error(`Change '${changeId}' not found`);
|
|
359
374
|
}
|
|
360
|
-
//
|
|
361
|
-
|
|
362
|
-
if (!PHASE_ORDER.includes(normalizedPhase)) {
|
|
363
|
-
throw new Error(`Invalid phase: ${phase}. Valid phases: ${PHASE_ORDER.join(', ')}`);
|
|
364
|
-
}
|
|
365
|
-
// Update progress.json
|
|
375
|
+
// Update progress.json (initializeProgress creates metrics/ recursively,
|
|
376
|
+
// which also creates the change directory itself when missing).
|
|
366
377
|
await initializeProgress(changeId, normalizedPhase);
|
|
367
378
|
// Read and display result
|
|
368
379
|
const progressPath = path.join(changeDir, 'metrics', 'progress.json');
|