@fission-ai/openspec 1.6.0 → 1.7.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 (175) hide show
  1. package/README.md +28 -1
  2. package/dist/cli/index.js +73 -7
  3. package/dist/commands/change.d.ts +0 -1
  4. package/dist/commands/change.js +90 -50
  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 +21 -11
  9. package/dist/commands/show.js +5 -2
  10. package/dist/commands/spec.js +20 -24
  11. package/dist/commands/validate.js +18 -3
  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 +89 -6
  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 +7 -2
  19. package/dist/core/archive.d.ts +0 -1
  20. package/dist/core/archive.js +96 -33
  21. package/dist/core/artifact-graph/graph.d.ts +16 -0
  22. package/dist/core/artifact-graph/graph.js +30 -6
  23. package/dist/core/artifact-graph/instruction-loader.d.ts +27 -2
  24. package/dist/core/artifact-graph/instruction-loader.js +55 -7
  25. package/dist/core/artifact-graph/resolver.d.ts +14 -0
  26. package/dist/core/artifact-graph/resolver.js +34 -6
  27. package/dist/core/change-metadata/schema.d.ts +1 -0
  28. package/dist/core/change-metadata/schema.js +6 -0
  29. package/dist/core/change-status-policy.d.ts +1 -1
  30. package/dist/core/command-generation/adapters/amazon-q.d.ts +4 -0
  31. package/dist/core/command-generation/adapters/amazon-q.js +7 -1
  32. package/dist/core/command-generation/adapters/antigravity.js +2 -1
  33. package/dist/core/command-generation/adapters/auggie.js +2 -1
  34. package/dist/core/command-generation/adapters/bob.d.ts +5 -1
  35. package/dist/core/command-generation/adapters/bob.js +6 -5
  36. package/dist/core/command-generation/adapters/claude.js +1 -8
  37. package/dist/core/command-generation/adapters/codebuddy.js +3 -2
  38. package/dist/core/command-generation/adapters/continue.js +3 -2
  39. package/dist/core/command-generation/adapters/costrict.js +2 -1
  40. package/dist/core/command-generation/adapters/crush.js +5 -5
  41. package/dist/core/command-generation/adapters/cursor.js +2 -2
  42. package/dist/core/command-generation/adapters/devin.d.ts +19 -0
  43. package/dist/core/command-generation/adapters/devin.js +36 -0
  44. package/dist/core/command-generation/adapters/factory.js +2 -1
  45. package/dist/core/command-generation/adapters/gemini.js +37 -2
  46. package/dist/core/command-generation/adapters/github-copilot.js +2 -1
  47. package/dist/core/command-generation/adapters/iflow.js +5 -4
  48. package/dist/core/command-generation/adapters/index.d.ts +2 -2
  49. package/dist/core/command-generation/adapters/index.js +2 -2
  50. package/dist/core/command-generation/adapters/junie.js +2 -1
  51. package/dist/core/command-generation/adapters/kiro.js +2 -1
  52. package/dist/core/command-generation/adapters/lingma.js +5 -5
  53. package/dist/core/command-generation/adapters/oh-my-pi.d.ts +2 -2
  54. package/dist/core/command-generation/adapters/oh-my-pi.js +3 -5
  55. package/dist/core/command-generation/adapters/opencode.js +3 -5
  56. package/dist/core/command-generation/adapters/pi.d.ts +2 -2
  57. package/dist/core/command-generation/adapters/pi.js +3 -6
  58. package/dist/core/command-generation/adapters/qoder.js +5 -5
  59. package/dist/core/command-generation/adapters/qwen.d.ts +7 -3
  60. package/dist/core/command-generation/adapters/qwen.js +12 -7
  61. package/dist/core/command-generation/adapters/roocode.d.ts +4 -4
  62. package/dist/core/command-generation/adapters/roocode.js +4 -4
  63. package/dist/core/command-generation/adapters/trae.js +1 -21
  64. package/dist/core/command-generation/adapters/zcode.d.ts +16 -0
  65. package/dist/core/command-generation/adapters/zcode.js +33 -0
  66. package/dist/core/command-generation/generator.d.ts +8 -0
  67. package/dist/core/command-generation/generator.js +15 -1
  68. package/dist/core/command-generation/index.d.ts +1 -1
  69. package/dist/core/command-generation/index.js +1 -1
  70. package/dist/core/command-generation/invocation.d.ts +73 -0
  71. package/dist/core/command-generation/invocation.js +77 -0
  72. package/dist/core/command-generation/registry.js +4 -4
  73. package/dist/core/command-generation/types.d.ts +9 -2
  74. package/dist/core/command-generation/yaml.d.ts +20 -6
  75. package/dist/core/command-generation/yaml.js +31 -21
  76. package/dist/core/command-surface.d.ts +15 -0
  77. package/dist/core/command-surface.js +33 -0
  78. package/dist/core/completions/command-registry.js +8 -2
  79. package/dist/core/completions/generators/powershell-generator.js +15 -8
  80. package/dist/core/completions/installers/zsh-installer.d.ts +9 -0
  81. package/dist/core/completions/installers/zsh-installer.js +20 -4
  82. package/dist/core/config-prompts.d.ts +1 -1
  83. package/dist/core/config-prompts.js +14 -1
  84. package/dist/core/config-schema.d.ts +7 -1
  85. package/dist/core/config-schema.js +40 -1
  86. package/dist/core/config.d.ts +12 -0
  87. package/dist/core/config.js +21 -3
  88. package/dist/core/global-config.d.ts +5 -0
  89. package/dist/core/init.d.ts +35 -0
  90. package/dist/core/init.js +225 -39
  91. package/dist/core/legacy-cleanup.d.ts +59 -0
  92. package/dist/core/legacy-cleanup.js +249 -22
  93. package/dist/core/list.js +5 -7
  94. package/dist/core/migration.d.ts +71 -1
  95. package/dist/core/migration.js +294 -1
  96. package/dist/core/onboarding-commands.d.ts +30 -0
  97. package/dist/core/onboarding-commands.js +38 -0
  98. package/dist/core/parsers/change-parser.d.ts +17 -2
  99. package/dist/core/parsers/change-parser.js +33 -20
  100. package/dist/core/parsers/code-fence.d.ts +15 -0
  101. package/dist/core/parsers/code-fence.js +49 -0
  102. package/dist/core/parsers/markdown-parser.js +2 -1
  103. package/dist/core/parsers/requirement-blocks.d.ts +8 -0
  104. package/dist/core/parsers/requirement-blocks.js +60 -35
  105. package/dist/core/parsers/requirement-text.d.ts +1 -8
  106. package/dist/core/parsers/requirement-text.js +4 -42
  107. package/dist/core/parsers/spec-structure.js +3 -29
  108. package/dist/core/profile-sync-drift.d.ts +0 -8
  109. package/dist/core/profile-sync-drift.js +9 -45
  110. package/dist/core/project-config.d.ts +25 -6
  111. package/dist/core/project-config.js +77 -7
  112. package/dist/core/references.js +42 -4
  113. package/dist/core/relationship-health.d.ts +8 -0
  114. package/dist/core/relationship-health.js +13 -0
  115. package/dist/core/root-selection.d.ts +9 -6
  116. package/dist/core/root-selection.js +42 -5
  117. package/dist/core/shared/tool-detection.d.ts +25 -5
  118. package/dist/core/shared/tool-detection.js +105 -6
  119. package/dist/core/specs-apply.d.ts +8 -33
  120. package/dist/core/specs-apply.js +252 -157
  121. package/dist/core/store/git.d.ts +13 -0
  122. package/dist/core/store/git.js +24 -0
  123. package/dist/core/templates/workflows/apply-change.js +54 -4
  124. package/dist/core/templates/workflows/archive-change.js +166 -42
  125. package/dist/core/templates/workflows/bulk-archive-change.js +240 -63
  126. package/dist/core/templates/workflows/continue-change.js +32 -40
  127. package/dist/core/templates/workflows/explore.js +12 -0
  128. package/dist/core/templates/workflows/ff-change.js +46 -30
  129. package/dist/core/templates/workflows/new-change.js +2 -2
  130. package/dist/core/templates/workflows/onboard.js +4 -4
  131. package/dist/core/templates/workflows/propose.js +50 -32
  132. package/dist/core/templates/workflows/store-selection.d.ts +1 -1
  133. package/dist/core/templates/workflows/store-selection.js +1 -1
  134. package/dist/core/templates/workflows/sync-specs.js +172 -22
  135. package/dist/core/templates/workflows/update-change.js +20 -12
  136. package/dist/core/templates/workflows/verify-change.js +16 -10
  137. package/dist/core/update.d.ts +39 -5
  138. package/dist/core/update.js +288 -71
  139. package/dist/core/validation/constants.d.ts +4 -1
  140. package/dist/core/validation/constants.js +4 -1
  141. package/dist/core/validation/validator.d.ts +1 -7
  142. package/dist/core/validation/validator.js +92 -36
  143. package/dist/core/version-check.d.ts +152 -0
  144. package/dist/core/version-check.js +736 -0
  145. package/dist/core/view.js +12 -17
  146. package/dist/prompts/searchable-multi-select.js +1 -1
  147. package/dist/telemetry/index.d.ts +1 -1
  148. package/dist/telemetry/index.js +55 -33
  149. package/dist/ui/welcome-screen.d.ts +9 -1
  150. package/dist/ui/welcome-screen.js +91 -38
  151. package/dist/utils/change-metadata.d.ts +30 -0
  152. package/dist/utils/change-metadata.js +101 -7
  153. package/dist/utils/change-utils.d.ts +10 -4
  154. package/dist/utils/change-utils.js +20 -13
  155. package/dist/utils/command-references.d.ts +80 -6
  156. package/dist/utils/command-references.js +138 -7
  157. package/dist/utils/date.d.ts +8 -0
  158. package/dist/utils/date.js +13 -0
  159. package/dist/utils/index.d.ts +1 -1
  160. package/dist/utils/index.js +1 -1
  161. package/dist/utils/item-discovery.d.ts +19 -0
  162. package/dist/utils/item-discovery.js +30 -48
  163. package/dist/utils/shell-detection.d.ts +1 -1
  164. package/dist/utils/shell-detection.js +64 -11
  165. package/dist/utils/spec-discovery.d.ts +40 -0
  166. package/dist/utils/spec-discovery.js +102 -0
  167. package/package.json +14 -12
  168. package/schemas/spec-driven/schema.yaml +60 -5
  169. package/schemas/spec-driven/templates/design.md +2 -2
  170. package/schemas/spec-driven/templates/proposal.md +5 -1
  171. package/schemas/spec-driven/templates/spec.md +3 -0
  172. package/dist/core/command-generation/adapters/codex.d.ts +0 -16
  173. package/dist/core/command-generation/adapters/codex.js +0 -39
  174. package/dist/core/command-generation/adapters/windsurf.d.ts +0 -14
  175. package/dist/core/command-generation/adapters/windsurf.js +0 -38
