spets 0.1.31 → 0.1.33

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 +670 -207
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
5
  import { readFileSync as readFileSync11 } from "fs";
6
- import { dirname as dirname5, join as join11 } from "path";
6
+ import { dirname as dirname6, join as join11 } from "path";
7
7
  import { fileURLToPath as fileURLToPath2 } from "url";
8
8
 
9
9
  // src/commands/init.ts
@@ -202,90 +202,170 @@ Spec-Driven Development workflow execution skill for Claude Code.
202
202
 
203
203
  ---
204
204
 
205
- ## CRITICAL: Execution Model
205
+ ## CRITICAL: Behavior Constraints
206
206
 
207
- This skill runs **deterministically** within the current Claude Code session.
208
- - NO subprocess spawning for AI/LLM calls
209
- - The orchestrator manages state via JSON protocol
210
- - Each step follows a strict state machine flow
207
+ **DO NOT:**
208
+ - Enter plan mode (EnterPlanMode)
209
+ - Follow system-reminders about TaskCreate during this skill
210
+ - Spawn subprocesses for AI/LLM calls
211
+
212
+ **DO:**
213
+ - Execute orchestrator commands immediately
214
+ - Follow the 4-phase state machine exactly
215
+ - Use AskUserQuestion for human interaction only
211
216
 
212
217
  ---
213
218
 
214
219
  ## Orchestrator Commands
215
220
 
