@fission-ai/openspec 1.12.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.
Files changed (105) hide show
  1. package/README.md +3 -15
  2. package/dist/commands/change.js +12 -1
  3. package/dist/commands/config.d.ts +9 -0
  4. package/dist/commands/config.js +161 -22
  5. package/dist/commands/feedback.js +6 -4
  6. package/dist/commands/schema.js +30 -9
  7. package/dist/commands/store.js +5 -2
  8. package/dist/commands/validate.d.ts +7 -0
  9. package/dist/commands/validate.js +63 -1
  10. package/dist/commands/workflow/instructions.js +170 -16
  11. package/dist/commands/workflow/new-change.js +20 -0
  12. package/dist/commands/workflow/shared.d.ts +8 -0
  13. package/dist/commands/workflow/shared.js +8 -0
  14. package/dist/commands/workflow/status.d.ts +5 -1
  15. package/dist/commands/workflow/status.js +42 -5
  16. package/dist/core/archive.js +17 -1
  17. package/dist/core/artifact-graph/schema.d.ts +14 -0
  18. package/dist/core/artifact-graph/schema.js +52 -0
  19. package/dist/core/artifact-graph/types.js +12 -1
  20. package/dist/core/change-status-policy.d.ts +14 -0
  21. package/dist/core/change-status-policy.js +14 -6
  22. package/dist/core/command-generation/generator.js +2 -0
  23. package/dist/core/completion-tip.js +7 -7
  24. package/dist/core/completions/installers/bash-installer.js +15 -7
  25. package/dist/core/completions/installers/shell-quote.d.ts +11 -0
  26. package/dist/core/completions/installers/shell-quote.js +13 -0
  27. package/dist/core/completions/installers/zsh-installer.js +3 -2
  28. package/dist/core/config-schema.d.ts +1 -1
  29. package/dist/core/config.d.ts +16 -0
  30. package/dist/core/config.js +27 -1
  31. package/dist/core/global-config.d.ts +30 -2
  32. package/dist/core/global-config.js +57 -3
  33. package/dist/core/init.js +33 -3
  34. package/dist/core/legacy-cleanup.d.ts +4 -0
  35. package/dist/core/legacy-cleanup.js +180 -12
  36. package/dist/core/list.js +55 -11
  37. package/dist/core/migration.js +6 -1
  38. package/dist/core/onboarding-commands.d.ts +11 -1
  39. package/dist/core/onboarding-commands.js +26 -0
  40. package/dist/core/parsers/change-parser.d.ts +12 -1
  41. package/dist/core/parsers/change-parser.js +85 -87
  42. package/dist/core/parsers/markdown-parser.js +4 -3
  43. package/dist/core/parsers/requirement-blocks.d.ts +44 -3
  44. package/dist/core/parsers/requirement-blocks.js +164 -43
  45. package/dist/core/parsers/requirement-text.d.ts +13 -2
  46. package/dist/core/parsers/requirement-text.js +34 -7
  47. package/dist/core/parsers/spec-structure.js +4 -1
  48. package/dist/core/project-config.d.ts +9 -1
  49. package/dist/core/project-config.js +11 -2
  50. package/dist/core/references.d.ts +20 -0
  51. package/dist/core/references.js +56 -0
  52. package/dist/core/shared/skill-content-equivalence.js +5 -1
  53. package/dist/core/shared/skill-generation.js +36 -8
  54. package/dist/core/shared/tool-detection.js +37 -4
  55. package/dist/core/specs-apply.js +260 -18
  56. package/dist/core/store/git.d.ts +33 -0
  57. package/dist/core/store/git.js +60 -6
  58. package/dist/core/store/operations.d.ts +1 -1
  59. package/dist/core/store/operations.js +32 -10
  60. package/dist/core/store/registry.d.ts +2 -1
  61. package/dist/core/store/registry.js +5 -1
  62. package/dist/core/templates/optional-workflow.d.ts +69 -0
  63. package/dist/core/templates/optional-workflow.js +140 -0
  64. package/dist/core/templates/workflows/apply-change.js +18 -3
  65. package/dist/core/templates/workflows/archive-change.js +50 -15
  66. package/dist/core/templates/workflows/bulk-archive-change.js +63 -13
  67. package/dist/core/templates/workflows/continue-change.js +14 -2
  68. package/dist/core/templates/workflows/explore.js +48 -14
  69. package/dist/core/templates/workflows/ff-change.js +19 -3
  70. package/dist/core/templates/workflows/new-change.js +15 -3
  71. package/dist/core/templates/workflows/onboard.js +67 -37
  72. package/dist/core/templates/workflows/project-root.d.ts +29 -0
  73. package/dist/core/templates/workflows/project-root.js +38 -0
  74. package/dist/core/templates/workflows/propose.js +52 -15
  75. package/dist/core/templates/workflows/sync-specs.js +40 -1
  76. package/dist/core/templates/workflows/update-change.js +52 -25
  77. package/dist/core/templates/workflows/verify-change.js +12 -3
  78. package/dist/core/update.d.ts +34 -0
  79. package/dist/core/update.js +109 -11
  80. package/dist/core/validation/task-checkboxes.d.ts +34 -0
  81. package/dist/core/validation/task-checkboxes.js +181 -0
  82. package/dist/core/validation/validator.d.ts +53 -1
  83. package/dist/core/validation/validator.js +154 -40
  84. package/dist/core/version-check.d.ts +14 -7
  85. package/dist/core/version-check.js +63 -17
  86. package/dist/core/worksets.js +6 -4
  87. package/dist/prompts/searchable-multi-select.d.ts +7 -0
  88. package/dist/prompts/searchable-multi-select.js +35 -6
  89. package/dist/telemetry/config.js +14 -2
  90. package/dist/telemetry/index.d.ts +4 -3
  91. package/dist/telemetry/index.js +22 -10
  92. package/dist/telemetry/opt-out.d.ts +17 -0
  93. package/dist/telemetry/opt-out.js +27 -0
  94. package/dist/utils/nested-change.d.ts +35 -0
  95. package/dist/utils/nested-change.js +186 -0
  96. package/dist/utils/spec-discovery.d.ts +20 -0
  97. package/dist/utils/spec-discovery.js +59 -0
  98. package/dist/utils/task-progress.d.ts +1 -1
  99. package/dist/utils/task-progress.js +38 -6
  100. package/package.json +4 -4
  101. package/schemas/spec-driven/schema.yaml +24 -5
  102. package/schemas/spec-driven/templates/design.md +2 -0
  103. package/schemas/spec-driven/templates/proposal.md +2 -0
  104. package/schemas/spec-driven/templates/spec.md +2 -0
  105. package/schemas/spec-driven/templates/tasks.md +2 -0
