@fission-ai/openspec 0.18.0 → 0.19.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 (44) hide show
  1. package/README.md +52 -0
  2. package/dist/cli/index.js +32 -2
  3. package/dist/commands/artifact-workflow.js +6 -1
  4. package/dist/commands/completion.js +42 -6
  5. package/dist/core/completions/command-registry.js +7 -1
  6. package/dist/core/completions/factory.d.ts +15 -2
  7. package/dist/core/completions/factory.js +19 -1
  8. package/dist/core/completions/generators/bash-generator.d.ts +32 -0
  9. package/dist/core/completions/generators/bash-generator.js +174 -0
  10. package/dist/core/completions/generators/fish-generator.d.ts +32 -0
  11. package/dist/core/completions/generators/fish-generator.js +157 -0
  12. package/dist/core/completions/generators/powershell-generator.d.ts +32 -0
  13. package/dist/core/completions/generators/powershell-generator.js +198 -0
  14. package/dist/core/completions/generators/zsh-generator.d.ts +0 -14
  15. package/dist/core/completions/generators/zsh-generator.js +55 -124
  16. package/dist/core/completions/installers/bash-installer.d.ts +87 -0
  17. package/dist/core/completions/installers/bash-installer.js +318 -0
  18. package/dist/core/completions/installers/fish-installer.d.ts +43 -0
  19. package/dist/core/completions/installers/fish-installer.js +143 -0
  20. package/dist/core/completions/installers/powershell-installer.d.ts +88 -0
  21. package/dist/core/completions/installers/powershell-installer.js +327 -0
  22. package/dist/core/completions/installers/zsh-installer.d.ts +1 -12
  23. package/dist/core/completions/templates/bash-templates.d.ts +6 -0
  24. package/dist/core/completions/templates/bash-templates.js +24 -0
  25. package/dist/core/completions/templates/fish-templates.d.ts +7 -0
  26. package/dist/core/completions/templates/fish-templates.js +39 -0
  27. package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
  28. package/dist/core/completions/templates/powershell-templates.js +25 -0
  29. package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
  30. package/dist/core/completions/templates/zsh-templates.js +36 -0
  31. package/dist/core/config.js +1 -0
  32. package/dist/core/configurators/slash/codebuddy.js +6 -9
  33. package/dist/core/configurators/slash/continue.d.ts +9 -0
  34. package/dist/core/configurators/slash/continue.js +46 -0
  35. package/dist/core/configurators/slash/registry.js +3 -0
  36. package/dist/core/templates/skill-templates.d.ts +10 -0
  37. package/dist/core/templates/skill-templates.js +482 -20
  38. package/dist/telemetry/config.d.ts +32 -0
  39. package/dist/telemetry/config.js +68 -0
  40. package/dist/telemetry/index.d.ts +31 -0
  41. package/dist/telemetry/index.js +145 -0
  42. package/dist/utils/file-system.d.ts +6 -0
  43. package/dist/utils/file-system.js +43 -2
  44. package/package.json +2 -1
@@ -7,6 +7,291 @@
7
7
  * - Windsurf
8
8
  * - Other Agent Skills-compatible editors
9
9
  */
