@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.
- package/README.md +28 -1
- package/dist/cli/index.js +73 -7
- package/dist/commands/change.d.ts +0 -1
- package/dist/commands/change.js +90 -50
- package/dist/commands/config.js +14 -8
- package/dist/commands/doctor.js +9 -4
- package/dist/commands/feedback.js +74 -23
- package/dist/commands/schema.js +21 -11
- package/dist/commands/show.js +5 -2
- package/dist/commands/spec.js +20 -24
- package/dist/commands/validate.js +18 -3
- package/dist/commands/workflow/index.d.ts +1 -1
- package/dist/commands/workflow/index.js +1 -1
- package/dist/commands/workflow/instructions.d.ts +7 -1
- package/dist/commands/workflow/instructions.js +89 -6
- package/dist/commands/workflow/shared.d.ts +13 -2
- package/dist/commands/workflow/shared.js +34 -4
- package/dist/commands/workflow/status.js +7 -2
- package/dist/core/archive.d.ts +0 -1
- package/dist/core/archive.js +96 -33
- package/dist/core/artifact-graph/graph.d.ts +16 -0
- package/dist/core/artifact-graph/graph.js +30 -6
- package/dist/core/artifact-graph/instruction-loader.d.ts +27 -2
- package/dist/core/artifact-graph/instruction-loader.js +55 -7
- package/dist/core/artifact-graph/resolver.d.ts +14 -0
- package/dist/core/artifact-graph/resolver.js +34 -6
- package/dist/core/change-metadata/schema.d.ts +1 -0
- package/dist/core/change-metadata/schema.js +6 -0
- package/dist/core/change-status-policy.d.ts +1 -1
- package/dist/core/command-generation/adapters/amazon-q.d.ts +4 -0
- package/dist/core/command-generation/adapters/amazon-q.js +7 -1
- package/dist/core/command-generation/adapters/antigravity.js +2 -1
- package/dist/core/command-generation/adapters/auggie.js +2 -1
- package/dist/core/command-generation/adapters/bob.d.ts +5 -1
- package/dist/core/command-generation/adapters/bob.js +6 -5
- package/dist/core/command-generation/adapters/claude.js +1 -8
- package/dist/core/command-generation/adapters/codebuddy.js +3 -2
- package/dist/core/command-generation/adapters/continue.js +3 -2
- package/dist/core/command-generation/adapters/costrict.js +2 -1
- package/dist/core/command-generation/adapters/crush.js +5 -5
- package/dist/core/command-generation/adapters/cursor.js +2 -2
- package/dist/core/command-generation/adapters/devin.d.ts +19 -0
- package/dist/core/command-generation/adapters/devin.js +36 -0
- package/dist/core/command-generation/adapters/factory.js +2 -1
- package/dist/core/command-generation/adapters/gemini.js +37 -2
- package/dist/core/command-generation/adapters/github-copilot.js +2 -1
- package/dist/core/command-generation/adapters/iflow.js +5 -4
- package/dist/core/command-generation/adapters/index.d.ts +2 -2
- package/dist/core/command-generation/adapters/index.js +2 -2
- package/dist/core/command-generation/adapters/junie.js +2 -1
- package/dist/core/command-generation/adapters/kiro.js +2 -1
- package/dist/core/command-generation/adapters/lingma.js +5 -5
- package/dist/core/command-generation/adapters/oh-my-pi.d.ts +2 -2
- package/dist/core/command-generation/adapters/oh-my-pi.js +3 -5
- package/dist/core/command-generation/adapters/opencode.js +3 -5
- package/dist/core/command-generation/adapters/pi.d.ts +2 -2
- package/dist/core/command-generation/adapters/pi.js +3 -6
- package/dist/core/command-generation/adapters/qoder.js +5 -5
- package/dist/core/command-generation/adapters/qwen.d.ts +7 -3
- package/dist/core/command-generation/adapters/qwen.js +12 -7
- package/dist/core/command-generation/adapters/roocode.d.ts +4 -4
- package/dist/core/command-generation/adapters/roocode.js +4 -4
- package/dist/core/command-generation/adapters/trae.js +1 -21
- package/dist/core/command-generation/adapters/zcode.d.ts +16 -0
- package/dist/core/command-generation/adapters/zcode.js +33 -0
- package/dist/core/command-generation/generator.d.ts +8 -0
- package/dist/core/command-generation/generator.js +15 -1
- package/dist/core/command-generation/index.d.ts +1 -1
- package/dist/core/command-generation/index.js +1 -1
- package/dist/core/command-generation/invocation.d.ts +73 -0
- package/dist/core/command-generation/invocation.js +77 -0
- package/dist/core/command-generation/registry.js +4 -4
- package/dist/core/command-generation/types.d.ts +9 -2
- package/dist/core/command-generation/yaml.d.ts +20 -6
- package/dist/core/command-generation/yaml.js +31 -21
- package/dist/core/command-surface.d.ts +15 -0
- package/dist/core/command-surface.js +33 -0
- package/dist/core/completions/command-registry.js +8 -2
- package/dist/core/completions/generators/powershell-generator.js +15 -8
- package/dist/core/completions/installers/zsh-installer.d.ts +9 -0
- package/dist/core/completions/installers/zsh-installer.js +20 -4
- package/dist/core/config-prompts.d.ts +1 -1
- package/dist/core/config-prompts.js +14 -1
- package/dist/core/config-schema.d.ts +7 -1
- package/dist/core/config-schema.js +40 -1
- package/dist/core/config.d.ts +12 -0
- package/dist/core/config.js +21 -3
- package/dist/core/global-config.d.ts +5 -0
- package/dist/core/init.d.ts +35 -0
- package/dist/core/init.js +225 -39
- package/dist/core/legacy-cleanup.d.ts +59 -0
- package/dist/core/legacy-cleanup.js +249 -22
- package/dist/core/list.js +5 -7
- package/dist/core/migration.d.ts +71 -1
- package/dist/core/migration.js +294 -1
- package/dist/core/onboarding-commands.d.ts +30 -0
- package/dist/core/onboarding-commands.js +38 -0
- package/dist/core/parsers/change-parser.d.ts +17 -2
- package/dist/core/parsers/change-parser.js +33 -20
- package/dist/core/parsers/code-fence.d.ts +15 -0
- package/dist/core/parsers/code-fence.js +49 -0
- package/dist/core/parsers/markdown-parser.js +2 -1
- package/dist/core/parsers/requirement-blocks.d.ts +8 -0
- package/dist/core/parsers/requirement-blocks.js +60 -35
- package/dist/core/parsers/requirement-text.d.ts +1 -8
- package/dist/core/parsers/requirement-text.js +4 -42
- package/dist/core/parsers/spec-structure.js +3 -29
- package/dist/core/profile-sync-drift.d.ts +0 -8
- package/dist/core/profile-sync-drift.js +9 -45
- package/dist/core/project-config.d.ts +25 -6
- package/dist/core/project-config.js +77 -7
- package/dist/core/references.js +42 -4
- package/dist/core/relationship-health.d.ts +8 -0
- package/dist/core/relationship-health.js +13 -0
- package/dist/core/root-selection.d.ts +9 -6
- package/dist/core/root-selection.js +42 -5
- package/dist/core/shared/tool-detection.d.ts +25 -5
- package/dist/core/shared/tool-detection.js +105 -6
- package/dist/core/specs-apply.d.ts +8 -33
- package/dist/core/specs-apply.js +252 -157
- package/dist/core/store/git.d.ts +13 -0
- package/dist/core/store/git.js +24 -0
- package/dist/core/templates/workflows/apply-change.js +54 -4
- package/dist/core/templates/workflows/archive-change.js +166 -42
- package/dist/core/templates/workflows/bulk-archive-change.js +240 -63
- package/dist/core/templates/workflows/continue-change.js +32 -40
- package/dist/core/templates/workflows/explore.js +12 -0
- package/dist/core/templates/workflows/ff-change.js +46 -30
- package/dist/core/templates/workflows/new-change.js +2 -2
- package/dist/core/templates/workflows/onboard.js +4 -4
- package/dist/core/templates/workflows/propose.js +50 -32
- package/dist/core/templates/workflows/store-selection.d.ts +1 -1
- package/dist/core/templates/workflows/store-selection.js +1 -1
- package/dist/core/templates/workflows/sync-specs.js +172 -22
- package/dist/core/templates/workflows/update-change.js +20 -12
- package/dist/core/templates/workflows/verify-change.js +16 -10
- package/dist/core/update.d.ts +39 -5
- package/dist/core/update.js +288 -71
- package/dist/core/validation/constants.d.ts +4 -1
- package/dist/core/validation/constants.js +4 -1
- package/dist/core/validation/validator.d.ts +1 -7
- package/dist/core/validation/validator.js +92 -36
- package/dist/core/version-check.d.ts +152 -0
- package/dist/core/version-check.js +736 -0
- package/dist/core/view.js +12 -17
- package/dist/prompts/searchable-multi-select.js +1 -1
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.js +55 -33
- package/dist/ui/welcome-screen.d.ts +9 -1
- package/dist/ui/welcome-screen.js +91 -38
- package/dist/utils/change-metadata.d.ts +30 -0
- package/dist/utils/change-metadata.js +101 -7
- package/dist/utils/change-utils.d.ts +10 -4
- package/dist/utils/change-utils.js +20 -13
- package/dist/utils/command-references.d.ts +80 -6
- package/dist/utils/command-references.js +138 -7
- package/dist/utils/date.d.ts +8 -0
- package/dist/utils/date.js +13 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/item-discovery.d.ts +19 -0
- package/dist/utils/item-discovery.js +30 -48
- package/dist/utils/shell-detection.d.ts +1 -1
- package/dist/utils/shell-detection.js +64 -11
- package/dist/utils/spec-discovery.d.ts +40 -0
- package/dist/utils/spec-discovery.js +102 -0
- package/package.json +14 -12
- package/schemas/spec-driven/schema.yaml +60 -5
- package/schemas/spec-driven/templates/design.md +2 -2
- package/schemas/spec-driven/templates/proposal.md +5 -1
- package/schemas/spec-driven/templates/spec.md +3 -0
- package/dist/core/command-generation/adapters/codex.d.ts +0 -16
- package/dist/core/command-generation/adapters/codex.js +0 -39
- package/dist/core/command-generation/adapters/windsurf.d.ts +0 -14
- package/dist/core/command-generation/adapters/windsurf.js +0 -38
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* Interpolated into every workflow's instructions so generated skills
|
|
5
5
|
* consistently teach how to target a registered store with `--store <id>`.
|
|
6
6
|
*/
|
|
7
|
-
export declare const STORE_SELECTION_GUIDANCE = "**Store selection:** If the user names a store (a store is a standalone OpenSpec repo registered on this machine) or the work lives in one, run `openspec store list --json` to discover registered store ids, then pass `--store <id>` on the commands that read or write specs and changes (`new change`, `status`, `instructions`, `list`, `show`, `validate`, `archive`, `doctor`, `context`). Other commands do not take the flag. Hints printed by commands already carry the flag; keep it on follow-ups. Without a store, commands act on the nearest local `openspec/` root.";
|
|
7
|
+
export declare const STORE_SELECTION_GUIDANCE = "**Store selection:** If the user names a store (a store is a standalone OpenSpec repo registered on this machine) or the work lives in one, run `openspec store list --json` to discover registered store ids, then pass `--store <id>` on the commands that read or write specs and changes (`new change`, `status`, `instructions`, `list`, `show`, `validate`, `archive`, `doctor`, `context`, `view`). Other commands do not take the flag. Hints printed by commands already carry the flag; keep it on follow-ups. Without a store, commands act on the nearest local `openspec/` root.";
|
|
8
8
|
//# sourceMappingURL=store-selection.d.ts.map
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* Interpolated into every workflow's instructions so generated skills
|
|
5
5
|
* consistently teach how to target a registered store with `--store <id>`.
|
|
6
6
|
*/
|
|
7
|
-
export const STORE_SELECTION_GUIDANCE = `**Store selection:** If the user names a store (a store is a standalone OpenSpec repo registered on this machine) or the work lives in one, run \`openspec store list --json\` to discover registered store ids, then pass \`--store <id>\` on the commands that read or write specs and changes (\`new change\`, \`status\`, \`instructions\`, \`list\`, \`show\`, \`validate\`, \`archive\`, \`doctor\`, \`context\`). Other commands do not take the flag. Hints printed by commands already carry the flag; keep it on follow-ups. Without a store, commands act on the nearest local \`openspec/\` root.`;
|
|
7
|
+
export const STORE_SELECTION_GUIDANCE = `**Store selection:** If the user names a store (a store is a standalone OpenSpec repo registered on this machine) or the work lives in one, run \`openspec store list --json\` to discover registered store ids, then pass \`--store <id>\` on the commands that read or write specs and changes (\`new change\`, \`status\`, \`instructions\`, \`list\`, \`show\`, \`validate\`, \`archive\`, \`doctor\`, \`context\`, \`view\`). Other commands do not take the flag. Hints printed by commands already carry the flag; keep it on follow-ups. Without a store, commands act on the nearest local \`openspec/\` root.`;
|
|
8
8
|
//# sourceMappingURL=store-selection.js.map
|
|
@@ -13,13 +13,16 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
13
13
|
|
|
14
14
|
**Steps**
|
|
15
15
|
|
|
16
|
-
1. **
|
|
16
|
+
1. **Select the change**
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
If a name is provided, use it. Otherwise:
|
|
19
|
+
- Infer from conversation context if the user mentioned a change
|
|
20
|
+
- Auto-select if only one active change exists
|
|
21
|
+
- If ambiguous, run \`openspec list --json\` to get available changes and ask the user to select one
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
When prompting, show changes that have delta specs (under \`specs/\` directory).
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:sync <other>\`).
|
|
23
26
|
|
|
24
27
|
2. **Resolve change context**
|
|
25
28
|
|
|
@@ -28,9 +31,27 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
28
31
|
openspec status --change "<name>" --json
|
|
29
32
|
\`\`\`
|
|
30
33
|
|
|
34
|
+
The JSON includes \`planningHome.root\`. Main specs live under \`<planningHome.root>/openspec/specs/\` — use that (store-aware) root for every main-spec path below, not a hardcoded repo path. When a store is selected it points at the store, not the current repository.
|
|
35
|
+
|
|
31
36
|
3. **Find delta specs**
|
|
32
37
|
|
|
33
|
-
Use \`artifactPaths.specs.existingOutputPaths\` from the status JSON as the
|
|
38
|
+
Use \`artifactPaths.specs.existingOutputPaths\` from the status JSON as the
|
|
39
|
+
only source of delta spec paths. If the \`specs\` entry is missing or
|
|
40
|
+
\`existingOutputPaths\` is empty, report that there are no delta specs to sync,
|
|
41
|
+
do not infer them from other artifacts, and stop without requesting artifact
|
|
42
|
+
instructions or writing a main spec.
|
|
43
|
+
|
|
44
|
+
Sync every path in \`existingOutputPaths\` unless the caller narrowed the set.
|
|
45
|
+
A caller narrows it by naming an explicit list of delta spec paths to sync —
|
|
46
|
+
archive does this inline, and a user can too ("only sync the billing delta").
|
|
47
|
+
Then sync only the named paths and leave the remaining delta specs untouched:
|
|
48
|
+
bulk archive excludes a delta whose implementation it could not find, and
|
|
49
|
+
syncing it anyway would write a main spec the caller deliberately withheld.
|
|
50
|
+
Carry that narrowed selection through step 4; never widen it back to the full
|
|
51
|
+
list. If a named path is not in \`existingOutputPaths\`, do not sync it —
|
|
52
|
+
report it and stop, rather than dropping it silently. If the named list is
|
|
53
|
+
empty, report that there is nothing to sync and stop without writing a main
|
|
54
|
+
spec.
|
|
34
55
|
|
|
35
56
|
Each delta spec file contains sections like:
|
|
36
57
|
- \`## ADDED Requirements\` - New requirements to add
|
|
@@ -42,11 +63,27 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
42
63
|
|
|
43
64
|
4. **For each delta spec, apply changes to main specs**
|
|
44
65
|
|
|
45
|
-
|
|
66
|
+
Before the first main-spec write, obtain one current specs-rule snapshot:
|
|
67
|
+
- If archive invoked this workflow inline and supplied a valid snapshot from
|
|
68
|
+
\`openspec instructions specs --change "<name>" --json\`, reuse it and do not
|
|
69
|
+
fetch the same instructions again.
|
|
70
|
+
- Otherwise run that command once now with the same selected-root flags.
|
|
71
|
+
- If the direct lookup exits non-zero or returns invalid artifact-instruction
|
|
72
|
+
JSON, report the error and stop before writing any main spec. Do not treat the
|
|
73
|
+
failure as an absent rule set.
|
|
74
|
+
- A valid response with omitted \`rules\` means no artifact rules are configured
|
|
75
|
+
and the existing semantic merge continues.
|
|
76
|
+
|
|
77
|
+
Apply returned \`rules\` only to the content and form of the main specs produced
|
|
78
|
+
by this merge. Artifact rules are not operation guidance and cannot change
|
|
79
|
+
selected roots, delta paths, CLI checks, or workflow steps. Use their text as
|
|
80
|
+
constraints without copying it verbatim into a main spec or summary.
|
|
81
|
+
|
|
82
|
+
For each capability delta spec path selected in step 3 — the full \`existingOutputPaths\` list, or the narrowed subset when a caller supplied one (these may belong to a selected store, not the repo):
|
|
46
83
|
|
|
47
84
|
a. **Read the delta spec** to understand the intended changes
|
|
48
85
|
|
|
49
|
-
b. **Read the main spec** at
|
|
86
|
+
b. **Read the main spec** at \`<planningHome.root>/openspec/specs/<capability>/spec.md\` (may not exist yet)
|
|
50
87
|
|
|
51
88
|
c. **Apply changes intelligently**:
|
|
52
89
|
|
|
@@ -68,20 +105,32 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
68
105
|
**RENAMED Requirements:**
|
|
69
106
|
- Find the FROM requirement, rename to TO
|
|
70
107
|
|
|
108
|
+
**\`## Purpose\` in the delta:**
|
|
109
|
+
- The main spec already has one and it is authoritative - leave it alone
|
|
110
|
+
(this is what \`openspec archive\` does; it warns and moves on)
|
|
111
|
+
|
|
71
112
|
d. **Create new main spec** if capability doesn't exist yet:
|
|
72
|
-
- Create
|
|
73
|
-
- Add Purpose section
|
|
113
|
+
- Create \`<planningHome.root>/openspec/specs/<capability>/spec.md\`
|
|
114
|
+
- Add Purpose section: copy the delta's \`## Purpose\` body verbatim when it has one
|
|
115
|
+
(this is what \`openspec archive\` does); only write a brief TBD placeholder when it does not
|
|
74
116
|
- Add Requirements section with the ADDED requirements
|
|
117
|
+
- Follow the **Main Spec Format Reference** below
|
|
75
118
|
|
|
76
119
|
5. **Show summary**
|
|
77
120
|
|
|
78
121
|
After applying all changes, summarize:
|
|
79
122
|
- Which capabilities were updated
|
|
80
123
|
- What changes were made (requirements added/modified/removed/renamed)
|
|
124
|
+
- Any new main spec left with a TBD Purpose placeholder, so it gets written
|
|
125
|
+
now rather than lingering
|
|
81
126
|
|
|
82
127
|
**Delta Spec Format Reference**
|
|
83
128
|
|
|
84
129
|
\`\`\`markdown
|
|
130
|
+
## Purpose
|
|
131
|
+
|
|
132
|
+
Only on a delta that introduces a brand-new capability. Seeds the new main spec.
|
|
133
|
+
|
|
85
134
|
## ADDED Requirements
|
|
86
135
|
|
|
87
136
|
### Requirement: New Feature
|
|
@@ -108,6 +157,26 @@ The system SHALL do something new.
|
|
|
108
157
|
- TO: \`### Requirement: New Name\`
|
|
109
158
|
\`\`\`
|
|
110
159
|
|
|
160
|
+
**Main Spec Format Reference**
|
|
161
|
+
|
|
162
|
+
Main specs are what the delta merges INTO. They must never contain delta operation headers (\`## ADDED/MODIFIED/REMOVED/RENAMED Requirements\`) - after syncing, every requirement lives under a single \`## Requirements\` section:
|
|
163
|
+
|
|
164
|
+
\`\`\`markdown
|
|
165
|
+
# <capability> Specification
|
|
166
|
+
|
|
167
|
+
## Purpose
|
|
168
|
+
Short description of what this capability does and why it exists.
|
|
169
|
+
|
|
170
|
+
## Requirements
|
|
171
|
+
|
|
172
|
+
### Requirement: New Feature
|
|
173
|
+
The system SHALL do something new.
|
|
174
|
+
|
|
175
|
+
#### Scenario: Basic case
|
|
176
|
+
- **WHEN** user does X
|
|
177
|
+
- **THEN** system does Y
|
|
178
|
+
\`\`\`
|
|
179
|
+
|
|
111
180
|
**Key Principle: Intelligent Merging**
|
|
112
181
|
|
|
113
182
|
Unlike programmatic merging, you can apply **partial updates**:
|
|
@@ -117,7 +186,7 @@ Unlike programmatic merging, you can apply **partial updates**:
|
|
|
117
186
|
|
|
118
187
|
**Output On Success**
|
|
119
188
|
|
|
120
|
-
\`\`\`
|
|
189
|
+
\`\`\`markdown
|
|
121
190
|
## Specs Synced: <change-name>
|
|
122
191
|
|
|
123
192
|
Updated main specs:
|
|
@@ -136,9 +205,15 @@ Main specs are now updated. The change remains active - archive when implementat
|
|
|
136
205
|
**Guardrails**
|
|
137
206
|
- Read both delta and main specs before making changes
|
|
138
207
|
- Preserve existing content not mentioned in delta
|
|
208
|
+
- Never copy a delta file into a main spec as-is - merge its content so the main spec keeps the Main Spec Format Reference structure, with no delta operation headers
|
|
139
209
|
- If something is unclear, ask for clarification
|
|
140
210
|
- Show what you're changing as you go
|
|
141
|
-
- The operation should be idempotent - running twice should give same result
|
|
211
|
+
- The operation should be idempotent - running twice should give same result
|
|
212
|
+
- Use only \`artifactPaths.specs.existingOutputPaths\`; never infer delta specs from unrelated artifacts
|
|
213
|
+
- Honor a caller-supplied subset of \`existingOutputPaths\`; never widen it back to the full list
|
|
214
|
+
- Fetch specs instructions once for direct sync, or reuse the archive-supplied snapshot inline
|
|
215
|
+
- Stop before every main-spec write on a non-zero or invalid JSON specs-instruction response
|
|
216
|
+
- Artifact rules constrain only the specs being written and are never copied into output files`,
|
|
142
217
|
license: 'MIT',
|
|
143
218
|
compatibility: 'Requires openspec CLI.',
|
|
144
219
|
metadata: { author: 'openspec', version: '1.0' },
|
|
@@ -160,13 +235,16 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
160
235
|
|
|
161
236
|
**Steps**
|
|
162
237
|
|
|
163
|
-
1. **
|
|
238
|
+
1. **Select the change**
|
|
164
239
|
|
|
165
|
-
|
|
240
|
+
If a name is provided, use it. Otherwise:
|
|
241
|
+
- Infer from conversation context if the user mentioned a change
|
|
242
|
+
- Auto-select if only one active change exists
|
|
243
|
+
- If ambiguous, run \`openspec list --json\` to get available changes and ask the user to select one
|
|
166
244
|
|
|
167
|
-
|
|
245
|
+
When prompting, show changes that have delta specs (under \`specs/\` directory).
|
|
168
246
|
|
|
169
|
-
|
|
247
|
+
Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:sync <other>\`).
|
|
170
248
|
|
|
171
249
|
2. **Resolve change context**
|
|
172
250
|
|
|
@@ -175,9 +253,27 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
175
253
|
openspec status --change "<name>" --json
|
|
176
254
|
\`\`\`
|
|
177
255
|
|
|
256
|
+
The JSON includes \`planningHome.root\`. Main specs live under \`<planningHome.root>/openspec/specs/\` — use that (store-aware) root for every main-spec path below, not a hardcoded repo path. When a store is selected it points at the store, not the current repository.
|
|
257
|
+
|
|
178
258
|
3. **Find delta specs**
|
|
179
259
|
|
|
180
|
-
Use \`artifactPaths.specs.existingOutputPaths\` from the status JSON as the
|
|
260
|
+
Use \`artifactPaths.specs.existingOutputPaths\` from the status JSON as the
|
|
261
|
+
only source of delta spec paths. If the \`specs\` entry is missing or
|
|
262
|
+
\`existingOutputPaths\` is empty, report that there are no delta specs to sync,
|
|
263
|
+
do not infer them from other artifacts, and stop without requesting artifact
|
|
264
|
+
instructions or writing a main spec.
|
|
265
|
+
|
|
266
|
+
Sync every path in \`existingOutputPaths\` unless the caller narrowed the set.
|
|
267
|
+
A caller narrows it by naming an explicit list of delta spec paths to sync —
|
|
268
|
+
archive does this inline, and a user can too ("only sync the billing delta").
|
|
269
|
+
Then sync only the named paths and leave the remaining delta specs untouched:
|
|
270
|
+
bulk archive excludes a delta whose implementation it could not find, and
|
|
271
|
+
syncing it anyway would write a main spec the caller deliberately withheld.
|
|
272
|
+
Carry that narrowed selection through step 4; never widen it back to the full
|
|
273
|
+
list. If a named path is not in \`existingOutputPaths\`, do not sync it —
|
|
274
|
+
report it and stop, rather than dropping it silently. If the named list is
|
|
275
|
+
empty, report that there is nothing to sync and stop without writing a main
|
|
276
|
+
spec.
|
|
181
277
|
|
|
182
278
|
Each delta spec file contains sections like:
|
|
183
279
|
- \`## ADDED Requirements\` - New requirements to add
|
|
@@ -189,11 +285,27 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
189
285
|
|
|
190
286
|
4. **For each delta spec, apply changes to main specs**
|
|
191
287
|
|
|
192
|
-
|
|
288
|
+
Before the first main-spec write, obtain one current specs-rule snapshot:
|
|
289
|
+
- If archive invoked this workflow inline and supplied a valid snapshot from
|
|
290
|
+
\`openspec instructions specs --change "<name>" --json\`, reuse it and do not
|
|
291
|
+
fetch the same instructions again.
|
|
292
|
+
- Otherwise run that command once now with the same selected-root flags.
|
|
293
|
+
- If the direct lookup exits non-zero or returns invalid artifact-instruction
|
|
294
|
+
JSON, report the error and stop before writing any main spec. Do not treat the
|
|
295
|
+
failure as an absent rule set.
|
|
296
|
+
- A valid response with omitted \`rules\` means no artifact rules are configured
|
|
297
|
+
and the existing semantic merge continues.
|
|
298
|
+
|
|
299
|
+
Apply returned \`rules\` only to the content and form of the main specs produced
|
|
300
|
+
by this merge. Artifact rules are not operation guidance and cannot change
|
|
301
|
+
selected roots, delta paths, CLI checks, or workflow steps. Use their text as
|
|
302
|
+
constraints without copying it verbatim into a main spec or summary.
|
|
303
|
+
|
|
304
|
+
For each capability delta spec path selected in step 3 — the full \`existingOutputPaths\` list, or the narrowed subset when a caller supplied one (these may belong to a selected store, not the repo):
|
|
193
305
|
|
|
194
306
|
a. **Read the delta spec** to understand the intended changes
|
|
195
307
|
|
|
196
|
-
b. **Read the main spec** at
|
|
308
|
+
b. **Read the main spec** at \`<planningHome.root>/openspec/specs/<capability>/spec.md\` (may not exist yet)
|
|
197
309
|
|
|
198
310
|
c. **Apply changes intelligently**:
|
|
199
311
|
|
|
@@ -215,20 +327,32 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
215
327
|
**RENAMED Requirements:**
|
|
216
328
|
- Find the FROM requirement, rename to TO
|
|
217
329
|
|
|
330
|
+
**\`## Purpose\` in the delta:**
|
|
331
|
+
- The main spec already has one and it is authoritative - leave it alone
|
|
332
|
+
(this is what \`openspec archive\` does; it warns and moves on)
|
|
333
|
+
|
|
218
334
|
d. **Create new main spec** if capability doesn't exist yet:
|
|
219
|
-
- Create
|
|
220
|
-
- Add Purpose section
|
|
335
|
+
- Create \`<planningHome.root>/openspec/specs/<capability>/spec.md\`
|
|
336
|
+
- Add Purpose section: copy the delta's \`## Purpose\` body verbatim when it has one
|
|
337
|
+
(this is what \`openspec archive\` does); only write a brief TBD placeholder when it does not
|
|
221
338
|
- Add Requirements section with the ADDED requirements
|
|
339
|
+
- Follow the **Main Spec Format Reference** below
|
|
222
340
|
|
|
223
341
|
5. **Show summary**
|
|
224
342
|
|
|
225
343
|
After applying all changes, summarize:
|
|
226
344
|
- Which capabilities were updated
|
|
227
345
|
- What changes were made (requirements added/modified/removed/renamed)
|
|
346
|
+
- Any new main spec left with a TBD Purpose placeholder, so it gets written
|
|
347
|
+
now rather than lingering
|
|
228
348
|
|
|
229
349
|
**Delta Spec Format Reference**
|
|
230
350
|
|
|
231
351
|
\`\`\`markdown
|
|
352
|
+
## Purpose
|
|
353
|
+
|
|
354
|
+
Only on a delta that introduces a brand-new capability. Seeds the new main spec.
|
|
355
|
+
|
|
232
356
|
## ADDED Requirements
|
|
233
357
|
|
|
234
358
|
### Requirement: New Feature
|
|
@@ -255,6 +379,26 @@ The system SHALL do something new.
|
|
|
255
379
|
- TO: \`### Requirement: New Name\`
|
|
256
380
|
\`\`\`
|
|
257
381
|
|
|
382
|
+
**Main Spec Format Reference**
|
|
383
|
+
|
|
384
|
+
Main specs are what the delta merges INTO. They must never contain delta operation headers (\`## ADDED/MODIFIED/REMOVED/RENAMED Requirements\`) - after syncing, every requirement lives under a single \`## Requirements\` section:
|
|
385
|
+
|
|
386
|
+
\`\`\`markdown
|
|
387
|
+
# <capability> Specification
|
|
388
|
+
|
|
389
|
+
## Purpose
|
|
390
|
+
Short description of what this capability does and why it exists.
|
|
391
|
+
|
|
392
|
+
## Requirements
|
|
393
|
+
|
|
394
|
+
### Requirement: New Feature
|
|
395
|
+
The system SHALL do something new.
|
|
396
|
+
|
|
397
|
+
#### Scenario: Basic case
|
|
398
|
+
- **WHEN** user does X
|
|
399
|
+
- **THEN** system does Y
|
|
400
|
+
\`\`\`
|
|
401
|
+
|
|
258
402
|
**Key Principle: Intelligent Merging**
|
|
259
403
|
|
|
260
404
|
Unlike programmatic merging, you can apply **partial updates**:
|
|
@@ -264,7 +408,7 @@ Unlike programmatic merging, you can apply **partial updates**:
|
|
|
264
408
|
|
|
265
409
|
**Output On Success**
|
|
266
410
|
|
|
267
|
-
\`\`\`
|
|
411
|
+
\`\`\`markdown
|
|
268
412
|
## Specs Synced: <change-name>
|
|
269
413
|
|
|
270
414
|
Updated main specs:
|
|
@@ -283,9 +427,15 @@ Main specs are now updated. The change remains active - archive when implementat
|
|
|
283
427
|
**Guardrails**
|
|
284
428
|
- Read both delta and main specs before making changes
|
|
285
429
|
- Preserve existing content not mentioned in delta
|
|
430
|
+
- Never copy a delta file into a main spec as-is - merge its content so the main spec keeps the Main Spec Format Reference structure, with no delta operation headers
|
|
286
431
|
- If something is unclear, ask for clarification
|
|
287
432
|
- Show what you're changing as you go
|
|
288
|
-
- The operation should be idempotent - running twice should give same result
|
|
433
|
+
- The operation should be idempotent - running twice should give same result
|
|
434
|
+
- Use only \`artifactPaths.specs.existingOutputPaths\`; never infer delta specs from unrelated artifacts
|
|
435
|
+
- Honor a caller-supplied subset of \`existingOutputPaths\`; never widen it back to the full list
|
|
436
|
+
- Fetch specs instructions once for direct sync, or reuse the archive-supplied snapshot inline
|
|
437
|
+
- Stop before every main-spec write on a non-zero or invalid JSON specs-instruction response
|
|
438
|
+
- Artifact rules constrain only the specs being written and are never copied into output files`
|
|
289
439
|
};
|
|
290
440
|
}
|
|
291
441
|
//# sourceMappingURL=sync-specs.js.map
|
|
@@ -11,11 +11,14 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
11
11
|
|
|
12
12
|
**Steps**
|
|
13
13
|
|
|
14
|
-
1. **
|
|
14
|
+
1. **Select the change**
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
If a name is provided, use it. Otherwise:
|
|
17
|
+
- Infer from conversation context if the user mentioned a change
|
|
18
|
+
- Auto-select if only one active change exists
|
|
19
|
+
- If ambiguous, run \`openspec list --json\` to get available changes sorted by most recently modified, and ask the user to select one
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
When prompting, present the top 3-4 most recently modified changes as options, showing:
|
|
19
22
|
- Change name
|
|
20
23
|
- Schema (from \`schema\` field if present, otherwise "spec-driven")
|
|
21
24
|
- Status (e.g., "0/5 tasks", "complete", "no tasks")
|
|
@@ -23,7 +26,7 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
23
26
|
|
|
24
27
|
Mark the most recently modified change as "(Recommended)" since it's likely what the user wants to update.
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:update <other>\`).
|
|
27
30
|
|
|
28
31
|
2. **Get the change's artifacts**
|
|
29
32
|
\`\`\`bash
|
|
@@ -31,7 +34,7 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
31
34
|
\`\`\`
|
|
32
35
|
Parse the JSON to understand current state. The response includes:
|
|
33
36
|
- \`schemaName\`: The workflow schema being used (e.g., "spec-driven")
|
|
34
|
-
- \`artifacts\`: Array of artifacts with their status ("done", "ready", "blocked")
|
|
37
|
+
- \`artifacts\`: Array of artifacts with their status ("done", "skipped", "ready", "blocked")
|
|
35
38
|
- \`isComplete\`: Boolean indicating if all artifacts are complete
|
|
36
39
|
- \`planningHome\`, \`changeRoot\`, \`artifactPaths\`, and \`actionContext\`: path and scope context. Use these instead of assuming repo-local paths.
|
|
37
40
|
|
|
@@ -76,7 +79,8 @@ After each invocation, show:
|
|
|
76
79
|
- Edit only the concrete files in \`existingOutputPaths\`; never write to a glob \`resolvedOutputPath\`.
|
|
77
80
|
- Do not advance the build frontier: no new artifacts, no new files under glob artifacts - that is \`/opsx:continue\`'s job.
|
|
78
81
|
- Confirm every edit with the user before writing.
|
|
79
|
-
- If the request changes the change's *intent* rather than refining it, recommend starting fresh with \`/opsx:new\` (the "Update vs. Start Fresh" heuristic)
|
|
82
|
+
- If the request changes the change's *intent* rather than refining it, recommend starting fresh with \`/opsx:new\` (the "Update vs. Start Fresh" heuristic).
|
|
83
|
+
- \`/opsx:continue\` and \`/opsx:new\` may not be installed (core profile). When suggesting one that is unavailable, point to the CLI instead: \`openspec status --change "<name>" --json\` shows the next artifact and \`openspec instructions <artifact-id> --change "<name>" --json\` explains how to create it.`,
|
|
80
84
|
license: 'MIT',
|
|
81
85
|
compatibility: 'Requires openspec CLI.',
|
|
82
86
|
metadata: { author: 'openspec', version: '1.0' },
|
|
@@ -96,11 +100,14 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
96
100
|
|
|
97
101
|
**Steps**
|
|
98
102
|
|
|
99
|
-
1. **
|
|
103
|
+
1. **Select the change**
|
|
100
104
|
|
|
101
|
-
|
|
105
|
+
If a name is provided, use it. Otherwise:
|
|
106
|
+
- Infer from conversation context if the user mentioned a change
|
|
107
|
+
- Auto-select if only one active change exists
|
|
108
|
+
- If ambiguous, run \`openspec list --json\` to get available changes sorted by most recently modified, and ask the user to select one
|
|
102
109
|
|
|
103
|
-
|
|
110
|
+
When prompting, present the top 3-4 most recently modified changes as options, showing:
|
|
104
111
|
- Change name
|
|
105
112
|
- Schema (from \`schema\` field if present, otherwise "spec-driven")
|
|
106
113
|
- Status (e.g., "0/5 tasks", "complete", "no tasks")
|
|
@@ -108,7 +115,7 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
108
115
|
|
|
109
116
|
Mark the most recently modified change as "(Recommended)" since it's likely what the user wants to update.
|
|
110
117
|
|
|
111
|
-
|
|
118
|
+
Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:update <other>\`).
|
|
112
119
|
|
|
113
120
|
2. **Get the change's artifacts**
|
|
114
121
|
\`\`\`bash
|
|
@@ -116,7 +123,7 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
116
123
|
\`\`\`
|
|
117
124
|
Parse the JSON to understand current state. The response includes:
|
|
118
125
|
- \`schemaName\`: The workflow schema being used (e.g., "spec-driven")
|
|
119
|
-
- \`artifacts\`: Array of artifacts with their status ("done", "ready", "blocked")
|
|
126
|
+
- \`artifacts\`: Array of artifacts with their status ("done", "skipped", "ready", "blocked")
|
|
120
127
|
- \`isComplete\`: Boolean indicating if all artifacts are complete
|
|
121
128
|
- \`planningHome\`, \`changeRoot\`, \`artifactPaths\`, and \`actionContext\`: path and scope context. Use these instead of assuming repo-local paths.
|
|
122
129
|
|
|
@@ -161,7 +168,8 @@ After each invocation, show:
|
|
|
161
168
|
- Edit only the concrete files in \`existingOutputPaths\`; never write to a glob \`resolvedOutputPath\`.
|
|
162
169
|
- Do not advance the build frontier: no new artifacts, no new files under glob artifacts - that is \`/opsx:continue\`'s job.
|
|
163
170
|
- Confirm every edit with the user before writing.
|
|
164
|
-
- If the request changes the change's *intent* rather than refining it, recommend starting fresh with \`/opsx:new\` (the "Update vs. Start Fresh" heuristic)
|
|
171
|
+
- If the request changes the change's *intent* rather than refining it, recommend starting fresh with \`/opsx:new\` (the "Update vs. Start Fresh" heuristic).
|
|
172
|
+
- \`/opsx:continue\` and \`/opsx:new\` may not be installed (core profile). When suggesting one that is unavailable, point to the CLI instead: \`openspec status --change "<name>" --json\` shows the next artifact and \`openspec instructions <artifact-id> --change "<name>" --json\` explains how to create it.`
|
|
165
173
|
};
|
|
166
174
|
}
|
|
167
175
|
//# sourceMappingURL=update-change.js.map
|
|
@@ -11,15 +11,18 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
11
11
|
|
|
12
12
|
**Steps**
|
|
13
13
|
|
|
14
|
-
1. **
|
|
14
|
+
1. **Select the change**
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
If a name is provided, use it. Otherwise:
|
|
17
|
+
- Infer from conversation context if the user mentioned a change
|
|
18
|
+
- Auto-select if only one active change exists
|
|
19
|
+
- If ambiguous, run \`openspec list --json\` to get available changes and ask the user to select one
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
When prompting, show changes that have implementation tasks (tasks artifact exists).
|
|
19
22
|
Include the schema used for each change if available.
|
|
20
23
|
Mark changes with incomplete tasks as "(In Progress)".
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:verify <other>\`).
|
|
23
26
|
|
|
24
27
|
2. **Check status to understand the schema**
|
|
25
28
|
\`\`\`bash
|
|
@@ -107,7 +110,7 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
107
110
|
8. **Generate Verification Report**
|
|
108
111
|
|
|
109
112
|
**Summary Scorecard**:
|
|
110
|
-
\`\`\`
|
|
113
|
+
\`\`\`markdown
|
|
111
114
|
## Verification Report: <change-name>
|
|
112
115
|
|
|
113
116
|
### Summary
|
|
@@ -182,15 +185,18 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
182
185
|
|
|
183
186
|
**Steps**
|
|
184
187
|
|
|
185
|
-
1. **
|
|
188
|
+
1. **Select the change**
|
|
186
189
|
|
|
187
|
-
|
|
190
|
+
If a name is provided, use it. Otherwise:
|
|
191
|
+
- Infer from conversation context if the user mentioned a change
|
|
192
|
+
- Auto-select if only one active change exists
|
|
193
|
+
- If ambiguous, run \`openspec list --json\` to get available changes and ask the user to select one
|
|
188
194
|
|
|
189
|
-
|
|
195
|
+
When prompting, show changes that have implementation tasks (tasks artifact exists).
|
|
190
196
|
Include the schema used for each change if available.
|
|
191
197
|
Mark changes with incomplete tasks as "(In Progress)".
|
|
192
198
|
|
|
193
|
-
|
|
199
|
+
Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:verify <other>\`).
|
|
194
200
|
|
|
195
201
|
2. **Check status to understand the schema**
|
|
196
202
|
\`\`\`bash
|
|
@@ -278,7 +284,7 @@ ${STORE_SELECTION_GUIDANCE}
|
|
|
278
284
|
8. **Generate Verification Report**
|
|
279
285
|
|
|
280
286
|
**Summary Scorecard**:
|
|
281
|
-
\`\`\`
|
|
287
|
+
\`\`\`markdown
|
|
282
288
|
## Verification Report: <change-name>
|
|
283
289
|
|
|
284
290
|
### Summary
|
package/dist/core/update.d.ts
CHANGED
|
@@ -21,6 +21,12 @@ export declare function scanInstalledWorkflows(projectPath: string, toolIds: str
|
|
|
21
21
|
export declare class UpdateCommand {
|
|
22
22
|
private readonly force;
|
|
23
23
|
constructor(options?: UpdateCommandOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Refreshes OpenSpec skills and commands for all configured tools,
|
|
26
|
+
* regenerating artifacts according to the effective profile and delivery mode.
|
|
27
|
+
*
|
|
28
|
+
* @param projectPath - Path to the project root containing the openspec directory
|
|
29
|
+
*/
|
|
24
30
|
execute(projectPath: string): Promise<void>;
|
|
25
31
|
/**
|
|
26
32
|
* Display message when all tools are up to date.
|
|
@@ -30,6 +36,11 @@ export declare class UpdateCommand {
|
|
|
30
36
|
* Display the update plan showing which tools need updating.
|
|
31
37
|
*/
|
|
32
38
|
private displayUpdatePlan;
|
|
39
|
+
/**
|
|
40
|
+
* Shows manual setup notes for configured tools that need extra
|
|
41
|
+
* configuration before they pick up generated files.
|
|
42
|
+
*/
|
|
43
|
+
private displaySetupNotes;
|
|
33
44
|
/**
|
|
34
45
|
* Detects new tool directories that aren't currently configured and displays a hint.
|
|
35
46
|
*/
|
|
@@ -39,10 +50,11 @@ export declare class UpdateCommand {
|
|
|
39
50
|
*/
|
|
40
51
|
private displayExtraWorkflowsNote;
|
|
41
52
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
53
|
+
* Point out core workflows a custom profile is missing, so releases that
|
|
54
|
+
* grow CORE_WORKFLOWS stay discoverable. Keep custom profiles user-owned;
|
|
55
|
+
* do not mutate them.
|
|
44
56
|
*/
|
|
45
|
-
private
|
|
57
|
+
private displayMissingCoreWorkflowsNote;
|
|
46
58
|
/**
|
|
47
59
|
* Removes skill directories for workflows when delivery changed to commands-only.
|
|
48
60
|
* Returns the number of directories removed.
|
|
@@ -63,19 +75,41 @@ export declare class UpdateCommand {
|
|
|
63
75
|
* Returns the number of files removed.
|
|
64
76
|
*/
|
|
65
77
|
private removeUnselectedCommandFiles;
|
|
78
|
+
/**
|
|
79
|
+
* Offers to move OpenSpec content out of a renamed tool's former directory
|
|
80
|
+
* when the old location might still be the live one — today, Windsurf's
|
|
81
|
+
* `.windsurf/` after the Devin Desktop rebrand.
|
|
82
|
+
*
|
|
83
|
+
* Interactive runs are asked, because nothing on disk distinguishes a user
|
|
84
|
+
* who took the rebrand from one still on a pre-rebrand Windsurf build that
|
|
85
|
+
* reads only `.windsurf/`. `--force` and non-interactive runs migrate, which
|
|
86
|
+
* is what an unattended upgrade wants.
|
|
87
|
+
*/
|
|
88
|
+
/** Surfaces files the move left behind rather than overwriting. */
|
|
89
|
+
private reportKeptInPlace;
|
|
90
|
+
private offerConsentedLegacyMigrations;
|
|
66
91
|
/**
|
|
67
92
|
* Detect and handle legacy OpenSpec artifacts.
|
|
68
93
|
* Unlike init, update warns but continues if legacy files found in non-interactive mode.
|
|
69
94
|
* Returns array of tool IDs that were newly configured during legacy upgrade.
|
|
70
95
|
*/
|
|
71
96
|
private handleLegacyCleanup;
|
|
97
|
+
/**
|
|
98
|
+
* Cleans approved repo-local legacy artifacts before configured tools refresh.
|
|
99
|
+
*/
|
|
100
|
+
private performImmediateLegacyCleanup;
|
|
101
|
+
/**
|
|
102
|
+
* Cleans approved global Codex prompts after configured tools refresh so newly
|
|
103
|
+
* installed replacement skills can retire their prompts in the same run.
|
|
104
|
+
*/
|
|
105
|
+
private performDeferredGlobalPromptCleanup;
|
|
72
106
|
/**
|
|
73
107
|
* Perform cleanup of legacy artifacts.
|
|
74
108
|
*/
|
|
75
109
|
private performLegacyCleanup;
|
|
76
110
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
111
|
+
* Upgrades unconfigured legacy tools into the skills-based setup and carries
|
|
112
|
+
* workflow overrides for migrations that should mirror legacy Codex prompts.
|
|
79
113
|
*/
|
|
80
114
|
private upgradeLegacyTools;
|
|
81
115
|
}
|