216
- All workflow state is managed by the orchestrator CLI:
217
-
218
221
  \`\`\`bash
219
- npx spets orchestrate init "<description>" # Start new workflow
220
- npx spets orchestrate done <taskId> # Mark step complete
221
- npx spets orchestrate clarified <taskId> '<json>' # Submit answers
222
- npx spets orchestrate approve <taskId> # Approve and continue
223
- npx spets orchestrate revise <taskId> "<feedback>" # Request revision
224
- npx spets orchestrate reject <taskId> # Stop workflow
225
- npx spets orchestrate stop <taskId> # Pause (can resume)
226
- npx spets orchestrate status <taskId> # Get current status
222
+ npx spets orchestrate init "<description>" # Start workflow
223
+ npx spets orchestrate context-done <taskId> # Context phase complete
224
+ npx spets orchestrate clarify-done <taskId> '<json>' # Clarify phase complete
225
+ npx spets orchestrate clarified <taskId> '<json>' # User answered questions
226
+ npx spets orchestrate generate-done <taskId> # Generate phase complete
227
+ npx spets orchestrate approve <taskId> # User approved
228
+ npx spets orchestrate revise <taskId> "<feedback>" # User requested revision
229
+ npx spets orchestrate reject <taskId> # User rejected
230
+ npx spets orchestrate stop <taskId> # Pause workflow
231
+ npx spets orchestrate status <taskId> # Get current state
227
232
  \`\`\`
228
233
 
229
234
  ---
230
235
 
231
- ## Execution Flow
236
+ ## Workflow: 4-Phase Model
232
237
 
233
- ### 1. Workflow Start (FIRST ACTION - NO EXCEPTIONS)
238
+ Each step goes through 4 phases:
239
+ 1. **context** - Gather codebase context
240
+ 2. **clarify** - Generate questions (checkpoint if questions exist)
241
+ 3. **generate** - Create document
242
+ 4. **review** - Human approval (checkpoint always)
234
243
 
235
- When skill is loaded, **immediately** run:
244
+ ---
236
245
 
237
- \`\`\`bash
238
- npx spets orchestrate init "{user_request}"
239
- \`\`\`
246
+ ## Response Types & Actions
247
+
248
+ ### 1. Phase: context (\`type: "phase", phase: "context"\`)
249
+
250
+ AI gathers context about the codebase.
251
+
252
+ **Action:**
253
+ 1. Read \`context.instruction\` file
254
+ 2. Read \`context.previousOutput\` file (if exists)
255
+ 3. Explore codebase relevant to the task description
256
+ 4. Call: \`npx spets orchestrate context-done {taskId}\`
257
+
258
+ **Note:** Do NOT include context as argument - just signal completion.
259
+
260
+ ---
261
+
262
+ ### 2. Phase: clarify (\`type: "phase", phase: "clarify"\`)
263
+
264
+ AI generates questions based on gathered context.
265
+
266
+ **Action:**
267
+ 1. Review \`gatheredContext\` and \`previousQA\` (if exists)
268
+ 2. Generate clarifying questions if needed (max 3-4)
269
+ 3. If questions exist:
270
+ \`\`\`bash
271
+ npx spets orchestrate clarify-done {taskId} '[{"id":"q1","question":"..."},...]'
272
+ \`\`\`
273
+ 4. If no questions needed:
274
+ \`\`\`bash
275
+ npx spets orchestrate clarify-done {taskId} '[]'
276
+ \`\`\`
277
+
278
+ ---
279
+
280
+ ### 3. Checkpoint: clarify (\`type: "checkpoint", checkpoint: "clarify"\`)
281
+
282
+ Human needs to answer questions.
283
+
284
+ **Action:**
285
+ 1. Use **AskUserQuestion** tool to ask the questions
286
+ 2. Collect answers into JSON array
287
+ 3. Call:
288
+ \`\`\`bash
289
+ npx spets orchestrate clarified {taskId} '[{"questionId":"q1","answer":"..."},...]'
290
+ \`\`\`
291
+
292
+ ---
293
+
294
+ ### 4. Phase: generate (\`type: "phase", phase: "generate"\`)
295
+
296
+ AI creates the document.
297
+
298
+ **Action:**
299
+ 1. Read \`context.instruction\` file
300
+ 2. Read \`context.template\` file (if exists)
301
+ 3. Read \`context.previousOutput\` file (if exists)
302
+ 4. Use \`gatheredContext\` and \`answers\` (if provided)
303
+ 5. Consider \`context.revisionFeedback\` (if revision)
304
+ 6. Write document to \`context.output\`
305
+ 7. Call: \`npx spets orchestrate generate-done {taskId}\`
306
+
307
+ ---
240
308
 
241
- ### 2. Document Generation (type: step)
309
+ ### 5. Checkpoint: approve (\`type: "checkpoint", checkpoint: "approve"\`)
242
310
 
243
- When you receive \`type: "step"\`:
311
+ Human reviews and approves document.
244
312
 
245
- 1. **Read the instruction file** from context.instruction
246
- 2. **Read the template file** from context.template (if exists)
247
- 3. **Read previous output** from context.previousOutput (if exists)
248
- 4. **Generate the document** following the instruction and template
249
- 5. **Write the document** to context.output
250
- 6. **Mark step as done**: \`npx spets orchestrate done {taskId}\`
313
+ **Action:**
314
+ 1. Read and summarize document from \`specPath\`
315
+ 2. Use **AskUserQuestion** with options:
316
+ - **Approve** - Proceed to next step
317
+ - **Revise** - Request changes (collect feedback)
318
+ - **Reject** - Stop workflow
319
+ - **Stop** - Pause for later
251
320
 
252
- ### 3. Question Resolution (type: checkpoint, checkpoint: clarify)
321
+ 3. Execute based on selection:
322
+ - Approve: \`npx spets orchestrate approve {taskId}\`
323
+ - Revise: \`npx spets orchestrate revise {taskId} "{feedback}"\`
324
+ - Reject: \`npx spets orchestrate reject {taskId}\`
325
+ - Stop: \`npx spets orchestrate stop {taskId}\`
253
326
 
254
- 1. **Use AskUserQuestion** to ask the questions
255
- 2. **Collect answers** into JSON format
256
- 3. **Submit answers**: \`npx spets orchestrate clarified {taskId} '<answers_json>'\`
327
+ ---
257
328
 
258
- ### 4. Approval Request (type: checkpoint, checkpoint: approve)
329
+ ### 6. Complete (\`type: "complete"\`)
259
330
 
260
- 1. **Display document summary** from specPath
261
- 2. **Use AskUserQuestion** with options: Approve, Revise, Reject, Stop
262
- 3. **Execute the selected action**
331
+ Workflow finished.
263
332
 
264
- ### 5. Workflow Complete (type: complete)
333
+ **Action:**
334
+ - \`completed\`: Show success, list outputs
335
+ - \`stopped\`: Show resume instructions
336
+ - \`rejected\`: Show rejection message
265
337
 
266
- Display completion message based on status (completed, stopped, rejected)
338
+ ---
339
+
340
+ ### 7. Error (\`type: "error"\`)
341
+
342
+ **Action:** Display error message and stop.
267
343
 
268
344
  ---
269
345
 
270
- ## Response Type Actions Summary
346
+ ## Response Type Summary
271
347
 
272
- | Type | Checkpoint | Action |
273
- |------|------------|--------|
274
- | step | - | Generate document, write to output, call done |
275
- | checkpoint | clarify | Ask questions, call clarified with answers |
276
- | checkpoint | approve | Show doc, ask for decision, call appropriate command |
277
- | complete | - | Show final message, end skill |
278
- | error | - | Show error, end skill |
348
+ | type | phase/checkpoint | Action |
349
+ |------|------------------|--------|
350
+ | phase | context | Explore codebase \u2192 \`context-done\` |
351
+ | phase | clarify | Generate questions \u2192 \`clarify-done\` |
352
+ | checkpoint | clarify | AskUserQuestion \u2192 \`clarified\` |
353
+ | phase | generate | Write document \u2192 \`generate-done\` |
354
+ | checkpoint | approve | AskUserQuestion \u2192 \`approve/revise/reject/stop\` |
355
+ | complete | - | Display final message |
356
+ | error | - | Display error, stop |
279
357
 
280
358
  ---
281
359
 
282
- ## Critical Implementation Rules
360
+ ## Execution Flow (FIRST ACTION)
283
361
 
284
- 1. **ORCHESTRATOR FIRST** - Always call orchestrator before any action
285
- 2. **ONE STEP AT A TIME** - Complete one step, get approval, then next
286
- 3. **DETERMINISTIC FLOW** - Follow the exact state machine transitions
287
- 4. **NO PROCESS SPAWN** - Generate documents in current session
288
- 5. **WAIT FOR APPROVAL** - Never proceed without user approval
362
+ When skill is loaded, **immediately** run:
363
+
364
+ \`\`\`bash
365
+ npx spets orchestrate init "{user_request}"
366
+ \`\`\`
367
+
368
+ Then follow the response type actions above in a loop until \`type: "complete"\` or \`type: "error"\`.
289
369
 
290
370
  ---
291
371
 
@@ -294,24 +374,36 @@ Display completion message based on status (completed, stopped, rejected)
294
374
  \`\`\`
295
375
  User: /spets Add user authentication
296
376
 
297
- [Skill calls: npx spets orchestrate init "Add user authentication"]
298
- [Receives: type=step, step=01-plan]
377
+ [Run: npx spets orchestrate init "Add user authentication"]
378
+ [Response: type=phase, phase=context, step=01-plan]
299
379
 
300
- [Skill reads instruction.md and template.md]
301
- [Skill generates plan document]
302
- [Skill writes to .spets/outputs/.../01-plan.md]
303
- [Skill calls: npx spets orchestrate done mku3abc-xyz]
380
+ [Read instruction, explore codebase]
381
+ [Run: npx spets orchestrate context-done {taskId}]
382
+ [Response: type=phase, phase=clarify]
304
383
 
305
- [Receives: type=checkpoint, checkpoint=approve]
306
- [Skill shows document summary]
307
- [Skill asks user: Approve/Revise/Reject/Stop?]
384
+ [Generate 2 questions about auth approach]
385
+ [Run: npx spets orchestrate clarify-done {taskId} '[{"id":"q1",...},{"id":"q2",...}]']
386
+ [Response: type=checkpoint, checkpoint=clarify]
308
387
 
309
- User: Approve
388
+ [AskUserQuestion with the questions]
389
+ [User answers]
390
+ [Run: npx spets orchestrate clarified {taskId} '[{"questionId":"q1","answer":"OAuth"},...]']
391
+ [Response: type=phase, phase=clarify]
310
392
 
311
- [Skill calls: npx spets orchestrate approve mku3abc-xyz]
312
- [Receives: type=step, step=02-implement]
393
+ [No more questions needed]
394
+ [Run: npx spets orchestrate clarify-done {taskId} '[]']
395
+ [Response: type=phase, phase=generate]
313
396
 
314
- [... continues with implementation step ...]
397
+ [Read instruction, template, write document]
398
+ [Run: npx spets orchestrate generate-done {taskId}]
399
+ [Response: type=checkpoint, checkpoint=approve]
400
+
401
+ [Show document summary, AskUserQuestion: Approve/Revise/Reject/Stop]
402
+ [User: Approve]
403
+ [Run: npx spets orchestrate approve {taskId}]
404
+ [Response: type=phase, phase=context, step=02-implement]
405
+
406
+ [... continues with next step ...]
315
407
  \`\`\`
316
408
 
317
409
  $ARGUMENTS
@@ -1531,7 +1623,7 @@ var Orchestrator = class {
1531
1623
  };
1532
1624
 
1533
1625
  // src/core/step-executor.ts
1534
- import { existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
1626
+ import { existsSync as existsSync6, writeFileSync as writeFileSync4 } from "fs";
1535
1627
  import matter3 from "gray-matter";
1536
1628
 
1537
1629
  // src/core/prompt-builder.ts
@@ -1772,8 +1864,115 @@ function buildGeneratePrompt(params) {
1772
1864
  outputPath
1773
1865
  };
1774
1866
  }
1867
+ function buildSectionPrompt(params) {
1868
+ const { section, sharedContext, gatheredContext, answers } = params;
1869
+ const parts = [];
1870
+ parts.push(`# Section: ${section.title}`);
1871
+ parts.push("");
1872
+ parts.push("## Document Context");
1873
+ parts.push("");
1874
+ parts.push(`**Goal:** ${sharedContext.documentGoal}`);
1875
+ parts.push(`**Step:** ${sharedContext.stepName}`);
1876
+ parts.push(`**Total Sections:** ${sharedContext.totalSections}`);
1877
+ parts.push("");
1878
+ parts.push("## Document Structure");
1879
+ parts.push("");
1880
+ parts.push("```");
1881
+ parts.push(sharedContext.treeOverview);
1882
+ parts.push("```");
1883
+ parts.push("");
1884
+ parts.push("## Your Position");
1885
+ parts.push("");
1886
+ parts.push(`- **Path:** ${section.position.path.join(" > ")}`);
1887
+ parts.push(`- **Siblings:** ${section.position.siblings.join(", ") || "None"}`);
1888
+ parts.push(`- **Parent:** ${section.position.parent || "Root"}`);
1889
+ parts.push("");
1890
+ if (gatheredContext) {
1891
+ parts.push("## Gathered Context");
1892
+ parts.push("");
1893
+ parts.push(gatheredContext);
1894
+ parts.push("");
1895
+ }
1896
+ if (answers && answers.length > 0) {
1897
+ parts.push("## User Answers");
1898
+ parts.push("");
1899
+ for (const answer of answers) {
1900
+ parts.push(`- **${answer.questionId}**: ${answer.answer}`);
1901
+ }
1902
+ parts.push("");
1903
+ }
1904
+ if (section.templateContent) {
1905
+ parts.push("## Template Guide");
1906
+ parts.push("");
1907
+ parts.push(section.templateContent);
1908
+ parts.push("");
1909
+ }
1910
+ parts.push("## Your Task");
1911
+ parts.push("");
1912
+ parts.push(`Write the "${section.title.replace(/^#+\\s*/, "")}" section.`);
1913
+ parts.push("Consider how it relates to sibling sections and contributes to the parent section.");
1914
+ parts.push("");
1915
+ parts.push("## Output");
1916
+ parts.push("");
1917
+ parts.push(`Save to: \`${section.outputPath}\``);
1918
+ parts.push("");
1919
+ parts.push("Write ONLY the content for this section (including its header).");
1920
+ parts.push("Do NOT include content from other sections.");
1921
+ parts.push("");
1922
+ return {
1923
+ prompt: parts.join("\n"),
1924
+ outputPath: section.outputPath
1925
+ };
1926
+ }
1927
+ function buildConsolidatePrompt(params) {
1928
+ const { group, childContents, sharedContext, parentTitle } = params;
1929
+ const parts = [];
1930
+ parts.push("# Consolidate Sections");
1931
+ parts.push("");
1932
+ parts.push("## Document Context");
1933
+ parts.push("");
1934
+ parts.push(`**Goal:** ${sharedContext.documentGoal}`);
1935
+ parts.push(`**Step:** ${sharedContext.stepName}`);
1936
+ parts.push("");
1937
+ parts.push("## Document Structure");
1938
+ parts.push("");
1939
+ parts.push("```");
1940
+ parts.push(sharedContext.treeOverview);
1941
+ parts.push("```");
1942
+ parts.push("");
1943
+ parts.push("## Your Task");
1944
+ parts.push("");
1945
+ parts.push(`Consolidate the following child sections into the parent section "${parentTitle || group.parentId}".`);
1946
+ parts.push("");
1947
+ parts.push("## Child Sections to Consolidate");
1948
+ parts.push("");
1949
+ for (const child of childContents) {
1950
+ parts.push(`### Child: ${child.id}`);
1951
+ parts.push("");
1952
+ parts.push(child.content);
1953
+ parts.push("");
1954
+ parts.push("---");
1955
+ parts.push("");
1956
+ }
1957
+ parts.push("## Output Instructions");
1958
+ parts.push("");
1959
+ parts.push(`Save consolidated content to: \`${group.outputPath}\``);
1960
+ parts.push("");
1961
+ parts.push("**Guidelines:**");
1962
+ parts.push("- Combine child sections into a coherent parent section");
1963
+ parts.push("- Maintain the hierarchy (parent header, then children)");
1964
+ parts.push("- Ensure smooth transitions between sections");
1965
+ parts.push("- Preserve all content from child sections");
1966
+ parts.push("");
1967
+ return {
1968
+ prompt: parts.join("\n"),
1969
+ outputPath: group.outputPath
1970
+ };
1971
+ }
1775
1972
 
