@fission-ai/openspec 1.4.1 → 1.6.0-beta.1

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 (241) hide show
  1. package/README.md +37 -4
  2. package/dist/cli/index.d.ts +5 -0
  3. package/dist/cli/index.js +95 -95
  4. package/dist/commands/change.d.ts +5 -2
  5. package/dist/commands/change.js +23 -55
  6. package/dist/commands/config.js +6 -65
  7. package/dist/commands/context.d.ts +3 -0
  8. package/dist/commands/context.js +155 -0
  9. package/dist/commands/doctor.d.ts +8 -0
  10. package/dist/commands/doctor.js +163 -0
  11. package/dist/commands/shared-gather.d.ts +14 -0
  12. package/dist/commands/shared-gather.js +31 -0
  13. package/dist/commands/shared-output.d.ts +18 -0
  14. package/dist/commands/shared-output.js +61 -0
  15. package/dist/commands/show.d.ts +11 -6
  16. package/dist/commands/show.js +70 -25
  17. package/dist/commands/spec.d.ts +5 -1
  18. package/dist/commands/spec.js +15 -4
  19. package/dist/commands/store.d.ts +3 -0
  20. package/dist/commands/store.js +547 -0
  21. package/dist/commands/validate.d.ts +10 -0
  22. package/dist/commands/validate.js +88 -40
  23. package/dist/commands/workflow/index.d.ts +0 -2
  24. package/dist/commands/workflow/index.js +0 -1
  25. package/dist/commands/workflow/instructions.d.ts +11 -1
  26. package/dist/commands/workflow/instructions.js +71 -22
  27. package/dist/commands/workflow/new-change.d.ts +6 -3
  28. package/dist/commands/workflow/new-change.js +42 -77
  29. package/dist/commands/workflow/shared.d.ts +15 -3
  30. package/dist/commands/workflow/shared.js +20 -3
  31. package/dist/commands/workflow/status.d.ts +2 -0
  32. package/dist/commands/workflow/status.js +19 -17
  33. package/dist/commands/workset-input.d.ts +19 -0
  34. package/dist/commands/workset-input.js +112 -0
  35. package/dist/commands/workset-prompts.d.ts +12 -0
  36. package/dist/commands/workset-prompts.js +143 -0
  37. package/dist/commands/workset.d.ts +25 -0
  38. package/dist/commands/workset.js +446 -0
  39. package/dist/core/archive.d.ts +17 -6
  40. package/dist/core/archive.js +220 -68
  41. package/dist/core/artifact-graph/index.d.ts +1 -1
  42. package/dist/core/artifact-graph/instruction-loader.d.ts +18 -13
  43. package/dist/core/artifact-graph/instruction-loader.js +8 -31
  44. package/dist/core/change-metadata/schema.d.ts +1 -0
  45. package/dist/core/change-metadata/schema.js +4 -2
  46. package/dist/core/change-status-policy.d.ts +5 -18
  47. package/dist/core/change-status-policy.js +2 -37
  48. package/dist/core/command-generation/adapters/bob.js +1 -14
  49. package/dist/core/command-generation/adapters/claude.d.ts +1 -1
  50. package/dist/core/command-generation/adapters/claude.js +4 -15
  51. package/dist/core/command-generation/adapters/cursor.js +1 -14
  52. package/dist/core/command-generation/adapters/index.d.ts +2 -0
  53. package/dist/core/command-generation/adapters/index.js +2 -0
  54. package/dist/core/command-generation/adapters/oh-my-pi.d.ts +21 -0
  55. package/dist/core/command-generation/adapters/oh-my-pi.js +44 -0
  56. package/dist/core/command-generation/adapters/pi.js +1 -14
  57. package/dist/core/command-generation/adapters/trae.d.ts +13 -0
  58. package/dist/core/command-generation/adapters/trae.js +48 -0
  59. package/dist/core/command-generation/adapters/windsurf.js +1 -14
  60. package/dist/core/command-generation/registry.js +4 -0
  61. package/dist/core/command-generation/yaml.d.ts +22 -0
  62. package/dist/core/command-generation/yaml.js +38 -0
  63. package/dist/core/completions/command-registry.js +87 -289
  64. package/dist/core/completions/generators/zsh-generator.js +3 -1
  65. package/dist/core/completions/installers/bash-installer.js +3 -0
  66. package/dist/core/completions/installers/fish-installer.js +8 -0
  67. package/dist/core/completions/installers/powershell-installer.js +30 -2
  68. package/dist/core/completions/installers/zsh-installer.js +3 -0
  69. package/dist/core/completions/shared-flags.d.ts +1 -0
  70. package/dist/core/completions/shared-flags.js +5 -0
  71. package/dist/core/config-schema.d.ts +2 -1
  72. package/dist/core/config-schema.js +26 -0
  73. package/dist/core/config.js +1 -0
  74. package/dist/core/file-state.d.ts +36 -0
  75. package/dist/core/file-state.js +112 -0
  76. package/dist/core/global-config.d.ts +2 -0
  77. package/dist/core/id.d.ts +17 -0
  78. package/dist/core/id.js +30 -0
  79. package/dist/core/index.d.ts +3 -3
  80. package/dist/core/index.js +3 -3
  81. package/dist/core/init.js +27 -6
  82. package/dist/core/list.d.ts +2 -0
  83. package/dist/core/list.js +37 -14
  84. package/dist/core/openers.d.ts +77 -0
  85. package/dist/core/openers.js +251 -0
  86. package/dist/core/openspec-root.d.ts +45 -0
  87. package/dist/core/openspec-root.js +195 -0
  88. package/dist/core/parsers/change-parser.js +2 -1
  89. package/dist/core/parsers/markdown-parser.d.ts +0 -3
  90. package/dist/core/parsers/markdown-parser.js +5 -59
  91. package/dist/core/parsers/requirement-blocks.d.ts +11 -0
  92. package/dist/core/parsers/requirement-blocks.js +42 -8
  93. package/dist/core/parsers/requirement-text.d.ts +55 -0
  94. package/dist/core/parsers/requirement-text.js +136 -0
  95. package/dist/core/planning-home.d.ts +1 -6
  96. package/dist/core/planning-home.js +2 -43
  97. package/dist/core/profile-sync-drift.js +1 -0
  98. package/dist/core/profiles.d.ts +2 -2
  99. package/dist/core/profiles.js +2 -1
  100. package/dist/core/project-config.d.ts +44 -1
  101. package/dist/core/project-config.js +160 -10
  102. package/dist/core/references.d.ts +63 -0
  103. package/dist/core/references.js +310 -0
  104. package/dist/core/relationship-health.d.ts +65 -0
  105. package/dist/core/relationship-health.js +64 -0
  106. package/dist/core/root-selection.d.ts +122 -0
  107. package/dist/core/root-selection.js +337 -0
  108. package/dist/core/schemas/base.schema.js +7 -2
  109. package/dist/core/shared/allowed-tools.d.ts +12 -0
  110. package/dist/core/shared/allowed-tools.js +12 -0
  111. package/dist/core/shared/skill-generation.js +5 -1
  112. package/dist/core/shared/tool-detection.d.ts +2 -2
  113. package/dist/core/shared/tool-detection.js +2 -0
  114. package/dist/core/specs-apply.d.ts +6 -1
  115. package/dist/core/specs-apply.js +41 -5
  116. package/dist/core/store/errors.d.ts +20 -0
  117. package/dist/core/{context-store → store}/errors.js +3 -3
  118. package/dist/core/store/foundation.d.ts +56 -0
  119. package/dist/core/store/foundation.js +251 -0
  120. package/dist/core/store/git.d.ts +23 -0
  121. package/dist/core/store/git.js +137 -0
  122. package/dist/core/{context-store → store}/index.d.ts +0 -1
  123. package/dist/core/{context-store → store}/index.js +0 -1
  124. package/dist/core/store/operations.d.ts +114 -0
  125. package/dist/core/store/operations.js +803 -0
  126. package/dist/core/store/registry.d.ts +58 -0
  127. package/dist/core/store/registry.js +275 -0
  128. package/dist/core/templates/skill-templates.d.ts +1 -0
  129. package/dist/core/templates/skill-templates.js +1 -0
  130. package/dist/core/templates/workflows/apply-change.js +5 -4
  131. package/dist/core/templates/workflows/archive-change.js +5 -4
  132. package/dist/core/templates/workflows/bulk-archive-change.js +5 -4
  133. package/dist/core/templates/workflows/continue-change.js +7 -2
  134. package/dist/core/templates/workflows/explore.js +5 -0
  135. package/dist/core/templates/workflows/ff-change.js +5 -0
  136. package/dist/core/templates/workflows/new-change.js +5 -0
  137. package/dist/core/templates/workflows/onboard.js +4 -1
  138. package/dist/core/templates/workflows/propose.js +5 -0
  139. package/dist/core/templates/workflows/store-selection.d.ts +8 -0
  140. package/dist/core/templates/workflows/store-selection.js +8 -0
  141. package/dist/core/templates/workflows/sync-specs.js +5 -4
  142. package/dist/core/templates/workflows/update-change.d.ts +10 -0
  143. package/dist/core/templates/workflows/update-change.js +167 -0
  144. package/dist/core/templates/workflows/verify-change.js +5 -4
  145. package/dist/core/update.js +4 -4
  146. package/dist/core/validation/validator.d.ts +7 -0
  147. package/dist/core/validation/validator.js +101 -38
  148. package/dist/core/view.js +1 -1
  149. package/dist/core/working-set.d.ts +47 -0
  150. package/dist/core/working-set.js +43 -0
  151. package/dist/core/worksets.d.ts +75 -0
  152. package/dist/core/worksets.js +245 -0
  153. package/dist/core/zod-issues.d.ts +4 -0
  154. package/dist/core/zod-issues.js +10 -0
  155. package/dist/utils/change-metadata.d.ts +1 -0
  156. package/dist/utils/change-metadata.js +1 -1
  157. package/dist/utils/change-utils.js +15 -0
  158. package/dist/utils/file-system.js +36 -17
  159. package/dist/utils/task-progress.d.ts +10 -1
  160. package/dist/utils/task-progress.js +66 -2
  161. package/package.json +26 -23
  162. package/dist/commands/context-store.d.ts +0 -3
  163. package/dist/commands/context-store.js +0 -475
  164. package/dist/commands/initiative.d.ts +0 -13
  165. package/dist/commands/initiative.js +0 -318
  166. package/dist/commands/workflow/initiative-link.d.ts +0 -24
  167. package/dist/commands/workflow/initiative-link.js +0 -47
  168. package/dist/commands/workflow/set-change.d.ts +0 -13
  169. package/dist/commands/workflow/set-change.js +0 -87
  170. package/dist/commands/workspace/context-status.d.ts +0 -4
  171. package/dist/commands/workspace/context-status.js +0 -59
  172. package/dist/commands/workspace/open-target-selection.d.ts +0 -13
  173. package/dist/commands/workspace/open-target-selection.js +0 -146
  174. package/dist/commands/workspace/open-view.d.ts +0 -62
  175. package/dist/commands/workspace/open-view.js +0 -249
  176. package/dist/commands/workspace/open.d.ts +0 -37
  177. package/dist/commands/workspace/open.js +0 -110
  178. package/dist/commands/workspace/opener-selection.d.ts +0 -11
  179. package/dist/commands/workspace/opener-selection.js +0 -98
  180. package/dist/commands/workspace/operations.d.ts +0 -29
  181. package/dist/commands/workspace/operations.js +0 -543
  182. package/dist/commands/workspace/prompt-theme.d.ts +0 -29
  183. package/dist/commands/workspace/prompt-theme.js +0 -24
  184. package/dist/commands/workspace/registration.d.ts +0 -13
  185. package/dist/commands/workspace/registration.js +0 -84
  186. package/dist/commands/workspace/selection.d.ts +0 -8
  187. package/dist/commands/workspace/selection.js +0 -104
  188. package/dist/commands/workspace/setup-prompts.d.ts +0 -13
  189. package/dist/commands/workspace/setup-prompts.js +0 -121
  190. package/dist/commands/workspace/types.d.ts +0 -103
  191. package/dist/commands/workspace/types.js +0 -36
  192. package/dist/commands/workspace.d.ts +0 -5
  193. package/dist/commands/workspace.js +0 -574
  194. package/dist/core/collections/index.d.ts +0 -3
  195. package/dist/core/collections/index.js +0 -3
  196. package/dist/core/collections/initiatives/collection.d.ts +0 -4
  197. package/dist/core/collections/initiatives/collection.js +0 -17
  198. package/dist/core/collections/initiatives/index.d.ts +0 -6
  199. package/dist/core/collections/initiatives/index.js +0 -6
  200. package/dist/core/collections/initiatives/operations.d.ts +0 -49
  201. package/dist/core/collections/initiatives/operations.js +0 -175
  202. package/dist/core/collections/initiatives/resolution.d.ts +0 -87
  203. package/dist/core/collections/initiatives/resolution.js +0 -374
  204. package/dist/core/collections/initiatives/schema.d.ts +0 -41
  205. package/dist/core/collections/initiatives/schema.js +0 -134
  206. package/dist/core/collections/initiatives/templates.d.ts +0 -12
  207. package/dist/core/collections/initiatives/templates.js +0 -90
  208. package/dist/core/collections/runtime.d.ts +0 -46
  209. package/dist/core/collections/runtime.js +0 -194
  210. package/dist/core/context-store/binding.d.ts +0 -53
  211. package/dist/core/context-store/binding.js +0 -197
  212. package/dist/core/context-store/errors.d.ts +0 -20
  213. package/dist/core/context-store/foundation.d.ts +0 -55
  214. package/dist/core/context-store/foundation.js +0 -321
  215. package/dist/core/context-store/operations.d.ts +0 -85
  216. package/dist/core/context-store/operations.js +0 -528
  217. package/dist/core/context-store/registry.d.ts +0 -45
  218. package/dist/core/context-store/registry.js +0 -229
  219. package/dist/core/workspace/foundation.d.ts +0 -67
  220. package/dist/core/workspace/foundation.js +0 -295
  221. package/dist/core/workspace/index.d.ts +0 -8
  222. package/dist/core/workspace/index.js +0 -8
  223. package/dist/core/workspace/legacy-state.d.ts +0 -28
  224. package/dist/core/workspace/legacy-state.js +0 -200
  225. package/dist/core/workspace/link-input.d.ts +0 -9
  226. package/dist/core/workspace/link-input.js +0 -32
  227. package/dist/core/workspace/open-surface.d.ts +0 -45
  228. package/dist/core/workspace/open-surface.js +0 -215
  229. package/dist/core/workspace/openers.d.ts +0 -21
  230. package/dist/core/workspace/openers.js +0 -124
  231. package/dist/core/workspace/registry.d.ts +0 -24
  232. package/dist/core/workspace/registry.js +0 -146
  233. package/dist/core/workspace/skills.d.ts +0 -57
  234. package/dist/core/workspace/skills.js +0 -334
  235. package/dist/core/workspace/state-io.d.ts +0 -10
  236. package/dist/core/workspace/state-io.js +0 -121
  237. package/schemas/workspace-planning/schema.yaml +0 -72
  238. package/schemas/workspace-planning/templates/design.md +0 -33
  239. package/schemas/workspace-planning/templates/proposal.md +0 -28
  240. package/schemas/workspace-planning/templates/spec.md +0 -9
  241. package/schemas/workspace-planning/templates/tasks.md +0 -15
