@fission-ai/openspec 1.6.0 → 1.8.0

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 (208) hide show
  1. package/README.md +31 -2
  2. package/dist/cli/index.js +79 -8
  3. package/dist/commands/change.d.ts +0 -1
  4. package/dist/commands/change.js +105 -51
  5. package/dist/commands/config.js +14 -8
  6. package/dist/commands/doctor.js +9 -4
  7. package/dist/commands/feedback.js +74 -23
  8. package/dist/commands/schema.js +110 -31
  9. package/dist/commands/show.js +5 -2
  10. package/dist/commands/spec.js +49 -29
  11. package/dist/commands/validate.js +20 -5
  12. package/dist/commands/workflow/index.d.ts +1 -1
  13. package/dist/commands/workflow/index.js +1 -1
  14. package/dist/commands/workflow/instructions.d.ts +7 -1
  15. package/dist/commands/workflow/instructions.js +121 -33
  16. package/dist/commands/workflow/shared.d.ts +13 -2
  17. package/dist/commands/workflow/shared.js +34 -4
  18. package/dist/commands/workflow/status.js +9 -4
  19. package/dist/commands/workflow/templates.js +15 -5
  20. package/dist/core/archive.d.ts +14 -1
  21. package/dist/core/archive.js +1332 -155
  22. package/dist/core/artifact-graph/graph.d.ts +16 -0
  23. package/dist/core/artifact-graph/graph.js +30 -6
  24. package/dist/core/artifact-graph/index.d.ts +1 -1
  25. package/dist/core/artifact-graph/index.js +1 -1
  26. package/dist/core/artifact-graph/instruction-loader.d.ts +30 -3
  27. package/dist/core/artifact-graph/instruction-loader.js +70 -12
  28. package/dist/core/artifact-graph/outputs.d.ts +1 -0
  29. package/dist/core/artifact-graph/outputs.js +67 -5
  30. package/dist/core/artifact-graph/resolver.d.ts +14 -0
  31. package/dist/core/artifact-graph/resolver.js +69 -15
  32. package/dist/core/artifact-graph/types.js +21 -3
  33. package/dist/core/available-tools.d.ts +2 -2
  34. package/dist/core/available-tools.js +14 -3
  35. package/dist/core/change-metadata/schema.d.ts +2 -0
  36. package/dist/core/change-metadata/schema.js +13 -0
  37. package/dist/core/change-status-policy.d.ts +1 -1
  38. package/dist/core/change-status-policy.js +2 -2
  39. package/dist/core/command-generation/adapters/amazon-q.d.ts +4 -0
  40. package/dist/core/command-generation/adapters/amazon-q.js +7 -1
  41. package/dist/core/command-generation/adapters/antigravity.js +2 -1
  42. package/dist/core/command-generation/adapters/auggie.js +2 -1
  43. package/dist/core/command-generation/adapters/bob.d.ts +5 -1
  44. package/dist/core/command-generation/adapters/bob.js +6 -5
  45. package/dist/core/command-generation/adapters/claude.js +1 -8
  46. package/dist/core/command-generation/adapters/codebuddy.js +3 -2
  47. package/dist/core/command-generation/adapters/continue.js +3 -2
  48. package/dist/core/command-generation/adapters/costrict.js +2 -1
  49. package/dist/core/command-generation/adapters/crush.js +5 -5
  50. package/dist/core/command-generation/adapters/cursor.js +2 -2
  51. package/dist/core/command-generation/adapters/devin.d.ts +19 -0
  52. package/dist/core/command-generation/adapters/devin.js +36 -0
  53. package/dist/core/command-generation/adapters/factory.js +2 -1
  54. package/dist/core/command-generation/adapters/gemini.js +37 -2
  55. package/dist/core/command-generation/adapters/github-copilot.js +2 -1
  56. package/dist/core/command-generation/adapters/iflow.js +5 -4
  57. package/dist/core/command-generation/adapters/index.d.ts +2 -2
  58. package/dist/core/command-generation/adapters/index.js +2 -2
  59. package/dist/core/command-generation/adapters/junie.js +2 -1
  60. package/dist/core/command-generation/adapters/kiro.js +2 -1
  61. package/dist/core/command-generation/adapters/lingma.js +5 -5
  62. package/dist/core/command-generation/adapters/oh-my-pi.d.ts +2 -2
  63. package/dist/core/command-generation/adapters/oh-my-pi.js +3 -5
  64. package/dist/core/command-generation/adapters/opencode.js +3 -5
  65. package/dist/core/command-generation/adapters/pi.d.ts +2 -2
  66. package/dist/core/command-generation/adapters/pi.js +3 -6
  67. package/dist/core/command-generation/adapters/qoder.js +5 -5
  68. package/dist/core/command-generation/adapters/qwen.d.ts +7 -3
  69. package/dist/core/command-generation/adapters/qwen.js +12 -7
  70. package/dist/core/command-generation/adapters/roocode.d.ts +4 -4
  71. package/dist/core/command-generation/adapters/roocode.js +4 -4
  72. package/dist/core/command-generation/adapters/trae.js +1 -21
  73. package/dist/core/command-generation/adapters/zcode.d.ts +16 -0
  74. package/dist/core/command-generation/adapters/zcode.js +33 -0
  75. package/dist/core/command-generation/generator.d.ts +8 -0
  76. package/dist/core/command-generation/generator.js +15 -1
  77. package/dist/core/command-generation/index.d.ts +1 -1
  78. package/dist/core/command-generation/index.js +1 -1
  79. package/dist/core/command-generation/invocation.d.ts +73 -0
  80. package/dist/core/command-generation/invocation.js +77 -0
  81. package/dist/core/command-generation/registry.js +4 -4
  82. package/dist/core/command-generation/types.d.ts +9 -2
  83. package/dist/core/command-generation/yaml.d.ts +20 -6
  84. package/dist/core/command-generation/yaml.js +31 -21
  85. package/dist/core/command-surface.d.ts +15 -0
  86. package/dist/core/command-surface.js +33 -0
  87. package/dist/core/completions/command-registry.js +16 -2
  88. package/dist/core/completions/generators/powershell-generator.js +15 -8
  89. package/dist/core/completions/installers/zsh-installer.d.ts +9 -0
  90. package/dist/core/completions/installers/zsh-installer.js +20 -4
  91. package/dist/core/config-prompts.d.ts +1 -1
  92. package/dist/core/config-prompts.js +14 -1
  93. package/dist/core/config-schema.d.ts +10 -1
  94. package/dist/core/config-schema.js +67 -1
  95. package/dist/core/config.d.ts +15 -0
  96. package/dist/core/config.js +45 -5
  97. package/dist/core/file-state.js +56 -24
  98. package/dist/core/github-copilot/cloud-agent.d.ts +95 -0
  99. package/dist/core/github-copilot/cloud-agent.js +497 -0
  100. package/dist/core/global-config.d.ts +16 -0
  101. package/dist/core/init.d.ts +58 -0
  102. package/dist/core/init.js +450 -69
  103. package/dist/core/legacy-cleanup.d.ts +59 -0
  104. package/dist/core/legacy-cleanup.js +253 -24
  105. package/dist/core/list.js +5 -7
  106. package/dist/core/migration.d.ts +73 -1
  107. package/dist/core/migration.js +360 -11
  108. package/dist/core/onboarding-commands.d.ts +30 -0
  109. package/dist/core/onboarding-commands.js +38 -0
  110. package/dist/core/parsers/change-parser.d.ts +17 -2
  111. package/dist/core/parsers/change-parser.js +33 -20
  112. package/dist/core/parsers/code-fence.d.ts +15 -0
  113. package/dist/core/parsers/code-fence.js +49 -0
  114. package/dist/core/parsers/markdown-parser.js +2 -1
  115. package/dist/core/parsers/requirement-blocks.d.ts +18 -0
  116. package/dist/core/parsers/requirement-blocks.js +120 -35
  117. package/dist/core/parsers/requirement-text.d.ts +1 -8
  118. package/dist/core/parsers/requirement-text.js +4 -42
  119. package/dist/core/parsers/spec-structure.d.ts +1 -1
  120. package/dist/core/parsers/spec-structure.js +20 -30
  121. package/dist/core/profile-sync-drift.d.ts +0 -8
  122. package/dist/core/profile-sync-drift.js +48 -49
  123. package/dist/core/project-config.d.ts +28 -6
  124. package/dist/core/project-config.js +108 -8
  125. package/dist/core/references.js +42 -4
  126. package/dist/core/relationship-health.d.ts +8 -0
  127. package/dist/core/relationship-health.js +13 -0
  128. package/dist/core/root-selection.d.ts +9 -6
  129. package/dist/core/root-selection.js +42 -5
  130. package/dist/core/shared/index.d.ts +1 -0
  131. package/dist/core/shared/index.js +1 -0
  132. package/dist/core/shared/skill-content-equivalence.d.ts +7 -0
  133. package/dist/core/shared/skill-content-equivalence.js +41 -0
  134. package/dist/core/shared/skill-paths.d.ts +13 -0
  135. package/dist/core/shared/skill-paths.js +23 -0
  136. package/dist/core/shared/tool-detection.d.ts +25 -5
  137. package/dist/core/shared/tool-detection.js +166 -36
  138. package/dist/core/shared-skill-target.d.ts +16 -0
  139. package/dist/core/shared-skill-target.js +156 -0
  140. package/dist/core/specs-apply.d.ts +80 -33
  141. package/dist/core/specs-apply.js +659 -171
  142. package/dist/core/store/git.d.ts +13 -0
  143. package/dist/core/store/git.js +24 -0
  144. package/dist/core/templates/skill-templates.d.ts +1 -1
  145. package/dist/core/templates/skill-templates.js +1 -1
  146. package/dist/core/templates/workflows/apply-change.d.ts +10 -0
  147. package/dist/core/templates/workflows/apply-change.js +48 -158
  148. package/dist/core/templates/workflows/archive-change.js +170 -42
  149. package/dist/core/templates/workflows/bulk-archive-change.js +256 -75
  150. package/dist/core/templates/workflows/continue-change.js +38 -46
  151. package/dist/core/templates/workflows/explore.js +54 -18
  152. package/dist/core/templates/workflows/ff-change.js +46 -30
  153. package/dist/core/templates/workflows/new-change.js +2 -2
  154. package/dist/core/templates/workflows/onboard.js +13 -7
  155. package/dist/core/templates/workflows/propose.js +116 -46
  156. package/dist/core/templates/workflows/store-selection.d.ts +1 -1
  157. package/dist/core/templates/workflows/store-selection.js +1 -1
  158. package/dist/core/templates/workflows/sync-specs.js +260 -32
  159. package/dist/core/templates/workflows/update-change.js +26 -16
  160. package/dist/core/templates/workflows/verify-change.js +16 -10
  161. package/dist/core/update.d.ts +40 -5
  162. package/dist/core/update.js +389 -93
  163. package/dist/core/validation/constants.d.ts +4 -1
  164. package/dist/core/validation/constants.js +4 -1
  165. package/dist/core/validation/validator.d.ts +22 -8
  166. package/dist/core/validation/validator.js +222 -50
  167. package/dist/core/version-check.d.ts +152 -0
  168. package/dist/core/version-check.js +731 -0
  169. package/dist/core/view.js +12 -17
  170. package/dist/prompts/searchable-multi-select.js +1 -1
  171. package/dist/telemetry/config.d.ts +3 -4
  172. package/dist/telemetry/index.d.ts +10 -5
  173. package/dist/telemetry/index.js +75 -41
  174. package/dist/ui/welcome-screen.d.ts +9 -1
  175. package/dist/ui/welcome-screen.js +91 -38
  176. package/dist/utils/change-metadata.d.ts +43 -0
  177. package/dist/utils/change-metadata.js +123 -7
  178. package/dist/utils/change-utils.d.ts +10 -4
  179. package/dist/utils/change-utils.js +20 -13
  180. package/dist/utils/ci.d.ts +12 -0
  181. package/dist/utils/ci.js +16 -0
  182. package/dist/utils/command-references.d.ts +92 -6
  183. package/dist/utils/command-references.js +180 -7
  184. package/dist/utils/date.d.ts +8 -0
  185. package/dist/utils/date.js +13 -0
  186. package/dist/utils/file-system.d.ts +10 -0
  187. package/dist/utils/file-system.js +70 -0
  188. package/dist/utils/index.d.ts +1 -1
  189. package/dist/utils/index.js +1 -1
  190. package/dist/utils/interactive.d.ts +23 -0
  191. package/dist/utils/interactive.js +32 -0
  192. package/dist/utils/item-discovery.d.ts +19 -0
  193. package/dist/utils/item-discovery.js +30 -48
  194. package/dist/utils/shell-detection.d.ts +1 -1
  195. package/dist/utils/shell-detection.js +64 -11
  196. package/dist/utils/spec-discovery.d.ts +40 -0
  197. package/dist/utils/spec-discovery.js +115 -0
  198. package/dist/utils/task-progress.d.ts +17 -0
  199. package/dist/utils/task-progress.js +41 -13
  200. package/package.json +14 -12
  201. package/schemas/spec-driven/schema.yaml +67 -10
  202. package/schemas/spec-driven/templates/design.md +2 -2
  203. package/schemas/spec-driven/templates/proposal.md +10 -4
  204. package/schemas/spec-driven/templates/spec.md +3 -0
  205. package/dist/core/command-generation/adapters/codex.d.ts +0 -16
  206. package/dist/core/command-generation/adapters/codex.js +0 -39
  207. package/dist/core/command-generation/adapters/windsurf.d.ts +0 -14
  208. package/dist/core/command-generation/adapters/windsurf.js +0 -38