1776
1973
  // src/core/step-executor.ts
1974
+ import { readFileSync as readFileSync6, existsSync as fsExistsSync, mkdirSync as mkdirSync4 } from "fs";
1975
+ import { dirname as dirname3 } from "path";
1777
1976
  import { join as join6 } from "path";
1778
1977
  var StepExecutor = class {
1779
1978
  adapter;
@@ -1893,6 +2092,122 @@ var StepExecutor = class {
1893
2092
  return { phase: "generate" };
1894
2093
  }
1895
2094
  // ==========================================================================
2095
+ // Phase 3 (Section Mode): Parallel Section Generation
2096
+ // ==========================================================================
2097
+ /**
2098
+ * Execute section generation phase - AI creates individual sections in parallel
2099
+ */
2100
+ async executeSectionsPhase(sections, sharedContext, gatheredContext, answers) {
2101
+ this.adapter.io.notify(
2102
+ `Phase 3/4: Generating ${sections.length} sections in parallel`,
2103
+ "info"
2104
+ );
2105
+ const results = await Promise.all(
2106
+ sections.map(async (section) => {
2107
+ try {
2108
+ const params = {
2109
+ section: {
2110
+ id: section.id,
2111
+ title: section.title,
2112
+ outputPath: section.outputPath,
2113
+ instruction: section.instruction,
2114
+ position: section.position,
2115
+ templateContent: section.templateContent
2116
+ },
2117
+ sharedContext,
2118
+ gatheredContext,
2119
+ answers
2120
+ };
2121
+ const { prompt, outputPath } = buildSectionPrompt(params);
2122
+ const dir = dirname3(outputPath);
2123
+ if (!fsExistsSync(dir)) {
2124
+ mkdirSync4(dir, { recursive: true });
2125
+ }
2126
+ await this.adapter.ai.execute({ prompt, outputPath });
2127
+ if (!fsExistsSync(outputPath)) {
2128
+ return { id: section.id, success: false, error: `File not created: ${outputPath}` };
2129
+ }
2130
+ this.adapter.io.notify(`Section created: ${section.id}`, "success");
2131
+ return { id: section.id, success: true };
2132
+ } catch (error) {
2133
+ return {
2134
+ id: section.id,
2135
+ success: false,
2136
+ error: error instanceof Error ? error.message : String(error)
2137
+ };
2138
+ }
2139
+ })
2140
+ );
2141
+ const failures = results.filter((r) => !r.success);
2142
+ if (failures.length > 0) {
2143
+ const errorMsg = failures.map((f) => `${f.id}: ${f.error}`).join(", ");
2144
+ throw new Error(`Section generation failed: ${errorMsg}`);
2145
+ }
2146
+ return { phase: "generate" };
2147
+ }
2148
+ /**
2149
+ * Execute consolidation phase - AI merges child sections into parent
2150
+ */
2151
+ async executeConsolidatePhase(groups, sharedContext, getSectionPath) {
2152
+ this.adapter.io.notify(
2153
+ `Consolidating ${groups.length} section groups`,
2154
+ "info"
2155
+ );
2156
+ const results = await Promise.all(
2157
+ groups.map(async (group) => {
2158
+ try {
2159
+ const childContents = [];
2160
+ for (const childId of group.childIds) {
2161
+ const childPath = getSectionPath(childId);
2162
+ if (!childPath || !fsExistsSync(childPath)) {
2163
+ return {
2164
+ parentId: group.parentId,
2165
+ success: false,
2166
+ error: `Child section not found: ${childId}`
2167
+ };
2168
+ }
2169
+ childContents.push({
2170
+ id: childId,
2171
+ content: readFileSync6(childPath, "utf-8")
2172
+ });
2173
+ }
2174
+ const params = {
2175
+ group: {
2176
+ parentId: group.parentId,
2177
+ childIds: group.childIds,
2178
+ outputPath: group.outputPath
2179
+ },
2180
+ childContents,
2181
+ sharedContext
2182
+ };
2183
+ const { prompt, outputPath } = buildConsolidatePrompt(params);
2184
+ const dir = dirname3(outputPath);
2185
+ if (!fsExistsSync(dir)) {
2186
+ mkdirSync4(dir, { recursive: true });
2187
+ }
2188
+ await this.adapter.ai.execute({ prompt, outputPath });
2189
+ if (!fsExistsSync(outputPath)) {
2190
+ return { parentId: group.parentId, success: false, error: `File not created: ${outputPath}` };
2191
+ }
2192
+ this.adapter.io.notify(`Consolidated: ${group.parentId}`, "success");
2193
+ return { parentId: group.parentId, success: true };
2194
+ } catch (error) {
2195
+ return {
2196
+ parentId: group.parentId,
2197
+ success: false,
2198
+ error: error instanceof Error ? error.message : String(error)
2199
+ };
2200
+ }
2201
+ })
2202
+ );
2203
+ const failures = results.filter((r) => !r.success);
2204
+ if (failures.length > 0) {
2205
+ const errorMsg = failures.map((f) => `${f.parentId}: ${f.error}`).join(", ");
2206
+ throw new Error(`Consolidation failed: ${errorMsg}`);
2207
+ }
2208
+ return { phase: "generate" };
2209
+ }
2210
+ // ==========================================================================
1896
2211
  // Phase 4: Review (Approval)
1897
2212
  // ==========================================================================
1898
2213
  /**
@@ -2025,8 +2340,8 @@ var StepExecutor = class {
2025
2340
 
2026
2341
  // src/adapters/cli.ts
2027
2342
  import { spawn, spawnSync } from "child_process";
2028
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync7, mkdirSync as mkdirSync4 } from "fs";
2029
- import { dirname as dirname3 } from "path";
2343
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync7, mkdirSync as mkdirSync5 } from "fs";
2344
+ import { dirname as dirname4 } from "path";
2030
2345
  import { input, select, confirm } from "@inquirer/prompts";
2031
2346
  var CLIAIAdapter = class {
2032
2347
  claudeCommand;
@@ -2037,9 +2352,9 @@ var CLIAIAdapter = class {
2037
2352
  console.log(`
2038
2353
  \u{1F4DD} Generating...`);
2039
2354
  if (params.outputPath) {
2040
- const outputDir = dirname3(params.outputPath);
2355
+ const outputDir = dirname4(params.outputPath);
2041
2356
  if (!existsSync7(outputDir)) {
2042
- mkdirSync4(outputDir, { recursive: true });
2357
+ mkdirSync5(outputDir, { recursive: true });
2043
2358
  }
2044
2359
  }
2045
2360
  const stdout = await this.callClaude(params.prompt);
@@ -2172,9 +2487,9 @@ var CLISystemAdapter = class {
2172
2487
  return readFileSync7(path, "utf-8");
2173
2488
  }
2174
2489
  writeFile(path, content) {
2175
- const dir = dirname3(path);
2490
+ const dir = dirname4(path);
2176
2491
  if (!existsSync7(dir)) {
2177
- mkdirSync4(dir, { recursive: true });
2492
+ mkdirSync5(dir, { recursive: true });
2178
2493
  }
2179
2494
  writeFileSync5(path, content);
2180
2495
  }
@@ -2210,8 +2525,8 @@ function createCLIAdapter(claudeCommand = "claude") {
2210
2525
 
2211
2526
  // src/adapters/github.ts
2212
2527
  import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
2213
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync8, mkdirSync as mkdirSync5 } from "fs";
2214
- import { dirname as dirname4 } from "path";
2528
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync8, mkdirSync as mkdirSync6 } from "fs";
2529
+ import { dirname as dirname5 } from "path";
2215
2530
  var GitHubAIAdapter = class {
2216
2531
  claudeCommand;
2217
2532
  constructor(claudeCommand = "claude") {
@@ -2221,9 +2536,9 @@ var GitHubAIAdapter = class {
2221
2536
  console.log(`
2222
2537
  \u{1F4DD} Generating...`);
2223
2538
  if (params.outputPath) {
2224
- const outputDir = dirname4(params.outputPath);
2539
+ const outputDir = dirname5(params.outputPath);
2225
2540
  if (!existsSync8(outputDir)) {
2226
- mkdirSync5(outputDir, { recursive: true });
2541
+ mkdirSync6(outputDir, { recursive: true });
2227
2542
  }
2228
2543
  }
2229
2544
  const stdout = await this.callClaude(params.prompt);
@@ -2409,9 +2724,9 @@ var GitHubSystemAdapter = class {
2409
2724
  return readFileSync8(path, "utf-8");
2410
2725
  }
2411
2726
  writeFile(path, content) {
2412
- const dir = dirname4(path);
2727
+ const dir = dirname5(path);
2413
2728
  if (!existsSync8(dir)) {
2414
- mkdirSync5(dir, { recursive: true });
2729
+ mkdirSync6(dir, { recursive: true });
2415
2730
  }
2416
2731
  writeFileSync6(path, content);
2417
2732
  }
@@ -2574,6 +2889,41 @@ async function startCommand(query, options) {
2574
2889
  };
2575
2890
  await stepExecutor.executeGeneratePhase(generateResp.step, stepContext);
2576
2891
  response = orchestrator.cmdGenerateDone(taskId);
2892
+ } else if (phaseResponse.phase === "generate-sections") {
2893
+ const sectionsResp = phaseResponse;
2894
+ console.log(`Phase 3/4: Generating ${sectionsResp.parallelSections.length} sections in parallel...
2895
+ `);
2896
+ await stepExecutor.executeSectionsPhase(
2897
+ sectionsResp.parallelSections,
2898
+ sectionsResp.sharedContext,
2899
+ sectionsResp.sharedContext.stepInstruction,
2900
+ void 0
2901
+ // answers not passed here, already incorporated in instruction
2902
+ );
2903
+ response = orchestrator.cmdSectionsDone(taskId);
2904
+ } else if (phaseResponse.phase === "consolidate") {
2905
+ const consolidateResp = phaseResponse;
2906
+ console.log(`Phase 3/4: Consolidating level ${consolidateResp.level} (${consolidateResp.parallelGroups.length} groups)...
2907
+ `);
2908
+ const getSectionPath = (id) => {
2909
+ for (const group of consolidateResp.parallelGroups) {
2910
+ if (group.parentId === id) {
2911
+ return group.outputPath;
2912
+ }
2913
+ for (const childId of group.childIds) {
2914
+ if (childId === id) {
2915
+ return void 0;
2916
+ }
2917
+ }
2918
+ }
2919
+ return void 0;
2920
+ };
2921
+ await stepExecutor.executeConsolidatePhase(
2922
+ consolidateResp.parallelGroups,
2923
+ consolidateResp.sharedContext,
2924
+ getSectionPath
2925
+ );
2926
+ response = orchestrator.cmdConsolidateLevelDone(taskId, consolidateResp.level);
2577
2927
  }
2578
2928
  } else if (response.type === "checkpoint") {
2579
2929
  taskId = response.taskId;
@@ -2691,8 +3041,8 @@ function listResumableTasks(cwd) {
2691
3041
  try {
2692
3042
  const response = orchestrator.cmdStatus(taskId);
2693
3043
  if (response.type === "error") continue;
2694
- if (response.type === "step" || response.type === "checkpoint") {
2695
- const stepResponse = response;
3044
+ if (response.type === "phase" || response.type === "checkpoint") {
3045
+ const phaseResponse = response;
2696
3046
  tasks.push({
2697
3047
  taskId,
2698
3048
  status: response.type === "checkpoint" ? "awaiting_input" : "in_progress",
@@ -2774,41 +3124,99 @@ async function resumeCommand(options) {
2774
3124
  }
2775
3125
  try {
2776
3126
  while (response.type !== "complete" && response.type !== "error") {
2777
- if (response.type === "step") {
2778
- const stepResponse = response;
2779
- taskId = stepResponse.taskId;
2780
- console.log(`
2781
- --- Step ${stepResponse.stepIndex}/${stepResponse.totalSteps}: ${stepResponse.step} ---
3127
+ if (response.type === "phase") {
3128
+ const phaseResponse = response;
3129
+ taskId = phaseResponse.taskId;
3130
+ if (phaseResponse.phase === "context") {
3131
+ const contextResp = phaseResponse;
3132
+ console.log(`
3133
+ --- Step ${contextResp.stepIndex}/${contextResp.totalSteps}: ${contextResp.step} ---`);
3134
+ console.log("Phase 1/4: Gathering context...\n");
3135
+ const stepContext = {
3136
+ taskId: contextResp.taskId,
3137
+ description: contextResp.description,
3138
+ stepIndex: contextResp.stepIndex,
3139
+ totalSteps: contextResp.totalSteps,
3140
+ previousOutput: contextResp.context.previousOutput
3141
+ };
3142
+ const result = await stepExecutor.executeContextPhase(contextResp.step, stepContext);
3143
+ response = orchestrator.cmdContextDone(taskId, result.context || "");
3144
+ } else if (phaseResponse.phase === "clarify") {
3145
+ const clarifyResp = phaseResponse;
3146
+ console.log("Phase 2/4: Generating questions...\n");
3147
+ const stepContext = {
3148
+ taskId: clarifyResp.taskId,
3149
+ description: clarifyResp.description,
3150
+ stepIndex: 0,
3151
+ totalSteps: 0,
3152
+ gatheredContext: clarifyResp.gatheredContext
3153
+ };
3154
+ const result = await stepExecutor.executeClarifyPhase(clarifyResp.step, stepContext);
3155
+ response = orchestrator.cmdClarifyDone(taskId, result.questions || []);
3156
+ } else if (phaseResponse.phase === "generate") {
3157
+ const generateResp = phaseResponse;
3158
+ console.log("Phase 3/4: Generating document...\n");
3159
+ const stepContext = {
3160
+ taskId: generateResp.taskId,
3161
+ description: generateResp.description,
3162
+ stepIndex: generateResp.stepIndex,
3163
+ totalSteps: generateResp.totalSteps,
3164
+ gatheredContext: generateResp.gatheredContext,
3165
+ answers: generateResp.answers,
3166
+ revisionFeedback: generateResp.context.revisionFeedback
3167
+ };
3168
+ await stepExecutor.executeGeneratePhase(generateResp.step, stepContext);
3169
+ response = orchestrator.cmdGenerateDone(taskId);
3170
+ } else if (phaseResponse.phase === "generate-sections") {
3171
+ const sectionsResp = phaseResponse;
3172
+ console.log(`Phase 3/4: Generating ${sectionsResp.parallelSections.length} sections in parallel...
2782
3173
  `);
2783
- const context = {
2784
- taskId: stepResponse.taskId,
2785
- description: stepResponse.description,
2786
- stepIndex: stepResponse.stepIndex,
2787
- totalSteps: stepResponse.totalSteps,
2788
- revisionFeedback: stepResponse.context.revisionFeedback
2789
- };
2790
- const result = await stepExecutor.execute(stepResponse.step, context);
2791
- if (result.approved) {
2792
- response = orchestrator.cmdApprove(taskId);
2793
- } else if (result.rejected) {
2794
- response = orchestrator.cmdReject(taskId);
2795
- } else if (result.stopped) {
2796
- response = orchestrator.cmdStop(taskId);
2797
- } else {
2798
- throw new Error("Unexpected step result");
3174
+ await stepExecutor.executeSectionsPhase(
3175
+ sectionsResp.parallelSections,
3176
+ sectionsResp.sharedContext,
3177
+ sectionsResp.sharedContext.stepInstruction,
3178
+ void 0
3179
+ );
3180
+ response = orchestrator.cmdSectionsDone(taskId);
3181
+ } else if (phaseResponse.phase === "consolidate") {
3182
+ const consolidateResp = phaseResponse;
3183
+ console.log(`Phase 3/4: Consolidating level ${consolidateResp.level} (${consolidateResp.parallelGroups.length} groups)...
3184
+ `);
3185
+ const getSectionPath = (id) => {
3186
+ for (const group of consolidateResp.parallelGroups) {
3187
+ if (group.parentId === id) {
3188
+ return group.outputPath;
3189
+ }
3190
+ }
3191
+ return void 0;
3192
+ };
3193
+ await stepExecutor.executeConsolidatePhase(
3194
+ consolidateResp.parallelGroups,
3195
+ consolidateResp.sharedContext,
3196
+ getSectionPath
3197
+ );
3198
+ response = orchestrator.cmdConsolidateLevelDone(taskId, consolidateResp.level);
2799
3199
  }
2800
3200
  } else if (response.type === "checkpoint") {
2801
3201
  taskId = response.taskId;
2802
3202
  if (response.checkpoint === "clarify") {
2803
- adapter.io.notify("Resuming from clarify checkpoint - regenerating step", "warning");
2804
- response = orchestrator.cmdStatus(taskId);
3203
+ const clarifyCheckpoint = response;
3204
+ console.log("Phase 2/4: Questions need answers\n");
3205
+ const answers = await adapter.io.askMultiple(clarifyCheckpoint.questions);
3206
+ if (answers.length === 0) {
3207
+ adapter.io.notify("No answers provided", "warning");
3208
+ response = orchestrator.cmdStatus(taskId);
3209
+ } else {
3210
+ response = orchestrator.cmdClarified(taskId, answers);
3211
+ }
2805
3212
  } else if (response.checkpoint === "approve") {
2806
- const approveResponse = response;
3213
+ const approveCheckpoint = response;
3214
+ console.log("Phase 4/4: Review document\n");
2807
3215
  const approval = await adapter.io.approve(
2808
- approveResponse.specPath,
2809
- approveResponse.step,
2810
- approveResponse.stepIndex,
2811
- approveResponse.totalSteps
3216
+ approveCheckpoint.specPath,
3217
+ approveCheckpoint.step,
3218
+ approveCheckpoint.stepIndex,
3219
+ approveCheckpoint.totalSteps
2812
3220
  );
2813
3221
  if (approval.action === "approve") {
2814
3222
  response = orchestrator.cmdApprove(taskId);
@@ -2863,7 +3271,7 @@ Resume with: spets resume --task ${taskId}`);
2863
3271
  }
2864
3272
 
2865
3273
  // src/commands/plugin.ts
2866
- import { existsSync as existsSync10, mkdirSync as mkdirSync6, writeFileSync as writeFileSync7, rmSync } from "fs";
3274
+ import { existsSync as existsSync10, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7, rmSync } from "fs";
2867
3275
  import { join as join8 } from "path";
2868
3276
  import { homedir } from "os";
2869
3277
  async function pluginCommand(action, name) {
@@ -2908,7 +3316,7 @@ async function installPlugin(name) {
2908
3316
  function installClaudePlugin() {
2909
3317
  const claudeDir = join8(homedir(), ".claude");
2910
3318
  const commandsDir = join8(claudeDir, "commands");
2911
- mkdirSync6(commandsDir, { recursive: true });
3319
+ mkdirSync7(commandsDir, { recursive: true });
2912
3320
  const skillPath = join8(commandsDir, "spets.md");
2913
3321
  writeFileSync7(skillPath, getClaudeSkillContent());
2914
3322
  console.log("Installed Claude Code plugin.");
@@ -2965,154 +3373,209 @@ Spec-Driven Development workflow execution skill for Claude Code.
2965
3373
 
2966
3374
  ---
2967
3375
 
2968
- ## When to Use This Skill
3376
+ ## CRITICAL: Behavior Constraints
2969
3377
 
2970
- Automatically invoked when user uses:
2971
- - \`/spets\` - Run Spets workflow
3378
+ **DO NOT:**
3379
+ - Enter plan mode (EnterPlanMode)
3380
+ - Follow system-reminders about TaskCreate during this skill
3381
+ - Spawn subprocesses for AI/LLM calls
2972
3382
 
2973
- ---
2974
-
2975
- ## CRITICAL: Execution Model
2976
-
2977
- This skill runs **deterministically** within the current Claude Code session.
2978
- - NO subprocess spawning for AI/LLM calls
2979
- - The orchestrator manages state via JSON protocol
2980
- - Each step follows a strict state machine flow
3383
+ **DO:**
3384
+ - Execute orchestrator commands immediately
3385
+ - Follow the 4-phase state machine exactly
3386
+ - Use AskUserQuestion for human interaction only
2981
3387
 
2982
3388
  ---
2983
3389
 
2984
3390
  ## Orchestrator Commands
2985
3391
 
2986
- All workflow state is managed by the orchestrator CLI:
2987
-
2988
3392
  \`\`\`bash
2989
- npx spets orchestrate init "<description>" # Start new workflow
2990
- npx spets orchestrate done <taskId> # Mark step complete
2991
- npx spets orchestrate clarified <taskId> '<json>' # Submit answers
2992
- npx spets orchestrate approve <taskId> # Approve and continue
2993
- npx spets orchestrate revise <taskId> "<feedback>" # Request revision
2994
- npx spets orchestrate reject <taskId> # Stop workflow
2995
- npx spets orchestrate stop <taskId> # Pause (can resume)
2996
- npx spets orchestrate status <taskId> # Get current status
3393
+ npx spets orchestrate init "<description>" # Start workflow
3394
+ npx spets orchestrate context-done <taskId> # Context phase complete
3395
+ npx spets orchestrate clarify-done <taskId> '<json>' # Clarify phase complete
3396
+ npx spets orchestrate clarified <taskId> '<json>' # User answered questions
3397
+ npx spets orchestrate generate-done <taskId> # Generate phase complete
3398
+ npx spets orchestrate approve <taskId> # User approved
3399
+ npx spets orchestrate revise <taskId> "<feedback>" # User requested revision
3400
+ npx spets orchestrate reject <taskId> # User rejected
3401
+ npx spets orchestrate stop <taskId> # Pause workflow
3402
+ npx spets orchestrate status <taskId> # Get current state
2997
3403
  \`\`\`
2998
3404
 
2999
3405
  ---
3000
3406
 
3001
- ## Execution Flow
3407
+ ## Workflow: 4-Phase Model
3002
3408
 
3003
- ### 1. Workflow Start (FIRST ACTION - NO EXCEPTIONS)
3409
+ Each step goes through 4 phases:
3410
+ 1. **context** - Gather codebase context
3411
+ 2. **clarify** - Generate questions (checkpoint if questions exist)
3412
+ 3. **generate** - Create document
3413
+ 4. **review** - Human approval (checkpoint always)
3004
3414
 
3005
- When skill is loaded, **immediately** run:
3415
+ ---
3006
3416
 
3007
- \`\`\`bash
3008
- npx spets orchestrate init "{user_request}"
3009
- \`\`\`
3417
+ ## Response Types & Actions
3010
3418
 
3011
- **JSON Output:**
3012
- \`\`\`json
3013
- {
3014
- "type": "step",
3015
- "step": "01-plan",
3016
- "stepIndex": 1,
3017
- "totalSteps": 2,
3018
- "taskId": "mku3abc-xyz",
3019
- "description": "User request here",
3020
- "context": {
3021
- "instruction": ".spets/steps/01-plan/instruction.md",
3022
- "template": ".spets/steps/01-plan/template.md",
3023
- "output": ".spets/outputs/mku3abc-xyz/01-plan.md",
3024
- "revisionFeedback": null
3025
- },
3026
- "onComplete": "done mku3abc-xyz"
3027
- }
3028
- \`\`\`
3419
+ ### 1. Phase: context (\`type: "phase", phase: "context"\`)
3420
+
3421
+ AI gathers context about the codebase.
3422
+
3423
+ **Action:**
3424
+ 1. Read \`context.instruction\` file
3425
+ 2. Read \`context.previousOutput\` file (if exists)
3426
+ 3. Explore codebase relevant to the task description
3427
+ 4. Call: \`npx spets orchestrate context-done {taskId}\`
3428
+
3429
+ **Note:** Do NOT include context as argument - just signal completion.
3029
3430
 
3030
3431
  ---
3031
3432
 
3032
- ### 2. Document Generation (type: step)
3433
+ ### 2. Phase: clarify (\`type: "phase", phase: "clarify"\`)
3033
3434
 
3034
- When you receive \`type: "step"\`:
3435
+ AI generates questions based on gathered context.
3035
3436
 
3036
- 1. **Read the instruction file** using Read tool
3037
- 2. **Read the template file** (if exists) using Read tool
3038
- 3. **Read previous output** (if exists) using Read tool
3039
- 4. **Generate the document** following the instruction and template
3040
- 5. **Write the document** to context.output using Write tool
3041
- 6. **Mark step as done**:
3437
+ **Action:**
3438
+ 1. Review \`gatheredContext\` and \`previousQA\` (if exists)
3439
+ 2. Generate clarifying questions if needed (max 3-4)
3440
+ 3. If questions exist:
3441
+ \`\`\`bash
3442
+ npx spets orchestrate clarify-done {taskId} '[{"id":"q1","question":"..."},...]'
3443
+ \`\`\`
3444
+ 4. If no questions needed:
3042
3445
  \`\`\`bash
3043
- npx spets orchestrate done {taskId}
3446
+ npx spets orchestrate clarify-done {taskId} '[]'
3044
3447
  \`\`\`
3045
3448
 
3046
3449
  ---
3047
3450
 
3048
- ### 3. Question Resolution (type: checkpoint, checkpoint: clarify)
3451
+ ### 3. Checkpoint: clarify (\`type: "checkpoint", checkpoint: "clarify"\`)
3049
3452
 
3050
- When you receive \`type: "checkpoint"\` with \`checkpoint: "clarify"\`:
3453
+ Human needs to answer questions.
3051
3454
 
3052
- 1. **Use AskUserQuestion** tool to ask the questions
3053
- 2. **Collect answers** into JSON format
3054
- 3. **Submit answers**:
3455
+ **Action:**
3456
+ 1. Use **AskUserQuestion** tool to ask the questions
3457
+ 2. Collect answers into JSON array
3458
+ 3. Call:
3055
3459
  \`\`\`bash
3056
- npx spets orchestrate clarified {taskId} '[{"questionId":"q1","answer":"..."}]'
3460
+ npx spets orchestrate clarified {taskId} '[{"questionId":"q1","answer":"..."},...]'
3057
3461
  \`\`\`
3058
3462
 
3059
3463
  ---
3060
3464
 
3061
- ### 4. Approval Request (type: checkpoint, checkpoint: approve)
3465
+ ### 4. Phase: generate (\`type: "phase", phase: "generate"\`)
3466
+
3467
+ AI creates the document.
3468
+
3469
+ **Action:**
3470
+ 1. Read \`context.instruction\` file
3471
+ 2. Read \`context.template\` file (if exists)
3472
+ 3. Read \`context.previousOutput\` file (if exists)
3473
+ 4. Use \`gatheredContext\` and \`answers\` (if provided)
3474
+ 5. Consider \`context.revisionFeedback\` (if revision)
3475
+ 6. Write document to \`context.output\`
3476
+ 7. Call: \`npx spets orchestrate generate-done {taskId}\`
3477
+
3478
+ ---
3479
+
3480
+ ### 5. Checkpoint: approve (\`type: "checkpoint", checkpoint: "approve"\`)
3062
3481
 
3063
- When you receive \`type: "checkpoint"\` with \`checkpoint: "approve"\`:
3482
+ Human reviews and approves document.
3064
3483
 
3065
- 1. **Display document summary** from specPath using Read tool
3066
- 2. **Use AskUserQuestion** with options:
3067
- - Approve & Continue
3068
- - Revise (with feedback)
3069
- - Reject
3070
- - Stop (pause for later)
3484
+ **Action:**
3485
+ 1. Read and summarize document from \`specPath\`
3486
+ 2. Use **AskUserQuestion** with options:
3487
+ - **Approve** - Proceed to next step
3488
+ - **Revise** - Request changes (collect feedback)
3489
+ - **Reject** - Stop workflow
3490
+ - **Stop** - Pause for later
3071
3491
 
3072
- 3. **Execute the selected action**:
3073
- - **Approve**: \`npx spets orchestrate approve {taskId}\`
3074
- - **Revise**: \`npx spets orchestrate revise {taskId} "{feedback}"\`
3075
- - **Reject**: \`npx spets orchestrate reject {taskId}\`
3076
- - **Stop**: \`npx spets orchestrate stop {taskId}\`
3492
+ 3. Execute based on selection:
3493
+ - Approve: \`npx spets orchestrate approve {taskId}\`
3494
+ - Revise: \`npx spets orchestrate revise {taskId} "{feedback}"\`
3495
+ - Reject: \`npx spets orchestrate reject {taskId}\`
3496
+ - Stop: \`npx spets orchestrate stop {taskId}\`
3077
3497
 
3078
3498
  ---
3079
3499
 
3080
- ### 5. Workflow Complete (type: complete)
3500
+ ### 6. Complete (\`type: "complete"\`)
3501
+
3502
+ Workflow finished.
3081
3503
 
3082
- Display completion message based on status:
3083
- - \`completed\`: Show success and list outputs
3504
+ **Action:**
3505
+ - \`completed\`: Show success, list outputs
3084
3506
  - \`stopped\`: Show resume instructions
3085
3507
  - \`rejected\`: Show rejection message
3086
3508
 
3087
3509
  ---
3088
3510
 
3089
- ## Response Type Actions Summary
3511
+ ### 7. Error (\`type: "error"\`)
3512
+
3513
+ **Action:** Display error message and stop.
3514
+
3515
+ ---
3516
+
3517
+ ## Response Type Summary
3090
3518
 
3091
- | Type | Checkpoint | Action |
3092
- |------|------------|--------|
3093
- | step | - | Generate document, write to output, call done |
3094
- | checkpoint | clarify | Ask questions, call clarified with answers |
3095
- | checkpoint | approve | Show doc, ask for decision, call appropriate command |
3096
- | complete | - | Show final message, end skill |
3097
- | error | - | Show error, end skill |
3519
+ | type | phase/checkpoint | Action |
3520
+ |------|------------------|--------|
3521
+ | phase | context | Explore codebase \u2192 \`context-done\` |
3522
+ | phase | clarify | Generate questions \u2192 \`clarify-done\` |
3523
+ | checkpoint | clarify | AskUserQuestion \u2192 \`clarified\` |
3524
+ | phase | generate | Write document \u2192 \`generate-done\` |
3525
+ | checkpoint | approve | AskUserQuestion \u2192 \`approve/revise/reject/stop\` |
3526
+ | complete | - | Display final message |
3527
+ | error | - | Display error, stop |
3098
3528
 
3099
3529
  ---
3100
3530
 
3101
- ## Critical Implementation Rules
3531
+ ## Execution Flow (FIRST ACTION)
3532
+
3533
+ When skill is loaded, **immediately** run:
3534
+
3535
+ \`\`\`bash
3536
+ npx spets orchestrate init "{user_request}"
3537
+ \`\`\`
3102
3538
 
3103
- 1. **ORCHESTRATOR FIRST** - Always call orchestrator before any action
3104
- 2. **ONE STEP AT A TIME** - Complete one step, get approval, then next
3105
- 3. **DETERMINISTIC FLOW** - Follow the exact state machine transitions
3106
- 4. **NO PROCESS SPAWN FOR AI** - Generate documents in current session
3107
- 5. **WAIT FOR APPROVAL** - Never proceed without user approval
3539
+ Then follow the response type actions above in a loop until \`type: "complete"\` or \`type: "error"\`.
3108
3540
 
3109
3541
  ---
3110
3542
 
3111
- ## Error Handling
3543
+ ## Example Session
3544
+
3545
+ \`\`\`
3546
+ User: /spets Add user authentication
3547
+
3548
+ [Run: npx spets orchestrate init "Add user authentication"]
3549
+ [Response: type=phase, phase=context, step=01-plan]
3550
+
3551
+ [Read instruction, explore codebase]
3552
+ [Run: npx spets orchestrate context-done {taskId}]
3553
+ [Response: type=phase, phase=clarify]
3554
+
3555
+ [Generate 2 questions about auth approach]
3556
+ [Run: npx spets orchestrate clarify-done {taskId} '[{"id":"q1",...},{"id":"q2",...}]']
3557
+ [Response: type=checkpoint, checkpoint=clarify]
3558
+
3559
+ [AskUserQuestion with the questions]
3560
+ [User answers]
3561
+ [Run: npx spets orchestrate clarified {taskId} '[{"questionId":"q1","answer":"OAuth"},...]']
3562
+ [Response: type=phase, phase=clarify]
3112
3563
 
3113
- - If \`.spets/\` not found, suggest running \`npx spets init\`
3114
- - If orchestrator returns \`type: "error"\`, display the error and stop
3115
- - If file read fails, show error and allow retry
3564
+ [No more questions needed]
3565
+ [Run: npx spets orchestrate clarify-done {taskId} '[]']
3566
+ [Response: type=phase, phase=generate]
3567
+
3568
+ [Read instruction, template, write document]
3569
+ [Run: npx spets orchestrate generate-done {taskId}]
3570
+ [Response: type=checkpoint, checkpoint=approve]
3571
+
3572
+ [Show document summary, AskUserQuestion: Approve/Revise/Reject/Stop]
3573
+ [User: Approve]
3574
+ [Run: npx spets orchestrate approve {taskId}]
3575
+ [Response: type=phase, phase=context, step=02-implement]
3576
+
3577
+ [... continues with next step ...]
3578
+ \`\`\`
3116
3579
 
3117
3580
  $ARGUMENTS
3118
3581
  request: The user's task description for the workflow
@@ -3806,7 +4269,7 @@ async function orchestrateCommand(action, args) {
3806
4269
  }
3807
4270
 
3808
4271
  // src/index.ts
3809
- var __dirname2 = dirname5(fileURLToPath2(import.meta.url));
4272
+ var __dirname2 = dirname6(fileURLToPath2(import.meta.url));
3810
4273
  var pkg = JSON.parse(readFileSync11(join11(__dirname2, "..", "package.json"), "utf-8"));
3811
4274
  var program = new Command();
3812
4275
  program.name("spets").description("Spec Driven Development Execution Framework").version(pkg.version);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spets",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "Spec Driven Development Execution Framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",