spets 0.2.1 → 0.2.2

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 (2) hide show
  1. package/dist/index.js +148 -158
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -273,62 +273,37 @@ async function listPlugins() {
273
273
  function getClaudeSkillContent() {
274
274
  return `# Spets Executor
275
275
 
276
- You execute spets orchestrator commands. Parse JSON, follow instructions, repeat.
276
+ You execute spets workflow commands. Follow orchestrator instructions exactly.
277
277
 
278
278
  ## Startup
279
279
 
280
280
  IF \`$ARGUMENTS\` starts with "resume":
281
- 1. RUN \`npx spets orchestrate resume\`
281
+ RUN \`npx spets orchestrate resume\`
282
+ ELSE IF \`$ARGUMENTS\` starts with "list":
283
+ RUN \`npx spets orchestrate list\`
282
284
  ELSE:
283
- 1. RUN \`npx spets orchestrate init "$ARGUMENTS"\`
284
-
285
- Then GOTO **Loop**.
285
+ RUN \`npx spets orchestrate init "$ARGUMENTS"\`
286
286
 
287
287
  ## Loop
288
288
 
289
- 1. PARSE JSON response
290
- 2. SWITCH on \`type\`:
291
-
292
- ### type="phase"
293
- - EXECUTE what \`prompt\` says
294
- - RUN \`onComplete\` with your output as JSON argument
295
- - GOTO Loop
296
-
297
- ### type="checkpoint", checkpoint="clarify"
298
- - ASK user each decision in \`decisions[]\` using AskUserQuestion
299
- - Format each decision as a question with its options
300
- - RUN \`onComplete\` with \`[{decisionId, selectedOptionId}, ...]\`
301
- - GOTO Loop
289
+ 1. Parse the JSON response
290
+ 2. Read the \`instructions\` field
291
+ 3. Follow the instructions exactly
292
+ 4. Repeat until the response says to stop
302
293
 
303
- ### type="checkpoint", checkpoint="approve"
304
- - READ \`specPath\`, summarize key points to user
305
- - ASK user using AskUserQuestion with options: Approve / Revise / Reject / Stop
306
- - RUN matching \`onComplete\` based on user's choice
307
- - GOTO Loop
294
+ ## Rules
308
295
 
309
- ### type="checkpoint", checkpoint="knowledge"
310
- - Show \`suggestedKnowledge[]\` to user
311
- - ASK user if they want to save, modify, or skip
312
- - If save: RUN \`onComplete\` with entries JSON
313
- - If skip: RUN \`onSkip\`
314
- - GOTO Loop
315
-
316
- ### type="list"
317
- - Show \`tasks[]\` to user with taskId, description, status, currentStep
318
- - ASK user which task to resume
319
- - RUN \`npx spets orchestrate resume <selectedTaskId>\`
320
- - GOTO Loop
321
-
322
- ### type="complete" or "error"
323
- - PRINT message
324
- - STOP
296
+ - NEVER skip or modify orchestrator commands
297
+ - NEVER improvise steps \u2014 only do what instructions say
298
+ - Always pass JSON output as a single-quoted string argument
299
+ - Minify JSON when passing as command arguments
325
300
 
326
301
  ## Forbidden
327
302
 
328
303
  EnterPlanMode, TaskCreate, TaskUpdate
329
304
 
330
305
  $ARGUMENTS
331
- description: Task description for the workflow (or "resume" to continue a previous workflow)
306
+ description: Task description for the workflow (or "resume" to list/continue previous workflows)
332
307
  `;
333
308
  }
334
309
  function getCodexSkillContent() {
@@ -339,65 +314,37 @@ description: SDD workflow executor - orchestrator-controlled spec-driven develop
339
314
 
340
315
  # Spets Executor
341
316
 
342
- You execute spets orchestrator commands. Parse JSON, follow instructions, repeat.
317
+ You execute spets workflow commands. Follow orchestrator instructions exactly.
343
318
 
344
319
  ## Startup
345
320
 
346
321
  IF \`$ARGUMENTS\` starts with "resume":
347
- 1. RUN \`npx spets orchestrate resume\`
322
+ RUN \`npx spets orchestrate resume\`
323
+ ELSE IF \`$ARGUMENTS\` starts with "list":
324
+ RUN \`npx spets orchestrate list\`
348
325
  ELSE:
349
- 1. RUN \`npx spets orchestrate init "$ARGUMENTS"\`
350
-
351
- Then GOTO **Loop**.
326
+ RUN \`npx spets orchestrate init "$ARGUMENTS"\`
352
327
 
353
328
  ## Loop
354
329
 
355
- 1. PARSE JSON response
356
- 2. SWITCH on \`type\`:
330
+ 1. Parse the JSON response
331
+ 2. Read the \`instructions\` field
332
+ 3. Follow the instructions exactly
333
+ 4. Repeat until the response says to stop
357
334
 
358
- ### type="phase"
359
- - EXECUTE what \`prompt\` says
360
- - RUN \`onComplete\` with your output as minified JSON argument
361
- - GOTO Loop
335
+ ## Rules
362
336
 
363
- ### type="checkpoint", checkpoint="clarify"
364
- - FORMAT decisions as table for user:
365
- | # | Decision | Context | Options |
366
- |---|----------|---------|---------|
367
- | d1 | ... | ... | 1. ... 2. ... |
368
- - ASK user to pick an option for each decision
369
- - RUN \`onComplete\` with \`[{decisionId, selectedOptionId}, ...]\`
370
- - GOTO Loop
371
-
372
- ### type="checkpoint", checkpoint="approve"
373
- - READ \`specPath\`, summarize key points to user
374
- - ASK user with options: Approve / Revise / Reject / Stop
375
- - RUN matching \`onComplete\` based on user's choice
376
- - GOTO Loop
377
-
378
- ### type="checkpoint", checkpoint="knowledge"
379
- - Show \`suggestedKnowledge[]\` to user
380
- - ASK user if they want to save, modify, or skip
381
- - If save: RUN \`onComplete\` with entries JSON
382
- - If skip: RUN \`onSkip\`
383
- - GOTO Loop
384
-
385
- ### type="list"
386
- - Show \`tasks[]\` to user with taskId, description, status, currentStep
387
- - ASK user which task to resume
388
- - RUN \`npx spets orchestrate resume <selectedTaskId>\`
389
- - GOTO Loop
390
-
391
- ### type="complete" or "error"
392
- - PRINT message
393
- - STOP
337
+ - NEVER skip or modify orchestrator commands
338
+ - NEVER improvise steps \u2014 only do what instructions say
339
+ - Always pass JSON output as a single-quoted string argument
340
+ - Minify JSON when passing as command arguments
394
341
 
395
342
  ## Forbidden
396
343
 
397
344
  Planning mode, task tracking tools
398
345
 
399
346
  $ARGUMENTS
400
- description: Task description for the workflow (or "resume" to continue a previous workflow)
347
+ description: Task description for the workflow (or "resume" to list/continue previous workflows)
401
348
  `;
402
349
  }
403
350
  function getGeminiSkillContent() {
@@ -408,61 +355,37 @@ description: SDD workflow executor - orchestrator-controlled spec-driven develop
408
355
 
409
356
  # Spets Executor
410
357
 
411
- You execute spets orchestrator commands. Parse JSON, follow instructions, repeat.
358
+ You execute spets workflow commands. Follow orchestrator instructions exactly.
412
359
 
413
360
  ## Startup
414
361
 
415
362
  IF \`$ARGUMENTS\` starts with "resume":
416
- 1. RUN \`npx spets orchestrate resume\`
363
+ RUN \`npx spets orchestrate resume\`
364
+ ELSE IF \`$ARGUMENTS\` starts with "list":
365
+ RUN \`npx spets orchestrate list\`
417
366
  ELSE:
418
- 1. RUN \`npx spets orchestrate init "$ARGUMENTS"\`
419
-
420
- Then GOTO **Loop**.
367
+ RUN \`npx spets orchestrate init "$ARGUMENTS"\`
421
368
 
422
369
  ## Loop
423
370
 
424
- 1. PARSE JSON response
425
- 2. SWITCH on \`type\`:
371
+ 1. Parse the JSON response
372
+ 2. Read the \`instructions\` field
373
+ 3. Follow the instructions exactly
374
+ 4. Repeat until the response says to stop
426
375
 
427
- ### type="phase"
428
- - EXECUTE what \`prompt\` says
429
- - RUN \`onComplete\` with your output as JSON argument
430
- - GOTO Loop
376
+ ## Rules
431
377
 
432
- ### type="checkpoint", checkpoint="clarify"
433
- - ASK user each decision in \`decisions[]\`
434
- - RUN \`onComplete\` with \`[{decisionId, selectedOptionId}, ...]\`
435
- - GOTO Loop
436
-
437
- ### type="checkpoint", checkpoint="approve"
438
- - READ \`specPath\`, summarize key points to user
439
- - ASK user with options: Approve / Revise / Reject / Stop
440
- - RUN matching \`onComplete\` based on user's choice
441
- - GOTO Loop
442
-
443
- ### type="checkpoint", checkpoint="knowledge"
444
- - Show \`suggestedKnowledge[]\` to user
445
- - ASK user if they want to save, modify, or skip
446
- - If save: RUN \`onComplete\` with entries JSON
447
- - If skip: RUN \`onSkip\`
448
- - GOTO Loop
449
-
450
- ### type="list"
451
- - Show \`tasks[]\` to user with taskId, description, status, currentStep
452
- - ASK user which task to resume
453
- - RUN \`npx spets orchestrate resume <selectedTaskId>\`
454
- - GOTO Loop
455
-
456
- ### type="complete" or "error"
457
- - PRINT message
458
- - STOP
378
+ - NEVER skip or modify orchestrator commands
379
+ - NEVER improvise steps \u2014 only do what instructions say
380
+ - Always pass JSON output as a single-quoted string argument
381
+ - Minify JSON when passing as command arguments
459
382
 
460
383
  ## Forbidden
461
384
 
462
385
  Planning mode, task tracking tools
463
386
 
464
387
  $ARGUMENTS
465
- description: Task description for the workflow (or "resume" to continue a previous workflow)
388
+ description: Task description for the workflow (or "resume" to list/continue previous workflows)
466
389
  `;
467
390
  }
468
391
 
@@ -504,19 +427,26 @@ async function initCommand(options) {
504
427
  const hookTemplate = join2(__dirname, "..", "templates", "hooks", "cleanup-branch.sh");
505
428
  if (existsSync2(hookTemplate)) {
506
429
  const hookDest = join2(spetsDir, "hooks", "cleanup-branch.sh");
507
- cpSync(hookTemplate, hookDest);
508
- try {
509
- execSync(`chmod +x "${hookDest}"`);
510
- } catch {
430
+ if (!existsSync2(hookDest)) {
431
+ cpSync(hookTemplate, hookDest);
432
+ try {
433
+ execSync(`chmod +x "${hookDest}"`);
434
+ } catch {
435
+ }
511
436
  }
512
437
  }
513
438
  const knowledgeGuideTemplate = join2(__dirname, "..", "templates", "knowledge", "guide.md");
514
439
  if (existsSync2(knowledgeGuideTemplate)) {
515
440
  const guideDest = join2(spetsDir, "knowledge", "guide.md");
516
- cpSync(knowledgeGuideTemplate, guideDest);
441
+ if (!existsSync2(guideDest)) {
442
+ cpSync(knowledgeGuideTemplate, guideDest);
443
+ }
517
444
  }
518
445
  const githubInfo = getGitHubInfoFromRemote();
519
- writeFileSync2(join2(spetsDir, "config.yml"), getDefaultConfig(githubInfo));
446
+ const configPath = join2(spetsDir, "config.yml");
447
+ if (!existsSync2(configPath)) {
448
+ writeFileSync2(configPath, getDefaultConfig(githubInfo));
449
+ }
520
450
  createDefaultSteps(spetsDir);
521
451
  createClaudeCommand(cwd);
522
452
  printEnhancedInitOutput(options);
@@ -740,20 +670,23 @@ async function runInteractiveSetup(cwd, spetsDir, options) {
740
670
  const hookTemplate = join2(__dirname, "..", "templates", "hooks", "cleanup-branch.sh");
741
671
  if (existsSync2(hookTemplate)) {
742
672
  const hookDest = join2(spetsDir, "hooks", "cleanup-branch.sh");
743
- cpSync(hookTemplate, hookDest);
744
- try {
745
- execSync(`chmod +x "${hookDest}"`);
746
- } catch {
673
+ if (!existsSync2(hookDest)) {
674
+ cpSync(hookTemplate, hookDest);
675
+ try {
676
+ execSync(`chmod +x "${hookDest}"`);
677
+ } catch {
678
+ }
747
679
  }
748
680
  }
749
681
  const knowledgeGuideTemplate = join2(__dirname, "..", "templates", "knowledge", "guide.md");
750
- if (existsSync2(knowledgeGuideTemplate)) {
751
- cpSync(knowledgeGuideTemplate, join2(spetsDir, "knowledge", "guide.md"));
682
+ const guideDest = join2(spetsDir, "knowledge", "guide.md");
683
+ if (existsSync2(knowledgeGuideTemplate) && !existsSync2(guideDest)) {
684
+ cpSync(knowledgeGuideTemplate, guideDest);
685
+ }
686
+ const configPath = join2(spetsDir, "config.yml");
687
+ if (!existsSync2(configPath)) {
688
+ writeFileSync2(configPath, getDefaultConfig(githubInfo, { agent, githubEnabled }));
752
689
  }
753
- writeFileSync2(
754
- join2(spetsDir, "config.yml"),
755
- getDefaultConfig(githubInfo, { agent, githubEnabled })
756
- );
757
690
  createDefaultSteps(spetsDir);
758
691
  createClaudeCommand(cwd);
759
692
  if (githubEnabled && githubInfo) {
@@ -765,10 +698,16 @@ async function runInteractiveSetup(cwd, spetsDir, options) {
765
698
  function createDefaultSteps(spetsDir) {
766
699
  const planDir = join2(spetsDir, "steps", "01-plan");
767
700
  mkdirSync2(planDir, { recursive: true });
768
- writeFileSync2(join2(planDir, "template.md"), getPlanTemplate());
701
+ const planTemplatePath = join2(planDir, "template.md");
702
+ if (!existsSync2(planTemplatePath)) {
703
+ writeFileSync2(planTemplatePath, getPlanTemplate());
704
+ }
769
705
  const implementDir = join2(spetsDir, "steps", "02-implement");
770
706
  mkdirSync2(implementDir, { recursive: true });
771
- writeFileSync2(join2(implementDir, "template.md"), getImplementTemplate());
707
+ const implementTemplatePath = join2(implementDir, "template.md");
708
+ if (!existsSync2(implementTemplatePath)) {
709
+ writeFileSync2(implementTemplatePath, getImplementTemplate());
710
+ }
772
711
  }
773
712
  function getPlanTemplate() {
774
713
  const fullTemplate = readFileSync(join2(__dirname, "..", "templates", "steps", "01-plan", "template.md"), "utf-8");
@@ -1753,6 +1692,36 @@ function buildKnowledgeExtractPrompt(params) {
1753
1692
  return parts.join("\n");
1754
1693
  }
1755
1694
 
1695
+ // src/orchestrator/instructions.ts
1696
+ function phaseWithJsonOutput(onComplete) {
1697
+ return `Execute the prompt. Then run:
1698
+ ${onComplete} '<your_json_output>'`;
1699
+ }
1700
+ function phaseExecute(outputFile, onComplete) {
1701
+ return `Execute the prompt \u2014 write the document to ${outputFile}. Then run:
1702
+ ${onComplete}`;
1703
+ }
1704
+ function checkpointClarify(onComplete) {
1705
+ return [
1706
+ `Present each decision to the user with its options. Collect their choices. Then run:`,
1707
+ ` ${onComplete} '<answers_json>'`,
1708
+ `Answer format: [{decisionId, selectedOptionId, customInput?}, ...]`
1709
+ ].join("\n");
1710
+ }
1711
+ function checkpointApprove(specPath, cmds) {
1712
+ return [
1713
+ `Read the document at ${specPath}. Summarize key points to the user. Ask: Approve / Revise / Reject / Stop. Then run the matching command:`,
1714
+ ` approve: ${cmds.approve}`,
1715
+ ` revise: ${cmds.revise}`,
1716
+ ` reject: ${cmds.reject}`,
1717
+ ` stop: ${cmds.stop}`
1718
+ ].join("\n");
1719
+ }
1720
+ var PRINT_MESSAGE_AND_STOP = "Print the message. Stop.";
1721
+ var PRINT_ERROR_AND_STOP = "Print the error. Stop.";
1722
+ var LIST_TASKS = "Show tasks to user. Ask which to resume. Run:\n npx spets orchestrate resume <selectedTaskId>";
1723
+ var LIST_EMPTY = "No resumable tasks found. Show this to the user. Stop.";
1724
+
1756
1725
  // src/orchestrator/responses.ts
1757
1726
  function buildPhaseExploreResponse(cwd, state) {
1758
1727
  const steps = getSteps(cwd);
@@ -1774,6 +1743,7 @@ function buildPhaseExploreResponse(cwd, state) {
1774
1743
  previousOutput,
1775
1744
  cwd
1776
1745
  });
1746
+ const onComplete = `npx spets orchestrate explore-done ${state.taskId}`;
1777
1747
  return {
1778
1748
  type: "phase",
1779
1749
  phase: "explore",
@@ -1786,7 +1756,8 @@ function buildPhaseExploreResponse(cwd, state) {
1786
1756
  context: {
1787
1757
  previousOutput
1788
1758
  },
1789
- onComplete: `npx spets orchestrate explore-done ${state.taskId}`
1759
+ onComplete,
1760
+ instructions: phaseWithJsonOutput(onComplete)
1790
1761
  };
1791
1762
  }
1792
1763
  function buildPhaseClarifyResponse(cwd, state) {
@@ -1801,6 +1772,7 @@ function buildPhaseClarifyResponse(cwd, state) {
1801
1772
  // Legacy support
1802
1773
  cwd
1803
1774
  });
1775
+ const onComplete = `npx spets orchestrate clarify-done ${state.taskId}`;
1804
1776
  return {
1805
1777
  type: "phase",
1806
1778
  phase: "clarify",
@@ -1812,7 +1784,8 @@ function buildPhaseClarifyResponse(cwd, state) {
1812
1784
  previousDecisions: state.decisionHistory,
1813
1785
  previousQA: state.qaHistory,
1814
1786
  // Legacy support
1815
- onComplete: `npx spets orchestrate clarify-done ${state.taskId}`
1787
+ onComplete,
1788
+ instructions: phaseWithJsonOutput(onComplete)
1816
1789
  };
1817
1790
  }
1818
1791
  function buildPhaseExecuteResponse(cwd, state) {
@@ -1855,6 +1828,8 @@ ${issues}`;
1855
1828
  verifyFeedback,
1856
1829
  cwd
1857
1830
  });
1831
+ const onComplete = `npx spets orchestrate execute-done ${state.taskId}`;
1832
+ const outputFile = join9(outputPath, state.taskId, `${state.currentStep}.md`);
1858
1833
  return {
1859
1834
  type: "phase",
1860
1835
  phase: "execute",
@@ -1869,11 +1844,12 @@ ${issues}`;
1869
1844
  context: {
1870
1845
  template: hasTemplate ? templatePath : void 0,
1871
1846
  previousOutput,
1872
- output: join9(outputPath, state.taskId, `${state.currentStep}.md`),
1847
+ output: outputFile,
1873
1848
  revisionFeedback: state.revisionFeedback,
1874
1849
  verifyFeedback
1875
1850
  },
1876
- onComplete: `npx spets orchestrate execute-done ${state.taskId}`
1851
+ onComplete,
1852
+ instructions: phaseExecute(outputFile, onComplete)
1877
1853
  };
1878
1854
  }
1879
1855
  function buildPhaseVerifyResponse(cwd, state) {
@@ -1892,6 +1868,7 @@ function buildPhaseVerifyResponse(cwd, state) {
1892
1868
  loadedKnowledge: state.loadedKnowledge?.map((k) => ({ filename: k.filename, content: k.content })),
1893
1869
  cwd
1894
1870
  });
1871
+ const onComplete = `npx spets orchestrate verify-done ${state.taskId}`;
1895
1872
  return {
1896
1873
  type: "phase",
1897
1874
  phase: "verify",
@@ -1907,7 +1884,8 @@ function buildPhaseVerifyResponse(cwd, state) {
1907
1884
  template: hasTemplate ? templatePath : void 0,
1908
1885
  document: documentPath
1909
1886
  },
1910
- onComplete: `npx spets orchestrate verify-done ${state.taskId}`
1887
+ onComplete,
1888
+ instructions: phaseWithJsonOutput(onComplete)
1911
1889
  };
1912
1890
  }
1913
1891
  function buildPhaseKnowledgeResponse(cwd, state) {
@@ -1920,6 +1898,7 @@ function buildPhaseKnowledgeResponse(cwd, state) {
1920
1898
  guide,
1921
1899
  cwd
1922
1900
  });
1901
+ const onComplete = `npx spets orchestrate knowledge-extract-done ${state.taskId}`;
1923
1902
  return {
1924
1903
  type: "phase",
1925
1904
  phase: "knowledge",
@@ -1932,21 +1911,31 @@ function buildPhaseKnowledgeResponse(cwd, state) {
1932
1911
  totalSteps: state.totalSteps
1933
1912
  },
1934
1913
  guide,
1935
- onComplete: `npx spets orchestrate knowledge-extract-done ${state.taskId}`
1914
+ onComplete,
1915
+ instructions: phaseWithJsonOutput(onComplete)
1936
1916
  };
1937
1917
  }
1938
1918
  function buildCheckpointClarifyResponse(state) {
1919
+ const onComplete = `npx spets orchestrate clarified ${state.taskId}`;
1939
1920
  return {
1940
1921
  type: "checkpoint",
1941
1922
  checkpoint: "clarify",
1942
1923
  taskId: state.taskId,
1943
1924
  step: state.currentStep,
1944
1925
  decisions: state.decisions || [],
1945
- onComplete: `npx spets orchestrate clarified ${state.taskId} '<answers_json>'`
1926
+ onComplete: `${onComplete} '<answers_json>'`,
1927
+ instructions: checkpointClarify(onComplete)
1946
1928
  };
1947
1929
  }
1948
1930
  function buildCheckpointApproveResponse(cwd, state) {
1949
1931
  const outputPath = getOutputPath(cwd);
1932
+ const specPath = join9(outputPath, state.taskId, `${state.currentStep}.md`);
1933
+ const cmds = {
1934
+ approve: `npx spets orchestrate approve ${state.taskId}`,
1935
+ revise: `npx spets orchestrate revise ${state.taskId} '<feedback>'`,
1936
+ reject: `npx spets orchestrate reject ${state.taskId}`,
1937
+ stop: `npx spets orchestrate stop ${state.taskId}`
1938
+ };
1950
1939
  return {
1951
1940
  type: "checkpoint",
1952
1941
  checkpoint: "approve",
@@ -1954,14 +1943,10 @@ function buildCheckpointApproveResponse(cwd, state) {
1954
1943
  step: state.currentStep,
1955
1944
  stepIndex: state.stepIndex,
1956
1945
  totalSteps: state.totalSteps,
1957
- specPath: join9(outputPath, state.taskId, `${state.currentStep}.md`),
1946
+ specPath,
1958
1947
  options: ["approve", "revise", "reject", "stop"],
1959
- onComplete: {
1960
- approve: `npx spets orchestrate approve ${state.taskId}`,
1961
- revise: `npx spets orchestrate revise ${state.taskId} '<feedback>'`,
1962
- reject: `npx spets orchestrate reject ${state.taskId}`,
1963
- stop: `npx spets orchestrate stop ${state.taskId}`
1964
- }
1948
+ onComplete: cmds,
1949
+ instructions: checkpointApprove(specPath, cmds)
1965
1950
  };
1966
1951
  }
1967
1952
  function buildCompleteResponse(cwd, state, status) {
@@ -1984,11 +1969,12 @@ function buildCompleteResponse(cwd, state, status) {
1984
1969
  status,
1985
1970
  taskId: state.taskId,
1986
1971
  outputs,
1987
- message: messages[status]
1972
+ message: messages[status],
1973
+ instructions: PRINT_MESSAGE_AND_STOP
1988
1974
  };
1989
1975
  }
1990
1976
  function buildErrorResponse(error, taskId, step) {
1991
- const response = { type: "error", error };
1977
+ const response = { type: "error", error, instructions: PRINT_ERROR_AND_STOP };
1992
1978
  if (taskId) response.taskId = taskId;
1993
1979
  if (step) response.step = step;
1994
1980
  return response;
@@ -2330,7 +2316,7 @@ var Orchestrator = class {
2330
2316
  const outputPath = getOutputPath(this.cwd);
2331
2317
  const tasks = [];
2332
2318
  if (!existsSync11(outputPath)) {
2333
- return { type: "list", tasks: [] };
2319
+ return { type: "list", tasks: [], instructions: LIST_EMPTY };
2334
2320
  }
2335
2321
  const dirs = readdirSync2(outputPath, { withFileTypes: true }).filter((d) => d.isDirectory());
2336
2322
  for (const dir of dirs) {
@@ -2352,7 +2338,11 @@ var Orchestrator = class {
2352
2338
  const bTime = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
2353
2339
  return bTime - aTime;
2354
2340
  });
2355
- return { type: "list", tasks };
2341
+ return {
2342
+ type: "list",
2343
+ tasks,
2344
+ instructions: tasks.length > 0 ? LIST_TASKS : LIST_EMPTY
2345
+ };
2356
2346
  }
2357
2347
  /**
2358
2348
  * Get current workflow status
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spets",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Spec Driven Development Execution Framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",