@fission-ai/openspec 1.4.1 → 1.5.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 +24 -3
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.js +95 -95
- package/dist/commands/change.d.ts +5 -1
- package/dist/commands/change.js +17 -15
- package/dist/commands/config.js +6 -65
- package/dist/commands/context.d.ts +3 -0
- package/dist/commands/context.js +155 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.js +163 -0
- package/dist/commands/shared-gather.d.ts +14 -0
- package/dist/commands/shared-gather.js +31 -0
- package/dist/commands/shared-output.d.ts +18 -0
- package/dist/commands/shared-output.js +61 -0
- package/dist/commands/show.d.ts +11 -6
- package/dist/commands/show.js +70 -25
- package/dist/commands/spec.d.ts +5 -1
- package/dist/commands/spec.js +15 -4
- package/dist/commands/store.d.ts +3 -0
- package/dist/commands/store.js +547 -0
- package/dist/commands/validate.d.ts +2 -0
- package/dist/commands/validate.js +75 -39
- package/dist/commands/workflow/index.d.ts +0 -2
- package/dist/commands/workflow/index.js +0 -1
- package/dist/commands/workflow/instructions.d.ts +11 -1
- package/dist/commands/workflow/instructions.js +71 -22
- package/dist/commands/workflow/new-change.d.ts +6 -3
- package/dist/commands/workflow/new-change.js +42 -77
- package/dist/commands/workflow/shared.d.ts +15 -3
- package/dist/commands/workflow/shared.js +20 -3
- package/dist/commands/workflow/status.d.ts +2 -0
- package/dist/commands/workflow/status.js +19 -17
- package/dist/commands/workset-input.d.ts +19 -0
- package/dist/commands/workset-input.js +112 -0
- package/dist/commands/workset-prompts.d.ts +12 -0
- package/dist/commands/workset-prompts.js +143 -0
- package/dist/commands/workset.d.ts +25 -0
- package/dist/commands/workset.js +446 -0
- package/dist/core/archive.d.ts +17 -6
- package/dist/core/archive.js +209 -56
- package/dist/core/artifact-graph/index.d.ts +1 -1
- package/dist/core/artifact-graph/instruction-loader.d.ts +18 -13
- package/dist/core/artifact-graph/instruction-loader.js +8 -31
- package/dist/core/change-metadata/schema.d.ts +1 -0
- package/dist/core/change-metadata/schema.js +4 -2
- package/dist/core/change-status-policy.d.ts +5 -18
- package/dist/core/change-status-policy.js +2 -37
- package/dist/core/command-generation/adapters/bob.js +1 -14
- package/dist/core/command-generation/adapters/claude.js +1 -14
- package/dist/core/command-generation/adapters/cursor.js +1 -14
- package/dist/core/command-generation/adapters/pi.js +1 -14
- package/dist/core/command-generation/adapters/windsurf.js +1 -14
- package/dist/core/command-generation/yaml.d.ts +22 -0
- package/dist/core/command-generation/yaml.js +38 -0
- package/dist/core/completions/command-registry.js +87 -289
- package/dist/core/completions/generators/zsh-generator.js +3 -1
- package/dist/core/completions/installers/bash-installer.js +3 -0
- package/dist/core/completions/installers/fish-installer.js +8 -0
- package/dist/core/completions/installers/powershell-installer.js +30 -2
- package/dist/core/completions/installers/zsh-installer.js +3 -0
- package/dist/core/completions/shared-flags.d.ts +1 -0
- package/dist/core/completions/shared-flags.js +5 -0
- package/dist/core/config-schema.d.ts +2 -1
- package/dist/core/config-schema.js +26 -0
- package/dist/core/file-state.d.ts +36 -0
- package/dist/core/file-state.js +112 -0
- package/dist/core/global-config.d.ts +2 -0
- package/dist/core/id.d.ts +17 -0
- package/dist/core/id.js +30 -0
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +3 -3
- package/dist/core/init.js +24 -4
- package/dist/core/list.d.ts +2 -0
- package/dist/core/list.js +19 -5
- package/dist/core/openers.d.ts +77 -0
- package/dist/core/openers.js +251 -0
- package/dist/core/openspec-root.d.ts +45 -0
- package/dist/core/openspec-root.js +192 -0
- package/dist/core/planning-home.d.ts +1 -6
- package/dist/core/planning-home.js +2 -43
- package/dist/core/project-config.d.ts +44 -1
- package/dist/core/project-config.js +160 -10
- package/dist/core/references.d.ts +63 -0
- package/dist/core/references.js +310 -0
- package/dist/core/relationship-health.d.ts +65 -0
- package/dist/core/relationship-health.js +64 -0
- package/dist/core/root-selection.d.ts +122 -0
- package/dist/core/root-selection.js +337 -0
- package/dist/core/specs-apply.d.ts +6 -1
- package/dist/core/specs-apply.js +6 -4
- package/dist/core/store/errors.d.ts +20 -0
- package/dist/core/{context-store → store}/errors.js +3 -3
- package/dist/core/store/foundation.d.ts +56 -0
- package/dist/core/store/foundation.js +251 -0
- package/dist/core/store/git.d.ts +23 -0
- package/dist/core/store/git.js +137 -0
- package/dist/core/{context-store → store}/index.d.ts +0 -1
- package/dist/core/{context-store → store}/index.js +0 -1
- package/dist/core/store/operations.d.ts +114 -0
- package/dist/core/store/operations.js +783 -0
- package/dist/core/store/registry.d.ts +58 -0
- package/dist/core/store/registry.js +275 -0
- package/dist/core/templates/workflows/apply-change.js +5 -4
- package/dist/core/templates/workflows/archive-change.js +5 -4
- package/dist/core/templates/workflows/bulk-archive-change.js +5 -4
- package/dist/core/templates/workflows/continue-change.js +7 -2
- package/dist/core/templates/workflows/explore.js +5 -0
- package/dist/core/templates/workflows/ff-change.js +5 -0
- package/dist/core/templates/workflows/new-change.js +5 -0
- package/dist/core/templates/workflows/onboard.js +4 -1
- package/dist/core/templates/workflows/propose.js +5 -0
- package/dist/core/templates/workflows/store-selection.d.ts +8 -0
- package/dist/core/templates/workflows/store-selection.js +8 -0
- package/dist/core/templates/workflows/sync-specs.js +5 -4
- package/dist/core/templates/workflows/verify-change.js +5 -4
- package/dist/core/working-set.d.ts +47 -0
- package/dist/core/working-set.js +43 -0
- package/dist/core/worksets.d.ts +75 -0
- package/dist/core/worksets.js +245 -0
- package/dist/core/zod-issues.d.ts +4 -0
- package/dist/core/zod-issues.js +10 -0
- package/dist/utils/change-metadata.d.ts +1 -0
- package/dist/utils/change-metadata.js +1 -1
- package/dist/utils/change-utils.js +15 -0
- package/dist/utils/file-system.js +36 -17
- package/package.json +6 -6
- package/dist/commands/context-store.d.ts +0 -3
- package/dist/commands/context-store.js +0 -475
- package/dist/commands/initiative.d.ts +0 -13
- package/dist/commands/initiative.js +0 -318
- package/dist/commands/workflow/initiative-link.d.ts +0 -24
- package/dist/commands/workflow/initiative-link.js +0 -47
- package/dist/commands/workflow/set-change.d.ts +0 -13
- package/dist/commands/workflow/set-change.js +0 -87
- package/dist/commands/workspace/context-status.d.ts +0 -4
- package/dist/commands/workspace/context-status.js +0 -59
- package/dist/commands/workspace/open-target-selection.d.ts +0 -13
- package/dist/commands/workspace/open-target-selection.js +0 -146
- package/dist/commands/workspace/open-view.d.ts +0 -62
- package/dist/commands/workspace/open-view.js +0 -249
- package/dist/commands/workspace/open.d.ts +0 -37
- package/dist/commands/workspace/open.js +0 -110
- package/dist/commands/workspace/opener-selection.d.ts +0 -11
- package/dist/commands/workspace/opener-selection.js +0 -98
- package/dist/commands/workspace/operations.d.ts +0 -29
- package/dist/commands/workspace/operations.js +0 -543
- package/dist/commands/workspace/prompt-theme.d.ts +0 -29
- package/dist/commands/workspace/prompt-theme.js +0 -24
- package/dist/commands/workspace/registration.d.ts +0 -13
- package/dist/commands/workspace/registration.js +0 -84
- package/dist/commands/workspace/selection.d.ts +0 -8
- package/dist/commands/workspace/selection.js +0 -104
- package/dist/commands/workspace/setup-prompts.d.ts +0 -13
- package/dist/commands/workspace/setup-prompts.js +0 -121
- package/dist/commands/workspace/types.d.ts +0 -103
- package/dist/commands/workspace/types.js +0 -36
- package/dist/commands/workspace.d.ts +0 -5
- package/dist/commands/workspace.js +0 -574
- package/dist/core/collections/index.d.ts +0 -3
- package/dist/core/collections/index.js +0 -3
- package/dist/core/collections/initiatives/collection.d.ts +0 -4
- package/dist/core/collections/initiatives/collection.js +0 -17
- package/dist/core/collections/initiatives/index.d.ts +0 -6
- package/dist/core/collections/initiatives/index.js +0 -6
- package/dist/core/collections/initiatives/operations.d.ts +0 -49
- package/dist/core/collections/initiatives/operations.js +0 -175
- package/dist/core/collections/initiatives/resolution.d.ts +0 -87
- package/dist/core/collections/initiatives/resolution.js +0 -374
- package/dist/core/collections/initiatives/schema.d.ts +0 -41
- package/dist/core/collections/initiatives/schema.js +0 -134
- package/dist/core/collections/initiatives/templates.d.ts +0 -12
- package/dist/core/collections/initiatives/templates.js +0 -90
- package/dist/core/collections/runtime.d.ts +0 -46
- package/dist/core/collections/runtime.js +0 -194
- package/dist/core/context-store/binding.d.ts +0 -53
- package/dist/core/context-store/binding.js +0 -197
- package/dist/core/context-store/errors.d.ts +0 -20
- package/dist/core/context-store/foundation.d.ts +0 -55
- package/dist/core/context-store/foundation.js +0 -321
- package/dist/core/context-store/operations.d.ts +0 -85
- package/dist/core/context-store/operations.js +0 -528
- package/dist/core/context-store/registry.d.ts +0 -45
- package/dist/core/context-store/registry.js +0 -229
- package/dist/core/workspace/foundation.d.ts +0 -67
- package/dist/core/workspace/foundation.js +0 -295
- package/dist/core/workspace/index.d.ts +0 -8
- package/dist/core/workspace/index.js +0 -8
- package/dist/core/workspace/legacy-state.d.ts +0 -28
- package/dist/core/workspace/legacy-state.js +0 -200
- package/dist/core/workspace/link-input.d.ts +0 -9
- package/dist/core/workspace/link-input.js +0 -32
- package/dist/core/workspace/open-surface.d.ts +0 -45
- package/dist/core/workspace/open-surface.js +0 -215
- package/dist/core/workspace/openers.d.ts +0 -21
- package/dist/core/workspace/openers.js +0 -124
- package/dist/core/workspace/registry.d.ts +0 -24
- package/dist/core/workspace/registry.js +0 -146
- package/dist/core/workspace/skills.d.ts +0 -57
- package/dist/core/workspace/skills.js +0 -334
- package/dist/core/workspace/state-io.d.ts +0 -10
- package/dist/core/workspace/state-io.js +0 -121
- package/schemas/workspace-planning/schema.yaml +0 -72
- package/schemas/workspace-planning/templates/design.md +0 -33
- package/schemas/workspace-planning/templates/proposal.md +0 -28
- package/schemas/workspace-planning/templates/spec.md +0 -9
- package/schemas/workspace-planning/templates/tasks.md +0 -15
|
@@ -56,6 +56,7 @@ export const COMMAND_REGISTRY = [
|
|
|
56
56
|
values: ['recent', 'name'],
|
|
57
57
|
},
|
|
58
58
|
COMMON_FLAGS.json,
|
|
59
|
+
COMMON_FLAGS.store,
|
|
59
60
|
],
|
|
60
61
|
},
|
|
61
62
|
{
|
|
@@ -91,6 +92,7 @@ export const COMMAND_REGISTRY = [
|
|
|
91
92
|
takesValue: true,
|
|
92
93
|
},
|
|
93
94
|
COMMON_FLAGS.noInteractive,
|
|
95
|
+
COMMON_FLAGS.store,
|
|
94
96
|
],
|
|
95
97
|
},
|
|
96
98
|
{
|
|
@@ -125,6 +127,7 @@ export const COMMAND_REGISTRY = [
|
|
|
125
127
|
description: 'Show specific requirement by ID (JSON only, spec-specific)',
|
|
126
128
|
takesValue: true,
|
|
127
129
|
},
|
|
130
|
+
COMMON_FLAGS.store,
|
|
128
131
|
],
|
|
129
132
|
},
|
|
130
133
|
{
|
|
@@ -147,6 +150,11 @@ export const COMMAND_REGISTRY = [
|
|
|
147
150
|
name: 'no-validate',
|
|
148
151
|
description: 'Skip validation (not recommended)',
|
|
149
152
|
},
|
|
153
|
+
{
|
|
154
|
+
name: 'json',
|
|
155
|
+
description: 'Output as JSON (non-interactive)',
|
|
156
|
+
},
|
|
157
|
+
COMMON_FLAGS.store,
|
|
150
158
|
],
|
|
151
159
|
},
|
|
152
160
|
{
|
|
@@ -164,6 +172,7 @@ export const COMMAND_REGISTRY = [
|
|
|
164
172
|
takesValue: true,
|
|
165
173
|
},
|
|
166
174
|
COMMON_FLAGS.json,
|
|
175
|
+
COMMON_FLAGS.store,
|
|
167
176
|
],
|
|
168
177
|
},
|
|
169
178
|
{
|
|
@@ -183,6 +192,7 @@ export const COMMAND_REGISTRY = [
|
|
|
183
192
|
takesValue: true,
|
|
184
193
|
},
|
|
185
194
|
COMMON_FLAGS.json,
|
|
195
|
+
COMMON_FLAGS.store,
|
|
186
196
|
],
|
|
187
197
|
},
|
|
188
198
|
{
|
|
@@ -222,27 +232,7 @@ export const COMMAND_REGISTRY = [
|
|
|
222
232
|
},
|
|
223
233
|
{
|
|
224
234
|
name: 'goal',
|
|
225
|
-
description: '
|
|
226
|
-
takesValue: true,
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
name: 'areas',
|
|
230
|
-
description: 'Comma-separated affected workspace link names',
|
|
231
|
-
takesValue: true,
|
|
232
|
-
},
|
|
233
|
-
{
|
|
234
|
-
name: 'initiative',
|
|
235
|
-
description: 'Link the repo-local change to an initiative',
|
|
236
|
-
takesValue: true,
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
name: 'store',
|
|
240
|
-
description: 'Context store id for --initiative',
|
|
241
|
-
takesValue: true,
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
name: 'store-path',
|
|
245
|
-
description: 'Existing local context store root for --initiative',
|
|
235
|
+
description: 'Optional goal metadata to store with the change',
|
|
246
236
|
takesValue: true,
|
|
247
237
|
},
|
|
248
238
|
{
|
|
@@ -251,254 +241,64 @@ export const COMMAND_REGISTRY = [
|
|
|
251
241
|
takesValue: true,
|
|
252
242
|
},
|
|
253
243
|
COMMON_FLAGS.json,
|
|
244
|
+
COMMON_FLAGS.store,
|
|
254
245
|
],
|
|
255
246
|
},
|
|
256
247
|
],
|
|
257
248
|
},
|
|
258
249
|
{
|
|
259
|
-
name: '
|
|
260
|
-
description: '
|
|
261
|
-
flags: [],
|
|
262
|
-
subcommands: [
|
|
263
|
-
{
|
|
264
|
-
name: 'change',
|
|
265
|
-
description: 'Set repo-local change metadata',
|
|
266
|
-
acceptsPositional: true,
|
|
267
|
-
positionalType: 'change-id',
|
|
268
|
-
positionals: [{ name: 'name', type: 'change-id' }],
|
|
269
|
-
flags: [
|
|
270
|
-
{
|
|
271
|
-
name: 'initiative',
|
|
272
|
-
description: 'Link the repo-local change to an initiative',
|
|
273
|
-
takesValue: true,
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
name: 'store',
|
|
277
|
-
description: 'Context store id for --initiative',
|
|
278
|
-
takesValue: true,
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
name: 'store-path',
|
|
282
|
-
description: 'Existing local context store root for --initiative',
|
|
283
|
-
takesValue: true,
|
|
284
|
-
},
|
|
285
|
-
COMMON_FLAGS.json,
|
|
286
|
-
],
|
|
287
|
-
},
|
|
288
|
-
],
|
|
289
|
-
},
|
|
290
|
-
{
|
|
291
|
-
name: 'workspace',
|
|
292
|
-
description: 'Set up and inspect coordination workspaces',
|
|
293
|
-
flags: [],
|
|
294
|
-
subcommands: [
|
|
295
|
-
{
|
|
296
|
-
name: 'setup',
|
|
297
|
-
description: 'Set up a workspace and link existing repos or folders',
|
|
298
|
-
flags: [
|
|
299
|
-
{
|
|
300
|
-
name: 'name',
|
|
301
|
-
description: 'Workspace name',
|
|
302
|
-
takesValue: true,
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
name: 'link',
|
|
306
|
-
description: 'Repo or folder link. Use <path> or <name>=<path>',
|
|
307
|
-
takesValue: true,
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
name: 'opener',
|
|
311
|
-
description: 'Preferred opener: codex-cli, claude, github-copilot, or editor',
|
|
312
|
-
takesValue: true,
|
|
313
|
-
values: ['codex-cli', 'claude', 'github-copilot', 'editor'],
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
name: 'tools',
|
|
317
|
-
description: 'Install OpenSpec skills for agents (all, none, or comma-separated tool IDs)',
|
|
318
|
-
takesValue: true,
|
|
319
|
-
},
|
|
320
|
-
COMMON_FLAGS.json,
|
|
321
|
-
COMMON_FLAGS.noInteractive,
|
|
322
|
-
],
|
|
323
|
-
},
|
|
324
|
-
{
|
|
325
|
-
name: 'list',
|
|
326
|
-
description: 'List known OpenSpec workspaces',
|
|
327
|
-
flags: [
|
|
328
|
-
COMMON_FLAGS.json,
|
|
329
|
-
],
|
|
330
|
-
},
|
|
331
|
-
{
|
|
332
|
-
name: 'ls',
|
|
333
|
-
description: 'List known OpenSpec workspaces',
|
|
334
|
-
flags: [
|
|
335
|
-
COMMON_FLAGS.json,
|
|
336
|
-
],
|
|
337
|
-
},
|
|
338
|
-
{
|
|
339
|
-
name: 'link',
|
|
340
|
-
description: 'Link an existing repo or folder to a workspace',
|
|
341
|
-
acceptsPositional: true,
|
|
342
|
-
positionals: [
|
|
343
|
-
{ name: 'name-or-path', type: 'path', optional: true },
|
|
344
|
-
{ name: 'path', type: 'path', optional: true },
|
|
345
|
-
],
|
|
346
|
-
flags: [
|
|
347
|
-
{
|
|
348
|
-
name: 'workspace',
|
|
349
|
-
description: 'Workspace name from local workspace views',
|
|
350
|
-
takesValue: true,
|
|
351
|
-
},
|
|
352
|
-
COMMON_FLAGS.json,
|
|
353
|
-
COMMON_FLAGS.noInteractive,
|
|
354
|
-
],
|
|
355
|
-
},
|
|
356
|
-
{
|
|
357
|
-
name: 'relink',
|
|
358
|
-
description: 'Update the local path for an existing workspace link',
|
|
359
|
-
acceptsPositional: true,
|
|
360
|
-
positionals: [
|
|
361
|
-
{ name: 'name' },
|
|
362
|
-
{ name: 'path', type: 'path' },
|
|
363
|
-
],
|
|
364
|
-
flags: [
|
|
365
|
-
{
|
|
366
|
-
name: 'workspace',
|
|
367
|
-
description: 'Workspace name from local workspace views',
|
|
368
|
-
takesValue: true,
|
|
369
|
-
},
|
|
370
|
-
COMMON_FLAGS.json,
|
|
371
|
-
COMMON_FLAGS.noInteractive,
|
|
372
|
-
],
|
|
373
|
-
},
|
|
374
|
-
{
|
|
375
|
-
name: 'doctor',
|
|
376
|
-
description: 'Check what a workspace can resolve on this machine',
|
|
377
|
-
flags: [
|
|
378
|
-
{
|
|
379
|
-
name: 'workspace',
|
|
380
|
-
description: 'Workspace name from local workspace views',
|
|
381
|
-
takesValue: true,
|
|
382
|
-
},
|
|
383
|
-
COMMON_FLAGS.json,
|
|
384
|
-
COMMON_FLAGS.noInteractive,
|
|
385
|
-
],
|
|
386
|
-
},
|
|
387
|
-
{
|
|
388
|
-
name: 'update',
|
|
389
|
-
description: 'Refresh workspace-local OpenSpec guidance and agent skills',
|
|
390
|
-
acceptsPositional: true,
|
|
391
|
-
positionals: [{ name: 'name', optional: true }],
|
|
392
|
-
flags: [
|
|
393
|
-
{
|
|
394
|
-
name: 'workspace',
|
|
395
|
-
description: 'Workspace name from local workspace views',
|
|
396
|
-
takesValue: true,
|
|
397
|
-
},
|
|
398
|
-
{
|
|
399
|
-
name: 'tools',
|
|
400
|
-
description: 'Select agents for workspace skills-only delivery; global profile selects workflows',
|
|
401
|
-
takesValue: true,
|
|
402
|
-
},
|
|
403
|
-
COMMON_FLAGS.json,
|
|
404
|
-
COMMON_FLAGS.noInteractive,
|
|
405
|
-
],
|
|
406
|
-
},
|
|
407
|
-
{
|
|
408
|
-
name: 'open',
|
|
409
|
-
description: 'Open a workspace in an agent or VS Code editor',
|
|
410
|
-
acceptsPositional: true,
|
|
411
|
-
positionals: [{ name: 'name', optional: true }],
|
|
412
|
-
flags: [
|
|
413
|
-
{
|
|
414
|
-
name: 'workspace',
|
|
415
|
-
description: 'Workspace name from local workspace views',
|
|
416
|
-
takesValue: true,
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
name: 'initiative',
|
|
420
|
-
description: 'Open an initiative as a local workspace view',
|
|
421
|
-
takesValue: true,
|
|
422
|
-
},
|
|
423
|
-
{
|
|
424
|
-
name: 'store',
|
|
425
|
-
description: 'Context store id for --initiative',
|
|
426
|
-
takesValue: true,
|
|
427
|
-
},
|
|
428
|
-
{
|
|
429
|
-
name: 'store-path',
|
|
430
|
-
description: 'Existing local context store root for --initiative',
|
|
431
|
-
takesValue: true,
|
|
432
|
-
},
|
|
433
|
-
{
|
|
434
|
-
name: 'agent',
|
|
435
|
-
description: 'Use an agent for this session: codex-cli, claude, or github-copilot',
|
|
436
|
-
takesValue: true,
|
|
437
|
-
values: ['codex-cli', 'claude', 'github-copilot'],
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
name: 'editor',
|
|
441
|
-
description: 'Open the workspace in VS Code editor mode',
|
|
442
|
-
},
|
|
443
|
-
{
|
|
444
|
-
name: 'prepare-only',
|
|
445
|
-
description: 'Unsupported: preview surfaces belong to a future context/query command',
|
|
446
|
-
},
|
|
447
|
-
COMMON_FLAGS.json,
|
|
448
|
-
{
|
|
449
|
-
name: 'change',
|
|
450
|
-
description: 'Unsupported: change-scoped open belongs to future workspace change planning',
|
|
451
|
-
takesValue: true,
|
|
452
|
-
},
|
|
453
|
-
COMMON_FLAGS.noInteractive,
|
|
454
|
-
],
|
|
455
|
-
},
|
|
456
|
-
],
|
|
457
|
-
},
|
|
458
|
-
{
|
|
459
|
-
name: 'context-store',
|
|
460
|
-
description: 'Set up and inspect context stores',
|
|
250
|
+
name: 'store',
|
|
251
|
+
description: 'Create and manage stores - standalone OpenSpec repos you register on this machine',
|
|
461
252
|
flags: [],
|
|
462
253
|
subcommands: [
|
|
463
254
|
{
|
|
464
255
|
name: 'setup',
|
|
465
|
-
description: 'Create or register a local
|
|
256
|
+
description: 'Create or register a local store',
|
|
466
257
|
acceptsPositional: true,
|
|
467
258
|
positionals: [{ name: 'id', optional: true }],
|
|
468
259
|
flags: [
|
|
469
260
|
{
|
|
470
261
|
name: 'path',
|
|
471
|
-
description: 'Directory to use for the
|
|
262
|
+
description: 'Directory to use for the store',
|
|
472
263
|
takesValue: true,
|
|
473
264
|
},
|
|
474
265
|
{
|
|
475
266
|
name: 'init-git',
|
|
476
|
-
description: 'Initialize a Git repository in the
|
|
267
|
+
description: 'Initialize a Git repository in the store',
|
|
477
268
|
},
|
|
478
269
|
{
|
|
479
270
|
name: 'no-init-git',
|
|
480
271
|
description: 'Skip Git repository initialization',
|
|
481
272
|
},
|
|
273
|
+
{
|
|
274
|
+
name: 'remote',
|
|
275
|
+
description: 'Canonical clone source recorded in store.yaml',
|
|
276
|
+
takesValue: true,
|
|
277
|
+
},
|
|
482
278
|
COMMON_FLAGS.json,
|
|
483
279
|
],
|
|
484
280
|
},
|
|
485
281
|
{
|
|
486
282
|
name: 'register',
|
|
487
|
-
description: 'Register an existing
|
|
283
|
+
description: 'Register an existing store directory',
|
|
488
284
|
acceptsPositional: true,
|
|
489
285
|
positionals: [{ name: 'path', type: 'path', optional: true }],
|
|
490
286
|
flags: [
|
|
491
287
|
{
|
|
492
288
|
name: 'id',
|
|
493
|
-
description: '
|
|
289
|
+
description: 'Store id',
|
|
494
290
|
takesValue: true,
|
|
495
291
|
},
|
|
292
|
+
{
|
|
293
|
+
name: 'yes',
|
|
294
|
+
description: 'Confirm creating store identity metadata',
|
|
295
|
+
},
|
|
496
296
|
COMMON_FLAGS.json,
|
|
497
297
|
],
|
|
498
298
|
},
|
|
499
299
|
{
|
|
500
300
|
name: 'unregister',
|
|
501
|
-
description: 'Forget a local
|
|
301
|
+
description: 'Forget a local store registration without deleting files',
|
|
502
302
|
acceptsPositional: true,
|
|
503
303
|
positionals: [{ name: 'id' }],
|
|
504
304
|
flags: [
|
|
@@ -507,34 +307,34 @@ export const COMMAND_REGISTRY = [
|
|
|
507
307
|
},
|
|
508
308
|
{
|
|
509
309
|
name: 'remove',
|
|
510
|
-
description: 'Forget a local
|
|
310
|
+
description: 'Forget a local store registration and delete its local folder',
|
|
511
311
|
acceptsPositional: true,
|
|
512
312
|
positionals: [{ name: 'id' }],
|
|
513
313
|
flags: [
|
|
514
314
|
{
|
|
515
315
|
name: 'yes',
|
|
516
|
-
description: 'Confirm local
|
|
316
|
+
description: 'Confirm local store folder deletion',
|
|
517
317
|
},
|
|
518
318
|
COMMON_FLAGS.json,
|
|
519
319
|
],
|
|
520
320
|
},
|
|
521
321
|
{
|
|
522
322
|
name: 'list',
|
|
523
|
-
description: 'List registered
|
|
323
|
+
description: 'List registered stores',
|
|
524
324
|
flags: [
|
|
525
325
|
COMMON_FLAGS.json,
|
|
526
326
|
],
|
|
527
327
|
},
|
|
528
328
|
{
|
|
529
329
|
name: 'ls',
|
|
530
|
-
description: 'List registered
|
|
330
|
+
description: 'List registered stores',
|
|
531
331
|
flags: [
|
|
532
332
|
COMMON_FLAGS.json,
|
|
533
333
|
],
|
|
534
334
|
},
|
|
535
335
|
{
|
|
536
336
|
name: 'doctor',
|
|
537
|
-
description: 'Check local
|
|
337
|
+
description: 'Check local store registration and metadata',
|
|
538
338
|
acceptsPositional: true,
|
|
539
339
|
positionals: [{ name: 'id', optional: true }],
|
|
540
340
|
flags: [
|
|
@@ -544,88 +344,86 @@ export const COMMAND_REGISTRY = [
|
|
|
544
344
|
],
|
|
545
345
|
},
|
|
546
346
|
{
|
|
547
|
-
name: '
|
|
548
|
-
description: '
|
|
347
|
+
name: 'context',
|
|
348
|
+
description: 'Print the working context for the resolved OpenSpec root',
|
|
349
|
+
flags: [
|
|
350
|
+
COMMON_FLAGS.json,
|
|
351
|
+
COMMON_FLAGS.store,
|
|
352
|
+
{
|
|
353
|
+
name: 'code-workspace',
|
|
354
|
+
description: 'Also write a VS Code workspace file for the set',
|
|
355
|
+
takesValue: true,
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
name: 'force',
|
|
359
|
+
description: 'Overwrite an existing --code-workspace file',
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
name: 'doctor',
|
|
365
|
+
description: 'Report relationship health for the resolved OpenSpec root',
|
|
366
|
+
flags: [
|
|
367
|
+
COMMON_FLAGS.json,
|
|
368
|
+
COMMON_FLAGS.store,
|
|
369
|
+
],
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
name: 'workset',
|
|
373
|
+
description: 'Compose, keep, and open personal working views (purely local)',
|
|
549
374
|
flags: [],
|
|
550
375
|
subcommands: [
|
|
551
376
|
{
|
|
552
377
|
name: 'create',
|
|
553
|
-
description: '
|
|
378
|
+
description: 'Compose and save a named working view of folders you choose',
|
|
554
379
|
acceptsPositional: true,
|
|
555
|
-
positionals: [{ name: '
|
|
380
|
+
positionals: [{ name: 'name', optional: true }],
|
|
556
381
|
flags: [
|
|
557
382
|
{
|
|
558
|
-
name: '
|
|
559
|
-
description: '
|
|
383
|
+
name: 'member',
|
|
384
|
+
description: 'Member folder as <path> or <name>=<path>; repeatable, first is the primary',
|
|
560
385
|
takesValue: true,
|
|
561
386
|
},
|
|
562
387
|
{
|
|
563
|
-
name: '
|
|
564
|
-
description: '
|
|
565
|
-
takesValue: true,
|
|
566
|
-
},
|
|
567
|
-
{
|
|
568
|
-
name: 'title',
|
|
569
|
-
description: 'Initiative title',
|
|
570
|
-
takesValue: true,
|
|
571
|
-
},
|
|
572
|
-
{
|
|
573
|
-
name: 'summary',
|
|
574
|
-
description: 'Initiative summary',
|
|
388
|
+
name: 'tool',
|
|
389
|
+
description: 'Preferred tool to open this workset with',
|
|
575
390
|
takesValue: true,
|
|
576
391
|
},
|
|
577
392
|
COMMON_FLAGS.json,
|
|
578
393
|
],
|
|
579
394
|
},
|
|
580
395
|
{
|
|
581
|
-
name: '
|
|
582
|
-
description: 'Show
|
|
583
|
-
|
|
584
|
-
positionals: [{ name: 'id' }],
|
|
585
|
-
flags: [
|
|
586
|
-
{
|
|
587
|
-
name: 'store',
|
|
588
|
-
description: 'Context store id from the local context-store registry',
|
|
589
|
-
takesValue: true,
|
|
590
|
-
},
|
|
591
|
-
{
|
|
592
|
-
name: 'store-path',
|
|
593
|
-
description: 'Existing local context store root',
|
|
594
|
-
takesValue: true,
|
|
595
|
-
},
|
|
596
|
-
COMMON_FLAGS.json,
|
|
597
|
-
],
|
|
396
|
+
name: 'list',
|
|
397
|
+
description: 'Show saved worksets with their members',
|
|
398
|
+
flags: [COMMON_FLAGS.json],
|
|
598
399
|
},
|
|
599
400
|
{
|
|
600
|
-
name: '
|
|
601
|
-
description: '
|
|
401
|
+
name: 'ls',
|
|
402
|
+
description: 'Show saved worksets with their members',
|
|
403
|
+
flags: [COMMON_FLAGS.json],
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: 'open',
|
|
407
|
+
description: 'Open a saved workset in your tool (editor window or agent session)',
|
|
408
|
+
acceptsPositional: true,
|
|
409
|
+
positionals: [{ name: 'name' }],
|
|
602
410
|
flags: [
|
|
603
411
|
{
|
|
604
|
-
name: '
|
|
605
|
-
description: '
|
|
412
|
+
name: 'tool',
|
|
413
|
+
description: 'Open with this tool just this once',
|
|
606
414
|
takesValue: true,
|
|
607
415
|
},
|
|
608
|
-
{
|
|
609
|
-
name: 'store-path',
|
|
610
|
-
description: 'Existing local context store root',
|
|
611
|
-
takesValue: true,
|
|
612
|
-
},
|
|
613
|
-
COMMON_FLAGS.json,
|
|
614
416
|
],
|
|
615
417
|
},
|
|
616
418
|
{
|
|
617
|
-
name: '
|
|
618
|
-
description: '
|
|
419
|
+
name: 'remove',
|
|
420
|
+
description: 'Delete a saved workset (member folders are never touched)',
|
|
421
|
+
acceptsPositional: true,
|
|
422
|
+
positionals: [{ name: 'name' }],
|
|
619
423
|
flags: [
|
|
620
424
|
{
|
|
621
|
-
name: '
|
|
622
|
-
description: '
|
|
623
|
-
takesValue: true,
|
|
624
|
-
},
|
|
625
|
-
{
|
|
626
|
-
name: 'store-path',
|
|
627
|
-
description: 'Existing local context store root',
|
|
628
|
-
takesValue: true,
|
|
425
|
+
name: 'yes',
|
|
426
|
+
description: 'Confirm removal non-interactively',
|
|
629
427
|
},
|
|
630
428
|
COMMON_FLAGS.json,
|
|
631
429
|
],
|
|
@@ -250,7 +250,9 @@ compdef _openspec openspec
|
|
|
250
250
|
escapeDescription(desc) {
|
|
251
251
|
return desc
|
|
252
252
|
.replace(/\\/g, '\\\\')
|
|
253
|
-
|
|
253
|
+
// Inside zsh single quotes, backslash-quote does NOT escape; the
|
|
254
|
+
// idiom is close-quote, literal quote, reopen: '\''
|
|
255
|
+
.replace(/'/g, "'\\''")
|
|
254
256
|
.replace(/\[/g, '\\[')
|
|
255
257
|
.replace(/]/g, '\\]')
|
|
256
258
|
.replace(/:/g, '\\:');
|
|
@@ -210,6 +210,9 @@ export class BashInstaller {
|
|
|
210
210
|
// File doesn't exist or can't be read, proceed with installation
|
|
211
211
|
console.debug(`Unable to read existing completion file at ${targetPath}: ${error.message}`);
|
|
212
212
|
}
|
|
213
|
+
if (!(await FileSystemUtils.canWriteFile(targetPath))) {
|
|
214
|
+
throw new Error(`Path is not writable: ${targetPath}`);
|
|
215
|
+
}
|
|
213
216
|
// Ensure the directory exists
|
|
214
217
|
const targetDir = path.dirname(targetPath);
|
|
215
218
|
await fs.mkdir(targetDir, { recursive: true });
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
|
+
import { FileSystemUtils } from '../../../utils/file-system.js';
|
|
4
5
|
/**
|
|
5
6
|
* Installer for Fish completion scripts.
|
|
6
7
|
* Fish automatically loads completions from ~/.config/fish/completions/
|
|
@@ -70,6 +71,9 @@ export class FishInstaller {
|
|
|
70
71
|
// File doesn't exist or can't be read, proceed with installation
|
|
71
72
|
console.debug(`Unable to read existing completion file at ${targetPath}: ${error.message}`);
|
|
72
73
|
}
|
|
74
|
+
if (!(await FileSystemUtils.canWriteFile(targetPath))) {
|
|
75
|
+
throw new Error(`Path is not writable: ${targetPath}`);
|
|
76
|
+
}
|
|
73
77
|
// Ensure the directory exists
|
|
74
78
|
const targetDir = path.dirname(targetPath);
|
|
75
79
|
await fs.mkdir(targetDir, { recursive: true });
|
|
@@ -125,6 +129,10 @@ export class FishInstaller {
|
|
|
125
129
|
message: 'Completion script is not installed',
|
|
126
130
|
};
|
|
127
131
|
}
|
|
132
|
+
const targetDir = path.dirname(targetPath);
|
|
133
|
+
if (!(await FileSystemUtils.canWriteFile(targetDir))) {
|
|
134
|
+
throw new Error(`Path is not writable: ${targetDir}`);
|
|
135
|
+
}
|
|
128
136
|
// Remove the completion script
|
|
129
137
|
await fs.unlink(targetPath);
|
|
130
138
|
return {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
|
+
import { FileSystemUtils } from '../../../utils/file-system.js';
|
|
4
5
|
/**
|
|
5
6
|
* Installer for PowerShell completion scripts.
|
|
6
7
|
* Works with both Windows PowerShell 5.1 and PowerShell Core 7+
|
|
@@ -154,9 +155,23 @@ export class PowerShellInstaller {
|
|
|
154
155
|
let anyConfigured = false;
|
|
155
156
|
for (const profilePath of profilePaths) {
|
|
156
157
|
try {
|
|
157
|
-
// Create profile file if it doesn't exist
|
|
158
158
|
const profileDir = path.dirname(profilePath);
|
|
159
|
-
|
|
159
|
+
let profileExists = false;
|
|
160
|
+
try {
|
|
161
|
+
await fs.access(profilePath);
|
|
162
|
+
profileExists = true;
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
if (err?.code !== 'ENOENT') {
|
|
166
|
+
throw err;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (!profileExists) {
|
|
170
|
+
if (!(await FileSystemUtils.canWriteFile(profilePath))) {
|
|
171
|
+
throw new Error(`Path is not writable: ${profilePath}`);
|
|
172
|
+
}
|
|
173
|
+
await fs.mkdir(profileDir, { recursive: true });
|
|
174
|
+
}
|
|
160
175
|
let profileContent = '';
|
|
161
176
|
let fileEncoding = 'utf-8';
|
|
162
177
|
let fileBom = Buffer.alloc(0);
|
|
@@ -191,6 +206,9 @@ export class PowerShellInstaller {
|
|
|
191
206
|
'',
|
|
192
207
|
].join('\n');
|
|
193
208
|
const newContent = profileContent + openspecBlock;
|
|
209
|
+
if (!(await FileSystemUtils.canWriteFile(profilePath))) {
|
|
210
|
+
throw new Error(`Path is not writable: ${profilePath}`);
|
|
211
|
+
}
|
|
194
212
|
await this.writeProfileFile(profilePath, newContent, fileEncoding, fileBom);
|
|
195
213
|
anyConfigured = true;
|
|
196
214
|
}
|
|
@@ -246,6 +264,9 @@ export class PowerShellInstaller {
|
|
|
246
264
|
const afterBlock = profileContent.substring(endIndex + endMarker.length);
|
|
247
265
|
// Clean up extra newlines
|
|
248
266
|
const newContent = (beforeBlock.trimEnd() + '\n' + afterBlock.trimStart()).trim() + '\n';
|
|
267
|
+
if (!(await FileSystemUtils.canWriteFile(profilePath))) {
|
|
268
|
+
throw new Error(`Path is not writable: ${profilePath}`);
|
|
269
|
+
}
|
|
249
270
|
await this.writeProfileFile(profilePath, newContent, fileEncoding, fileBom);
|
|
250
271
|
anyRemoved = true;
|
|
251
272
|
}
|
|
@@ -287,6 +308,9 @@ export class PowerShellInstaller {
|
|
|
287
308
|
// File doesn't exist or can't be read, proceed with installation
|
|
288
309
|
console.debug(`Unable to read existing completion file at ${targetPath}: ${error.message}`);
|
|
289
310
|
}
|
|
311
|
+
if (!(await FileSystemUtils.canWriteFile(targetPath))) {
|
|
312
|
+
throw new Error(`Path is not writable: ${targetPath}`);
|
|
313
|
+
}
|
|
290
314
|
// Ensure the directory exists
|
|
291
315
|
const targetDir = path.dirname(targetPath);
|
|
292
316
|
await fs.mkdir(targetDir, { recursive: true });
|
|
@@ -367,6 +391,10 @@ export class PowerShellInstaller {
|
|
|
367
391
|
message: 'Completion script is not installed',
|
|
368
392
|
};
|
|
369
393
|
}
|
|
394
|
+
const targetDir = path.dirname(targetPath);
|
|
395
|
+
if (!(await FileSystemUtils.canWriteFile(targetDir))) {
|
|
396
|
+
throw new Error(`Path is not writable: ${targetDir}`);
|
|
397
|
+
}
|
|
370
398
|
// Remove the completion script
|
|
371
399
|
await fs.unlink(targetPath);
|
|
372
400
|
// Remove profile configuration
|
|
@@ -228,6 +228,9 @@ export class ZshInstaller {
|
|
|
228
228
|
// File doesn't exist or can't be read, proceed with installation
|
|
229
229
|
console.debug(`Unable to read existing completion file at ${targetPath}: ${error.message}`);
|
|
230
230
|
}
|
|
231
|
+
if (!(await FileSystemUtils.canWriteFile(targetPath))) {
|
|
232
|
+
throw new Error(`Path is not writable: ${targetPath}`);
|
|
233
|
+
}
|
|
231
234
|
// Ensure the directory exists
|
|
232
235
|
const targetDir = path.dirname(targetPath);
|
|
233
236
|
await fs.mkdir(targetDir, { recursive: true });
|