@@ -1,318 +0,0 @@
1
- import chalk from 'chalk';
2
- import { createInitiative, INITIATIVE_FILE_NAMES, listInitiativeViewReferences, mountInitiativesCollection, initiativeDiagnosticFromError as coreInitiativeDiagnosticFromError, resolveInitiativeViewReference as resolveCoreInitiativeViewReference, selectContextStoreForInitiative, formatContextStoreSelector, } from '../core/collections/initiatives/index.js';
3
- export class InitiativeCliError extends Error {
4
- diagnostic;
5
- constructor(message, code, options = {}) {
6
- super(message);
7
- this.diagnostic = {
8
- severity: 'error',
9
- code,
10
- message,
11
- ...options,
12
- };
13
- }
14
- }
15
- function printJson(payload) {
16
- console.log(JSON.stringify(payload, null, 2));
17
- }
18
- export function initiativeDiagnosticFromError(error) {
19
- if (error instanceof InitiativeCliError) {
20
- return error.diagnostic;
21
- }
22
- return coreInitiativeDiagnosticFromError(error);
23
- }
24
- function appendDiagnostic(payload, diagnostic) {
25
- return {
26
- ...payload,
27
- status: [...payload.status, diagnostic],
28
- };
29
- }
30
- function requireNonBlankOption(value, flagName, target, code) {
31
- if (value === undefined || value.trim().length === 0) {
32
- throw new InitiativeCliError(`Pass --${flagName} <value>.`, code, {
33
- target,
34
- fix: `openspec initiative create <id> --${flagName} <value>`,
35
- });
36
- }
37
- return value.trim();
38
- }
39
- function requireInitiativeId(id, commandName) {
40
- if (id === undefined || id.trim().length === 0) {
41
- throw new InitiativeCliError('Pass an initiative id.', 'initiative_id_required', {
42
- target: 'initiative.id',
43
- fix: `openspec initiative ${commandName} <id>`,
44
- });
45
- }
46
- return id.trim();
47
- }
48
- function toContextStoreOutput(selected) {
49
- return {
50
- id: selected.id,
51
- root: selected.root,
52
- source: selected.source,
53
- };
54
- }
55
- function toInitiativeOutput(selected, state) {
56
- const collection = mountInitiativesCollection(selected.root);
57
- return {
58
- ...state,
59
- store: selected.id,
60
- root: collection.resolvePath(state.id),
61
- store_path: collection.toStorePath(state.id),
62
- };
63
- }
64
- function listedInitiativeToOutput(initiative) {
65
- return {
66
- version: 1,
67
- id: initiative.id,
68
- title: initiative.title,
69
- summary: initiative.summary,
70
- status: initiative.status,
71
- created: initiative.created,
72
- owners: initiative.owners,
73
- metadata: initiative.metadata,
74
- store: initiative.store,
75
- root: initiative.root,
76
- store_path: initiative.storePath,
77
- };
78
- }
79
- function initiativeReferenceToShowOutput(reference) {
80
- return {
81
- version: 1,
82
- id: reference.id,
83
- title: reference.title,
84
- summary: reference.summary,
85
- created: reference.created,
86
- root: reference.root,
87
- store_path: reference.storePath,
88
- metadata_path: reference.metadataPath,
89
- };
90
- }
91
- function printCreateHuman(payload) {
92
- if (!payload.context_store || !payload.initiative) {
93
- return;
94
- }
95
- console.log(chalk.green('Created initiative'));
96
- console.log(`ID: ${payload.initiative.id}`);
97
- console.log(`Title: ${payload.initiative.title}`);
98
- console.log(`Status: ${payload.initiative.status}`);
99
- console.log(`Context store: ${payload.context_store.id}`);
100
- console.log(`Location: ${payload.initiative.root}`);
101
- console.log('');
102
- console.log(`Created files (${payload.created_files.length}):`);
103
- for (const fileName of payload.created_files) {
104
- console.log(` - ${fileName}`);
105
- }
106
- console.log('');
107
- console.log('Next useful commands:');
108
- console.log(` openspec initiative list ${formatContextStoreSelector(payload.context_store)}`);
109
- }
110
- function printTableHeader(includeStore) {
111
- const idHeader = 'ID'.padEnd(22);
112
- const storeHeader = includeStore ? `${'Store'.padEnd(12)}` : '';
113
- console.log(`${idHeader}${storeHeader}Title`);
114
- }
115
- function printInitiativeRow(initiative, includeStore) {
116
- const id = initiative.id.padEnd(22);
117
- const store = includeStore ? `${initiative.store.padEnd(12)}` : '';
118
- console.log(`${id}${store}${initiative.title}`);
119
- }
120
- function printListStatuses(statuses) {
121
- if (statuses.length === 0) {
122
- return;
123
- }
124
- console.log('');
125
- for (const status of statuses) {
126
- console.log(status.message);
127
- if (status.fix) {
128
- console.log(`Run: ${status.fix}`);
129
- }
130
- }
131
- }
132
- function printListHuman(payload) {
133
- if (payload.context_store) {
134
- console.log(`OpenSpec initiatives in ${payload.context_store.id} (${payload.initiatives.length})`);
135
- if (payload.initiatives.length === 0) {
136
- console.log('');
137
- console.log(`No initiatives found in ${payload.context_store.id}.`);
138
- console.log('');
139
- console.log(`Location: ${payload.context_store.root}`);
140
- return;
141
- }
142
- console.log('');
143
- printTableHeader(false);
144
- for (const initiative of payload.initiatives) {
145
- printInitiativeRow(initiative, false);
146
- }
147
- console.log('');
148
- console.log(`Location: ${payload.context_store.root}`);
149
- return;
150
- }
151
- if (payload.context_stores.length === 0) {
152
- console.log('No initiatives found because no context stores are registered.');
153
- return;
154
- }
155
- if (payload.initiatives.length === 0) {
156
- console.log('No initiatives found across registered context stores.');
157
- printListStatuses(payload.status);
158
- return;
159
- }
160
- console.log(`OpenSpec initiatives (${payload.initiatives.length} across ${payload.context_stores.length} stores)`);
161
- console.log('');
162
- printTableHeader(true);
163
- for (const initiative of payload.initiatives) {
164
- printInitiativeRow(initiative, true);
165
- }
166
- printListStatuses(payload.status);
167
- }
168
- function printShowHuman(payload) {
169
- if (!payload.context_store || !payload.initiative) {
170
- return;
171
- }
172
- console.log(`OpenSpec initiative: ${payload.initiative.title}`);
173
- console.log('');
174
- console.log(`ID: ${payload.initiative.id}`);
175
- console.log(`Summary: ${payload.initiative.summary}`);
176
- console.log(`Context store: ${payload.context_store.id}`);
177
- console.log(`Location: ${payload.initiative.root}`);
178
- console.log(`Metadata: ${payload.initiative.metadata_path}`);
179
- }
180
- function printDiagnosticMatches(diagnostic) {
181
- const matches = diagnostic.details?.matches ?? [];
182
- if (matches.length === 0) {
183
- return;
184
- }
185
- console.error('');
186
- console.error(diagnostic.code === 'initiative_lookup_incomplete' ? 'Partial matches:' : 'Matches:');
187
- for (const match of matches) {
188
- console.error(` ${match.context_store.id.padEnd(12)}${match.initiative.root}`);
189
- }
190
- }
191
- class InitiativeCommand {
192
- async create(id, options = {}) {
193
- try {
194
- const initiativeId = requireInitiativeId(id, 'create');
195
- const title = requireNonBlankOption(options.title, 'title', 'initiative.title', 'initiative_title_required');
196
- const summary = requireNonBlankOption(options.summary, 'summary', 'initiative.summary', 'initiative_summary_required');
197
- const selected = await selectContextStoreForInitiative(options, 'create');
198
- const collection = mountInitiativesCollection(selected.root);
199
- const state = await createInitiative({
200
- collection,
201
- id: initiativeId,
202
- title,
203
- summary,
204
- });
205
- const payload = {
206
- context_store: toContextStoreOutput(selected),
207
- initiative: toInitiativeOutput(selected, state),
208
- created_files: [...INITIATIVE_FILE_NAMES],
209
- status: [],
210
- };
211
- if (options.json) {
212
- printJson(payload);
213
- return;
214
- }
215
- printCreateHuman(payload);
216
- }
217
- catch (error) {
218
- this.handleFailure(options.json, { context_store: null, initiative: null, created_files: [], status: [] }, error);
219
- }
220
- }
221
- async list(options = {}) {
222
- try {
223
- const payload = await this.buildListPayload(options);
224
- if (options.json) {
225
- printJson(payload);
226
- return;
227
- }
228
- printListHuman(payload);
229
- }
230
- catch (error) {
231
- this.handleFailure(options.json, { context_store: null, context_stores: [], initiatives: [], status: [] }, error);
232
- }
233
- }
234
- async show(id, options = {}) {
235
- try {
236
- const initiativeId = requireInitiativeId(id, 'show');
237
- const payload = await this.buildShowPayload(initiativeId, options);
238
- if (options.json) {
239
- printJson(payload);
240
- return;
241
- }
242
- printShowHuman(payload);
243
- }
244
- catch (error) {
245
- this.handleFailure(options.json, { context_store: null, initiative: null, status: [] }, error);
246
- }
247
- }
248
- async buildListPayload(options) {
249
- const listed = await listInitiativeViewReferences(options);
250
- const contextStores = listed.contextStores.map((store) => ({
251
- context_store: toContextStoreOutput(store.contextStore),
252
- initiatives: store.initiatives.map(listedInitiativeToOutput),
253
- status: store.status,
254
- }));
255
- return {
256
- context_store: listed.contextStore ? toContextStoreOutput(listed.contextStore) : null,
257
- context_stores: contextStores,
258
- initiatives: listed.initiatives.map(listedInitiativeToOutput),
259
- status: listed.status,
260
- };
261
- }
262
- async buildShowPayload(initiativeId, options) {
263
- const reference = await resolveCoreInitiativeViewReference(initiativeId, options);
264
- return {
265
- context_store: {
266
- id: reference.store,
267
- root: reference.storeRoot,
268
- },
269
- initiative: initiativeReferenceToShowOutput(reference),
270
- status: [],
271
- };
272
- }
273
- handleFailure(json, payload, error) {
274
- const diagnostic = initiativeDiagnosticFromError(error);
275
- if (json) {
276
- printJson(appendDiagnostic(payload, diagnostic));
277
- process.exitCode = 1;
278
- return;
279
- }
280
- console.error(`Error: ${diagnostic.message}`);
281
- printDiagnosticMatches(diagnostic);
282
- if (diagnostic.fix) {
283
- console.error(`Fix: ${diagnostic.fix}`);
284
- }
285
- process.exitCode = 1;
286
- }
287
- }
288
- function addContextStoreSelectorOptions(command) {
289
- return command
290
- .option('--store <id>', 'Context store id from the local context-store registry')
291
- .option('--store-path <path>', 'Existing local context store root')
292
- .option('--json', 'Output as JSON');
293
- }
294
- export function registerInitiativeCommand(program) {
295
- const initiativeCommand = new InitiativeCommand();
296
- const initiative = program
297
- .command('initiative')
298
- .description('Create and list coordinated initiatives');
299
- addContextStoreSelectorOptions(initiative
300
- .command('create [id]')
301
- .description('Create an initiative in a context store')
302
- .option('--title <title>', 'Initiative title')
303
- .option('--summary <summary>', 'Initiative summary')).action(async (id, options) => {
304
- await initiativeCommand.create(id, options);
305
- });
306
- addContextStoreSelectorOptions(initiative
307
- .command('show <id>')
308
- .description('Show where an initiative lives and how to read it')).action(async (id, options) => {
309
- await initiativeCommand.show(id, options);
310
- });
311
- addContextStoreSelectorOptions(initiative
312
- .command('list')
313
- .alias('ls')
314
- .description('List initiatives across registered context stores')).action(async (options) => {
315
- await initiativeCommand.list(options);
316
- });
317
- }
318
- //# sourceMappingURL=initiative.js.map
@@ -1,24 +0,0 @@
1
- import type { PlanningHome } from '../../core/planning-home.js';
2
- import { type InitiativeLinkReference } from '../../core/collections/initiatives/index.js';
3
- export interface ChangeCommandStatus {
4
- severity: 'error' | 'warning';
5
- code: string;
6
- message: string;
7
- target?: string;
8
- fix?: string;
9
- details?: unknown;
10
- }
11
- export interface InitiativeSelectorOptions {
12
- initiative?: string;
13
- store?: string;
14
- storePath?: string;
15
- }
16
- export declare const REPO_LOCAL_INITIATIVE_LINK_ERROR = "Initiative links are supported only for repo-local changes. Run this command from the repo that owns the implementation plan.";
17
- export declare function printJson(payload: unknown): void;
18
- export declare function statusFromError(error: unknown): ChangeCommandStatus;
19
- export declare function assertInitiativeSelectorsHaveReference(options: InitiativeSelectorOptions): void;
20
- export declare function assertInitiativeReference(value: string | undefined): asserts value is string;
21
- export declare function assertRepoLocalInitiativeLinkPlanningHome(planningHome: PlanningHome): void;
22
- export declare function formatInitiativeLink(initiative: InitiativeLinkReference): string;
23
- export declare function sameInitiativeLink(left: InitiativeLinkReference | undefined, right: InitiativeLinkReference): boolean;
24
- //# sourceMappingURL=initiative-link.d.ts.map
@@ -1,47 +0,0 @@
1
- import { InitiativeResolutionError, } from '../../core/collections/initiatives/index.js';
2
- export const REPO_LOCAL_INITIATIVE_LINK_ERROR = 'Initiative links are supported only for repo-local changes. Run this command from the repo that owns the implementation plan.';
3
- export function printJson(payload) {
4
- console.log(JSON.stringify(payload, null, 2));
5
- }
6
- export function statusFromError(error) {
7
- if (error instanceof InitiativeResolutionError) {
8
- return {
9
- severity: 'error',
10
- code: error.code,
11
- message: error.message,
12
- ...(error.target ? { target: error.target } : {}),
13
- ...(error.fix ? { fix: error.fix } : {}),
14
- ...(error.details ? { details: error.details } : {}),
15
- };
16
- }
17
- return {
18
- severity: 'error',
19
- code: 'change_error',
20
- message: error instanceof Error ? error.message : String(error),
21
- };
22
- }
23
- export function assertInitiativeSelectorsHaveReference(options) {
24
- if (!options.initiative && (options.store !== undefined || options.storePath !== undefined)) {
25
- throw new Error('Pass --initiative when using --store or --store-path.');
26
- }
27
- if (options.initiative !== undefined && options.initiative.trim().length === 0) {
28
- throw new Error('Pass --initiative <id> to link a change to an initiative.');
29
- }
30
- }
31
- export function assertInitiativeReference(value) {
32
- if (value === undefined || value.trim().length === 0) {
33
- throw new Error('Pass --initiative <id> to set a change initiative link.');
34
- }
35
- }
36
- export function assertRepoLocalInitiativeLinkPlanningHome(planningHome) {
37
- if (planningHome.kind === 'workspace') {
38
- throw new Error(REPO_LOCAL_INITIATIVE_LINK_ERROR);
39
- }
40
- }
41
- export function formatInitiativeLink(initiative) {
42
- return `${initiative.store}/${initiative.id}`;
43
- }
44
- export function sameInitiativeLink(left, right) {
45
- return left?.store === right.store && left.id === right.id;
46
- }
47
- //# sourceMappingURL=initiative-link.js.map
@@ -1,13 +0,0 @@
1
- /**
2
- * Set Change Command
3
- *
4
- * Mutates checked-in repo-local change metadata.
5
- */
6
- export interface SetChangeOptions {
7
- initiative?: string;
8
- store?: string;
9
- storePath?: string;
10
- json?: boolean;
11
- }
12
- export declare function setChangeCommand(name: string | undefined, options: SetChangeOptions): Promise<void>;
13
- //# sourceMappingURL=set-change.d.ts.map
@@ -1,87 +0,0 @@
1
- /**
2
- * Set Change Command
3
- *
4
- * Mutates checked-in repo-local change metadata.
5
- */
6
- import path from 'node:path';
7
- import { getChangeDir, resolveCurrentPlanningHomeSync, } from '../../core/planning-home.js';
8
- import { readChangeMetadata, resolveSchemaForChange, writeChangeMetadata, } from '../../utils/change-metadata.js';
9
- import { validateChangeExists } from './shared.js';
10
- import { resolveInitiativeLinkReference, } from '../../core/collections/initiatives/index.js';
11
- import { assertInitiativeReference, assertRepoLocalInitiativeLinkPlanningHome, formatInitiativeLink, printJson, sameInitiativeLink, statusFromError, } from './initiative-link.js';
12
- function outputForSetChange(id, changeDir, schema, initiative, updated) {
13
- return {
14
- change: {
15
- id,
16
- path: changeDir,
17
- metadataPath: path.join(changeDir, '.openspec.yaml'),
18
- schema,
19
- },
20
- initiative,
21
- updated,
22
- };
23
- }
24
- function printSetChangeHuman(payload) {
25
- if (!payload.change || !payload.initiative) {
26
- return;
27
- }
28
- const verb = payload.updated ? 'Linked' : 'Change already linked';
29
- console.log(`${verb}: ${payload.change.id}`);
30
- console.log(`Initiative: ${formatInitiativeLink(payload.initiative)}`);
31
- console.log(`Metadata: ${payload.change.metadataPath}`);
32
- }
33
- export async function setChangeCommand(name, options) {
34
- try {
35
- if (!name) {
36
- throw new Error('Missing required argument <name>');
37
- }
38
- assertInitiativeReference(options.initiative);
39
- const planningHome = resolveCurrentPlanningHomeSync();
40
- assertRepoLocalInitiativeLinkPlanningHome(planningHome);
41
- const projectRoot = planningHome.root;
42
- const changeName = await validateChangeExists(name, projectRoot, planningHome.changesDir);
43
- const changeDir = getChangeDir(planningHome, changeName);
44
- const initiative = await resolveInitiativeLinkReference(options.initiative, {
45
- store: options.store,
46
- storePath: options.storePath,
47
- });
48
- const existingMetadata = readChangeMetadata(changeDir, projectRoot);
49
- const metadata = existingMetadata ?? {
50
- schema: resolveSchemaForChange(changeDir, undefined, projectRoot, { metadata: null }),
51
- };
52
- if (sameInitiativeLink(metadata.initiative, initiative)) {
53
- const payload = outputForSetChange(changeName, changeDir, metadata.schema, initiative, false);
54
- if (options.json) {
55
- printJson(payload);
56
- return;
57
- }
58
- printSetChangeHuman(payload);
59
- return;
60
- }
61
- if (metadata.initiative) {
62
- throw new Error(`Change '${changeName}' is already linked to initiative ${formatInitiativeLink(metadata.initiative)}.`);
63
- }
64
- writeChangeMetadata(changeDir, {
65
- ...metadata,
66
- initiative,
67
- }, projectRoot);
68
- const payload = outputForSetChange(changeName, changeDir, metadata.schema, initiative, true);
69
- if (options.json) {
70
- printJson(payload);
71
- return;
72
- }
73
- printSetChangeHuman(payload);
74
- }
75
- catch (error) {
76
- if (options.json) {
77
- printJson({
78
- change: null,
79
- status: [statusFromError(error)],
80
- });
81
- process.exitCode = 1;
82
- return;
83
- }
84
- throw error;
85
- }
86
- }
87
- //# sourceMappingURL=set-change.js.map
@@ -1,4 +0,0 @@
1
- import { type WorkspaceContextState } from '../../core/workspace/index.js';
2
- import { WorkspaceStatus } from './types.js';
3
- export declare function collectWorkspaceContextStatuses(context: WorkspaceContextState | null): Promise<WorkspaceStatus[]>;
4
- //# sourceMappingURL=context-status.d.ts.map
@@ -1,59 +0,0 @@
1
- import { mountInitiativesCollection, readInitiative, } from '../../core/collections/initiatives/index.js';
2
- import { formatContextStoreBinding, formatContextStoreBindingSelector, resolveContextStoreBinding, } from '../../core/context-store/index.js';
3
- import { getWorkspaceContextInitiativeId, } from '../../core/workspace/index.js';
4
- import { asErrorMessage, makeStatus } from './types.js';
5
- function contextStoreBindingWarningToStatus(warning) {
6
- return makeStatus('warning', warning.code, warning.message, {
7
- target: warning.target ? `workspace.context.store.${warning.target}` : 'workspace.context.store',
8
- ...(warning.fix ? { fix: warning.fix } : {}),
9
- });
10
- }
11
- export async function collectWorkspaceContextStatuses(context) {
12
- if (!context) {
13
- return [];
14
- }
15
- const initiativeId = getWorkspaceContextInitiativeId(context);
16
- const contextStoreLabel = formatContextStoreBinding(context.store);
17
- const selector = formatContextStoreBindingSelector(context.store);
18
- let resolvedStore;
19
- try {
20
- resolvedStore = await resolveContextStoreBinding(context.store);
21
- }
22
- catch (error) {
23
- return [
24
- makeStatus('error', 'workspace_context_store_unavailable', `Workspace context store '${contextStoreLabel}' could not be read: ${asErrorMessage(error)}`, {
25
- target: 'workspace.context.store',
26
- fix: context.store.selector.kind === 'registry'
27
- ? 'openspec context-store doctor'
28
- : `Check the path in .openspec-workspace/view.yaml or run openspec initiative show ${initiativeId} ${selector}`,
29
- }),
30
- ];
31
- }
32
- const statuses = resolvedStore.warnings.map(contextStoreBindingWarningToStatus);
33
- try {
34
- const initiative = await readInitiative({
35
- collection: mountInitiativesCollection(resolvedStore.root),
36
- id: initiativeId,
37
- });
38
- if (!initiative) {
39
- return [
40
- ...statuses,
41
- makeStatus('error', 'workspace_initiative_missing', `Workspace initiative '${contextStoreLabel}/${initiativeId}' was not found.`, {
42
- target: 'workspace.context.initiative',
43
- fix: `openspec initiative show ${initiativeId} ${selector}`,
44
- }),
45
- ];
46
- }
47
- return statuses;
48
- }
49
- catch (error) {
50
- return [
51
- ...statuses,
52
- makeStatus('error', 'workspace_initiative_unavailable', `Workspace initiative '${contextStoreLabel}/${initiativeId}' could not be read: ${asErrorMessage(error)}`, {
53
- target: 'workspace.context.initiative',
54
- fix: `openspec initiative show ${initiativeId} ${selector}`,
55
- }),
56
- ];
57
- }
58
- }
59
- //# sourceMappingURL=context-status.js.map
@@ -1,13 +0,0 @@
1
- import { type InitiativeViewReference } from '../../core/collections/initiatives/index.js';
2
- import { type SelectedWorkspace, type WorkspaceOpenOptions, type WorkspaceStatus } from './types.js';
3
- export type WorkspaceOpenTarget = {
4
- kind: 'workspace';
5
- selected: SelectedWorkspace;
6
- status: WorkspaceStatus[];
7
- } | {
8
- kind: 'initiative';
9
- initiative: InitiativeViewReference;
10
- status: WorkspaceStatus[];
11
- };
12
- export declare function selectWorkspaceOpenTarget(workspaceName: string | undefined, options: WorkspaceOpenOptions): Promise<WorkspaceOpenTarget>;
13
- //# sourceMappingURL=open-target-selection.d.ts.map