10
+ /**
11
+ * Template for openspec-explore skill
12
+ * Explore mode - adaptive thinking partner for exploring ideas and problems
13
+ */
14
+ export function getExploreSkillTemplate() {
15
+ return {
16
+ name: 'openspec-explore',
17
+ description: 'Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Use when the user wants to think through something before or during a change.',
18
+ instructions: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
19
+
20
+ **This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
21
+
22
+ ---
23
+
24
+ ## The Stance
25
+
26
+ - **Curious, not prescriptive** - Ask questions that emerge naturally, don't follow a script
27
+ - **Visual** - Use ASCII diagrams liberally when they'd help clarify thinking
28
+ - **Adaptive** - Follow interesting threads, pivot when new information emerges
29
+ - **Patient** - Don't rush to conclusions, let the shape of the problem emerge
30
+ - **Grounded** - Explore the actual codebase when relevant, don't just theorize
31
+
32
+ ---
33
+
34
+ ## What You Might Do
35
+
36
+ Depending on what the user brings, you might:
37
+
38
+ **Explore the problem space**
39
+ - Ask clarifying questions that emerge from what they said
40
+ - Challenge assumptions
41
+ - Reframe the problem
42
+ - Find analogies
43
+
44
+ **Investigate the codebase**
45
+ - Map existing architecture relevant to the discussion
46
+ - Find integration points
47
+ - Identify patterns already in use
48
+ - Surface hidden complexity
49
+
50
+ **Compare options**
51
+ - Brainstorm multiple approaches
52
+ - Build comparison tables
53
+ - Sketch tradeoffs
54
+ - Recommend a path (if asked)
55
+
56
+ **Visualize**
57
+ \`\`\`
58
+ ┌─────────────────────────────────────────┐
59
+ │ Use ASCII diagrams liberally │
60
+ ├─────────────────────────────────────────┤
61
+ │ │
62
+ │ ┌────────┐ ┌────────┐ │
63
+ │ │ State │────────▶│ State │ │
64
+ │ │ A │ │ B │ │
65
+ │ └────────┘ └────────┘ │
66
+ │ │
67
+ │ System diagrams, state machines, │
68
+ │ data flows, architecture sketches, │
69
+ │ dependency graphs, comparison tables │
70
+ │ │
71
+ └─────────────────────────────────────────┘
72
+ \`\`\`
73
+
74
+ **Surface risks and unknowns**
75
+ - Identify what could go wrong
76
+ - Find gaps in understanding
77
+ - Suggest spikes or investigations
78
+
79
+ ---
80
+
81
+ ## OpenSpec Awareness
82
+
83
+ You have full context of the OpenSpec system. Use it naturally, don't force it.
84
+
85
+ ### Check for context
86
+
87
+ At the start, quickly check what exists:
88
+ \`\`\`bash
89
+ openspec list --json
90
+ \`\`\`
91
+
92
+ This tells you:
93
+ - If there are active changes
94
+ - Their names, schemas, and status
95
+ - What the user might be working on
96
+
97
+ ### When no change exists
98
+
99
+ Think freely. When insights crystallize, you might offer:
100
+
101
+ - "This feels solid enough to start a change. Want me to create one?"
102
+ → Can transition to \`/opsx:new\` or \`/opsx:ff\`
103
+ - Or keep exploring - no pressure to formalize
104
+
105
+ ### When a change exists
106
+
107
+ If the user mentions a change or you detect one is relevant:
108
+
109
+ 1. **Read existing artifacts for context**
110
+ - \`openspec/changes/<name>/proposal.md\`
111
+ - \`openspec/changes/<name>/design.md\`
112
+ - \`openspec/changes/<name>/tasks.md\`
113
+ - etc.
114
+
115
+ 2. **Reference them naturally in conversation**
116
+ - "Your design mentions using Redis, but we just realized SQLite fits better..."
117
+ - "The proposal scopes this to premium users, but we're now thinking everyone..."
118
+
119
+ 3. **Offer to capture when decisions are made**
120
+
121
+ | Insight Type | Where to Capture |
122
+ |--------------|------------------|
123
+ | New requirement discovered | \`specs/<capability>/spec.md\` |
124
+ | Requirement changed | \`specs/<capability>/spec.md\` |
125
+ | Design decision made | \`design.md\` |
126
+ | Scope changed | \`proposal.md\` |
127
+ | New work identified | \`tasks.md\` |
128
+ | Assumption invalidated | Relevant artifact |
129
+
130
+ Example offers:
131
+ - "That's a design decision. Capture it in design.md?"
132
+ - "This is a new requirement. Add it to specs?"
133
+ - "This changes scope. Update the proposal?"
134
+
135
+ 4. **The user decides** - Offer and move on. Don't pressure. Don't auto-capture.
136
+
137
+ ---
138
+
139
+ ## What You Don't Have To Do
140
+
141
+ - Follow a script
142
+ - Ask the same questions every time
143
+ - Produce a specific artifact
144
+ - Reach a conclusion
145
+ - Stay on topic if a tangent is valuable
146
+ - Be brief (this is thinking time)
147
+
148
+ ---
149
+
150
+ ## Handling Different Entry Points
151
+
152
+ **User brings a vague idea:**
153
+ \`\`\`
154
+ User: I'm thinking about adding real-time collaboration
155
+
156
+ You: Real-time collab is a big space. Let me think about this...
157
+
158
+ COLLABORATION SPECTRUM
159
+ ════════════════════════════════════════════
160
+
161
+ Awareness Coordination Sync
162
+ │ │ │
163
+ ▼ ▼ ▼
164
+ ┌────────┐ ┌────────┐ ┌────────┐
165
+ │Presence│ │Cursors │ │ CRDT │
166
+ │ "3 │ │ Multi │ │Conflict│
167
+ │online" │ │ select │ │ free │
168
+ └────────┘ └────────┘ └────────┘
169
+ │ │ │
170
+ trivial moderate complex
171
+
172
+ Where's your head at?
173
+ \`\`\`
174
+
175
+ **User brings a specific problem:**
176
+ \`\`\`
177
+ User: The auth system is a mess
178
+
179
+ You: [reads codebase]
180
+
181
+ ┌─────────────────────────────────────────────┐
182
+ │ CURRENT AUTH FLOW │
183
+ └─────────────────────────────────────────────┘
184
+
185
+ ┌─────────────┼─────────────┐
186
+ ▼ ▼ ▼
187
+ ┌─────────┐ ┌─────────┐ ┌─────────┐
188
+ │ Google │ │ GitHub │ │ Email │
189
+ │ OAuth │ │ OAuth │ │ Magic │
190
+ └────┬────┘ └────┬────┘ └────┬────┘
191
+ │ │ │
192
+ └─────────────┼─────────────┘
193
+
194
+ ┌───────────┐
195
+ │ Session │
196
+ └─────┬─────┘
197
+
198
+
199
+ ┌───────────┐
200
+ │ Perms │
201
+ └───────────┘
202
+
203
+ I see three tangles. Which one's burning?
204
+ \`\`\`
205
+
206
+ **User is stuck mid-implementation:**
207
+ \`\`\`
208
+ User: /opsx:explore add-auth-system
209
+ The OAuth integration is more complex than expected
210
+
211
+ You: [reads change artifacts]
212
+
213
+ You're on task 4: "Implement OAuth flow"
214
+
215
+ Let me trace what's involved...
216
+
217
+ [draws diagram, explores options, suggests paths]
218
+
219
+ Want to update the design to reflect this?
220
+ Or add a spike task to investigate?
221
+ \`\`\`
222
+
223
+ **User wants to compare options:**
224
+ \`\`\`
225
+ User: Should we use Postgres or SQLite?
226
+
227
+ You: Generic answer is boring. What's the context?
228
+
229
+ User: A CLI tool that tracks local dev environments
230
+
231
+ You: That changes everything.
232
+
233
+ ┌─────────────────────────────────────────────────┐
234
+ │ CLI TOOL DATA STORAGE │
235
+ └─────────────────────────────────────────────────┘
236
+
237
+ Key constraints:
238
+ • No daemon running
239
+ • Must work offline
240
+ • Single user
241
+
242
+ SQLite Postgres
243
+ Deployment embedded ✓ needs server ✗
244
+ Offline yes ✓ no ✗
245
+ Single file yes ✓ no ✗
246
+
247
+ SQLite. Not even close.
248
+
249
+ Unless... is there a sync component?
250
+ \`\`\`
251
+
252
+ ---
253
+
254
+ ## Ending Discovery
255
+
256
+ There's no required ending. Discovery might:
257
+
258
+ - **Flow into action**: "Ready to start? /opsx:new or /opsx:ff"
259
+ - **Result in artifact updates**: "Updated design.md with these decisions"
260
+ - **Just provide clarity**: User has what they need, moves on
261
+ - **Continue later**: "We can pick this up anytime"
262
+
263
+ When it feels like things are crystallizing, you might summarize:
264
+
265
+ \`\`\`
266
+ ## What We Figured Out
267
+
268
+ **The problem**: [crystallized understanding]
269
+
270
+ **The approach**: [if one emerged]
271
+
272
+ **Open questions**: [if any remain]
273
+
274
+ **Next steps** (if ready):
275
+ - Create a change: /opsx:new <name>
276
+ - Fast-forward to tasks: /opsx:ff <name>
277
+ - Keep exploring: just keep talking
278
+ \`\`\`
279
+
280
+ But this summary is optional. Sometimes the thinking IS the value.
281
+
282
+ ---
283
+
284
+ ## Guardrails
285
+
286
+ - **Don't fake understanding** - If something is unclear, dig deeper
287
+ - **Don't rush** - Discovery is thinking time, not task time
288
+ - **Don't force structure** - Let patterns emerge naturally
289
+ - **Don't auto-capture** - Offer to save insights, don't just do it
290
+ - **Do visualize** - A good diagram is worth many paragraphs
291
+ - **Do explore the codebase** - Ground discussions in reality
292
+ - **Do question assumptions** - Including the user's and your own`
293
+ };
294
+ }
10
295
  /**
11
296
  * Template for openspec-new-change skill
12
297
  * Based on /opsx:new command
@@ -30,21 +315,22 @@ export function getNewChangeSkillTemplate() {
30
315
 
31
316
  **IMPORTANT**: Do NOT proceed without understanding what the user wants to build.
32
317
 
33
- 2. **Select a workflow schema**
318
+ 2. **Determine the workflow schema**
34
319
 
35
- Run \`openspec schemas --json\` to get available schemas with descriptions.
320
+ Use the default schema (omit \`--schema\`) unless the user explicitly requests a different workflow.
36
321
 
37
- Use the **AskUserQuestion tool** to let the user choose a workflow:
38
- - Present each schema with its description
39
- - Mark \`spec-driven\` as "(default)" if it's available
40
- - Example options: "spec-driven - proposal specs design tasks (default)", "tdd - tests → implementation → docs"
322
+ **Use a different schema only if the user mentions:**
323
+ - "tdd" or "test-driven" use \`--schema tdd\`
324
+ - A specific schema name use \`--schema <name>\`
325
+ - "show workflows" or "what workflows"run \`openspec schemas --json\` and let them choose
41
326
 
42
- If user doesn't have a preference, default to \`spec-driven\`.
327
+ **Otherwise**: Omit \`--schema\` to use the default.
43
328
 
44
329
  3. **Create the change directory**
45
330
  \`\`\`bash
46
- openspec new change "<name>" --schema "<selected-schema>"
331
+ openspec new change "<name>"
47
332
  \`\`\`
333
+ Add \`--schema <name>\` only if the user requested a specific workflow.
48
334
  This creates a scaffolded change at \`openspec/changes/<name>/\` with the selected schema.
49
335
 
50
336
  4. **Show the artifact status**
@@ -67,7 +353,7 @@ export function getNewChangeSkillTemplate() {
67
353
 
68
354
  After completing the steps, summarize:
69
355
  - Change name and location
70
- - Selected schema/workflow and its artifact sequence
356
+ - Schema/workflow being used and its artifact sequence
71
357
  - Current status (0/N artifacts complete)
72
358
  - The template for the first artifact
73
359
  - Prompt: "Ready to create the first artifact? Just describe what this change is about and I'll draft it, or ask me to continue."
@@ -77,7 +363,7 @@ After completing the steps, summarize:
77
363
  - Do NOT advance beyond showing the first artifact template
78
364
  - If the name is invalid (not kebab-case), ask for a valid name
79
365
  - If a change with that name already exists, suggest continuing that change instead
80
- - Always pass --schema to preserve the user's workflow choice`
366
+ - Pass --schema if using a non-default workflow`
81
367
  };
82
368
  }
83
369
  /**
@@ -581,6 +867,181 @@ Main specs are now updated. The change remains active - archive when implementat
581
867
  - The operation should be idempotent - running twice should give same result`
582
868
  };
583
869
  }
870
+ /**
871
+ * Template for /opsx:explore slash command
872
+ * Explore mode - adaptive thinking partner
873
+ */
874
+ export function getOpsxExploreCommandTemplate() {
875
+ return {
876
+ name: 'OPSX: Explore',
877
+ description: 'Enter explore mode - think through ideas, investigate problems, clarify requirements',
878
+ category: 'Workflow',
879
+ tags: ['workflow', 'explore', 'experimental', 'thinking'],
880
+ content: `Enter explore mode. Think deeply. Visualize freely. Follow the conversation wherever it goes.
881
+
882
+ **This is a stance, not a workflow.** There are no fixed steps, no required sequence, no mandatory outputs. You're a thinking partner helping the user explore.
883
+
884
+ **Input**: The argument after \`/opsx:explore\` is whatever the user wants to think about. Could be:
885
+ - A vague idea: "real-time collaboration"
886
+ - A specific problem: "the auth system is getting unwieldy"
887
+ - A change name: "add-dark-mode" (to explore in context of that change)
888
+ - A comparison: "postgres vs sqlite for this"
889
+ - Nothing (just enter explore mode)
890
+
891
+ ---
892
+
893
+ ## The Stance
894
+
895
+ - **Curious, not prescriptive** - Ask questions that emerge naturally, don't follow a script
896
+ - **Visual** - Use ASCII diagrams liberally when they'd help clarify thinking
897
+ - **Adaptive** - Follow interesting threads, pivot when new information emerges
898
+ - **Patient** - Don't rush to conclusions, let the shape of the problem emerge
899
+ - **Grounded** - Explore the actual codebase when relevant, don't just theorize
900
+
901
+ ---
902
+
903
+ ## What You Might Do
904
+
905
+ Depending on what the user brings, you might:
906
+
907
+ **Explore the problem space**
908
+ - Ask clarifying questions that emerge from what they said
909
+ - Challenge assumptions
910
+ - Reframe the problem
911
+ - Find analogies
912
+
913
+ **Investigate the codebase**
914
+ - Map existing architecture relevant to the discussion
915
+ - Find integration points
916
+ - Identify patterns already in use
917
+ - Surface hidden complexity
918
+
919
+ **Compare options**
920
+ - Brainstorm multiple approaches
921
+ - Build comparison tables
922
+ - Sketch tradeoffs
923
+ - Recommend a path (if asked)
924
+
925
+ **Visualize**
926
+ \`\`\`
927
+ ┌─────────────────────────────────────────┐
928
+ │ Use ASCII diagrams liberally │
929
+ ├─────────────────────────────────────────┤
930
+ │ │
931
+ │ ┌────────┐ ┌────────┐ │
932
+ │ │ State │────────▶│ State │ │
933
+ │ │ A │ │ B │ │
934
+ │ └────────┘ └────────┘ │
935
+ │ │
936
+ │ System diagrams, state machines, │
937
+ │ data flows, architecture sketches, │
938
+ │ dependency graphs, comparison tables │
939
+ │ │
940
+ └─────────────────────────────────────────┘
941
+ \`\`\`
942
+
943
+ **Surface risks and unknowns**
944
+ - Identify what could go wrong
945
+ - Find gaps in understanding
946
+ - Suggest spikes or investigations
947
+
948
+ ---
949
+
950
+ ## OpenSpec Awareness
951
+
952
+ You have full context of the OpenSpec system. Use it naturally, don't force it.
953
+
954
+ ### Check for context
955
+
956
+ At the start, quickly check what exists:
957
+ \`\`\`bash
958
+ openspec list --json
959
+ \`\`\`
960
+
961
+ This tells you:
962
+ - If there are active changes
963
+ - Their names, schemas, and status
964
+ - What the user might be working on
965
+
966
+ If the user mentioned a specific change name, read its artifacts for context.
967
+
968
+ ### When no change exists
969
+
970
+ Think freely. When insights crystallize, you might offer:
971
+
972
+ - "This feels solid enough to start a change. Want me to create one?"
973
+ → Can transition to \`/opsx:new\` or \`/opsx:ff\`
974
+ - Or keep exploring - no pressure to formalize
975
+
976
+ ### When a change exists
977
+
978
+ If the user mentions a change or you detect one is relevant:
979
+
980
+ 1. **Read existing artifacts for context**
981
+ - \`openspec/changes/<name>/proposal.md\`
982
+ - \`openspec/changes/<name>/design.md\`
983
+ - \`openspec/changes/<name>/tasks.md\`
984
+ - etc.
985
+
986
+ 2. **Reference them naturally in conversation**
987
+ - "Your design mentions using Redis, but we just realized SQLite fits better..."
988
+ - "The proposal scopes this to premium users, but we're now thinking everyone..."
989
+
990
+ 3. **Offer to capture when decisions are made**
991
+
992
+ | Insight Type | Where to Capture |
993
+ |--------------|------------------|
994
+ | New requirement discovered | \`specs/<capability>/spec.md\` |
995
+ | Requirement changed | \`specs/<capability>/spec.md\` |
996
+ | Design decision made | \`design.md\` |
997
+ | Scope changed | \`proposal.md\` |
998
+ | New work identified | \`tasks.md\` |
999
+ | Assumption invalidated | Relevant artifact |
1000
+
1001
+ Example offers:
1002
+ - "That's a design decision. Capture it in design.md?"
1003
+ - "This is a new requirement. Add it to specs?"
1004
+ - "This changes scope. Update the proposal?"
1005
+
1006
+ 4. **The user decides** - Offer and move on. Don't pressure. Don't auto-capture.
1007
+
1008
+ ---
1009
+
1010
+ ## What You Don't Have To Do
1011
+
1012
+ - Follow a script
1013
+ - Ask the same questions every time
1014
+ - Produce a specific artifact
1015
+ - Reach a conclusion
1016
+ - Stay on topic if a tangent is valuable
1017
+ - Be brief (this is thinking time)
1018
+
1019
+ ---
1020
+
1021
+ ## Ending Discovery
1022
+
1023
+ There's no required ending. Discovery might:
1024
+
1025
+ - **Flow into action**: "Ready to start? \`/opsx:new\` or \`/opsx:ff\`"
1026
+ - **Result in artifact updates**: "Updated design.md with these decisions"
1027
+ - **Just provide clarity**: User has what they need, moves on
1028
+ - **Continue later**: "We can pick this up anytime"
1029
+
1030
+ When things crystallize, you might offer a summary - but it's optional. Sometimes the thinking IS the value.
1031
+
1032
+ ---
1033
+
1034
+ ## Guardrails
1035
+
1036
+ - **Don't fake understanding** - If something is unclear, dig deeper
1037
+ - **Don't rush** - Discovery is thinking time, not task time
1038
+ - **Don't force structure** - Let patterns emerge naturally
1039
+ - **Don't auto-capture** - Offer to save insights, don't just do it
1040
+ - **Do visualize** - A good diagram is worth many paragraphs
1041
+ - **Do explore the codebase** - Ground discussions in reality
1042
+ - **Do question assumptions** - Including the user's and your own`
1043
+ };
1044
+ }
584
1045
  /**
585
1046
  * Template for /opsx:new slash command
586
1047
  */