@@ -19,5 +19,18 @@ export declare function gitHasRemote(storeRoot: string): Promise<boolean | null>
19
19
  * network touch. Null when there is no repository or no origin.
20
20
  */
21
21
  export declare function gitOriginUrl(storeRoot: string): Promise<string | null>;
22
+ export interface GitTrackingDrift {
23
+ ahead: number;
24
+ behind: number;
25
+ }
26
+ /**
27
+ * Ahead/behind counts of HEAD against its configured upstream tracking
28
+ * ref, read from local refs only — no fetch, no network. The comparison
29
+ * is therefore against the current local upstream ref (typically last
30
+ * updated by fetch, but it may be a local branch), not the live remote.
31
+ * Null when there is no repository, no upstream, a detached HEAD, or Git
32
+ * is unavailable: the absence of a comparison is not drift.
33
+ */
34
+ export declare function gitTrackingDrift(storeRoot: string): Promise<GitTrackingDrift | null>;
22
35
  export declare function gitDirectoryHasTrackedFiles(storeRoot: string, relativeDir: string): Promise<boolean | null>;
23
36
  //# sourceMappingURL=git.d.ts.map
@@ -130,6 +130,30 @@ export async function gitOriginUrl(storeRoot) {
130
130
  const url = stdout?.trim();
131
131
  return url ? url : null;
132
132
  }