@@ -21,13 +21,38 @@ ${STORE_SELECTION_GUIDANCE}
21
21
 
22
22
  2. **Prompt for change selection**
23
23
 
24
- Use **AskUserQuestion tool** with multi-select to let user choose changes:
24
+ Ask the user to choose changes (multi-select):
25
25
  - Show each change with its schema
26
26
  - Include an option for "All changes"
27
27
  - Allow any number of selections (1+ works, 2+ is the typical use case)
28
28
 
29
29
  **IMPORTANT**: Do NOT auto-select. Always let the user choose.
30
30
 
31
+ **Load current archive inputs once for the selected root before batch validation:**
32
+
33
+ Choose one selected change from this root and run
34
+ \`openspec instructions archive --change "<selected-change>" --json\` with the
35
+ same selected-root flags. This lookup is advisory and optional: it only supplies
36
+ extra prompt inputs, so it must never block the batch. If it fails or returns
37
+ invalid JSON — for example on an older CLI that does not support this command
38
+ yet — continue the batch with no context and no operation guidance. Do not
39
+ report an error and do not stop.
40
+
41
+ A valid response may omit \`context\` and \`operationGuidance\`. Treat
42
+ \`context\` as a required prompt-level input across the batch: read and consider
43
+ it, and apply relevant project facts, conventions, and constraints. Treat
44
+ \`operationGuidance\` as optional additive advice: read and consider every
45
+ entry, and follow entries that are applicable and compatible with the built-in
46
+ batch workflow.
47
+
48
+ Keep both fields separate from conflict analysis, explicit user choices,
49
+ resolved paths, CLI checks, and command contracts. If context conflicts with one
50
+ of those controlling inputs, report the conflict and preserve the controlling
51
+ value. If guidance is inapplicable or conflicts with a controlling input, do not
52
+ follow it and explain why. Do not infer skipped prompts, replacement paths, or
53
+ flags from either field, and do not copy their text verbatim into specs, changes,
54
+ or summaries. These are prompt-level behavior contracts, not enforceable checks.
55
+
31
56
  3. **Batch validation - gather status for all selected changes**
32
57
 
33
58
  For each selected change, collect:
@@ -43,12 +68,16 @@ ${STORE_SELECTION_GUIDANCE}
43
68
  c. **Delta specs** - Check \`artifactPaths.specs.existingOutputPaths\` from status JSON
44
69
  - List which capability specs exist
45
70
  - For each, extract requirement names (lines matching \`### Requirement: <name>\`)
46
-
71
+ - Treat this list as the only delta-spec source. If the \`specs\` entry is
72
+ missing or the list is empty, perform no spec sync or specs-instruction
73
+ lookup for that change; do not infer deltas from unrelated artifacts.
74
+ - Evaluate this independently for every change, including mixed-schema
75
+ batches where some schemas have no \`specs\` artifact.
47
76
  4. **Detect spec conflicts**
48
77
 
49
78
  Build a map of \`capability -> [changes that touch it]\`:
50
79
 
51
- \`\`\`
80
+ \`\`\`text
52
81
  auth -> [change-a, change-b] <- CONFLICT (2+ changes)
53
82
  api -> [change-c] <- OK (only 1 change)
54
83
  \`\`\`
@@ -71,15 +100,16 @@ ${STORE_SELECTION_GUIDANCE}
71
100
  - If neither implemented -> skip spec sync, warn user
72
101
 
73
102
  d. **Record resolution** for each conflict:
74
- - Which change's specs to apply
75
- - In what order (if both)
103
+ - An inclusion or exclusion decision for every delta spec, keyed by change and capability
104
+ - Which included delta specs to apply and in what order
105
+ - Which delta specs to exclude from sync because their implementation is missing
76
106
  - Rationale (what was found in codebase)
77
107
 
78
108
  6. **Show consolidated status table**
79
109
 
80
110
  Display a table summarizing all changes:
81
111
 
82
- \`\`\`
112
+ \`\`\`markdown
83
113
  | Change | Artifacts | Tasks | Specs | Conflicts | Status |
84
114
  |---------------------|-----------|-------|---------|-----------|--------|
85
115
  | schema-management | Done | 5/5 | 2 delta | None | Ready |
@@ -89,20 +119,20 @@ ${STORE_SELECTION_GUIDANCE}
89
119
  \`\`\`
90
120
 
91
121
  For conflicts, show the resolution:
92
- \`\`\`
122
+ \`\`\`text
93
123
  * Conflict resolution:
94
124
  - auth spec: Will apply add-oauth then add-jwt (both implemented, chronological order)
95
125
  \`\`\`
96
126
 
97
127
  For incomplete changes, show warnings:
98
- \`\`\`
128
+ \`\`\`text
99
129
  Warnings:
100
130
  - add-verify-skill: 1 incomplete artifact, 3 incomplete tasks
101
131
  \`\`\`
102
132
 
103
133
  7. **Confirm batch operation**
104
134
 
105
- Use **AskUserQuestion tool** with a single confirmation:
135
+ Ask the user a single confirmation question:
106
136
 
107
137
  - "Archive N changes?" with options based on status
108
138
  - Options might include:
@@ -112,31 +142,73 @@ ${STORE_SELECTION_GUIDANCE}
112
142
 
113
143
  If there are incomplete changes, make clear they'll be archived with warnings.
114
144
 
145
+ Route on the answer by intent, not by exact label — you wrote these labels,
146
+ so match what the user picked rather than the wording above:
147
+ - "Cancel" — stop, do not archive. Report that nothing was archived and skip the remaining steps.
148
+ - The archive-everything option — proceed with every selected change
149
+ - 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. If a \`Ready*\` change's conflict partner is skipped, re-derive that conflict's resolution using only the changes being archived.
150
+ - Anything else — ask again rather than archiving
151
+
152
+ Before step 8 writes the first main spec or moves any change, fetch every
153
+ required specs-rule snapshot for the confirmed batch. For each change that will
154
+ sync concrete \`artifactPaths.specs.existingOutputPaths\`, run
155
+ \`openspec instructions specs --change "<name>" --json\` exactly once with the
156
+ same selected-root flags. Obtain all snapshots before the first write or move.
157
+ If any lookup exits non-zero or returns invalid artifact-instruction JSON,
158
+ identify the affected change, report the error, and stop the whole batch before
159
+ any main-spec write or change move. Do not treat lookup failure as omitted
160
+ rules. A valid response without \`rules\` is the no-rules case.
161
+
115
162
  8. **Execute archive for each confirmed change**
116
163
 
164
+ Before processing, carry the recorded decisions from step 5 (after any step 7 re-derivation) into two per-delta sets:
165
+ - \`includedDeltas\`: all non-conflicting delta specs from confirmed changes plus conflict deltas selected for sync
166
+ - \`excludedDeltas\`: conflict deltas from confirmed changes excluded because their implementation is missing
167
+ - A single change can have both included and excluded delta specs. Keep the decision per delta; do not collapse it into a per-change sync flag.
168
+
117
169
  Process changes in the determined order (respecting conflict resolution):
118
170
 
119
- a. **Sync specs** if delta specs exist:
120
- - Use the openspec-sync-specs approach (agent-driven intelligent merge)
121
- - For conflicts, apply in resolved order
122
- - Track if sync was done
171
+ a. **Sync included delta specs**:
172
+ - Run the \`openspec-sync-specs\` workflow inline (agent-driven intelligent merge) 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.
173
+ - For conflicts, apply in resolved order.
174
+ - Pass that change's fetched specs-rule snapshot into inline sync; inline
175
+ sync must reuse it without fetching instructions again
176
+ - Apply artifact rules only to main specs produced by that change. They do
177
+ not change conflict resolution, archive behavior, or CLI contracts, and
178
+ their text is not copied into an output file
179
+ - Do not delegate to a background task — step 8c would move \`changeRoot\` out from under a sync that is still reading it.
180
+ - If a change has no included delta specs, do not run the sync workflow for it.
181
+
182
+ b. **Verify included delta specs before moving changeRoot**:
183
+ - Re-run the comparison only for delta specs in \`includedDeltas\` against main spec at \`<planningHome.root>/openspec/specs/<capability>/spec.md\` (use the store-aware \`planningHome.root\` from step 3 status JSON, not a hardcoded repo path).
184
+ - Verify that main specs are updated:
185
+ - ADDED requirements present
186
+ - MODIFIED requirements carrying scenario and description changes named in the delta, with their other scenarios intact
187
+ - REMOVED requirements gone
188
+ - RENAMED requirements present under the new name and absent under the old one
189
+ - Do not verify delta specs in \`excludedDeltas\`; they are intentionally left unsynced.
190
+ - If sync failed or any capability does not match verification, report what differs and fail/skip moving that change's \`changeRoot\` — do not archive that change. \`changeRoot\` remains intact.
191
+
192
+ c. **Perform the archive**:
193
+
194
+ Target name: 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\`).
123
195
 
124
- b. **Perform the archive**:
125
196
  \`\`\`bash
126
197
  mkdir -p "<planningHome.changesDir>/archive"
127
- mv "<changeRoot>" "<planningHome.changesDir>/archive/YYYY-MM-DD-<name>"
198
+ mv "<changeRoot>" "<planningHome.changesDir>/archive/<target-name>"
128
199
  \`\`\`
129
200
 
130
- c. **Track outcome** for each change:
201
+ d. **Track outcome** for each change:
131
202
  - Success: archived successfully
132
- - Failed: error during archive (record error)
203
+ - Failed: error during archive or spec verification (record error)
133
204
  - Skipped: user chose not to archive (if applicable)
205
+ - Sync skipped: for every delta in \`excludedDeltas\`, report \`sync skipped\` with the change, capability, and recorded reason. This is distinct from skipping the archive.
134
206
 
135
207
  9. **Display summary**
136
208
 
137
209
  Show final results:
138
210
 
139
- \`\`\`
211
+ \`\`\`markdown
140
212
  ## Bulk Archive Complete
141
213
 
142
214
  Archived 3 changes:
@@ -149,11 +221,12 @@ ${STORE_SELECTION_GUIDANCE}
149
221
 
150
222
  Spec sync summary:
151
223
  - 4 delta specs synced to main specs
152
- - 1 conflict resolved (auth: applied both in chronological order)
224
+ - 1 delta spec sync skipped (add-jwt/auth: implementation not found)
225
+ - 1 conflict resolved (auth: synced add-oauth, skipped add-jwt)
153
226
  \`\`\`
154
227
 
155
228
  If any failures:
156
- \`\`\`
229
+ \`\`\`text
157
230
  Failed 1 change:
158
231
  - some-change: Archive directory already exists
159
232
  \`\`\`
@@ -161,8 +234,8 @@ ${STORE_SELECTION_GUIDANCE}
161
234
  **Conflict Resolution Examples**
162
235
 
163
236
  Example 1: Only one implemented
164
- \`\`\`
165
- Conflict: specs/auth/spec.md touched by [add-oauth, add-jwt]
237
+ \`\`\`text
238
+ Conflict: <planningHome.root>/openspec/specs/auth/spec.md touched by [add-oauth, add-jwt]
166
239
 
167
240
  Checking add-oauth:
168
241
  - Delta adds "OAuth Provider Integration" requirement
@@ -176,8 +249,8 @@ Resolution: Only add-oauth is implemented. Will sync add-oauth specs only.
176
249
  \`\`\`
177
250
 
178
251
  Example 2: Both implemented
179
- \`\`\`
180
- Conflict: specs/api/spec.md touched by [add-rest-api, add-graphql]
252
+ \`\`\`text
253
+ Conflict: <planningHome.root>/openspec/specs/api/spec.md touched by [add-rest-api, add-graphql]
181
254
 
182
255
  Checking add-rest-api (created 2026-01-10):
183
256
  - Delta adds "REST Endpoints" requirement
@@ -193,12 +266,12 @@ then add-graphql specs (chronological order, newer takes precedence).
193
266
 
194
267
  **Output On Success**
195
268
 
196
- \`\`\`
269
+ \`\`\`markdown
197
270
  ## Bulk Archive Complete
198
271
 
199
272
  Archived N changes:
200
- - <change-1> -> archive/YYYY-MM-DD-<change-1>/
201
- - <change-2> -> archive/YYYY-MM-DD-<change-2>/
273
+ - <change-1> -> archive/<target-name-1>/
274
+ - <change-2> -> archive/<target-name-2>/
202
275
 
203
276
  Spec sync summary:
204
277
  - N delta specs synced to main specs
@@ -207,11 +280,11 @@ Spec sync summary:
207
280
 
208
281
  **Output On Partial Success**
209
282
 
210
- \`\`\`
283
+ \`\`\`markdown
211
284
  ## Bulk Archive Complete (partial)
212
285
 
213
286
  Archived N changes:
214
- - <change-1> -> archive/YYYY-MM-DD-<change-1>/
287
+ - <change-1> -> archive/<target-name-1>/
215
288
 
216
289
  Skipped M changes:
217
290
  - <change-2> (user chose not to archive incomplete)
@@ -222,7 +295,7 @@ Failed K changes:
222
295
 
223
296
  **Output When No Changes**
224
297
 
225
- \`\`\`
298
+ \`\`\`markdown
226
299
  ## No Changes to Archive
227
300
 
228
301
  No active changes found. Create a new change to get started.
@@ -236,10 +309,25 @@ No active changes found. Create a new change to get started.
236
309
  - Skip spec sync only when implementation is missing (warn user)
237
310
  - Show clear per-change status before confirming
238
311
  - Use single confirmation for entire batch
312
+ - Never archive after the user cancels the confirmation — a cancelled batch archives nothing
239
313
  - Track and report all outcomes (success/skip/fail)
240
314
  - Preserve .openspec.yaml when moving to archive
241
- - Archive directory target uses current date: YYYY-MM-DD-<name>
242
- - If archive target exists, fail that change but continue with others`,
315
+ - 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)
316
+ - If archive target exists, fail that change but continue with others
317
+ - If sync is requested, run the \`openspec-sync-specs\` workflow inline (agent-driven) for each change with included delta specs
318
+ - Carry the per-delta \`includedDeltas\` and \`excludedDeltas\` decisions into execution; sync and verify only included deltas
319
+ - Report every excluded delta as \`sync skipped\` without treating the archive itself as skipped
320
+ - 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>/spec.md\` before moving \`changeRoot\`
321
+ - Fetch archive inputs once per selected root before spec inspection or moves
322
+ - Fetch all required specs-rule snapshots before the batch's first main-spec write or move
323
+ - A failed archive-inputs lookup never blocks the batch; it proceeds with no context or guidance
324
+ - A failed specs instruction lookup stops the whole batch atomically
325
+ - Changes without concrete \`artifactPaths.specs.existingOutputPaths\` continue without spec sync
326
+ - Apply relevant runtime context across the batch and report conflicts
327
+ - Operation guidance remains advisory; consider every entry and explain rejected advice
328
+ - Keep runtime inputs, conflict analysis, CLI-derived values, and artifact rules separate
329
+ - Artifact rules constrain only written specs
330
+ - Never copy runtime input or artifact-rule text verbatim into output files`,
243
331
  license: 'MIT',
