@fission-ai/openspec 1.13.0 → 1.13.1
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/README.md +1 -1
- package/dist/commands/change.js +12 -1
- package/dist/commands/config.d.ts +9 -0
- package/dist/commands/config.js +161 -22
- package/dist/commands/feedback.js +6 -4
- package/dist/commands/schema.js +30 -9
- package/dist/commands/store.js +5 -2
- package/dist/commands/validate.d.ts +7 -0
- package/dist/commands/validate.js +63 -1
- package/dist/commands/workflow/instructions.js +33 -14
- package/dist/commands/workflow/new-change.js +20 -0
- package/dist/commands/workflow/shared.js +8 -0
- package/dist/commands/workflow/status.d.ts +5 -1
- package/dist/commands/workflow/status.js +42 -5
- package/dist/core/archive.js +17 -1
- package/dist/core/artifact-graph/schema.d.ts +14 -0
- package/dist/core/artifact-graph/schema.js +52 -0
- package/dist/core/artifact-graph/types.js +12 -1
- package/dist/core/change-status-policy.d.ts +14 -0
- package/dist/core/change-status-policy.js +14 -6
- package/dist/core/command-generation/generator.js +2 -0
- package/dist/core/completion-tip.js +7 -7
- package/dist/core/completions/installers/bash-installer.js +15 -7
- package/dist/core/completions/installers/shell-quote.d.ts +11 -0
- package/dist/core/completions/installers/shell-quote.js +13 -0
- package/dist/core/completions/installers/zsh-installer.js +3 -2
- package/dist/core/config-schema.d.ts +1 -1
- package/dist/core/config.d.ts +16 -0
- package/dist/core/config.js +27 -1
- package/dist/core/global-config.d.ts +30 -2
- package/dist/core/global-config.js +57 -3
- package/dist/core/init.js +13 -3
- package/dist/core/legacy-cleanup.d.ts +4 -0
- package/dist/core/legacy-cleanup.js +180 -12
- package/dist/core/list.js +55 -11
- package/dist/core/migration.js +6 -1
- package/dist/core/parsers/change-parser.d.ts +12 -1
- package/dist/core/parsers/change-parser.js +85 -87
- package/dist/core/parsers/markdown-parser.js +4 -3
- package/dist/core/parsers/requirement-blocks.d.ts +44 -3
- package/dist/core/parsers/requirement-blocks.js +90 -15
- package/dist/core/parsers/requirement-text.d.ts +13 -2
- package/dist/core/parsers/requirement-text.js +34 -7
- package/dist/core/parsers/spec-structure.js +4 -1
- package/dist/core/project-config.d.ts +9 -1
- package/dist/core/project-config.js +11 -2
- package/dist/core/references.d.ts +20 -0
- package/dist/core/references.js +56 -0
- package/dist/core/shared/skill-content-equivalence.js +5 -1
- package/dist/core/shared/skill-generation.js +36 -8
- package/dist/core/shared/tool-detection.js +9 -3
- package/dist/core/specs-apply.js +82 -11
- package/dist/core/store/git.d.ts +33 -0
- package/dist/core/store/git.js +60 -6
- package/dist/core/store/operations.d.ts +1 -1
- package/dist/core/store/operations.js +32 -10
- package/dist/core/store/registry.d.ts +2 -1
- package/dist/core/store/registry.js +5 -1
- package/dist/core/templates/optional-workflow.d.ts +69 -0
- package/dist/core/templates/optional-workflow.js +140 -0
- package/dist/core/templates/workflows/apply-change.js +18 -3
- package/dist/core/templates/workflows/archive-change.js +50 -15
- package/dist/core/templates/workflows/bulk-archive-change.js +63 -13
- package/dist/core/templates/workflows/continue-change.js +14 -2
- package/dist/core/templates/workflows/explore.js +32 -14
- package/dist/core/templates/workflows/ff-change.js +19 -3
- package/dist/core/templates/workflows/new-change.js +15 -3
- package/dist/core/templates/workflows/onboard.js +67 -37
- package/dist/core/templates/workflows/project-root.d.ts +29 -0
- package/dist/core/templates/workflows/project-root.js +38 -0
- package/dist/core/templates/workflows/propose.js +22 -5
- package/dist/core/templates/workflows/sync-specs.js +40 -1
- package/dist/core/templates/workflows/update-change.js +52 -25
- package/dist/core/templates/workflows/verify-change.js +12 -3
- package/dist/core/update.d.ts +12 -0
- package/dist/core/update.js +58 -3
- package/dist/core/validation/task-checkboxes.d.ts +34 -0
- package/dist/core/validation/task-checkboxes.js +181 -0
- package/dist/core/validation/validator.d.ts +53 -1
- package/dist/core/validation/validator.js +154 -40
- package/dist/core/version-check.d.ts +14 -7
- package/dist/core/version-check.js +63 -17
- package/dist/core/worksets.js +6 -4
- package/dist/prompts/searchable-multi-select.d.ts +7 -0
- package/dist/prompts/searchable-multi-select.js +35 -6
- package/dist/telemetry/config.js +14 -2
- package/dist/telemetry/index.d.ts +4 -3
- package/dist/telemetry/index.js +22 -10
- package/dist/telemetry/opt-out.d.ts +17 -0
- package/dist/telemetry/opt-out.js +27 -0
- package/dist/utils/nested-change.d.ts +35 -0
- package/dist/utils/nested-change.js +186 -0
- package/dist/utils/spec-discovery.d.ts +20 -0
- package/dist/utils/spec-discovery.js +59 -0
- package/dist/utils/task-progress.d.ts +1 -1
- package/dist/utils/task-progress.js +38 -6
- package/package.json +4 -4
- package/schemas/spec-driven/schema.yaml +10 -3
- package/schemas/spec-driven/templates/design.md +2 -0
- package/schemas/spec-driven/templates/proposal.md +2 -0
- package/schemas/spec-driven/templates/spec.md +2 -0
- package/schemas/spec-driven/templates/tasks.md +2 -0
|
@@ -1,14 +1,27 @@
|
|
|
1
|
+
import { optionalWorkflow } from '../optional-workflow.js';
|
|
1
2
|
import { STORE_SELECTION_GUIDANCE } from './store-selection.js';
|
|
3
|
+
import { PROJECT_ROOT_GUARD } from './project-root.js';
|
|
4
|
+
/**
|
|
5
|
+
* Archiving must merge delta specs into the main specs; the `sync` workflow is
|
|
6
|
+
* how it normally does that. A profile that selects `archive` gets `sync`
|
|
7
|
+
* injected (see getProfileWorkflows), but an install whose workflow set was
|
|
8
|
+
* read back off disk can still be missing it — in which case the merge has to
|
|
9
|
+
* happen inline rather than be handed to a workflow that is not there.
|
|
10
|
+
*/
|
|
11
|
+
const SYNC_INLINE_HANDOFF = optionalWorkflow('sync', 'Run the `/opsx:sync` workflow inline (agent-driven intelligent merge)', 'Perform the delta-to-main-spec merge inline yourself (agent-driven intelligent merge)');
|
|
12
|
+
const SYNC_GUARDRAIL = optionalWorkflow('sync', 'run the `/opsx:sync` workflow inline (agent-driven)', 'perform the delta-to-main-spec merge inline (agent-driven)');
|
|
2
13
|
export function getBulkArchiveChangeSkillTemplate() {
|
|
3
14
|
return {
|
|
4
15
|
name: 'openspec-bulk-archive-change',
|
|
5
|
-
description: 'Archive multiple completed changes at once. Use when archiving several parallel changes.',
|
|
16
|
+
description: 'Archive multiple completed OpenSpec changes at once. Use when archiving several parallel changes. Also use for a plural archive request - "openspec bulk-archive", "opsx bulk-archive", "openspec archive all", or "openspec archive these changes".',
|
|
6
17
|
instructions: `Archive multiple completed changes in a single operation.
|
|
7
18
|
|
|
8
19
|
This skill allows you to batch-archive changes, handling spec conflicts intelligently by checking the codebase to determine what's actually implemented.
|
|
9
20
|
|
|
10
21
|
${STORE_SELECTION_GUIDANCE}
|
|
11
22
|
|
|
23
|
+
${PROJECT_ROOT_GUARD}
|
|
24
|
+
|
|
12
25
|
\`<capability-path>\` is the spec directory relative to \`specs/\` (for example, \`user-auth\` or \`identity/user-auth\`). Preserve the full path from each delta spec when resolving its main spec.
|
|
13
26
|
|
|
14
27
|
**Input**: None required (prompts for selection)
|
|
@@ -64,7 +77,9 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
64
77
|
- Note which artifacts are \`done\` vs other states
|
|
65
78
|
|
|
66
79
|
b. **Task completion** - Read \`artifactPaths.tasks.existingOutputPaths\` from status JSON
|
|
67
|
-
-
|
|
80
|
+
- Complete means the checkbox holds only \`x\`/\`X\`, ignoring spacing
|
|
81
|
+
(\`- [ x]\` is complete); every other marker is incomplete (\`- [ ]\`,
|
|
82
|
+
\`- []\`, and unfamiliar ones such as \`- [~]\` or \`- [-]\`)
|
|
68
83
|
- If no tasks file exists, note as "No tasks"
|
|
69
84
|
|
|
70
85
|
c. **Delta specs** - Check \`artifactPaths.specs.existingOutputPaths\` from status JSON
|
|
@@ -75,6 +90,14 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
75
90
|
lookup for that change; do not infer deltas from unrelated artifacts.
|
|
76
91
|
- Evaluate this independently for every change, including mixed-schema
|
|
77
92
|
batches where some schemas have no \`specs\` artifact.
|
|
93
|
+
|
|
94
|
+
d. **Archive target** - Compute each change's target name once and record it as that change's \`<target-name>\`
|
|
95
|
+
- Use the change name as-is when it already starts with a \`YYYY-MM-DD-\` prefix; otherwise prepend the current date as \`YYYY-MM-DD-<name>\` (same rule as \`openspec archive\`)
|
|
96
|
+
- Check whether \`<planningHome.changesDir>/archive/<target-name>\` already exists
|
|
97
|
+
- If it exists, or another selected change resolves to the same target name, mark every such change \`Blocked\` with \`Archive directory already exists\`
|
|
98
|
+
- A blocked change is never synced or moved: show it as \`Blocked\` in the step 6 table, leave it out of conflict resolution (resolve its conflicts using only the other changes), and record it as Failed in step 8d
|
|
99
|
+
- Checking here, before any main spec is written, matches \`openspec archive\`: a collision found after sync would leave main specs rewritten for an archive that never happened
|
|
100
|
+
|
|
78
101
|
4. **Detect spec conflicts**
|
|
79
102
|
|
|
80
103
|
Build a map keyed by \`<capability-path>\`, the exact path relative to \`specs/\`:
|
|
@@ -147,8 +170,8 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
147
170
|
Route on the answer by intent, not by exact label — you wrote these labels,
|
|
148
171
|
so match what the user picked rather than the wording above:
|
|
149
172
|
- "Cancel" — stop, do not archive. Report that nothing was archived and skip the remaining steps.
|
|
150
|
-
- The archive-everything option — proceed with every selected change
|
|
151
|
-
- The ready-only option — proceed with only the changes the step 6 table marks \`Ready\` or \`Ready*\`, and record the rest as Skipped in step 8d
|
|
173
|
+
- The archive-everything option — proceed with every selected change that is not \`Blocked\`
|
|
174
|
+
- The ready-only option — proceed with only the changes the step 6 table marks \`Ready\` or \`Ready*\`, and record the rest as Skipped in step 8d, except \`Blocked\` changes, which stay Failed with \`Archive directory already exists\`. If a \`Ready*\` change's conflict partner is skipped, re-derive that conflict's resolution using only the changes being archived.
|
|
152
175
|
- Anything else — ask again rather than archiving
|
|
153
176
|
|
|
154
177
|
Before step 8 writes the first main spec or moves any change, fetch every
|
|
@@ -193,13 +216,20 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
193
216
|
|
|
194
217
|
c. **Perform the archive**:
|
|
195
218
|
|
|
196
|
-
Target name: use the change
|
|
219
|
+
Target name: use the \`<target-name>\` recorded for this change in step 3d, unchanged. Never recompute it here: a batch that runs past midnight would check one date in step 3 and move to another.
|
|
220
|
+
|
|
221
|
+
**Check if target already exists:**
|
|
222
|
+
- Check again immediately before the move, even though step 3 already checked: the target can appear mid-batch
|
|
223
|
+
- If yes: record this change as Failed with \`Archive directory already exists\`, leave \`changeRoot\` where it is, report any main specs step 8a already synced for it, and continue with the remaining changes
|
|
224
|
+
- If no: move \`changeRoot\` to the archive directory
|
|
197
225
|
|
|
198
226
|
\`\`\`bash
|
|
199
227
|
mkdir -p "<planningHome.changesDir>/archive"
|
|
200
228
|
mv "<changeRoot>" "<planningHome.changesDir>/archive/<target-name>"
|
|
201
229
|
\`\`\`
|
|
202
230
|
|
|
231
|
+
**Confirm the move did not nest:** \`mv\` exits 0 even when the target appeared after the check, moving the change *inside* it. If \`<planningHome.changesDir>/archive/<target-name>/<change-directory-name>\` now exists (the last path segment of \`changeRoot\`), move that directory back to \`changeRoot\` and record this change as Failed with \`Archive directory already exists\`. Never report it as archived.
|
|
232
|
+
|
|
203
233
|
d. **Track outcome** for each change:
|
|
204
234
|
- Success: archived successfully
|
|
205
235
|
- Failed: error during archive or spec verification (record error)
|
|
@@ -314,8 +344,9 @@ No active changes found. Create a new change to get started.
|
|
|
314
344
|
- Never archive after the user cancels the confirmation — a cancelled batch archives nothing
|
|
315
345
|
- Track and report all outcomes (success/skip/fail)
|
|
316
346
|
- Preserve .openspec.yaml when moving to archive
|
|
317
|
-
- Archive directory target uses current date: YYYY-MM-DD-<name>; a name that already starts with a \`YYYY-MM-DD-\` prefix is used as-is (never stack a second date)
|
|
347
|
+
- Archive directory target uses the current date, computed once in step 3d and reused at the move: YYYY-MM-DD-<name>; a name that already starts with a \`YYYY-MM-DD-\` prefix is used as-is (never stack a second date)
|
|
318
348
|
- If archive target exists, fail that change but continue with others
|
|
349
|
+
- Check every archive target in step 3, before the first main-spec write; a change whose target exists is never synced or moved
|
|
319
350
|
- If sync is requested, run the \`openspec-sync-specs\` workflow inline (agent-driven) for each change with included delta specs
|
|
320
351
|
- Carry the per-delta \`includedDeltas\` and \`excludedDeltas\` decisions into execution; sync and verify only included deltas
|
|
321
352
|
- Report every excluded delta as \`sync skipped\` without treating the archive itself as skipped
|
|
@@ -347,6 +378,8 @@ This skill allows you to batch-archive changes, handling spec conflicts intellig
|
|
|
347
378
|
|
|
348
379
|
${STORE_SELECTION_GUIDANCE}
|
|
349
380
|
|
|
381
|
+
${PROJECT_ROOT_GUARD}
|
|
382
|
+
|
|
350
383
|
\`<capability-path>\` is the spec directory relative to \`specs/\` (for example, \`user-auth\` or \`identity/user-auth\`). Preserve the full path from each delta spec when resolving its main spec.
|
|
351
384
|
|
|
352
385
|
**Input**: None required (prompts for selection)
|
|
@@ -402,7 +435,9 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
402
435
|
- Note which artifacts are \`done\` vs other states
|
|
403
436
|
|
|
404
437
|
b. **Task completion** - Read \`artifactPaths.tasks.existingOutputPaths\` from status JSON
|
|
405
|
-
-
|
|
438
|
+
- Complete means the checkbox holds only \`x\`/\`X\`, ignoring spacing
|
|
439
|
+
(\`- [ x]\` is complete); every other marker is incomplete (\`- [ ]\`,
|
|
440
|
+
\`- []\`, and unfamiliar ones such as \`- [~]\` or \`- [-]\`)
|
|
406
441
|
- If no tasks file exists, note as "No tasks"
|
|
407
442
|
|
|
408
443
|
c. **Delta specs** - Check \`artifactPaths.specs.existingOutputPaths\` from status JSON
|
|
@@ -414,6 +449,13 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
414
449
|
- Evaluate this independently for every change, including mixed-schema
|
|
415
450
|
batches where some schemas have no \`specs\` artifact.
|
|
416
451
|
|
|
452
|
+
d. **Archive target** - Compute each change's target name once and record it as that change's \`<target-name>\`
|
|
453
|
+
- Use the change name as-is when it already starts with a \`YYYY-MM-DD-\` prefix; otherwise prepend the current date as \`YYYY-MM-DD-<name>\` (same rule as \`openspec archive\`)
|
|
454
|
+
- Check whether \`<planningHome.changesDir>/archive/<target-name>\` already exists
|
|
455
|
+
- If it exists, or another selected change resolves to the same target name, mark every such change \`Blocked\` with \`Archive directory already exists\`
|
|
456
|
+
- A blocked change is never synced or moved: show it as \`Blocked\` in the step 6 table, leave it out of conflict resolution (resolve its conflicts using only the other changes), and record it as Failed in step 8d
|
|
457
|
+
- Checking here, before any main spec is written, matches \`openspec archive\`: a collision found after sync would leave main specs rewritten for an archive that never happened
|
|
458
|
+
|
|
417
459
|
4. **Detect spec conflicts**
|
|
418
460
|
|
|
419
461
|
Build a map keyed by \`<capability-path>\`, the exact path relative to \`specs/\`:
|
|
@@ -486,8 +528,8 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
486
528
|
Route on the answer by intent, not by exact label — you wrote these labels,
|
|
487
529
|
so match what the user picked rather than the wording above:
|
|
488
530
|
- "Cancel" — stop, do not archive. Report that nothing was archived and skip the remaining steps.
|
|
489
|
-
- The archive-everything option — proceed with every selected change
|
|
490
|
-
- The ready-only option — proceed with only the changes the step 6 table marks \`Ready\` or \`Ready*\`, and record the rest as Skipped in step 8d
|
|
531
|
+
- The archive-everything option — proceed with every selected change that is not \`Blocked\`
|
|
532
|
+
- The ready-only option — proceed with only the changes the step 6 table marks \`Ready\` or \`Ready*\`, and record the rest as Skipped in step 8d, except \`Blocked\` changes, which stay Failed with \`Archive directory already exists\`. If a \`Ready*\` change's conflict partner is skipped, re-derive that conflict's resolution using only the changes being archived.
|
|
491
533
|
- Anything else — ask again rather than archiving
|
|
492
534
|
|
|
493
535
|
Before step 8 writes the first main spec or moves any change, fetch every
|
|
@@ -510,7 +552,7 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
510
552
|
Process changes in the determined order (respecting conflict resolution):
|
|
511
553
|
|
|
512
554
|
a. **Sync included delta specs**:
|
|
513
|
-
-
|
|
555
|
+
- ${SYNC_INLINE_HANDOFF} only for changes with entries in \`includedDeltas\`, passing only the included delta paths and explicitly instructing it to ignore that change's \`excludedDeltas\`. Wait for it to finish.
|
|
514
556
|
- For conflicts, apply in resolved order.
|
|
515
557
|
- Pass that change's fetched specs-rule snapshot into inline sync; inline
|
|
516
558
|
sync must reuse it without fetching instructions again
|
|
@@ -532,13 +574,20 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
532
574
|
|
|
533
575
|
c. **Perform the archive**:
|
|
534
576
|
|
|
535
|
-
Target name: use the change
|
|
577
|
+
Target name: use the \`<target-name>\` recorded for this change in step 3d, unchanged. Never recompute it here: a batch that runs past midnight would check one date in step 3 and move to another.
|
|
578
|
+
|
|
579
|
+
**Check if target already exists:**
|
|
580
|
+
- Check again immediately before the move, even though step 3 already checked: the target can appear mid-batch
|
|
581
|
+
- If yes: record this change as Failed with \`Archive directory already exists\`, leave \`changeRoot\` where it is, report any main specs step 8a already synced for it, and continue with the remaining changes
|
|
582
|
+
- If no: move \`changeRoot\` to the archive directory
|
|
536
583
|
|
|
537
584
|
\`\`\`bash
|
|
538
585
|
mkdir -p "<planningHome.changesDir>/archive"
|
|
539
586
|
mv "<changeRoot>" "<planningHome.changesDir>/archive/<target-name>"
|
|
540
587
|
\`\`\`
|
|
541
588
|
|
|
589
|
+
**Confirm the move did not nest:** \`mv\` exits 0 even when the target appeared after the check, moving the change *inside* it. If \`<planningHome.changesDir>/archive/<target-name>/<change-directory-name>\` now exists (the last path segment of \`changeRoot\`), move that directory back to \`changeRoot\` and record this change as Failed with \`Archive directory already exists\`. Never report it as archived.
|
|
590
|
+
|
|
542
591
|
d. **Track outcome** for each change:
|
|
543
592
|
- Success: archived successfully
|
|
544
593
|
- Failed: error during archive or spec verification (record error)
|
|
@@ -653,9 +702,10 @@ No active changes found. Create a new change to get started.
|
|
|
653
702
|
- Never archive after the user cancels the confirmation — a cancelled batch archives nothing
|
|
654
703
|
- Track and report all outcomes (success/skip/fail)
|
|
655
704
|
- Preserve .openspec.yaml when moving to archive
|
|
656
|
-
- Archive directory target uses current date: YYYY-MM-DD-<name>; a name that already starts with a \`YYYY-MM-DD-\` prefix is used as-is (never stack a second date)
|
|
705
|
+
- Archive directory target uses the current date, computed once in step 3d and reused at the move: YYYY-MM-DD-<name>; a name that already starts with a \`YYYY-MM-DD-\` prefix is used as-is (never stack a second date)
|
|
657
706
|
- If archive target exists, fail that change but continue with others
|
|
658
|
-
-
|
|
707
|
+
- Check every archive target in step 3, before the first main-spec write; a change whose target exists is never synced or moved
|
|
708
|
+
- If sync is requested, ${SYNC_GUARDRAIL} for each change with included delta specs
|
|
659
709
|
- Carry the per-delta \`includedDeltas\` and \`excludedDeltas\` decisions into execution; sync and verify only included deltas
|
|
660
710
|
- Report every excluded delta as \`sync skipped\` without treating the archive itself as skipped
|
|
661
711
|
- Never archive a change while a spec sync is still in flight — run the sync inline and verify main specs at \`<planningHome.root>/openspec/specs/<capability-path>/spec.md\` before moving \`changeRoot\`
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
+
import { optionalWorkflow } from '../optional-workflow.js';
|
|
1
2
|
import { STORE_SELECTION_GUIDANCE } from './store-selection.js';
|
|
3
|
+
import { PROJECT_ROOT_GUARD } from './project-root.js';
|
|
4
|
+
/**
|
|
5
|
+
* The planning-complete handoff. Neither `apply` nor `archive` is guaranteed
|
|
6
|
+
* to be installed, so each half is resolved at generation time (see
|
|
7
|
+
* optional-workflow.ts).
|
|
8
|
+
*/
|
|
9
|
+
const PLANNING_COMPLETE_HANDOFF = optionalWorkflow('apply', 'You can now implement this change with `/opsx:apply`.', 'You can now implement this change - `openspec instructions apply --change "<name>" --json` returns the tasks and how to work them.') + ' ' + optionalWorkflow('archive', 'Once implementation and any tracked work are complete, archive it with `/opsx:archive`.', 'Once implementation and any tracked work are complete, archive it with `openspec archive "<name>"`.');
|
|
2
10
|
export function getContinueChangeSkillTemplate() {
|
|
3
11
|
return {
|
|
4
12
|
name: 'openspec-continue-change',
|
|
5
|
-
description: 'Continue working on an OpenSpec change by creating the next artifact. Use when the user wants to progress their change, create the next artifact, or continue their workflow.',
|
|
13
|
+
description: 'Continue working on an OpenSpec change by creating the next artifact. Use when the user wants to progress their change, create the next artifact, or continue their workflow. Also use when the user says "openspec continue" or "opsx continue".',
|
|
6
14
|
instructions: `Continue working on a change by creating the next artifact.
|
|
7
15
|
|
|
8
16
|
${STORE_SELECTION_GUIDANCE}
|
|
9
17
|
|
|
18
|
+
${PROJECT_ROOT_GUARD}
|
|
19
|
+
|
|
10
20
|
**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
11
21
|
|
|
12
22
|
**Steps**
|
|
@@ -124,6 +134,8 @@ export function getOpsxContinueCommandTemplate() {
|
|
|
124
134
|
|
|
125
135
|
${STORE_SELECTION_GUIDANCE}
|
|
126
136
|
|
|
137
|
+
${PROJECT_ROOT_GUARD}
|
|
138
|
+
|
|
127
139
|
**Input**: Optionally specify a change name after \`/opsx:continue\` (e.g., \`/opsx:continue add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
|
|
128
140
|
|
|
129
141
|
**Steps**
|
|
@@ -162,7 +174,7 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
162
174
|
**If all planning artifacts are complete (\`isPlanningComplete: true\`, or legacy \`isComplete: true\`)**:
|
|
163
175
|
- Congratulate the user
|
|
164
176
|
- Show final status including the schema used
|
|
165
|
-
- Suggest: "Planning is complete!
|
|
177
|
+
- Suggest: "Planning is complete! ${PLANNING_COMPLETE_HANDOFF}"
|
|
166
178
|
- STOP
|
|
167
179
|
|
|
168
180
|
---
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { optionalWorkflow } from '../optional-workflow.js';
|
|
1
2
|
import { STORE_SELECTION_GUIDANCE } from './store-selection.js';
|
|
3
|
+
import { PROJECT_ROOT_GUARD } from './project-root.js';
|
|
2
4
|
const PLANNING_GUIDANCE = `## Planning a Change
|
|
3
5
|
|
|
4
6
|
When the user is planning a change, guide them toward shared understanding with focused discovery questions. For open-ended discussion, follow the conversation without imposing an interview or a required output.
|
|
@@ -20,18 +22,32 @@ across devices in scope? That determines whether local storage is enough.
|
|
|
20
22
|
If this stays a single-device tool, I recommend keeping SQLite to avoid
|
|
21
23
|
adding a service to operate; shared state would need a separate sync design.
|
|
22
24
|
\`\`\``;
|
|
25
|
+
/**
|
|
26
|
+
* Explore's handoffs. A custom profile can install explore without propose or
|
|
27
|
+
* apply, so each reference is resolved at generation time (see
|
|
28
|
+
* optional-workflow.ts) instead of naming a workflow that may not exist. The
|
|
29
|
+
* fallbacks point at explore's own capture path and the always-present CLI.
|
|
30
|
+
*/
|
|
31
|
+
const IMPLEMENT_REQUEST_HANDOFF = optionalWorkflow('propose', 'point them at `/opsx:propose`, which turns the discussion into a change', 'offer to capture the discussion as a change, as described below');
|
|
32
|
+
const CAPTURE_PLANNING_HANDOFF = optionalWorkflow('propose', '`/opsx:propose` writes the remaining planning artifacts', 'any remaining planning artifacts can be captured here the same way');
|
|
33
|
+
const CAPTURE_APPLY_HANDOFF = optionalWorkflow('apply', '`/opsx:apply` implements the change once tasks exist', 'implementation works from the change\'s tasks (`openspec instructions apply --change "<name>" --json`), outside explore mode');
|
|
34
|
+
const DISCOVERY_END_HANDOFF = optionalWorkflow('propose', 'Ready to start? Run `/opsx:propose` and this becomes a change.', 'Ready to start? I can capture this as a change.');
|
|
35
|
+
const SUMMARY_NEXT_STEP = optionalWorkflow('propose', '- Turn this into a change: `/opsx:propose`', '- Capture this as a change: ask me to');
|
|
36
|
+
const GUARDRAIL_HANDOFF = optionalWorkflow('propose', '`/opsx:propose` turns the discussion into a change, and the work happens there', 'offer to capture the discussion as a change, and the work happens from that change');
|
|
23
37
|
export function getExploreSkillTemplate() {
|
|
24
38
|
return {
|
|
25
39
|
name: 'openspec-explore',
|
|
26
|
-
description: 'Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Use when the user wants to think through something before or during
|
|
40
|
+
description: 'Enter OpenSpec explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements in a project that uses OpenSpec. Use when the user wants to think through something before or during an OpenSpec change. Also use when the user says "openspec explore" or "opsx explore".',
|
|
27
41
|
instructions: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
|
|
28
42
|
|
|
29
|
-
**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, investigate the codebase, and run read-only commands or tools without confirmation, but you must NEVER write code or implement features. If the user asks you to implement something,
|
|
43
|
+
**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, investigate the codebase, and run read-only commands or tools without confirmation, but you must NEVER write code or implement features. If the user asks you to implement something, do not start it here: say that explore mode does not implement, and ${IMPLEMENT_REQUEST_HANDOFF}. The work happens from that change, never from explore mode. You MAY create or update OpenSpec change artifacts (proposals, designs, specs) within a confirmed scope—that's capturing thinking, not implementing. Answering design or clarifying questions is never consent to write. Before the first write-capable action, name the artifacts or files you would change and what you would do, ask a direct yes/no question, and wait for the user's confirmation in a separate message. Confirmation covers only the scope you described; ask again before expanding it. An explicit request from the user to capture the exploration as a new change is itself that confirmation, covering the change and the change artifacts the request names; scaffold it first as described below.
|
|
30
44
|
|
|
31
45
|
**This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
|
|
32
46
|
|
|
33
47
|
${STORE_SELECTION_GUIDANCE}
|
|
34
48
|
|
|
49
|
+
${PROJECT_ROOT_GUARD}
|
|
50
|
+
|
|
35
51
|
---
|
|
36
52
|
|
|
37
53
|
## The Stance
|
|
@@ -136,14 +152,14 @@ Think freely. When insights crystallize, you might offer:
|
|
|
136
152
|
- "This feels solid enough to start a change. Want me to create a proposal?"
|
|
137
153
|
- Or keep exploring - no pressure to formalize
|
|
138
154
|
|
|
139
|
-
If the user asks you to capture the exploration as a new change,
|
|
155
|
+
If the user asks you to capture the exploration as a new change, that request is the confirmation required above. It covers scaffolding that change and creating the change artifacts the request names, and nothing else. This holds only when the request is theirs: a yes to an offer you made confirms only the scope your offer itself named, so name the change and the artifacts in the offer. Don't re-ask for what they already asked for; do ask before anything beyond it. Transition seamlessly into the requested capture:
|
|
140
156
|
|
|
141
157
|
1. Run \`openspec new change "<name>"\` (with \`--store <id>\` when applicable) before creating any artifacts. Never create a new change directory under \`openspec/changes/\` by hand; the CLI scaffold creates required metadata such as \`.openspec.yaml\`. Keep the selected \`--store <id>\` on every applicable follow-up \`status\` and \`instructions\` command.
|
|
142
158
|
2. Run \`openspec status --change "<name>" --json\` (append the confirmed \`--store "<id>"\` only for a registered standalone store), then process the requested artifacts in dependency order. For each requested artifact that is \`ready\`, run \`openspec instructions "<artifact-id>" --change "<name>" --json\` (append the confirmed \`--store "<id>"\` only for a registered standalone store). Before creating a requested artifact, evaluate any condition in its own \`instruction\` against the explored change; record a deliberate skip instead when the condition does not apply. If a requested artifact is blocked by a direct prerequisite the user did not request, run \`openspec instructions "<prerequisite-id>" --change "<name>" --json\` (append the confirmed \`--store "<id>"\` only for a registered standalone store) for that prerequisite whether it is \`ready\` or \`blocked\`. If its own \`instruction\` states a condition, evaluate that condition against the explored change and record a deliberate skip only when the condition does not apply. If the condition applies, or the prerequisite is not conditional, treat it as a normal prerequisite and ask before expanding the capture. Do not create an unrequested prerequisite unless the user approves.
|
|
143
159
|
3. Follow the returned \`template\` and \`instruction\` fields. Read completed dependency files listed in \`dependencies\`, and apply \`context\` and \`rules\` as constraints without copying them into the artifact. If the instruction delegates creation to a specific skill or command, invoke it; otherwise write the artifact to \`resolvedOutputPath\`, using the instruction to choose a concrete path when it is a glob. Verify that the selected concrete output exists.
|
|
144
160
|
4. After creating each artifact, re-run \`openspec status --change "<name>" --json\` (append the confirmed \`--store "<id>"\` only for a registered standalone store) and continue until every requested artifact is \`done\`, \`skipped\`, or was deliberately skipped because its own \`instruction\` stated a condition that did not apply. Tell the user about a deliberate conditional skip, remember it, and do not reconsider it. Dependencies are enablers, not gates: if a requested artifact is still \`blocked\` only because you deliberately skipped a conditional prerequisite, run \`openspec instructions "<artifact-id>" --change "<name>" --json\` (append the confirmed \`--store "<id>"\` only for a registered standalone store) despite the blocked status, then create it using step 3 only when those recorded conditional skips are its sole missing dependencies. If a requested artifact is blocked by a prerequisite the user did not ask to capture and cannot be conditionally skipped, explain that dependency and ask before expanding the capture.
|
|
145
161
|
|
|
146
|
-
Capture the artifact(s) the user requested without asking them to invoke another workflow command. If they asked only to start a change, stop after scaffolding and show its status.
|
|
162
|
+
Capture the artifact(s) the user requested without asking them to invoke another workflow command. If they asked only to start a change, stop after scaffolding and show its status. When the requested capture is done, stop there and name where the work continues: ${CAPTURE_PLANNING_HANDOFF}, and ${CAPTURE_APPLY_HANDOFF}. Capturing artifacts never starts implementing them.
|
|
147
163
|
|
|
148
164
|
### When a change exists
|
|
149
165
|
|
|
@@ -299,7 +315,7 @@ You: That changes everything.
|
|
|
299
315
|
|
|
300
316
|
There's no required ending. Discovery might:
|
|
301
317
|
|
|
302
|
-
- **Flow into a proposal**: "
|
|
318
|
+
- **Flow into a proposal**: "${DISCOVERY_END_HANDOFF}"
|
|
303
319
|
- **Result in artifact updates**: "Updated design.md with these decisions"
|
|
304
320
|
- **Just provide clarity**: User has what they need, moves on
|
|
305
321
|
- **Continue later**: "We can pick this up anytime"
|
|
@@ -316,7 +332,7 @@ When it feels like things are crystallizing, you might summarize:
|
|
|
316
332
|
**Open questions**: [if any remain]
|
|
317
333
|
|
|
318
334
|
**Next steps** (if ready):
|
|
319
|
-
|
|
335
|
+
${SUMMARY_NEXT_STEP}
|
|
320
336
|
- Keep exploring: just keep talking
|
|
321
337
|
\`\`\`
|
|
322
338
|
|
|
@@ -326,11 +342,11 @@ But this summary is optional. Sometimes the thinking IS the value.
|
|
|
326
342
|
|
|
327
343
|
## Guardrails
|
|
328
344
|
|
|
329
|
-
- **Don't implement** - Never write code or implement features. Workflow configuration counts too: creating or editing schemas, templates, or \`openspec/config.yaml\` is a change, not thinking. Creating or updating OpenSpec change artifacts within the confirmed scope is fine, writing anything else is not.
|
|
345
|
+
- **Don't implement** - Never write code or implement features. Workflow configuration counts too: creating or editing schemas, templates, or \`openspec/config.yaml\` is a change, not thinking. Creating or updating OpenSpec change artifacts within the confirmed scope is fine, writing anything else is not. When the user is ready to build, name the handoff rather than starting: ${GUARDRAIL_HANDOFF}.
|
|
330
346
|
- **Don't fake understanding** - If something is unclear, dig deeper
|
|
331
347
|
- **Don't rush** - Discovery is thinking time, not task time
|
|
332
348
|
- **Don't force structure** - Let patterns emerge naturally
|
|
333
|
-
- **Don't auto-capture** - Offer to save insights, don't just do it. Read-only commands and tools need no confirmation. Before the first write-capable action—including \`openspec new change\` or another command that writes files—name the artifacts or files and proposed changes, ask a direct yes/no question, and wait for explicit confirmation in a separate user message. That confirmation covers only the described scope; ask again before expanding it. Answers to design or clarifying questions are never consent to write.
|
|
349
|
+
- **Don't auto-capture** - Offer to save insights, don't just do it. Read-only commands and tools need no confirmation. Before the first write-capable action—including \`openspec new change\` or another command that writes files—name the artifacts or files and proposed changes, ask a direct yes/no question, and wait for explicit confirmation in a separate user message. That confirmation covers only the described scope; ask again before expanding it. Answers to design or clarifying questions are never consent to write. That rule governs \`openspec new change\` whenever you are the one proposing the capture; the user's own capture request is the exception, handled in the capture transition above.
|
|
334
350
|
- **Don't manually scaffold changes** - Never create a new change directory under \`openspec/changes/\` by hand. Always use \`openspec new change "<name>"\` (with \`--store <id>\` when applicable) so required metadata such as \`.openspec.yaml\` is created before writing artifacts.
|
|
335
351
|
- **Do visualize** - A good diagram is worth many paragraphs
|
|
336
352
|
- **Do explore the codebase** - Ground discussions in reality
|
|
@@ -348,12 +364,14 @@ export function getOpsxExploreCommandTemplate() {
|
|
|
348
364
|
tags: ['workflow', 'explore', 'experimental', 'thinking'],
|
|
349
365
|
content: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
|
|
350
366
|
|
|
351
|
-
**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, investigate the codebase, and run read-only commands or tools without confirmation, but you must NEVER write code or implement features. If the user asks you to implement something,
|
|
367
|
+
**IMPORTANT: Explore mode is for thinking, not implementing.** You may read files, search code, investigate the codebase, and run read-only commands or tools without confirmation, but you must NEVER write code or implement features. If the user asks you to implement something, do not start it here: say that explore mode does not implement, and ${IMPLEMENT_REQUEST_HANDOFF}. The work happens from that change, never from explore mode. You MAY create or update OpenSpec change artifacts (proposals, designs, specs) within a confirmed scope—that's capturing thinking, not implementing. Answering design or clarifying questions is never consent to write. Before the first write-capable action, name the artifacts or files you would change and what you would do, ask a direct yes/no question, and wait for the user's confirmation in a separate message. Confirmation covers only the scope you described; ask again before expanding it. An explicit request from the user to capture the exploration as a new change is itself that confirmation, covering the change and the change artifacts the request names; scaffold it first as described below.
|
|
352
368
|
|
|
353
369
|
**This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
|
|
354
370
|
|
|
355
371
|
${STORE_SELECTION_GUIDANCE}
|
|
356
372
|
|
|
373
|
+
${PROJECT_ROOT_GUARD}
|
|
374
|
+
|
|
357
375
|
**Input**: The argument after \`/opsx:explore\` is whatever the user wants to think about. Could be:
|
|
358
376
|
- A vague idea: "real-time collaboration"
|
|
359
377
|
- A specific problem: "the auth system is getting unwieldy"
|
|
@@ -467,14 +485,14 @@ Think freely. When insights crystallize, you might offer:
|
|
|
467
485
|
- "This feels solid enough to start a change. Want me to create a proposal?"
|
|
468
486
|
- Or keep exploring - no pressure to formalize
|
|
469
487
|
|
|
470
|
-
If the user asks you to capture the exploration as a new change,
|
|
488
|
+
If the user asks you to capture the exploration as a new change, that request is the confirmation required above. It covers scaffolding that change and creating the change artifacts the request names, and nothing else. This holds only when the request is theirs: a yes to an offer you made confirms only the scope your offer itself named, so name the change and the artifacts in the offer. Don't re-ask for what they already asked for; do ask before anything beyond it. Transition seamlessly into the requested capture:
|
|
471
489
|
|
|
472
490
|
1. Run \`openspec new change "<name>"\` (with \`--store <id>\` when applicable) before creating any artifacts. Never create a new change directory under \`openspec/changes/\` by hand; the CLI scaffold creates required metadata such as \`.openspec.yaml\`. Keep the selected \`--store <id>\` on every applicable follow-up \`status\` and \`instructions\` command.
|
|
473
491
|
2. Run \`openspec status --change "<name>" --json\` (append the confirmed \`--store "<id>"\` only for a registered standalone store), then process the requested artifacts in dependency order. For each requested artifact that is \`ready\`, run \`openspec instructions "<artifact-id>" --change "<name>" --json\` (append the confirmed \`--store "<id>"\` only for a registered standalone store). Before creating a requested artifact, evaluate any condition in its own \`instruction\` against the explored change; record a deliberate skip instead when the condition does not apply. If a requested artifact is blocked by a direct prerequisite the user did not request, run \`openspec instructions "<prerequisite-id>" --change "<name>" --json\` (append the confirmed \`--store "<id>"\` only for a registered standalone store) for that prerequisite whether it is \`ready\` or \`blocked\`. If its own \`instruction\` states a condition, evaluate that condition against the explored change and record a deliberate skip only when the condition does not apply. If the condition applies, or the prerequisite is not conditional, treat it as a normal prerequisite and ask before expanding the capture. Do not create an unrequested prerequisite unless the user approves.
|
|
474
492
|
3. Follow the returned \`template\` and \`instruction\` fields. Read completed dependency files listed in \`dependencies\`, and apply \`context\` and \`rules\` as constraints without copying them into the artifact. If the instruction delegates creation to a specific skill or command, invoke it; otherwise write the artifact to \`resolvedOutputPath\`, using the instruction to choose a concrete path when it is a glob. Verify that the selected concrete output exists.
|
|
475
493
|
4. After creating each artifact, re-run \`openspec status --change "<name>" --json\` (append the confirmed \`--store "<id>"\` only for a registered standalone store) and continue until every requested artifact is \`done\`, \`skipped\`, or was deliberately skipped because its own \`instruction\` stated a condition that did not apply. Tell the user about a deliberate conditional skip, remember it, and do not reconsider it. Dependencies are enablers, not gates: if a requested artifact is still \`blocked\` only because you deliberately skipped a conditional prerequisite, run \`openspec instructions "<artifact-id>" --change "<name>" --json\` (append the confirmed \`--store "<id>"\` only for a registered standalone store) despite the blocked status, then create it using step 3 only when those recorded conditional skips are its sole missing dependencies. If a requested artifact is blocked by a prerequisite the user did not ask to capture and cannot be conditionally skipped, explain that dependency and ask before expanding the capture.
|
|
476
494
|
|
|
477
|
-
Capture the artifact(s) the user requested without asking them to invoke another workflow command. If they asked only to start a change, stop after scaffolding and show its status.
|
|
495
|
+
Capture the artifact(s) the user requested without asking them to invoke another workflow command. If they asked only to start a change, stop after scaffolding and show its status. When the requested capture is done, stop there and name where the work continues: ${CAPTURE_PLANNING_HANDOFF}, and ${CAPTURE_APPLY_HANDOFF}. Capturing artifacts never starts implementing them.
|
|
478
496
|
|
|
479
497
|
### When a change exists
|
|
480
498
|
|
|
@@ -526,7 +544,7 @@ If the user mentions a change or you detect one is relevant:
|
|
|
526
544
|
|
|
527
545
|
There's no required ending. Discovery might:
|
|
528
546
|
|
|
529
|
-
- **Flow into a proposal**: "
|
|
547
|
+
- **Flow into a proposal**: "${DISCOVERY_END_HANDOFF}"
|
|
530
548
|
- **Result in artifact updates**: "Updated design.md with these decisions"
|
|
531
549
|
- **Just provide clarity**: User has what they need, moves on
|
|
532
550
|
- **Continue later**: "We can pick this up anytime"
|
|
@@ -537,11 +555,11 @@ When things crystallize, you might offer a summary - but it's optional. Sometime
|
|
|
537
555
|
|
|
538
556
|
## Guardrails
|
|
539
557
|
|
|
540
|
-
- **Don't implement** - Never write code or implement features. Workflow configuration counts too: creating or editing schemas, templates, or \`openspec/config.yaml\` is a change, not thinking. Creating or updating OpenSpec change artifacts within the confirmed scope is fine, writing anything else is not.
|
|
558
|
+
- **Don't implement** - Never write code or implement features. Workflow configuration counts too: creating or editing schemas, templates, or \`openspec/config.yaml\` is a change, not thinking. Creating or updating OpenSpec change artifacts within the confirmed scope is fine, writing anything else is not. When the user is ready to build, name the handoff rather than starting: ${GUARDRAIL_HANDOFF}.
|
|
541
559
|
- **Don't fake understanding** - If something is unclear, dig deeper
|
|
542
560
|
- **Don't rush** - Discovery is thinking time, not task time
|
|
543
561
|
- **Don't force structure** - Let patterns emerge naturally
|
|
544
|
-
- **Don't auto-capture** - Offer to save insights, don't just do it. Read-only commands and tools need no confirmation. Before the first write-capable action—including \`openspec new change\` or another command that writes files—name the artifacts or files and proposed changes, ask a direct yes/no question, and wait for explicit confirmation in a separate user message. That confirmation covers only the described scope; ask again before expanding it. Answers to design or clarifying questions are never consent to write.
|
|
562
|
+
- **Don't auto-capture** - Offer to save insights, don't just do it. Read-only commands and tools need no confirmation. Before the first write-capable action—including \`openspec new change\` or another command that writes files—name the artifacts or files and proposed changes, ask a direct yes/no question, and wait for explicit confirmation in a separate user message. That confirmation covers only the described scope; ask again before expanding it. Answers to design or clarifying questions are never consent to write. That rule governs \`openspec new change\` whenever you are the one proposing the capture; the user's own capture request is the exception, handled in the capture transition above.
|
|
545
563
|
- **Don't manually scaffold changes** - Never create a new change directory under \`openspec/changes/\` by hand. Always use \`openspec new change "<name>"\` (with \`--store <id>\` when applicable) so required metadata such as \`.openspec.yaml\` is created before writing artifacts.
|
|
546
564
|
- **Do visualize** - A good diagram is worth many paragraphs
|
|
547
565
|
- **Do explore the codebase** - Ground discussions in reality
|
|
@@ -1,12 +1,26 @@
|
|
|
1
|
+
import { optionalWorkflow } from '../optional-workflow.js';
|
|
1
2
|
import { STORE_SELECTION_GUIDANCE } from './store-selection.js';
|
|
3
|
+
import { PROJECT_ROOT_GUARD } from './project-root.js';
|
|
4
|
+
/**
|
|
5
|
+
* The implementation handoff, resolved at generation time so a profile
|
|
6
|
+
* without `apply` is not told to run it (see optional-workflow.ts).
|
|
7
|
+
*
|
|
8
|
+
* The two surfaces word this differently on purpose (#258): a command-only
|
|
9
|
+
* tool has no conversational agent to ask, so its prompt names a command or
|
|
10
|
+
* the CLI and never invites "ask me to implement".
|
|
11
|
+
*/
|
|
12
|
+
const SKILL_APPLY_HANDOFF = optionalWorkflow('apply', 'Run `/opsx:apply` or ask me to implement to start working on the tasks.', 'Ask me to implement to start working on the tasks.');
|
|
13
|
+
const COMMAND_APPLY_HANDOFF = optionalWorkflow('apply', 'Run `/opsx:apply` to start implementing.', 'Run `openspec instructions apply --change "<name>" --json` to get the task list and start implementing.');
|
|
2
14
|
export function getFfChangeSkillTemplate() {
|
|
3
15
|
return {
|
|
4
16
|
name: 'openspec-ff-change',
|
|
5
|
-
description: 'Fast-forward through OpenSpec artifact creation. Use when the user wants to quickly create all artifacts needed for implementation without stepping through each one individually.',
|
|
17
|
+
description: 'Fast-forward through OpenSpec artifact creation. Use when the user wants to quickly create all artifacts needed for implementation without stepping through each one individually. Also use when the user says "openspec ff" or "opsx ff".',
|
|
6
18
|
instructions: `Fast-forward through artifact creation - generate everything needed to start implementation in one go.
|
|
7
19
|
|
|
8
20
|
${STORE_SELECTION_GUIDANCE}
|
|
9
21
|
|
|
22
|
+
${PROJECT_ROOT_GUARD}
|
|
23
|
+
|
|
10
24
|
**Input**: The user's request should include a change name (kebab-case) OR a description of what they want to build.
|
|
11
25
|
|
|
12
26
|
**Steps**
|
|
@@ -89,7 +103,7 @@ After completing all artifacts, summarize:
|
|
|
89
103
|
- Change name and location
|
|
90
104
|
- List of artifacts created with brief descriptions, plus any conditional artifact you skipped and why
|
|
91
105
|
- What's ready: "All artifacts needed for implementation are ready."
|
|
92
|
-
- Prompt: "
|
|
106
|
+
- Prompt: "${SKILL_APPLY_HANDOFF}"
|
|
93
107
|
|
|
94
108
|
**Artifact Creation Guidelines**
|
|
95
109
|
|
|
@@ -123,6 +137,8 @@ export function getOpsxFfCommandTemplate() {
|
|
|
123
137
|
|
|
124
138
|
${STORE_SELECTION_GUIDANCE}
|
|
125
139
|
|
|
140
|
+
${PROJECT_ROOT_GUARD}
|
|
141
|
+
|
|
126
142
|
**Input**: The argument after \`/opsx:ff\` is the change name (kebab-case), OR a description of what the user wants to build.
|
|
127
143
|
|
|
128
144
|
**Steps**
|
|
@@ -205,7 +221,7 @@ After completing all artifacts, summarize:
|
|
|
205
221
|
- Change name and location
|
|
206
222
|
- List of artifacts created with brief descriptions, plus any conditional artifact you skipped and why
|
|
207
223
|
- What's ready: "All artifacts needed for implementation are ready."
|
|
208
|
-
- Prompt: "
|
|
224
|
+
- Prompt: "${COMMAND_APPLY_HANDOFF}"
|
|
209
225
|
|
|
210
226
|
**Artifact Creation Guidelines**
|
|
211
227
|
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
+
import { optionalWorkflow } from '../optional-workflow.js';
|
|
1
2
|
import { STORE_SELECTION_GUIDANCE } from './store-selection.js';
|
|
3
|
+
import { PROJECT_ROOT_GUARD } from './project-root.js';
|
|
4
|
+
/**
|
|
5
|
+
* Handoffs to `continue`, which is not guaranteed to be installed alongside
|
|
6
|
+
* `new`; resolved at generation time (see optional-workflow.ts).
|
|
7
|
+
*/
|
|
8
|
+
const FIRST_ARTIFACT_PROMPT = optionalWorkflow('continue', 'Run `/opsx:continue` or just describe what this change is about and I\'ll draft it.', 'Just describe what this change is about and I\'ll draft it.');
|
|
9
|
+
const EXISTING_CHANGE_HINT = optionalWorkflow('continue', 'suggest using `/opsx:continue` instead', 'say so and ask whether to resume that change or pick a different name');
|
|
2
10
|
export function getNewChangeSkillTemplate() {
|
|
3
11
|
return {
|
|
4
12
|
name: 'openspec-new-change',
|
|
5
|
-
description: 'Start a new OpenSpec change using the experimental artifact workflow. Use when the user wants to create a new feature, fix, or modification with a structured step-by-step approach.',
|
|
13
|
+
description: 'Start a new OpenSpec change using the experimental artifact workflow. Use when the user wants to create a new feature, fix, or modification with a structured step-by-step approach. Also use when the user says "openspec new change" or "opsx new".',
|
|
6
14
|
instructions: `Start a new change using the experimental artifact-driven approach.
|
|
7
15
|
|
|
8
16
|
${STORE_SELECTION_GUIDANCE}
|
|
9
17
|
|
|
18
|
+
${PROJECT_ROOT_GUARD}
|
|
19
|
+
|
|
10
20
|
**Input**: The user's request should include a change name (kebab-case) OR a description of what they want to build.
|
|
11
21
|
|
|
12
22
|
**Steps**
|
|
@@ -83,6 +93,8 @@ export function getOpsxNewCommandTemplate() {
|
|
|
83
93
|
|
|
84
94
|
${STORE_SELECTION_GUIDANCE}
|
|
85
95
|
|
|
96
|
+
${PROJECT_ROOT_GUARD}
|
|
97
|
+
|
|
86
98
|
**Input**: The argument after \`/opsx:new\` is the change name (kebab-case), OR a description of what the user wants to build.
|
|
87
99
|
|
|
88
100
|
**Steps**
|
|
@@ -135,13 +147,13 @@ After completing the steps, summarize:
|
|
|
135
147
|
- Schema/workflow being used and its artifact sequence
|
|
136
148
|
- Current status (0/N artifacts complete)
|
|
137
149
|
- The template for the first artifact
|
|
138
|
-
- Prompt: "Ready to create the first artifact?
|
|
150
|
+
- Prompt: "Ready to create the first artifact? ${FIRST_ARTIFACT_PROMPT}"
|
|
139
151
|
|
|
140
152
|
**Guardrails**
|
|
141
153
|
- Do NOT create any artifacts yet - just show the instructions
|
|
142
154
|
- Do NOT advance beyond showing the first artifact template
|
|
143
155
|
- If the name is invalid (not kebab-case), ask for a valid name
|
|
144
|
-
- If a change with that name already exists,
|
|
156
|
+
- If a change with that name already exists, ${EXISTING_CHANGE_HINT}
|
|
145
157
|
- Pass --schema if using a non-default workflow`
|
|
146
158
|
};
|
|
147
159
|
}
|