133
+ /**
134
+ * Ahead/behind counts of HEAD against its configured upstream tracking
135
+ * ref, read from local refs only — no fetch, no network. The comparison
136
+ * is therefore against the current local upstream ref (typically last
137
+ * updated by fetch, but it may be a local branch), not the live remote.
138
+ * Null when there is no repository, no upstream, a detached HEAD, or Git
139
+ * is unavailable: the absence of a comparison is not drift.
140
+ */
141
+ export async function gitTrackingDrift(storeRoot) {
142
+ const stdout = await gitProbe(storeRoot, [
143
+ 'rev-list',
144
+ '--left-right',
145
+ '--count',
146
+ '@{upstream}...HEAD',
147
+ ]);
148
+ if (stdout === null)
149
+ return null;
150
+ const match = stdout.trim().match(/^(\d+)\s+(\d+)$/);
151
+ if (!match)
152
+ return null;
153
+ // `--left-right` orders the counts by side of the `...`: left is @{upstream}
154
+ // (commits we lack = behind), right is HEAD (commits upstream lacks = ahead).
155
+ return { behind: Number(match[1]), ahead: Number(match[2]) };
156
+ }
133
157
  export async function gitDirectoryHasTrackedFiles(storeRoot, relativeDir) {
134
158
  const stdout = await gitProbe(storeRoot, ['ls-files', '--', relativeDir]);
135
159
  return stdout === null ? null : stdout.trim().length > 0;
@@ -7,7 +7,7 @@ export type { SkillTemplate, CommandTemplate } from './types.js';
7
7
  export { getExploreSkillTemplate, getOpsxExploreCommandTemplate } from './workflows/explore.js';
8
8
  export { getNewChangeSkillTemplate, getOpsxNewCommandTemplate } from './workflows/new-change.js';
9
9
  export { getContinueChangeSkillTemplate, getOpsxContinueCommandTemplate } from './workflows/continue-change.js';
10
- export { getApplyChangeSkillTemplate, getOpsxApplyCommandTemplate } from './workflows/apply-change.js';
10
+ export { getApplyInstructions, getApplyChangeSkillTemplate, getOpsxApplyCommandTemplate } from './workflows/apply-change.js';
11
11
  export { getUpdateChangeSkillTemplate, getOpsxUpdateCommandTemplate } from './workflows/update-change.js';
12
12
  export { getFfChangeSkillTemplate, getOpsxFfCommandTemplate } from './workflows/ff-change.js';
13
13
  export { getSyncSpecsSkillTemplate, getOpsxSyncCommandTemplate } from './workflows/sync-specs.js';
@@ -6,7 +6,7 @@
6
6
  export { getExploreSkillTemplate, getOpsxExploreCommandTemplate } from './workflows/explore.js';
7
7
  export { getNewChangeSkillTemplate, getOpsxNewCommandTemplate } from './workflows/new-change.js';
8
8
  export { getContinueChangeSkillTemplate, getOpsxContinueCommandTemplate } from './workflows/continue-change.js';
9
- export { getApplyChangeSkillTemplate, getOpsxApplyCommandTemplate } from './workflows/apply-change.js';
9
+ export { getApplyInstructions, getApplyChangeSkillTemplate, getOpsxApplyCommandTemplate } from './workflows/apply-change.js';
10
10
  export { getUpdateChangeSkillTemplate, getOpsxUpdateCommandTemplate } from './workflows/update-change.js';
11
11
  export { getFfChangeSkillTemplate, getOpsxFfCommandTemplate } from './workflows/ff-change.js';
12
12
  export { getSyncSpecsSkillTemplate, getOpsxSyncCommandTemplate } from './workflows/sync-specs.js';
@@ -5,6 +5,16 @@
5
5
  * templates file into workflow-focused modules.
6
6
  */
7
7
  import type { SkillTemplate, CommandTemplate } from '../types.js';
8
+ /**
9
+ * The apply workflow instructions, authored once and rendered by both the
10
+ * skill and command surfaces. The surfaces are intentionally distinct, but
11
+ * they differ only in how they are invoked — the generation transformers
12
+ * rewrite the canonical `/opsx:<id>` tokens per surface downstream (see
13
+ * command-references.ts). The instruction text itself is shared, so the two
14
+ * cannot silently drift. Should a surface ever need genuinely different
15
+ * wording, add a parameter here and pass it from that surface's template.
16
+ */
17
+ export declare function getApplyInstructions(): string;
8
18
  export declare function getApplyChangeSkillTemplate(): SkillTemplate;
9
19
  export declare function getOpsxApplyCommandTemplate(): CommandTemplate;
10
20
  //# sourceMappingURL=apply-change.d.ts.map
@@ -1,13 +1,19 @@
1
1
  import { STORE_SELECTION_GUIDANCE } from './store-selection.js';
2
- export function getApplyChangeSkillTemplate() {
3
- return {
4
- name: 'openspec-apply-change',
5
- description: 'Implement tasks from an OpenSpec change. Use when the user wants to start implementing, continue implementation, or work through tasks.',
6
- instructions: `Implement tasks from an OpenSpec change.
2
+ /**
3
+ * The apply workflow instructions, authored once and rendered by both the
4
+ * skill and command surfaces. The surfaces are intentionally distinct, but
5
+ * they differ only in how they are invoked — the generation transformers
6
+ * rewrite the canonical `/opsx:<id>` tokens per surface downstream (see
7
+ * command-references.ts). The instruction text itself is shared, so the two
8
+ * cannot silently drift. Should a surface ever need genuinely different
9
+ * wording, add a parameter here and pass it from that surface's template.
10
+ */
11
+ export function getApplyInstructions() {
12
+ return `Implement tasks from an OpenSpec change.
7
13
 
8
14
  ${STORE_SELECTION_GUIDANCE}
9
15
 
10
- **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.
16
+ **Input**: Optionally specify a change name (e.g., \`/opsx:apply add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
11
17
 
12
18
  **Steps**
13
19
 
@@ -16,7 +22,7 @@ ${STORE_SELECTION_GUIDANCE}
16
22
  If a name is provided, use it. Otherwise:
17
23
  - Infer from conversation context if the user mentioned a change
18
24
  - Auto-select if only one active change exists
19
- - If ambiguous, run \`openspec list --json\` to get available changes and use the **AskUserQuestion tool** to let the user select
25
+ - If ambiguous, run \`openspec list --json\` to get available changes and ask the user to select one
20
26
 
21
27
  Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:apply <other>\`).
22
28
 
@@ -40,12 +46,29 @@ ${STORE_SELECTION_GUIDANCE}
40
46
  - Progress (total, complete, remaining)
41
47
  - Task list with status
42
48
  - Dynamic instruction based on current state
49
+ - Optional \`context\`: current required project instruction input from the selected root
50
+ - Optional \`operationGuidance\`: current advisory guidance for apply
43
51
 
44
52
  **Handle states:**
45
- - If \`state: "blocked"\` (missing artifacts): show message, suggest using openspec-continue-change
53
+ - If \`state: "blocked"\` (missing artifacts): show message, suggest using \`/opsx:continue\` (if it is not installed, run \`openspec status --change "<name>" --json\` to see the next artifact and \`openspec instructions <artifact-id> --change "<name>" --json\` for how to create it)
46
54
  - If \`state: "all_done"\`: congratulate, suggest archive
47
55
  - Otherwise: proceed to implementation
48
56
 
57
+ Treat \`context\` as a required prompt-level input. Read and consider it, and
58
+ apply relevant project facts, conventions, and constraints while implementing.
59
+ Treat \`operationGuidance\` as optional additive advice. Read and consider every
60
+ entry, and follow entries that are applicable and compatible with the built-in
61
+ workflow.
62
+
63
+ Keep both fields separate from CLI-returned state, missing artifacts, tasks,
64
+ progress, \`contextFiles\`, and the built-in \`instruction\`. They are not
65
+ evidence of task completion, do not replace the built-in instruction, and do
66
+ not permit bypassing a blocked state. If context conflicts with the built-in
67
+ instruction, an explicit user choice, or a CLI-controlled value, report the
68
+ conflict and preserve the controlling value. If guidance is inapplicable or
69
+ conflicts with those controlling inputs, do not follow it and explain why.
70
+ These are prompt-level behavior contracts, not enforceable checks.
71
+
49
72
  4. **Read context files**
50
73
 
51
74
  Read every file path listed under \`contextFiles\` from the apply instructions output.
@@ -53,6 +76,9 @@ ${STORE_SELECTION_GUIDANCE}
53
76
  - **spec-driven**: proposal, specs, design, tasks
54
77
  - Other schemas: follow the contextFiles from CLI output
55
78
 
79
+ Do not copy \`context\` or \`operationGuidance\` verbatim into implementation
80
+ files or planning artifacts unless the user separately asks for that content.
81
+
56
82
  5. **Show current progress**
57
83
 
58
84
  Display:
@@ -112,7 +138,7 @@ Working on task 4/7: <task description>
112
138
  - [x] Task 2
113
139
  ...
114
140
 
115
- All tasks complete! Ready to archive this change.
141
+ All tasks complete! You can archive this change with \`/opsx:archive\`.
116
142
  \`\`\`
117
143
 
118
144
  **Output On Pause (Issue Encountered)**
@@ -144,13 +170,24 @@ What would you like to do?
144
170
  - Update task checkbox immediately after completing each task
145
171
  - Pause on errors, blockers, or unclear requirements - don't guess
146
172
  - Use contextFiles from CLI output, don't assume specific file names
173
+ - Do not use context or operation guidance as proof that a task is complete
174
+ - Apply relevant project context; report conflicts with controlling workflow inputs
175
+ - Consider every guidance entry; explain any inapplicable or conflicting advice
176
+ - Do not copy runtime context or operation guidance into implementation files or planning artifacts
177
+ - Preserve CLI-controlled blocked/ready/all-done behavior and completion criteria
147
178
 
148
179
  **Fluid Workflow Integration**
149
180
 
150
181
  This skill supports the "actions on a change" model:
151
182
 
152
183
  - **Can be invoked anytime**: Before all artifacts are done (if tasks exist), after partial implementation, interleaved with other actions
153
- - **Allows artifact updates**: If implementation reveals design issues, suggest updating artifacts - not phase-locked, work fluidly`,
184
+ - **Allows artifact updates**: If implementation reveals design issues, suggest updating artifacts - not phase-locked, work fluidly`;
185
+ }
186
+ export function getApplyChangeSkillTemplate() {
187
+ return {
188
+ name: 'openspec-apply-change',
189
+ description: 'Implement tasks from an OpenSpec change. Use when the user wants to start implementing, continue implementation, or work through tasks.',
190
+ instructions: getApplyInstructions(),
154
191
  license: 'MIT',
155
192
  compatibility: 'Requires openspec CLI.',
156
193
  metadata: { author: 'openspec', version: '1.0' },
@@ -162,154 +199,7 @@ export function getOpsxApplyCommandTemplate() {
162
199
  description: 'Implement tasks from an OpenSpec change (Experimental)',
163
200
  category: 'Workflow',
164
201
  tags: ['workflow', 'artifacts', 'experimental'],
165
- content: `Implement tasks from an OpenSpec change.
166
-
167
- ${STORE_SELECTION_GUIDANCE}
168
-
169
- **Input**: Optionally specify a change name (e.g., \`/opsx:apply add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
170
-
171
- **Steps**
172
-
173
- 1. **Select the change**
174
-
175
- If a name is provided, use it. Otherwise:
176
- - Infer from conversation context if the user mentioned a change
177
- - Auto-select if only one active change exists
178
- - If ambiguous, run \`openspec list --json\` to get available changes and use the **AskUserQuestion tool** to let the user select
179
-
180
- Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:apply <other>\`).
181
-
182
- 2. **Check status to understand the schema**
183
- \`\`\`bash
184
- openspec status --change "<name>" --json
185
- \`\`\`
186
- Parse the JSON to understand:
187
- - \`schemaName\`: The workflow being used (e.g., "spec-driven")
188
- - \`planningHome\`, \`changeRoot\`, and \`actionContext\`: planning scope and edit constraints
189
- - Which artifact contains the tasks (typically "tasks" for spec-driven, check status for others)
190
-
191
- 3. **Get apply instructions**
192
-
193
- \`\`\`bash
194
- openspec instructions apply --change "<name>" --json
195
- \`\`\`
196
-
197
- This returns:
198
- - \`contextFiles\`: artifact ID -> array of concrete file paths (varies by schema)
199
- - Progress (total, complete, remaining)
200
- - Task list with status
201
- - Dynamic instruction based on current state
202
-
203
- **Handle states:**
204
- - If \`state: "blocked"\` (missing artifacts): show message, suggest using \`/opsx:continue\`
205
- - If \`state: "all_done"\`: congratulate, suggest archive
206
- - Otherwise: proceed to implementation
207
-
208
- 4. **Read context files**
209
-
210
- Read every file path listed under \`contextFiles\` from the apply instructions output.
211
- The files depend on the schema being used:
212
- - **spec-driven**: proposal, specs, design, tasks
213
- - Other schemas: follow the contextFiles from CLI output
214
-
215
- 5. **Show current progress**
216
-
217
- Display:
218
- - Schema being used
219
- - Progress: "N/M tasks complete"
220
- - Remaining tasks overview
221
- - Dynamic instruction from CLI
222
-
223
- 6. **Implement tasks (loop until done or blocked)**
224
-
225
- For each pending task:
226
- - Show which task is being worked on
227
- - Make the code changes required
228
- - Keep changes minimal and focused
229
- - Mark task complete in the tasks file: \`- [ ]\` → \`- [x]\`
230
- - Continue to next task
231
-
232
- **Pause if:**
233
- - Task is unclear → ask for clarification
234
- - Implementation reveals a design issue → suggest updating artifacts
235
- - Error or blocker encountered → report and wait for guidance
236
- - User interrupts
237
-
238
- 7. **On completion or pause, show status**
239
-
240
- Display:
241
- - Tasks completed this session
242
- - Overall progress: "N/M tasks complete"
243
- - If all done: suggest archive
244
- - If paused: explain why and wait for guidance
245
-
246
- **Output During Implementation**
247
-
248
- \`\`\`
249
- ## Implementing: <change-name> (schema: <schema-name>)
250
-
251
- Working on task 3/7: <task description>
252
- [...implementation happening...]
253
- ✓ Task complete
254
-
255
- Working on task 4/7: <task description>
256
- [...implementation happening...]
257
- ✓ Task complete
258
- \`\`\`
259
-
260
- **Output On Completion**
261
-
262
- \`\`\`
263
- ## Implementation Complete
264
-
265
- **Change:** <change-name>
266
- **Schema:** <schema-name>
267
- **Progress:** 7/7 tasks complete ✓
268
-
269
- ### Completed This Session
270
- - [x] Task 1
271
- - [x] Task 2
272
- ...
273
-
274
- All tasks complete! You can archive this change with \`/opsx:archive\`.
275
- \`\`\`
276
-
277
- **Output On Pause (Issue Encountered)**
278
-
279
- \`\`\`
280
- ## Implementation Paused
281
-
282
- **Change:** <change-name>
283
- **Schema:** <schema-name>
284
- **Progress:** 4/7 tasks complete
285
-
286
- ### Issue Encountered
287
- <description of the issue>
288
-
289
- **Options:**
290
- 1. <option 1>
291
- 2. <option 2>
292
- 3. Other approach
293
-
294
- What would you like to do?
295
- \`\`\`
296
-
297
- **Guardrails**
298
- - Keep going through tasks until done or blocked
299
- - Always read context files before starting (from the apply instructions output)
300
- - If task is ambiguous, pause and ask before implementing
301
- - If implementation reveals issues, pause and suggest artifact updates
302
- - Keep code changes minimal and scoped to each task
303
- - Update task checkbox immediately after completing each task
304
- - Pause on errors, blockers, or unclear requirements - don't guess
305
- - Use contextFiles from CLI output, don't assume specific file names
306
-
307
- **Fluid Workflow Integration**
308
-
309
- This skill supports the "actions on a change" model:
310
-
311
- - **Can be invoked anytime**: Before all artifacts are done (if tasks exist), after partial implementation, interleaved with other actions
312
- - **Allows artifact updates**: If implementation reveals design issues, suggest updating artifacts - not phase-locked, work fluidly`
202
+ content: getApplyInstructions(),
313
203
  };
314
204
  }
315
205
  //# sourceMappingURL=apply-change.js.map