spets 0.2.1 → 0.2.3
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/index.js +161 -165
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -104,8 +104,7 @@ async function installPlugin(name) {
|
|
|
104
104
|
installer();
|
|
105
105
|
}
|
|
106
106
|
function installClaudePlugin() {
|
|
107
|
-
const
|
|
108
|
-
const commandsDir = join(claudeDir, "commands");
|
|
107
|
+
const commandsDir = join(process.cwd(), ".claude", "commands");
|
|
109
108
|
mkdirSync(commandsDir, { recursive: true });
|
|
110
109
|
const skillPath = join(commandsDir, "spets.md");
|
|
111
110
|
writeFileSync(skillPath, getClaudeSkillContent());
|
|
@@ -148,13 +147,18 @@ function installGeminiPlugin() {
|
|
|
148
147
|
}
|
|
149
148
|
async function uninstallPlugin(name) {
|
|
150
149
|
if (name === "claude") {
|
|
151
|
-
const skillPath = join(
|
|
150
|
+
const skillPath = join(process.cwd(), ".claude", "commands", "spets.md");
|
|
151
|
+
const globalSkillPath = join(homedir(), ".claude", "commands", "spets.md");
|
|
152
152
|
const legacySkillPath = join(homedir(), ".claude", "commands", "sdd-do.md");
|
|
153
153
|
let uninstalled = false;
|
|
154
154
|
if (existsSync(skillPath)) {
|
|
155
155
|
rmSync(skillPath);
|
|
156
156
|
uninstalled = true;
|
|
157
157
|
}
|
|
158
|
+
if (existsSync(globalSkillPath)) {
|
|
159
|
+
rmSync(globalSkillPath);
|
|
160
|
+
uninstalled = true;
|
|
161
|
+
}
|
|
158
162
|
if (existsSync(legacySkillPath)) {
|
|
159
163
|
rmSync(legacySkillPath);
|
|
160
164
|
uninstalled = true;
|
|
@@ -241,13 +245,14 @@ async function uninstallPlugin(name) {
|
|
|
241
245
|
async function listPlugins() {
|
|
242
246
|
console.log("Available plugins:");
|
|
243
247
|
console.log("");
|
|
244
|
-
console.log(" claude - Claude Code /spets skill (
|
|
248
|
+
console.log(" claude - Claude Code /spets skill (project-level)");
|
|
245
249
|
console.log(" codex - Codex CLI $spets skill (project-level)");
|
|
246
250
|
console.log(" gemini - Gemini CLI spets skill (project-level)");
|
|
247
251
|
console.log("");
|
|
248
|
-
const
|
|
252
|
+
const claudeProjectPath = join(process.cwd(), ".claude", "commands", "spets.md");
|
|
253
|
+
const claudeGlobalPath = join(homedir(), ".claude", "commands", "spets.md");
|
|
249
254
|
const claudeLegacySkillPath = join(homedir(), ".claude", "commands", "sdd-do.md");
|
|
250
|
-
const claudeInstalled = existsSync(
|
|
255
|
+
const claudeInstalled = existsSync(claudeProjectPath) || existsSync(claudeGlobalPath) || existsSync(claudeLegacySkillPath);
|
|
251
256
|
const codexProjectPath = join(process.cwd(), ".codex", "skills", "spets", "SKILL.md");
|
|
252
257
|
const codexGlobalPath = join(homedir(), ".codex", "skills", "spets", "SKILL.md");
|
|
253
258
|
const codexInstalled = existsSync(codexProjectPath) || existsSync(codexGlobalPath);
|
|
@@ -259,7 +264,8 @@ async function listPlugins() {
|
|
|
259
264
|
const geminiLocation = existsSync(geminiProjectPath) ? "project" : existsSync(geminiLegacyCommandPath) ? "project" : existsSync(geminiLegacyGlobalPath) ? "global" : null;
|
|
260
265
|
console.log("Installed:");
|
|
261
266
|
const installed = [];
|
|
262
|
-
|
|
267
|
+
const claudeLocation = existsSync(claudeProjectPath) ? "project" : existsSync(claudeGlobalPath) ? "global" : "legacy";
|
|
268
|
+
if (claudeInstalled) installed.push(`claude (${claudeLocation})`);
|
|
263
269
|
if (codexInstalled) installed.push(`codex (${codexLocation})`);
|
|
264
270
|
if (geminiInstalled) installed.push(`gemini (${geminiLocation})`);
|
|
265
271
|
if (installed.length > 0) {
|
|
@@ -273,62 +279,37 @@ async function listPlugins() {
|
|
|
273
279
|
function getClaudeSkillContent() {
|
|
274
280
|
return `# Spets Executor
|
|
275
281
|
|
|
276
|
-
You execute spets
|
|
282
|
+
You execute spets workflow commands. Follow orchestrator instructions exactly.
|
|
277
283
|
|
|
278
284
|
## Startup
|
|
279
285
|
|
|
280
286
|
IF \`$ARGUMENTS\` starts with "resume":
|
|
281
|
-
|
|
287
|
+
RUN \`npx spets orchestrate resume\`
|
|
288
|
+
ELSE IF \`$ARGUMENTS\` starts with "list":
|
|
289
|
+
RUN \`npx spets orchestrate list\`
|
|
282
290
|
ELSE:
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
Then GOTO **Loop**.
|
|
291
|
+
RUN \`npx spets orchestrate init "$ARGUMENTS"\`
|
|
286
292
|
|
|
287
293
|
## Loop
|
|
288
294
|
|
|
289
|
-
1.
|
|
290
|
-
2.
|
|
291
|
-
|
|
292
|
-
|
|
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
|
|
302
|
-
|
|
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
|
|
295
|
+
1. Parse the JSON response
|
|
296
|
+
2. Read the \`instructions\` field
|
|
297
|
+
3. Follow the instructions exactly
|
|
298
|
+
4. Repeat until the response says to stop
|
|
308
299
|
|
|
309
|
-
|
|
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
|
|
300
|
+
## Rules
|
|
315
301
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
- GOTO Loop
|
|
321
|
-
|
|
322
|
-
### type="complete" or "error"
|
|
323
|
-
- PRINT message
|
|
324
|
-
- STOP
|
|
302
|
+
- NEVER skip or modify orchestrator commands
|
|
303
|
+
- NEVER improvise steps \u2014 only do what instructions say
|
|
304
|
+
- Always pass JSON output as a single-quoted string argument
|
|
305
|
+
- Minify JSON when passing as command arguments
|
|
325
306
|
|
|
326
307
|
## Forbidden
|
|
327
308
|
|
|
328
309
|
EnterPlanMode, TaskCreate, TaskUpdate
|
|
329
310
|
|
|
330
311
|
$ARGUMENTS
|
|
331
|
-
description: Task description for the workflow (or "resume" to continue
|
|
312
|
+
description: Task description for the workflow (or "resume" to list/continue previous workflows)
|
|
332
313
|
`;
|
|
333
314
|
}
|
|
334
315
|
function getCodexSkillContent() {
|
|
@@ -339,65 +320,37 @@ description: SDD workflow executor - orchestrator-controlled spec-driven develop
|
|
|
339
320
|
|
|
340
321
|
# Spets Executor
|
|
341
322
|
|
|
342
|
-
You execute spets
|
|
323
|
+
You execute spets workflow commands. Follow orchestrator instructions exactly.
|
|
343
324
|
|
|
344
325
|
## Startup
|
|
345
326
|
|
|
346
327
|
IF \`$ARGUMENTS\` starts with "resume":
|
|
347
|
-
|
|
328
|
+
RUN \`npx spets orchestrate resume\`
|
|
329
|
+
ELSE IF \`$ARGUMENTS\` starts with "list":
|
|
330
|
+
RUN \`npx spets orchestrate list\`
|
|
348
331
|
ELSE:
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
Then GOTO **Loop**.
|
|
332
|
+
RUN \`npx spets orchestrate init "$ARGUMENTS"\`
|
|
352
333
|
|
|
353
334
|
## Loop
|
|
354
335
|
|
|
355
|
-
1.
|
|
356
|
-
2.
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
- EXECUTE what \`prompt\` says
|
|
360
|
-
- RUN \`onComplete\` with your output as minified JSON argument
|
|
361
|
-
- GOTO Loop
|
|
362
|
-
|
|
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
|
|
336
|
+
1. Parse the JSON response
|
|
337
|
+
2. Read the \`instructions\` field
|
|
338
|
+
3. Follow the instructions exactly
|
|
339
|
+
4. Repeat until the response says to stop
|
|
384
340
|
|
|
385
|
-
|
|
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
|
|
341
|
+
## Rules
|
|
390
342
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
343
|
+
- NEVER skip or modify orchestrator commands
|
|
344
|
+
- NEVER improvise steps \u2014 only do what instructions say
|
|
345
|
+
- Always pass JSON output as a single-quoted string argument
|
|
346
|
+
- Minify JSON when passing as command arguments
|
|
394
347
|
|
|
395
348
|
## Forbidden
|
|
396
349
|
|
|
397
350
|
Planning mode, task tracking tools
|
|
398
351
|
|
|
399
352
|
$ARGUMENTS
|
|
400
|
-
description: Task description for the workflow (or "resume" to continue
|
|
353
|
+
description: Task description for the workflow (or "resume" to list/continue previous workflows)
|
|
401
354
|
`;
|
|
402
355
|
}
|
|
403
356
|
function getGeminiSkillContent() {
|
|
@@ -408,61 +361,37 @@ description: SDD workflow executor - orchestrator-controlled spec-driven develop
|
|
|
408
361
|
|
|
409
362
|
# Spets Executor
|
|
410
363
|
|
|
411
|
-
You execute spets
|
|
364
|
+
You execute spets workflow commands. Follow orchestrator instructions exactly.
|
|
412
365
|
|
|
413
366
|
## Startup
|
|
414
367
|
|
|
415
368
|
IF \`$ARGUMENTS\` starts with "resume":
|
|
416
|
-
|
|
369
|
+
RUN \`npx spets orchestrate resume\`
|
|
370
|
+
ELSE IF \`$ARGUMENTS\` starts with "list":
|
|
371
|
+
RUN \`npx spets orchestrate list\`
|
|
417
372
|
ELSE:
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
Then GOTO **Loop**.
|
|
373
|
+
RUN \`npx spets orchestrate init "$ARGUMENTS"\`
|
|
421
374
|
|
|
422
375
|
## Loop
|
|
423
376
|
|
|
424
|
-
1.
|
|
425
|
-
2.
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
- EXECUTE what \`prompt\` says
|
|
429
|
-
- RUN \`onComplete\` with your output as JSON argument
|
|
430
|
-
- GOTO Loop
|
|
431
|
-
|
|
432
|
-
### type="checkpoint", checkpoint="clarify"
|
|
433
|
-
- ASK user each decision in \`decisions[]\`
|
|
434
|
-
- RUN \`onComplete\` with \`[{decisionId, selectedOptionId}, ...]\`
|
|
435
|
-
- GOTO Loop
|
|
377
|
+
1. Parse the JSON response
|
|
378
|
+
2. Read the \`instructions\` field
|
|
379
|
+
3. Follow the instructions exactly
|
|
380
|
+
4. Repeat until the response says to stop
|
|
436
381
|
|
|
437
|
-
|
|
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
|
|
382
|
+
## Rules
|
|
442
383
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
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
|
|
384
|
+
- NEVER skip or modify orchestrator commands
|
|
385
|
+
- NEVER improvise steps \u2014 only do what instructions say
|
|
386
|
+
- Always pass JSON output as a single-quoted string argument
|
|
387
|
+
- Minify JSON when passing as command arguments
|
|
459
388
|
|
|
460
389
|
## Forbidden
|
|
461
390
|
|
|
462
391
|
Planning mode, task tracking tools
|
|
463
392
|
|
|
464
393
|
$ARGUMENTS
|
|
465
|
-
description: Task description for the workflow (or "resume" to continue
|
|
394
|
+
description: Task description for the workflow (or "resume" to list/continue previous workflows)
|
|
466
395
|
`;
|
|
467
396
|
}
|
|
468
397
|
|
|
@@ -504,19 +433,26 @@ async function initCommand(options) {
|
|
|
504
433
|
const hookTemplate = join2(__dirname, "..", "templates", "hooks", "cleanup-branch.sh");
|
|
505
434
|
if (existsSync2(hookTemplate)) {
|
|
506
435
|
const hookDest = join2(spetsDir, "hooks", "cleanup-branch.sh");
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
436
|
+
if (!existsSync2(hookDest)) {
|
|
437
|
+
cpSync(hookTemplate, hookDest);
|
|
438
|
+
try {
|
|
439
|
+
execSync(`chmod +x "${hookDest}"`);
|
|
440
|
+
} catch {
|
|
441
|
+
}
|
|
511
442
|
}
|
|
512
443
|
}
|
|
513
444
|
const knowledgeGuideTemplate = join2(__dirname, "..", "templates", "knowledge", "guide.md");
|
|
514
445
|
if (existsSync2(knowledgeGuideTemplate)) {
|
|
515
446
|
const guideDest = join2(spetsDir, "knowledge", "guide.md");
|
|
516
|
-
|
|
447
|
+
if (!existsSync2(guideDest)) {
|
|
448
|
+
cpSync(knowledgeGuideTemplate, guideDest);
|
|
449
|
+
}
|
|
517
450
|
}
|
|
518
451
|
const githubInfo = getGitHubInfoFromRemote();
|
|
519
|
-
|
|
452
|
+
const configPath = join2(spetsDir, "config.yml");
|
|
453
|
+
if (!existsSync2(configPath)) {
|
|
454
|
+
writeFileSync2(configPath, getDefaultConfig(githubInfo));
|
|
455
|
+
}
|
|
520
456
|
createDefaultSteps(spetsDir);
|
|
521
457
|
createClaudeCommand(cwd);
|
|
522
458
|
printEnhancedInitOutput(options);
|
|
@@ -740,20 +676,23 @@ async function runInteractiveSetup(cwd, spetsDir, options) {
|
|
|
740
676
|
const hookTemplate = join2(__dirname, "..", "templates", "hooks", "cleanup-branch.sh");
|
|
741
677
|
if (existsSync2(hookTemplate)) {
|
|
742
678
|
const hookDest = join2(spetsDir, "hooks", "cleanup-branch.sh");
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
679
|
+
if (!existsSync2(hookDest)) {
|
|
680
|
+
cpSync(hookTemplate, hookDest);
|
|
681
|
+
try {
|
|
682
|
+
execSync(`chmod +x "${hookDest}"`);
|
|
683
|
+
} catch {
|
|
684
|
+
}
|
|
747
685
|
}
|
|
748
686
|
}
|
|
749
687
|
const knowledgeGuideTemplate = join2(__dirname, "..", "templates", "knowledge", "guide.md");
|
|
750
|
-
|
|
751
|
-
|
|
688
|
+
const guideDest = join2(spetsDir, "knowledge", "guide.md");
|
|
689
|
+
if (existsSync2(knowledgeGuideTemplate) && !existsSync2(guideDest)) {
|
|
690
|
+
cpSync(knowledgeGuideTemplate, guideDest);
|
|
691
|
+
}
|
|
692
|
+
const configPath = join2(spetsDir, "config.yml");
|
|
693
|
+
if (!existsSync2(configPath)) {
|
|
694
|
+
writeFileSync2(configPath, getDefaultConfig(githubInfo, { agent, githubEnabled }));
|
|
752
695
|
}
|
|
753
|
-
writeFileSync2(
|
|
754
|
-
join2(spetsDir, "config.yml"),
|
|
755
|
-
getDefaultConfig(githubInfo, { agent, githubEnabled })
|
|
756
|
-
);
|
|
757
696
|
createDefaultSteps(spetsDir);
|
|
758
697
|
createClaudeCommand(cwd);
|
|
759
698
|
if (githubEnabled && githubInfo) {
|
|
@@ -765,10 +704,16 @@ async function runInteractiveSetup(cwd, spetsDir, options) {
|
|
|
765
704
|
function createDefaultSteps(spetsDir) {
|
|
766
705
|
const planDir = join2(spetsDir, "steps", "01-plan");
|
|
767
706
|
mkdirSync2(planDir, { recursive: true });
|
|
768
|
-
|
|
707
|
+
const planTemplatePath = join2(planDir, "template.md");
|
|
708
|
+
if (!existsSync2(planTemplatePath)) {
|
|
709
|
+
writeFileSync2(planTemplatePath, getPlanTemplate());
|
|
710
|
+
}
|
|
769
711
|
const implementDir = join2(spetsDir, "steps", "02-implement");
|
|
770
712
|
mkdirSync2(implementDir, { recursive: true });
|
|
771
|
-
|
|
713
|
+
const implementTemplatePath = join2(implementDir, "template.md");
|
|
714
|
+
if (!existsSync2(implementTemplatePath)) {
|
|
715
|
+
writeFileSync2(implementTemplatePath, getImplementTemplate());
|
|
716
|
+
}
|
|
772
717
|
}
|
|
773
718
|
function getPlanTemplate() {
|
|
774
719
|
const fullTemplate = readFileSync(join2(__dirname, "..", "templates", "steps", "01-plan", "template.md"), "utf-8");
|
|
@@ -1753,6 +1698,36 @@ function buildKnowledgeExtractPrompt(params) {
|
|
|
1753
1698
|
return parts.join("\n");
|
|
1754
1699
|
}
|
|
1755
1700
|
|
|
1701
|
+
// src/orchestrator/instructions.ts
|
|
1702
|
+
function phaseWithJsonOutput(onComplete) {
|
|
1703
|
+
return `Execute the prompt. Then run:
|
|
1704
|
+
${onComplete} '<your_json_output>'`;
|
|
1705
|
+
}
|
|
1706
|
+
function phaseExecute(outputFile, onComplete) {
|
|
1707
|
+
return `Execute the prompt \u2014 write the document to ${outputFile}. Then run:
|
|
1708
|
+
${onComplete}`;
|
|
1709
|
+
}
|
|
1710
|
+
function checkpointClarify(onComplete) {
|
|
1711
|
+
return [
|
|
1712
|
+
`Present each decision to the user with its options. Collect their choices. Then run:`,
|
|
1713
|
+
` ${onComplete} '<answers_json>'`,
|
|
1714
|
+
`Answer format: [{decisionId, selectedOptionId, customInput?}, ...]`
|
|
1715
|
+
].join("\n");
|
|
1716
|
+
}
|
|
1717
|
+
function checkpointApprove(specPath, cmds) {
|
|
1718
|
+
return [
|
|
1719
|
+
`Read the document at ${specPath}. Summarize key points to the user. Ask: Approve / Revise / Reject / Stop. Then run the matching command:`,
|
|
1720
|
+
` approve: ${cmds.approve}`,
|
|
1721
|
+
` revise: ${cmds.revise}`,
|
|
1722
|
+
` reject: ${cmds.reject}`,
|
|
1723
|
+
` stop: ${cmds.stop}`
|
|
1724
|
+
].join("\n");
|
|
1725
|
+
}
|
|
1726
|
+
var PRINT_MESSAGE_AND_STOP = "Print the message. Stop.";
|
|
1727
|
+
var PRINT_ERROR_AND_STOP = "Print the error. Stop.";
|
|
1728
|
+
var LIST_TASKS = "Show tasks to user. Ask which to resume. Run:\n npx spets orchestrate resume <selectedTaskId>";
|
|
1729
|
+
var LIST_EMPTY = "No resumable tasks found. Show this to the user. Stop.";
|
|
1730
|
+
|
|
1756
1731
|
// src/orchestrator/responses.ts
|
|
1757
1732
|
function buildPhaseExploreResponse(cwd, state) {
|
|
1758
1733
|
const steps = getSteps(cwd);
|
|
@@ -1774,6 +1749,7 @@ function buildPhaseExploreResponse(cwd, state) {
|
|
|
1774
1749
|
previousOutput,
|
|
1775
1750
|
cwd
|
|
1776
1751
|
});
|
|
1752
|
+
const onComplete = `npx spets orchestrate explore-done ${state.taskId}`;
|
|
1777
1753
|
return {
|
|
1778
1754
|
type: "phase",
|
|
1779
1755
|
phase: "explore",
|
|
@@ -1786,7 +1762,8 @@ function buildPhaseExploreResponse(cwd, state) {
|
|
|
1786
1762
|
context: {
|
|
1787
1763
|
previousOutput
|
|
1788
1764
|
},
|
|
1789
|
-
onComplete
|
|
1765
|
+
onComplete,
|
|
1766
|
+
instructions: phaseWithJsonOutput(onComplete)
|
|
1790
1767
|
};
|
|
1791
1768
|
}
|
|
1792
1769
|
function buildPhaseClarifyResponse(cwd, state) {
|
|
@@ -1801,6 +1778,7 @@ function buildPhaseClarifyResponse(cwd, state) {
|
|
|
1801
1778
|
// Legacy support
|
|
1802
1779
|
cwd
|
|
1803
1780
|
});
|
|
1781
|
+
const onComplete = `npx spets orchestrate clarify-done ${state.taskId}`;
|
|
1804
1782
|
return {
|
|
1805
1783
|
type: "phase",
|
|
1806
1784
|
phase: "clarify",
|
|
@@ -1812,7 +1790,8 @@ function buildPhaseClarifyResponse(cwd, state) {
|
|
|
1812
1790
|
previousDecisions: state.decisionHistory,
|
|
1813
1791
|
previousQA: state.qaHistory,
|
|
1814
1792
|
// Legacy support
|
|
1815
|
-
onComplete
|
|
1793
|
+
onComplete,
|
|
1794
|
+
instructions: phaseWithJsonOutput(onComplete)
|
|
1816
1795
|
};
|
|
1817
1796
|
}
|
|
1818
1797
|
function buildPhaseExecuteResponse(cwd, state) {
|
|
@@ -1855,6 +1834,8 @@ ${issues}`;
|
|
|
1855
1834
|
verifyFeedback,
|
|
1856
1835
|
cwd
|
|
1857
1836
|
});
|
|
1837
|
+
const onComplete = `npx spets orchestrate execute-done ${state.taskId}`;
|
|
1838
|
+
const outputFile = join9(outputPath, state.taskId, `${state.currentStep}.md`);
|
|
1858
1839
|
return {
|
|
1859
1840
|
type: "phase",
|
|
1860
1841
|
phase: "execute",
|
|
@@ -1869,11 +1850,12 @@ ${issues}`;
|
|
|
1869
1850
|
context: {
|
|
1870
1851
|
template: hasTemplate ? templatePath : void 0,
|
|
1871
1852
|
previousOutput,
|
|
1872
|
-
output:
|
|
1853
|
+
output: outputFile,
|
|
1873
1854
|
revisionFeedback: state.revisionFeedback,
|
|
1874
1855
|
verifyFeedback
|
|
1875
1856
|
},
|
|
1876
|
-
onComplete
|
|
1857
|
+
onComplete,
|
|
1858
|
+
instructions: phaseExecute(outputFile, onComplete)
|
|
1877
1859
|
};
|
|
1878
1860
|
}
|
|
1879
1861
|
function buildPhaseVerifyResponse(cwd, state) {
|
|
@@ -1892,6 +1874,7 @@ function buildPhaseVerifyResponse(cwd, state) {
|
|
|
1892
1874
|
loadedKnowledge: state.loadedKnowledge?.map((k) => ({ filename: k.filename, content: k.content })),
|
|
1893
1875
|
cwd
|
|
1894
1876
|
});
|
|
1877
|
+
const onComplete = `npx spets orchestrate verify-done ${state.taskId}`;
|
|
1895
1878
|
return {
|
|
1896
1879
|
type: "phase",
|
|
1897
1880
|
phase: "verify",
|
|
@@ -1907,7 +1890,8 @@ function buildPhaseVerifyResponse(cwd, state) {
|
|
|
1907
1890
|
template: hasTemplate ? templatePath : void 0,
|
|
1908
1891
|
document: documentPath
|
|
1909
1892
|
},
|
|
1910
|
-
onComplete
|
|
1893
|
+
onComplete,
|
|
1894
|
+
instructions: phaseWithJsonOutput(onComplete)
|
|
1911
1895
|
};
|
|
1912
1896
|
}
|
|
1913
1897
|
function buildPhaseKnowledgeResponse(cwd, state) {
|
|
@@ -1920,6 +1904,7 @@ function buildPhaseKnowledgeResponse(cwd, state) {
|
|
|
1920
1904
|
guide,
|
|
1921
1905
|
cwd
|
|
1922
1906
|
});
|
|
1907
|
+
const onComplete = `npx spets orchestrate knowledge-extract-done ${state.taskId}`;
|
|
1923
1908
|
return {
|
|
1924
1909
|
type: "phase",
|
|
1925
1910
|
phase: "knowledge",
|
|
@@ -1932,21 +1917,31 @@ function buildPhaseKnowledgeResponse(cwd, state) {
|
|
|
1932
1917
|
totalSteps: state.totalSteps
|
|
1933
1918
|
},
|
|
1934
1919
|
guide,
|
|
1935
|
-
onComplete
|
|
1920
|
+
onComplete,
|
|
1921
|
+
instructions: phaseWithJsonOutput(onComplete)
|
|
1936
1922
|
};
|
|
1937
1923
|
}
|
|
1938
1924
|
function buildCheckpointClarifyResponse(state) {
|
|
1925
|
+
const onComplete = `npx spets orchestrate clarified ${state.taskId}`;
|
|
1939
1926
|
return {
|
|
1940
1927
|
type: "checkpoint",
|
|
1941
1928
|
checkpoint: "clarify",
|
|
1942
1929
|
taskId: state.taskId,
|
|
1943
1930
|
step: state.currentStep,
|
|
1944
1931
|
decisions: state.decisions || [],
|
|
1945
|
-
onComplete:
|
|
1932
|
+
onComplete: `${onComplete} '<answers_json>'`,
|
|
1933
|
+
instructions: checkpointClarify(onComplete)
|
|
1946
1934
|
};
|
|
1947
1935
|
}
|
|
1948
1936
|
function buildCheckpointApproveResponse(cwd, state) {
|
|
1949
1937
|
const outputPath = getOutputPath(cwd);
|
|
1938
|
+
const specPath = join9(outputPath, state.taskId, `${state.currentStep}.md`);
|
|
1939
|
+
const cmds = {
|
|
1940
|
+
approve: `npx spets orchestrate approve ${state.taskId}`,
|
|
1941
|
+
revise: `npx spets orchestrate revise ${state.taskId} '<feedback>'`,
|
|
1942
|
+
reject: `npx spets orchestrate reject ${state.taskId}`,
|
|
1943
|
+
stop: `npx spets orchestrate stop ${state.taskId}`
|
|
1944
|
+
};
|
|
1950
1945
|
return {
|
|
1951
1946
|
type: "checkpoint",
|
|
1952
1947
|
checkpoint: "approve",
|
|
@@ -1954,14 +1949,10 @@ function buildCheckpointApproveResponse(cwd, state) {
|
|
|
1954
1949
|
step: state.currentStep,
|
|
1955
1950
|
stepIndex: state.stepIndex,
|
|
1956
1951
|
totalSteps: state.totalSteps,
|
|
1957
|
-
specPath
|
|
1952
|
+
specPath,
|
|
1958
1953
|
options: ["approve", "revise", "reject", "stop"],
|
|
1959
|
-
onComplete:
|
|
1960
|
-
|
|
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
|
-
}
|
|
1954
|
+
onComplete: cmds,
|
|
1955
|
+
instructions: checkpointApprove(specPath, cmds)
|
|
1965
1956
|
};
|
|
1966
1957
|
}
|
|
1967
1958
|
function buildCompleteResponse(cwd, state, status) {
|
|
@@ -1984,11 +1975,12 @@ function buildCompleteResponse(cwd, state, status) {
|
|
|
1984
1975
|
status,
|
|
1985
1976
|
taskId: state.taskId,
|
|
1986
1977
|
outputs,
|
|
1987
|
-
message: messages[status]
|
|
1978
|
+
message: messages[status],
|
|
1979
|
+
instructions: PRINT_MESSAGE_AND_STOP
|
|
1988
1980
|
};
|
|
1989
1981
|
}
|
|
1990
1982
|
function buildErrorResponse(error, taskId, step) {
|
|
1991
|
-
const response = { type: "error", error };
|
|
1983
|
+
const response = { type: "error", error, instructions: PRINT_ERROR_AND_STOP };
|
|
1992
1984
|
if (taskId) response.taskId = taskId;
|
|
1993
1985
|
if (step) response.step = step;
|
|
1994
1986
|
return response;
|
|
@@ -2330,7 +2322,7 @@ var Orchestrator = class {
|
|
|
2330
2322
|
const outputPath = getOutputPath(this.cwd);
|
|
2331
2323
|
const tasks = [];
|
|
2332
2324
|
if (!existsSync11(outputPath)) {
|
|
2333
|
-
return { type: "list", tasks: [] };
|
|
2325
|
+
return { type: "list", tasks: [], instructions: LIST_EMPTY };
|
|
2334
2326
|
}
|
|
2335
2327
|
const dirs = readdirSync2(outputPath, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
2336
2328
|
for (const dir of dirs) {
|
|
@@ -2352,7 +2344,11 @@ var Orchestrator = class {
|
|
|
2352
2344
|
const bTime = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
|
|
2353
2345
|
return bTime - aTime;
|
|
2354
2346
|
});
|
|
2355
|
-
return {
|
|
2347
|
+
return {
|
|
2348
|
+
type: "list",
|
|
2349
|
+
tasks,
|
|
2350
|
+
instructions: tasks.length > 0 ? LIST_TASKS : LIST_EMPTY
|
|
2351
|
+
};
|
|
2356
2352
|
}
|
|
2357
2353
|
/**
|
|
2358
2354
|
* Get current workflow status
|