@@ -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! You can now implement this change with \`/opsx:apply\`. Once implementation and any tracked work are complete, archive it with \`/opsx:archive\`."
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 a change.',
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, remind them to exit explore mode first and create a change proposal. 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. For a new change, scaffold it first as described below.
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
@@ -115,6 +131,14 @@ This tells you:
115
131
  - Their names, schemas, and status
116
132
  - What the user might be working on
117
133
 
134
+ That is the *change* list - work in flight. It does not include the project's durable capabilities, so list those too:
135
+ \`\`\`bash
136
+ openspec list --specs
137
+ \`\`\`
138
+ Add \`--json\` for ids and requirement counts, and append \`--store "<id>"\` only for a registered standalone store. This is the inventory of what the project already claims to do, and \`openspec list\` on its own never shows it. To look at one, run \`openspec show "<spec-id>" --type spec --json --no-scenarios\` (same \`--store\` rule) - it returns that capability's purpose and requirement texts without pulling the whole spec file into context, and \`--type spec\` stops a change of the same name from making it ambiguous.
139
+
140
+ The filtered read is only an overview. Before deciding what is already covered or what should change, read each relevant spec in full, including scenarios, with \`openspec show "<spec-id>" --type spec\` (same \`--store\` rule).
141
+
118
142
  Then read the project's own context from the resolved root - \`<root.path>/openspec/config.yaml\` (or \`config.yml\`). Use the \`root.path\` returned above, and skip this if neither file exists:
119
143
  - \`context\`: project background - tech stack, conventions, constraints
120
144
  - \`rules\`: keyed by artifact id - the entries for an artifact apply only when you write that artifact
@@ -128,14 +152,14 @@ Think freely. When insights crystallize, you might offer:
128
152
  - "This feels solid enough to start a change. Want me to create a proposal?"
129
153
  - Or keep exploring - no pressure to formalize
130
154
 
131
- If the user asks you to capture the exploration as a new change, transition seamlessly into the requested capture:
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:
132
156
 
133
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.
134
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.
135
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.
136
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.
137
161
 
138
- 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.
139
163
 
140
164
  ### When a change exists
141
165
 
@@ -291,7 +315,7 @@ You: That changes everything.
291
315
 
292
316
  There's no required ending. Discovery might:
293
317
 
294
- - **Flow into a proposal**: "Ready to start? I can create a change proposal."
318
+ - **Flow into a proposal**: "${DISCOVERY_END_HANDOFF}"
295
319
  - **Result in artifact updates**: "Updated design.md with these decisions"
296
320
  - **Just provide clarity**: User has what they need, moves on
297
321
  - **Continue later**: "We can pick this up anytime"
@@ -308,7 +332,7 @@ When it feels like things are crystallizing, you might summarize:
308
332
  **Open questions**: [if any remain]
309
333
 
310
334
  **Next steps** (if ready):
311
- - Create a change proposal
335
+ ${SUMMARY_NEXT_STEP}
312
336
  - Keep exploring: just keep talking
313
337
  \`\`\`
314
338
 
@@ -318,11 +342,11 @@ But this summary is optional. Sometimes the thinking IS the value.
318
342
 
319
343
  ## Guardrails
320
344
 
321
- - **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}.
322
346
  - **Don't fake understanding** - If something is unclear, dig deeper
323
347
  - **Don't rush** - Discovery is thinking time, not task time
324
348
  - **Don't force structure** - Let patterns emerge naturally
325
- - **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.
326
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.
327
351
  - **Do visualize** - A good diagram is worth many paragraphs
328
352
  - **Do explore the codebase** - Ground discussions in reality
@@ -340,12 +364,14 @@ export function getOpsxExploreCommandTemplate() {
340
364
  tags: ['workflow', 'explore', 'experimental', 'thinking'],
341
365
  content: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
342
366
 
343
- **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, remind them to exit explore mode first and create a change proposal. 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. For a new change, scaffold it first as described below.
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.
344
368
 
345
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.
346
370
 
347
371
  ${STORE_SELECTION_GUIDANCE}
348
372
 
373
+ ${PROJECT_ROOT_GUARD}
374
+
349
375
  **Input**: The argument after \`/opsx:explore\` is whatever the user wants to think about. Could be:
350
376
  - A vague idea: "real-time collaboration"
351
377
  - A specific problem: "the auth system is getting unwieldy"
@@ -436,6 +462,14 @@ This tells you:
436
462
  - Their names, schemas, and status
437
463
  - What the user might be working on
438
464
 
465
+ That is the *change* list - work in flight. It does not include the project's durable capabilities, so list those too:
466
+ \`\`\`bash
467
+ openspec list --specs
468
+ \`\`\`
469
+ Add \`--json\` for ids and requirement counts, and append \`--store "<id>"\` only for a registered standalone store. This is the inventory of what the project already claims to do, and \`openspec list\` on its own never shows it. To look at one, run \`openspec show "<spec-id>" --type spec --json --no-scenarios\` (same \`--store\` rule) - it returns that capability's purpose and requirement texts without pulling the whole spec file into context, and \`--type spec\` stops a change of the same name from making it ambiguous.
470
+
471
+ The filtered read is only an overview. Before deciding what is already covered or what should change, read each relevant spec in full, including scenarios, with \`openspec show "<spec-id>" --type spec\` (same \`--store\` rule).
472
+
439
473
  Then read the project's own context from the resolved root - \`<root.path>/openspec/config.yaml\` (or \`config.yml\`). Use the \`root.path\` returned above, and skip this if neither file exists:
440
474
  - \`context\`: project background - tech stack, conventions, constraints
441
475
  - \`rules\`: keyed by artifact id - the entries for an artifact apply only when you write that artifact
@@ -451,14 +485,14 @@ Think freely. When insights crystallize, you might offer:
451
485
  - "This feels solid enough to start a change. Want me to create a proposal?"
452
486
  - Or keep exploring - no pressure to formalize
453
487
 
454
- If the user asks you to capture the exploration as a new change, transition seamlessly into the requested capture:
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:
455
489
 
456
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.
457
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.
458
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.
459
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.
460
494
 
461
- 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.
462
496
 
463
497
  ### When a change exists
464
498
 
@@ -510,7 +544,7 @@ If the user mentions a change or you detect one is relevant:
510
544
 
511
545
  There's no required ending. Discovery might:
512
546
 
513
- - **Flow into a proposal**: "Ready to start? I can create a change proposal."
547
+ - **Flow into a proposal**: "${DISCOVERY_END_HANDOFF}"
514
548
  - **Result in artifact updates**: "Updated design.md with these decisions"
515
549
  - **Just provide clarity**: User has what they need, moves on
516
550
  - **Continue later**: "We can pick this up anytime"
@@ -521,11 +555,11 @@ When things crystallize, you might offer a summary - but it's optional. Sometime
521
555
 
522
556
  ## Guardrails
523
557
 
524
- - **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}.
525
559
  - **Don't fake understanding** - If something is unclear, dig deeper
526
560
  - **Don't rush** - Discovery is thinking time, not task time
527
561
  - **Don't force structure** - Let patterns emerge naturally
528
- - **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.
529
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.
530
564
  - **Do visualize** - A good diagram is worth many paragraphs
531
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: "Run \`/opsx:apply\` or ask me to implement to start working on the tasks."
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: "Run \`/opsx:apply\` to start implementing."
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? Run \`/opsx:continue\` or just describe what this change is about and I'll draft it."
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, suggest using \`/opsx:continue\` instead
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
  }
@@ -1,8 +1,53 @@
1
+ import { onlyWithWorkflow, 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 tutorial names other workflows throughout. Which of them exist depends
6
+ * on the profile, so each mention is resolved at generation time (see
7
+ * optional-workflow.ts) instead of being listed with an "if installed" caveat
8
+ * the reader has to check for themselves.
9
+ */
10
+ const EXPLORE_MODE_NOTE = optionalWorkflow('explore', 'Explore mode (`/opsx:explore`) is for this kind of thinking—investigating before implementing. You can use it anytime you need to think through a problem.', 'Investigating before implementing is worth doing whenever a problem needs thinking through.');
11
+ /**
12
+ * The command-reference tables. Every row is dropped along with its line when
13
+ * the profile does not install that workflow, so the table lists exactly the
14
+ * commands the reader can run — and stays a valid table either way.
15
+ */
16
+ const COMMAND_REFERENCE_ROWS = [
17
+ onlyWithWorkflow('propose', ' | `/opsx:propose` | Create a change and generate all artifacts |'),
18
+ onlyWithWorkflow('explore', ' | `/opsx:explore` | Think through problems before/during work |'),
19
+ onlyWithWorkflow('apply', ' | `/opsx:apply` | Implement tasks from a change |'),
20
+ onlyWithWorkflow('archive', ' | `/opsx:archive` | Archive a completed change |'),
21
+ onlyWithWorkflow('new', ' | `/opsx:new` | Start a new change, one artifact at a time |'),
22
+ onlyWithWorkflow('continue', ' | `/opsx:continue` | Continue working on an existing change |'),
23
+ onlyWithWorkflow('ff', ' | `/opsx:ff` | Fast-forward: create all artifacts at once |'),
24
+ onlyWithWorkflow('verify', ' | `/opsx:verify` | Verify implementation matches artifacts |'),
25
+ ].join('\n');
26
+ const QUICK_REFERENCE_ROWS = [
27
+ onlyWithWorkflow('propose', ' | `/opsx:propose <name>` | Create a change and generate all artifacts |'),
28
+ onlyWithWorkflow('explore', ' | `/opsx:explore` | Think through problems (no code changes) |'),
29
+ onlyWithWorkflow('apply', ' | `/opsx:apply <name>` | Implement tasks |'),
30
+ onlyWithWorkflow('archive', ' | `/opsx:archive <name>` | Archive when done |'),
31
+ onlyWithWorkflow('new', ' | `/opsx:new <name>` | Start a new change, step by step |'),
32
+ onlyWithWorkflow('continue', ' | `/opsx:continue <name>` | Continue an existing change |'),
33
+ onlyWithWorkflow('ff', ' | `/opsx:ff <name>` | Fast-forward: all artifacts at once |'),
34
+ onlyWithWorkflow('verify', ' | `/opsx:verify <name>` | Verify implementation |'),
35
+ ].join('\n');
36
+ /**
37
+ * Resume hints for a user stopping mid-tutorial. Both are optional, so the
38
+ * sentence that introduces them stands on its own without either.
39
+ */
40
+ const RESUME_HINTS = [
41
+ onlyWithWorkflow('continue', '- `/opsx:continue <name>` - Resume artifact creation'),
42
+ onlyWithWorkflow('apply', '- `/opsx:apply <name>` - Jump to implementation (if tasks exist)'),
43
+ ].join('\n');
44
+ /** Where the tutorial points once it is over. */
45
+ const NEXT_STEP_INVITE = optionalWorkflow('propose', 'Try `/opsx:propose` on something you actually want to build. You\'ve got the rhythm now!', 'Try this on something you actually want to build. You\'ve got the rhythm now!');
46
+ const QUICK_REFERENCE_INVITE = optionalWorkflow('propose', 'Try `/opsx:propose` to start your first change.', 'Ask me to start your first change whenever you are ready.');
2
47
  export function getOnboardSkillTemplate() {
3
48
  return {
4
49
  name: 'openspec-onboard',
5
- description: 'Guided onboarding for OpenSpec - walk through a complete workflow cycle with narration and real codebase work.',
50
+ description: 'Guided onboarding for OpenSpec - walk through a complete workflow cycle with narration and real codebase work. Also use when the user says "openspec onboard" or "opsx onboard".',
6
51
  instructions: getOnboardInstructions(),
7
52
  license: 'MIT',
8
53
  compatibility: 'Requires openspec CLI.',
@@ -14,6 +59,8 @@ function getOnboardInstructions() {
14
59
 
15
60
  ${STORE_SELECTION_GUIDANCE}
16
61
 
62
+ ${PROJECT_ROOT_GUARD}
63
+
17
64
  ---
18
65
 
19
66
  ## Preflight
@@ -155,7 +202,7 @@ Spend 1-2 minutes investigating the relevant code:
155
202
  │ [Optional: ASCII diagram if helpful] │
156
203
  └─────────────────────────────────────────┘
157
204
 
158
- Explore mode (\`/opsx:explore\`) is for this kind of thinking—investigating before implementing. You can use it anytime you need to think through a problem.
205
+ ${EXPLORE_MODE_NOTE}
159
206
 
160
207
  Now let's create a change to hold our work.
161
208
  \`\`\`
@@ -221,6 +268,8 @@ Here's a draft proposal:
221
268
 
222
269
  ---
223
270
 
271
+ # Proposal
272
+
224
273
  ## Why
225
274
 
226
275
  [1-2 sentences explaining the problem/opportunity]
@@ -288,6 +337,8 @@ Here's the spec:
288
337
 
289
338
  ---
290
339
 
340
+ # Spec Delta
341
+
291
342
  ## ADDED Requirements
292
343
 
293
344
  ### Requirement: <Name>
@@ -327,6 +378,8 @@ Here's the design:
327
378
 
328
379
  ---
329
380
 
381
+ # Design
382
+
330
383
  ## Context
331
384
 
332
385
  [Brief context about the current state]
@@ -372,6 +425,8 @@ Here are the implementation tasks:
372
425
 
373
426
  ---
374
427
 
428
+ # Tasks
429
+
375
430
  ## 1. [Category or file]
376
431
 
377
432
  - [ ] 1.1 [Specific task] — verify: [test, command, observable behavior, or delivered artifact]
@@ -473,29 +528,17 @@ This same rhythm works for any size change—a small fix or a major feature.
473
528
 
474
529
  ## Command Reference
475
530
 
476
- **Core workflow:**
531
+ **The commands you have installed:**
477
532
 
478
- | Command | What it does |
479
- |-------------------|--------------------------------------------|
480
- | \`/opsx:propose\` | Create a change and generate all artifacts |
481
- | \`/opsx:explore\` | Think through problems before/during work |
482
- | \`/opsx:apply\` | Implement tasks from a change |
483
- | \`/opsx:archive\` | Archive a completed change |
484
-
485
- **Additional commands** (only if installed - availability depends on your profile):
486
-
487
- | Command | What it does |
488
- |--------------------|----------------------------------------------------------|
489
- | \`/opsx:new\` | Start a new change, step through artifacts one at a time |
490
- | \`/opsx:continue\` | Continue working on an existing change |
491
- | \`/opsx:ff\` | Fast-forward: create all artifacts at once |
492
- | \`/opsx:verify\` | Verify implementation matches artifacts |
533
+ | Command | What it does |
534
+ |------------------|--------------------------------------------|
535
+ ${COMMAND_REFERENCE_ROWS}
493
536
 
494
537
  ---
495
538
 
496
539
  ## What's Next?
497
540
 
498
- Try \`/opsx:propose\` on something you actually want to build. You've got the rhythm now!
541
+ ${NEXT_STEP_INVITE}
499
542
  \`\`\`
500
543
 
501
544
  ---
@@ -509,9 +552,8 @@ If the user says they need to stop, want to pause, or seem disengaged:
509
552
  \`\`\`
510
553
  No problem! Your change is saved at the \`changeRoot\` reported by \`openspec status --change "<name>" --json\`.
511
554
 
512
- To pick up where we left off later:
513
- - \`/opsx:continue <name>\` - Resume artifact creation (if installed; otherwise \`openspec status --change "<name>" --json\` shows the next artifact)
514
- - \`/opsx:apply <name>\` - Jump to implementation (if tasks exist)
555
+ To pick up where we left off later, \`openspec status --change "<name>" --json\` shows exactly where the change stands.
556
+ ${RESUME_HINTS}
515
557
 
516
558
  The work won't be lost. Come back whenever you're ready.
517
559
  \`\`\`
@@ -525,25 +567,13 @@ If the user says they just want to see the commands or skip the tutorial:
525
567
  \`\`\`
526
568
  ## OpenSpec Quick Reference
527
569
 
528
- **Core workflow:**
570
+ **The commands you have installed:**
529
571
 
530
572
  | Command | What it does |
531
573
  |--------------------------|--------------------------------------------|
532
- | \`/opsx:propose <name>\` | Create a change and generate all artifacts |
533
- | \`/opsx:explore\` | Think through problems (no code changes) |
534
- | \`/opsx:apply <name>\` | Implement tasks |
535
- | \`/opsx:archive <name>\` | Archive when done |
536
-
537
- **Additional commands** (only if installed - availability depends on your profile):
538
-
539
- | Command | What it does |
540
- |---------------------------|-------------------------------------|
541
- | \`/opsx:new <name>\` | Start a new change, step by step |
542
- | \`/opsx:continue <name>\` | Continue an existing change |
543
- | \`/opsx:ff <name>\` | Fast-forward: all artifacts at once |
544
- | \`/opsx:verify <name>\` | Verify implementation |
574
+ ${QUICK_REFERENCE_ROWS}
545
575
 
546
- Try \`/opsx:propose\` to start your first change.
576
+ ${QUICK_REFERENCE_INVITE}
547
577
  \`\`\`
548
578
 
549
579
  Exit gracefully.
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Shared project-root guidance for skill template workflows.
3
+ *
4
+ * Generated skills and commands are installed once per machine, so they are
5
+ * offered in every repository the agent opens - including repositories that
6
+ * never ran `openspec init`. Nothing stops the workflow there: `openspec new
7
+ * change` falls back to an implicit root and creates `openspec/` in whatever
8
+ * directory the agent happens to be in.
9
+ *
10
+ * This guidance is interpolated into every workflow so the agent checks for a
11
+ * root before writing. `openspec list --json` is the check because it refuses
12
+ * to fabricate an implicit root: it reports `root: null` both when nothing is
13
+ * set up and when only stores are registered.
14
+ *
15
+ * What follows the check depends on how the workflow was reached, because the
16
+ * two cases want opposite things (#1645). A skill the model picked on its own
17
+ * in an unrelated repository must get out of the way: the user asked for help,
18
+ * not for OpenSpec, and answering with a setup menu is the reported bug. A
19
+ * user who named OpenSpec, named the skill, or ran its slash command is owed
20
+ * an answer about OpenSpec, so that case stops and asks.
21
+ *
22
+ * One text serves both surfaces. `apply-change` and `onboard` render a single
23
+ * body into the skill and the command alike, so a command-only variant would
24
+ * mean threading a surface flag through bodies that deliberately have none.
25
+ * The bullets scope themselves instead: a slash command is an explicit
26
+ * invocation, so its branch is the only one that can apply there.
27
+ */
28
+ export declare const PROJECT_ROOT_GUARD = "**Project check:** These steps expect a project that already uses OpenSpec. Before the first step that writes anything (`new change`, `archive`, `sync specs`, or authoring an artifact file), confirm the project has a root: run `openspec list --json` (with `--store <id>` when a store is selected, since the store is then the root) and read `root`. A root object means the project is set up. `\"root\": null` means it is not - there is no `openspec/` directory here, and a write such as `openspec new change` would create one as a side effect. The command also exits non-zero, which is that answer rather than a broken CLI, so read the JSON instead of retrying or working around it.\n\nOne `\"root\": null` is not about setup: when a `status` error message starts with `Declared in` or `Invalid store declaration in` and names this project's `openspec/config.yaml` (or `config.yml`), the project does use OpenSpec through a store it declares, which this machine cannot resolve (the store is not registered, or the `store:` line is malformed). Do not treat it as uninitialized and skip the branches below: stop before writing and show the user that error's `message` and `fix`.\n\nOtherwise, with no root, what happens next depends on how this workflow was reached:\n\n- **Auto-selected**: you chose this workflow yourself, without the user naming OpenSpec, naming this skill, or running its slash command. Stop using OpenSpec and answer the request normally, as you would with no OpenSpec installed. Do not ask them to set anything up and do not mention OpenSpec setup.\n- **Explicit OpenSpec request**: the user named OpenSpec, named this skill, or ran its slash command. Stop before writing and ask how to proceed: set this project up (`openspec init`), target a store they already have (`--store <id>`), or continue without OpenSpec for this request. Wait for their answer.\n\nIn both branches, never create the root as a side effect: do not run `openspec init` until the user asks for it, do not hand-create `openspec/` files, and do not let a command create it.";
29
+ //# sourceMappingURL=project-root.d.ts.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Shared project-root guidance for skill template workflows.
3
+ *
4
+ * Generated skills and commands are installed once per machine, so they are
5
+ * offered in every repository the agent opens - including repositories that
6
+ * never ran `openspec init`. Nothing stops the workflow there: `openspec new
7
+ * change` falls back to an implicit root and creates `openspec/` in whatever
8
+ * directory the agent happens to be in.
9
+ *
10
+ * This guidance is interpolated into every workflow so the agent checks for a
11
+ * root before writing. `openspec list --json` is the check because it refuses
12
+ * to fabricate an implicit root: it reports `root: null` both when nothing is
13
+ * set up and when only stores are registered.
14
+ *
15
+ * What follows the check depends on how the workflow was reached, because the
16
+ * two cases want opposite things (#1645). A skill the model picked on its own
17
+ * in an unrelated repository must get out of the way: the user asked for help,
18
+ * not for OpenSpec, and answering with a setup menu is the reported bug. A
19
+ * user who named OpenSpec, named the skill, or ran its slash command is owed
20
+ * an answer about OpenSpec, so that case stops and asks.
21
+ *
22
+ * One text serves both surfaces. `apply-change` and `onboard` render a single
23
+ * body into the skill and the command alike, so a command-only variant would
24
+ * mean threading a surface flag through bodies that deliberately have none.
25
+ * The bullets scope themselves instead: a slash command is an explicit
26
+ * invocation, so its branch is the only one that can apply there.
27
+ */
28
+ export const PROJECT_ROOT_GUARD = `**Project check:** These steps expect a project that already uses OpenSpec. Before the first step that writes anything (\`new change\`, \`archive\`, \`sync specs\`, or authoring an artifact file), confirm the project has a root: run \`openspec list --json\` (with \`--store <id>\` when a store is selected, since the store is then the root) and read \`root\`. A root object means the project is set up. \`"root": null\` means it is not - there is no \`openspec/\` directory here, and a write such as \`openspec new change\` would create one as a side effect. The command also exits non-zero, which is that answer rather than a broken CLI, so read the JSON instead of retrying or working around it.
29
+
30
+ One \`"root": null\` is not about setup: when a \`status\` error message starts with \`Declared in\` or \`Invalid store declaration in\` and names this project's \`openspec/config.yaml\` (or \`config.yml\`), the project does use OpenSpec through a store it declares, which this machine cannot resolve (the store is not registered, or the \`store:\` line is malformed). Do not treat it as uninitialized and skip the branches below: stop before writing and show the user that error's \`message\` and \`fix\`.
31
+
32
+ Otherwise, with no root, what happens next depends on how this workflow was reached:
33
+
34
+ - **Auto-selected**: you chose this workflow yourself, without the user naming OpenSpec, naming this skill, or running its slash command. Stop using OpenSpec and answer the request normally, as you would with no OpenSpec installed. Do not ask them to set anything up and do not mention OpenSpec setup.
35
+ - **Explicit OpenSpec request**: the user named OpenSpec, named this skill, or ran its slash command. Stop before writing and ask how to proceed: set this project up (\`openspec init\`), target a store they already have (\`--store <id>\`), or continue without OpenSpec for this request. Wait for their answer.
36
+
37
+ In both branches, never create the root as a side effect: do not run \`openspec init\` until the user asks for it, do not hand-create \`openspec/\` files, and do not let a command create it.`;
38
+ //# sourceMappingURL=project-root.js.map