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