244
332
  compatibility: 'Requires openspec CLI.',
245
333
  metadata: { author: 'openspec', version: '1.0' },
@@ -269,13 +357,38 @@ ${STORE_SELECTION_GUIDANCE}
269
357
 
270
358
  2. **Prompt for change selection**
271
359
 
272
- Use **AskUserQuestion tool** with multi-select to let user choose changes:
360
+ Ask the user to choose changes (multi-select):
273
361
  - Show each change with its schema
274
362
  - Include an option for "All changes"
275
363
  - Allow any number of selections (1+ works, 2+ is the typical use case)
276
364
 
277
365
  **IMPORTANT**: Do NOT auto-select. Always let the user choose.
278
366
 
367
+ **Load current archive inputs once for the selected root before batch validation:**
368
+
369
+ Choose one selected change from this root and run
370
+ \`openspec instructions archive --change "<selected-change>" --json\` with the
371
+ same selected-root flags. This lookup is advisory and optional: it only supplies
372
+ extra prompt inputs, so it must never block the batch. If it fails or returns
373
+ invalid JSON — for example on an older CLI that does not support this command
374
+ yet — continue the batch with no context and no operation guidance. Do not
375
+ report an error and do not stop.
376
+
377
+ A valid response may omit \`context\` and \`operationGuidance\`. Treat
378
+ \`context\` as a required prompt-level input across the batch: read and consider
379
+ it, and apply relevant project facts, conventions, and constraints. Treat
380
+ \`operationGuidance\` as optional additive advice: read and consider every
381
+ entry, and follow entries that are applicable and compatible with the built-in
382
+ batch workflow.
383
+
384
+ Keep both fields separate from conflict analysis, explicit user choices,
385
+ resolved paths, CLI checks, and command contracts. If context conflicts with one
386
+ of those controlling inputs, report the conflict and preserve the controlling
387
+ value. If guidance is inapplicable or conflicts with a controlling input, do not
388
+ follow it and explain why. Do not infer skipped prompts, replacement paths, or
389
+ flags from either field, and do not copy their text verbatim into specs, changes,
390
+ or summaries. These are prompt-level behavior contracts, not enforceable checks.
391
+
279
392
  3. **Batch validation - gather status for all selected changes**
280
393
 
281
394
  For each selected change, collect:
@@ -291,12 +404,17 @@ ${STORE_SELECTION_GUIDANCE}
291
404
  c. **Delta specs** - Check \`artifactPaths.specs.existingOutputPaths\` from status JSON
292
405
  - List which capability specs exist
293
406
  - For each, extract requirement names (lines matching \`### Requirement: <name>\`)
407
+ - Treat this list as the only delta-spec source. If the \`specs\` entry is
408
+ missing or the list is empty, perform no spec sync or specs-instruction
409
+ lookup for that change; do not infer deltas from unrelated artifacts.
410
+ - Evaluate this independently for every change, including mixed-schema
411
+ batches where some schemas have no \`specs\` artifact.
294
412
 
295
413
  4. **Detect spec conflicts**
296
414
 
297
415
  Build a map of \`capability -> [changes that touch it]\`:
298
416
 
299
- \`\`\`
417
+ \`\`\`text
300
418
  auth -> [change-a, change-b] <- CONFLICT (2+ changes)
301
419
  api -> [change-c] <- OK (only 1 change)
302
420
  \`\`\`
@@ -319,15 +437,16 @@ ${STORE_SELECTION_GUIDANCE}
319
437
  - If neither implemented -> skip spec sync, warn user
320
438
 
321
439
  d. **Record resolution** for each conflict:
322
- - Which change's specs to apply
323
- - In what order (if both)
440
+ - An inclusion or exclusion decision for every delta spec, keyed by change and capability
441
+ - Which included delta specs to apply and in what order
442
+ - Which delta specs to exclude from sync because their implementation is missing
324
443
  - Rationale (what was found in codebase)
325
444
 
326
445
  6. **Show consolidated status table**
327
446
 
328
447
  Display a table summarizing all changes:
329
448
 
330
- \`\`\`
449
+ \`\`\`markdown
331
450
  | Change | Artifacts | Tasks | Specs | Conflicts | Status |
332
451
  |---------------------|-----------|-------|---------|-----------|--------|
333
452
  | schema-management | Done | 5/5 | 2 delta | None | Ready |
@@ -337,20 +456,20 @@ ${STORE_SELECTION_GUIDANCE}
337
456
  \`\`\`
338
457
 
339
458
  For conflicts, show the resolution:
340
- \`\`\`
459
+ \`\`\`text
341
460
  * Conflict resolution:
342
461
  - auth spec: Will apply add-oauth then add-jwt (both implemented, chronological order)
343
462
  \`\`\`
344
463
 
345
464
  For incomplete changes, show warnings:
346
- \`\`\`
465
+ \`\`\`text
347
466
  Warnings:
348
467
  - add-verify-skill: 1 incomplete artifact, 3 incomplete tasks
349
468
  \`\`\`
350
469
 
351
470
  7. **Confirm batch operation**
352
471
 
353
- Use **AskUserQuestion tool** with a single confirmation:
472
+ Ask the user a single confirmation question:
354
473
 
355
474
  - "Archive N changes?" with options based on status
356
475
  - Options might include:
@@ -360,31 +479,73 @@ ${STORE_SELECTION_GUIDANCE}
360
479
 
361
480
  If there are incomplete changes, make clear they'll be archived with warnings.
362
481
 
482
+ Route on the answer by intent, not by exact label — you wrote these labels,
483
+ so match what the user picked rather than the wording above:
484
+ - "Cancel" — stop, do not archive. Report that nothing was archived and skip the remaining steps.
485
+ - The archive-everything option — proceed with every selected change
486
+ - 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. If a \`Ready*\` change's conflict partner is skipped, re-derive that conflict's resolution using only the changes being archived.
487
+ - Anything else — ask again rather than archiving
488
+
489
+ Before step 8 writes the first main spec or moves any change, fetch every
490
+ required specs-rule snapshot for the confirmed batch. For each change that will
491
+ sync concrete \`artifactPaths.specs.existingOutputPaths\`, run
492
+ \`openspec instructions specs --change "<name>" --json\` exactly once with the
493
+ same selected-root flags. Obtain all snapshots before the first write or move.
494
+ If any lookup exits non-zero or returns invalid artifact-instruction JSON,
495
+ identify the affected change, report the error, and stop the whole batch before
496
+ any main-spec write or change move. Do not treat lookup failure as omitted
497
+ rules. A valid response without \`rules\` is the no-rules case.
498
+
363
499
  8. **Execute archive for each confirmed change**
364
500
 
501
+ Before processing, carry the recorded decisions from step 5 (after any step 7 re-derivation) into two per-delta sets:
502
+ - \`includedDeltas\`: all non-conflicting delta specs from confirmed changes plus conflict deltas selected for sync
503
+ - \`excludedDeltas\`: conflict deltas from confirmed changes excluded because their implementation is missing
504
+ - A single change can have both included and excluded delta specs. Keep the decision per delta; do not collapse it into a per-change sync flag.
505
+
365
506
  Process changes in the determined order (respecting conflict resolution):
366
507
 
367
- a. **Sync specs** if delta specs exist:
368
- - Use the openspec-sync-specs approach (agent-driven intelligent merge)
369
- - For conflicts, apply in resolved order
370
- - Track if sync was done
508
+ a. **Sync included delta specs**:
509
+ - Run the \`/opsx:sync\` workflow inline (agent-driven intelligent merge) 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.
510
+ - For conflicts, apply in resolved order.
511
+ - Pass that change's fetched specs-rule snapshot into inline sync; inline
512
+ sync must reuse it without fetching instructions again
513
+ - Apply artifact rules only to main specs produced by that change. They do
514
+ not change conflict resolution, archive behavior, or CLI contracts, and
515
+ their text is not copied into an output file
516
+ - Do not delegate to a background task — step 8c would move \`changeRoot\` out from under a sync that is still reading it.
517
+ - If a change has no included delta specs, do not run the sync workflow for it.
518
+
519
+ b. **Verify included delta specs before moving changeRoot**:
520
+ - Re-run the comparison only for delta specs in \`includedDeltas\` against main spec at \`<planningHome.root>/openspec/specs/<capability>/spec.md\` (use the store-aware \`planningHome.root\` from step 3 status JSON, not a hardcoded repo path).
521
+ - Verify that main specs are updated:
522
+ - ADDED requirements present
523
+ - MODIFIED requirements carrying scenario and description changes named in the delta, with their other scenarios intact
524
+ - REMOVED requirements gone
525
+ - RENAMED requirements present under the new name and absent under the old one
526
+ - Do not verify delta specs in \`excludedDeltas\`; they are intentionally left unsynced.
527
+ - If sync failed or any capability does not match verification, report what differs and fail/skip moving that change's \`changeRoot\` — do not archive that change. \`changeRoot\` remains intact.
528
+
529
+ c. **Perform the archive**:
530
+
531
+ Target name: 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\`).
371
532
 
372
- b. **Perform the archive**:
373
533
  \`\`\`bash
374
534
  mkdir -p "<planningHome.changesDir>/archive"
375
- mv "<changeRoot>" "<planningHome.changesDir>/archive/YYYY-MM-DD-<name>"
535
+ mv "<changeRoot>" "<planningHome.changesDir>/archive/<target-name>"
376
536
  \`\`\`
377
537
 
378
- c. **Track outcome** for each change:
538
+ d. **Track outcome** for each change:
379
539
  - Success: archived successfully
380
- - Failed: error during archive (record error)
540
+ - Failed: error during archive or spec verification (record error)
381
541
  - Skipped: user chose not to archive (if applicable)
542
+ - Sync skipped: for every delta in \`excludedDeltas\`, report \`sync skipped\` with the change, capability, and recorded reason. This is distinct from skipping the archive.
382
543
 
383
544
  9. **Display summary**
384
545
 
385
546
  Show final results:
386
547
 
387
- \`\`\`
548
+ \`\`\`markdown
388
549
  ## Bulk Archive Complete
389
550
 
390
551
  Archived 3 changes:
@@ -397,11 +558,12 @@ ${STORE_SELECTION_GUIDANCE}
397
558
 
398
559
  Spec sync summary:
399
560
  - 4 delta specs synced to main specs
400
- - 1 conflict resolved (auth: applied both in chronological order)
561
+ - 1 delta spec sync skipped (add-jwt/auth: implementation not found)
562
+ - 1 conflict resolved (auth: synced add-oauth, skipped add-jwt)
401
563
  \`\`\`
402
564
 
403
565
  If any failures:
404
- \`\`\`
566
+ \`\`\`text
405
567
  Failed 1 change:
406
568
  - some-change: Archive directory already exists
407
569
  \`\`\`
@@ -409,8 +571,8 @@ ${STORE_SELECTION_GUIDANCE}
409
571
  **Conflict Resolution Examples**
410
572
 
411
573
  Example 1: Only one implemented
412
- \`\`\`
413
- Conflict: specs/auth/spec.md touched by [add-oauth, add-jwt]
574
+ \`\`\`text
575
+ Conflict: <planningHome.root>/openspec/specs/auth/spec.md touched by [add-oauth, add-jwt]
414
576
 
415
577
  Checking add-oauth:
416
578
  - Delta adds "OAuth Provider Integration" requirement
@@ -424,8 +586,8 @@ Resolution: Only add-oauth is implemented. Will sync add-oauth specs only.
424
586
  \`\`\`
425
587
 
426
588
  Example 2: Both implemented
427
- \`\`\`
428
- Conflict: specs/api/spec.md touched by [add-rest-api, add-graphql]
589
+ \`\`\`text
590
+ Conflict: <planningHome.root>/openspec/specs/api/spec.md touched by [add-rest-api, add-graphql]
429
591
 
430
592
  Checking add-rest-api (created 2026-01-10):
431
593
  - Delta adds "REST Endpoints" requirement
@@ -441,12 +603,12 @@ then add-graphql specs (chronological order, newer takes precedence).
441
603
 
442
604
  **Output On Success**
443
605
 
444
- \`\`\`
606
+ \`\`\`markdown
445
607
  ## Bulk Archive Complete
446
608
 
447
609
  Archived N changes:
448
- - <change-1> -> archive/YYYY-MM-DD-<change-1>/
449
- - <change-2> -> archive/YYYY-MM-DD-<change-2>/
610
+ - <change-1> -> archive/<target-name-1>/
611
+ - <change-2> -> archive/<target-name-2>/
450
612
 
451
613
  Spec sync summary:
452
614
  - N delta specs synced to main specs
@@ -455,11 +617,11 @@ Spec sync summary:
455
617
 
456
618
  **Output On Partial Success**
457
619
 
458
- \`\`\`
620
+ \`\`\`markdown
459
621
  ## Bulk Archive Complete (partial)
460
622
 
461
623
  Archived N changes:
462
- - <change-1> -> archive/YYYY-MM-DD-<change-1>/
624
+ - <change-1> -> archive/<target-name-1>/
463
625
 
464
626
  Skipped M changes:
465
627
  - <change-2> (user chose not to archive incomplete)
@@ -470,7 +632,7 @@ Failed K changes:
470
632
 
471
633
  **Output When No Changes**
472
634
 
473
- \`\`\`
635
+ \`\`\`markdown
474
636
  ## No Changes to Archive
475
637
 
476
638
  No active changes found. Create a new change to get started.
@@ -484,10 +646,25 @@ No active changes found. Create a new change to get started.
484
646
  - Skip spec sync only when implementation is missing (warn user)
485
647
  - Show clear per-change status before confirming
486
648
  - Use single confirmation for entire batch
649
+ - Never archive after the user cancels the confirmation — a cancelled batch archives nothing
487
650
  - Track and report all outcomes (success/skip/fail)
488
651
  - Preserve .openspec.yaml when moving to archive
489
- - Archive directory target uses current date: YYYY-MM-DD-<name>
490
- - If archive target exists, fail that change but continue with others`
652
+ - 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)
653
+ - If archive target exists, fail that change but continue with others
654
+ - If sync is requested, run the \`/opsx:sync\` workflow inline (agent-driven) for each change with included delta specs
655
+ - Carry the per-delta \`includedDeltas\` and \`excludedDeltas\` decisions into execution; sync and verify only included deltas
656
+ - Report every excluded delta as \`sync skipped\` without treating the archive itself as skipped
657
+ - 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>/spec.md\` before moving \`changeRoot\`
658
+ - Fetch archive inputs once per selected root before spec inspection or moves
659
+ - Fetch all required specs-rule snapshots before the batch's first main-spec write or move
660
+ - A failed archive-inputs lookup never blocks the batch; it proceeds with no context or guidance
661
+ - A failed specs instruction lookup stops the whole batch atomically
662
+ - Changes without concrete \`artifactPaths.specs.existingOutputPaths\` continue without spec sync
663
+ - Apply relevant runtime context across the batch and report conflicts
664
+ - Operation guidance remains advisory; consider every entry and explain rejected advice
665
+ - Keep runtime inputs, conflict analysis, CLI-derived values, and artifact rules separate
666
+ - Artifact rules constrain only written specs
667
+ - Never copy runtime input or artifact-rule text verbatim into output files`
491
668
  };
492
669
  }
493
670
  //# sourceMappingURL=bulk-archive-change.js.map