@@ -605,21 +1066,22 @@ export function getOpsxNewCommandTemplate() {
605
1066
 
606
1067
  **IMPORTANT**: Do NOT proceed without understanding what the user wants to build.
607
1068
 
608
- 2. **Select a workflow schema**
1069
+ 2. **Determine the workflow schema**
609
1070
 
610
- Run \`openspec schemas --json\` to get available schemas with descriptions.
1071
+ Use the default schema (omit \`--schema\`) unless the user explicitly requests a different workflow.
611
1072
 
612
- Use the **AskUserQuestion tool** to let the user choose a workflow:
613
- - Present each schema with its description
614
- - Mark \`spec-driven\` as "(default)" if it's available
615
- - Example options: "spec-driven - proposal specs design tasks (default)", "tdd - tests → implementation → docs"
1073
+ **Use a different schema only if the user mentions:**
1074
+ - "tdd" or "test-driven" use \`--schema tdd\`
1075
+ - A specific schema name use \`--schema <name>\`
1076
+ - "show workflows" or "what workflows"run \`openspec schemas --json\` and let them choose
616
1077
 
617
- If user doesn't have a preference, default to \`spec-driven\`.
1078
+ **Otherwise**: Omit \`--schema\` to use the default.
618
1079
 
619
1080
  3. **Create the change directory**
620
1081
  \`\`\`bash
621
- openspec new change "<name>" --schema "<selected-schema>"
1082
+ openspec new change "<name>"
622
1083
  \`\`\`
1084
+ Add \`--schema <name>\` only if the user requested a specific workflow.
623
1085
  This creates a scaffolded change at \`openspec/changes/<name>/\` with the selected schema.
624
1086
 
625
1087
  4. **Show the artifact status**
@@ -641,7 +1103,7 @@ export function getOpsxNewCommandTemplate() {
641
1103
 
642
1104
  After completing the steps, summarize:
643
1105
  - Change name and location
644
- - Selected schema/workflow and its artifact sequence
1106
+ - Schema/workflow being used and its artifact sequence
645
1107
  - Current status (0/N artifacts complete)
646
1108
  - The template for the first artifact
647
1109
  - Prompt: "Ready to create the first artifact? Run \`/opsx:continue\` or just describe what this change is about and I'll draft it."
@@ -651,7 +1113,7 @@ After completing the steps, summarize:
651
1113
  - Do NOT advance beyond showing the first artifact template
652
1114
  - If the name is invalid (not kebab-case), ask for a valid name
653
1115
  - If a change with that name already exists, suggest using \`/opsx:continue\` instead
654
- - Always pass --schema to preserve the user's workflow choice`
1116
+ - Pass --schema if using a non-default workflow`
655
1117
  };
656
1118
  }
657
1119
  /**
@@ -0,0 +1,32 @@
1
+ export interface TelemetryConfig {
2
+ anonymousId?: string;
3
+ noticeSeen?: boolean;
4
+ }
5
+ export interface GlobalConfig {
6
+ telemetry?: TelemetryConfig;
7
+ [key: string]: unknown;
8
+ }
9
+ /**
10
+ * Get the path to the global config file.
11
+ * Uses ~/.config/openspec/config.json on all platforms.
12
+ */
13
+ export declare function getConfigPath(): string;
14
+ /**
15
+ * Read the global config file.
16
+ * Returns an empty object if the file doesn't exist.
17
+ */
18
+ export declare function readConfig(): Promise<GlobalConfig>;
19
+ /**
20
+ * Write to the global config file.
21
+ * Preserves existing fields and merges in new values.
22
+ */
23
+ export declare function writeConfig(updates: Partial<GlobalConfig>): Promise<void>;
24
+ /**
25
+ * Get the telemetry config section.
26
+ */
27
+ export declare function getTelemetryConfig(): Promise<TelemetryConfig>;
28
+ /**
29
+ * Update the telemetry config section.
30
+ */
31
+ export declare function updateTelemetryConfig(updates: Partial<TelemetryConfig>): Promise<void>;
32
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Global configuration for telemetry state.
3
+ * Stores anonymous ID and notice-seen flag in ~/.config/openspec/config.json
4
+ */
5
+ import { promises as fs } from 'fs';
6
+ import path from 'path';
7
+ import os from 'os';
8
+ /**
9
+ * Get the path to the global config file.
10
+ * Uses ~/.config/openspec/config.json on all platforms.
11
+ */
12
+ export function getConfigPath() {
13
+ const configDir = path.join(os.homedir(), '.config', 'openspec');
14
+ return path.join(configDir, 'config.json');
15
+ }
16
+ /**
17
+ * Read the global config file.
18
+ * Returns an empty object if the file doesn't exist.
19
+ */
20
+ export async function readConfig() {
21
+ const configPath = getConfigPath();
22
+ try {
23
+ const content = await fs.readFile(configPath, 'utf-8');
24
+ return JSON.parse(content);
25
+ }
26
+ catch (error) {
27
+ if (error.code === 'ENOENT') {
28
+ return {};
29
+ }
30
+ // If parse fails or other error, return empty config
31
+ return {};
32
+ }
33
+ }
34
+ /**
35
+ * Write to the global config file.
36
+ * Preserves existing fields and merges in new values.
37
+ */
38
+ export async function writeConfig(updates) {
39
+ const configPath = getConfigPath();
40
+ const configDir = path.dirname(configPath);
41
+ // Ensure directory exists
42
+ await fs.mkdir(configDir, { recursive: true });
43
+ // Read existing config and merge
44
+ const existing = await readConfig();
45
+ const merged = { ...existing, ...updates };
46
+ // Deep merge for telemetry object
47
+ if (updates.telemetry && existing.telemetry) {
48
+ merged.telemetry = { ...existing.telemetry, ...updates.telemetry };
49
+ }
50
+ await fs.writeFile(configPath, JSON.stringify(merged, null, 2) + '\n');
51
+ }
52
+ /**
53
+ * Get the telemetry config section.
54
+ */
55
+ export async function getTelemetryConfig() {
56
+ const config = await readConfig();
57
+ return config.telemetry ?? {};
58
+ }
59
+ /**
60
+ * Update the telemetry config section.
61
+ */
62
+ export async function updateTelemetryConfig(updates) {
63
+ const existing = await getTelemetryConfig();
64
+ await writeConfig({
65
+ telemetry: { ...existing, ...updates },
66
+ });
67
+ }
68
+ //# sourceMappingURL=config.js.map