@fission-ai/openspec 1.14.0 → 1.14.2
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 +15 -31
- package/dist/cli/commands/config.d.ts +8 -0
- package/dist/cli/commands/config.js +88 -0
- package/dist/cli/commands/context.d.ts +3 -0
- package/dist/cli/commands/context.js +20 -0
- package/dist/cli/commands/doctor.d.ts +3 -0
- package/dist/cli/commands/doctor.js +18 -0
- package/dist/cli/commands/schema.d.ts +6 -0
- package/dist/cli/commands/schema.js +57 -0
- package/dist/cli/commands/spec.d.ts +3 -0
- package/dist/cli/commands/spec.js +42 -0
- package/dist/cli/commands/store.d.ts +3 -0
- package/dist/cli/commands/store.js +130 -0
- package/dist/cli/commands/workset.d.ts +3 -0
- package/dist/cli/commands/workset.js +96 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.js +86 -43
- package/dist/commands/completion.js +4 -1
- package/dist/commands/config.d.ts +16 -7
- package/dist/commands/config.js +342 -395
- package/dist/commands/context.d.ts +8 -2
- package/dist/commands/context.js +22 -37
- package/dist/commands/doctor.d.ts +6 -7
- package/dist/commands/doctor.js +14 -27
- package/dist/commands/schema.d.ts +19 -5
- package/dist/commands/schema.js +662 -702
- package/dist/commands/spec.d.ts +13 -4
- package/dist/commands/spec.js +91 -120
- package/dist/commands/store.d.ts +27 -2
- package/dist/commands/store.js +1 -120
- package/dist/commands/workflow/default-schema.d.ts +2 -0
- package/dist/commands/workflow/default-schema.js +4 -0
- package/dist/commands/workflow/instructions.js +1 -1
- package/dist/commands/workflow/shared.d.ts +1 -1
- package/dist/commands/workflow/shared.js +1 -1
- package/dist/commands/workset.d.ts +22 -2
- package/dist/commands/workset.js +1 -88
- package/dist/core/archive.js +32 -12
- package/dist/core/artifact-graph/outputs.js +39 -1
- package/dist/core/completion-tip.js +3 -1
- package/dist/core/completions/completion-provider.js +4 -2
- package/dist/core/config-schema.d.ts +1 -1
- package/dist/core/parsers/requirement-blocks.d.ts +11 -0
- package/dist/core/parsers/requirement-blocks.js +57 -0
- package/dist/core/specs-apply.js +5 -1
- package/dist/core/templates/workflows/apply-change.js +4 -3
- package/dist/core/templates/workflows/continue-change.js +17 -0
- package/dist/core/templates/workflows/explore.js +8 -4
- package/dist/core/templates/workflows/update-change.js +4 -4
- package/dist/core/templates/workflows/verify-change.js +26 -20
- package/dist/core/validation/validator.js +23 -2
- package/dist/core/view.js +2 -26
- package/dist/utils/change-metadata.d.ts +17 -0
- package/dist/utils/change-metadata.js +27 -2
- package/dist/utils/file-system.d.ts +7 -0
- package/dist/utils/file-system.js +25 -0
- package/package.json +1 -1
- package/schemas/spec-driven/schema.yaml +28 -4
package/dist/cli/index.js
CHANGED
|
@@ -1,34 +1,22 @@
|
|
|
1
|
-
import { asStatus } from '../commands/shared-output.js';
|
|
2
1
|
import { Command, Option } from 'commander';
|
|
3
2
|
import { createRequire } from 'module';
|
|
4
|
-
import ora from 'ora';
|
|
5
3
|
import path from 'path';
|
|
6
4
|
import { fileURLToPath } from 'url';
|
|
7
5
|
import { existsSync, promises as fs } from 'fs';
|
|
8
6
|
import { AI_TOOLS, TOOL_ID_ALIASES } from '../core/config.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { ValidateCommand } from '../commands/validate.js';
|
|
18
|
-
import { ShowCommand } from '../commands/show.js';
|
|
19
|
-
import { CompletionCommand } from '../commands/completion.js';
|
|
20
|
-
import { FeedbackCommand } from '../commands/feedback.js';
|
|
21
|
-
import { registerConfigCommand } from '../commands/config.js';
|
|
22
|
-
import { registerSchemaCommand } from '../commands/schema.js';
|
|
23
|
-
import { registerStoreCommand } from '../commands/store.js';
|
|
24
|
-
import { registerDoctorCommand } from '../commands/doctor.js';
|
|
25
|
-
import { registerContextCommand } from '../commands/context.js';
|
|
26
|
-
import { registerWorksetCommand } from '../commands/workset.js';
|
|
27
|
-
import { statusCommand, BATCH_STATUS_FAILURE_PAYLOAD, instructionsCommand, applyInstructionsCommand, archiveInstructionsCommand, templatesCommand, schemasCommand, newChangeCommand, DEFAULT_SCHEMA, } from '../commands/workflow/index.js';
|
|
28
|
-
import { maybeShowTelemetryNotice, trackCommand, shutdown } from '../telemetry/index.js';
|
|
29
|
-
import { maybeShowCompletionTip } from '../core/completion-tip.js';
|
|
7
|
+
import { registerSpecCommand } from './commands/spec.js';
|
|
8
|
+
import { registerConfigCommand } from './commands/config.js';
|
|
9
|
+
import { registerSchemaCommand } from './commands/schema.js';
|
|
10
|
+
import { registerStoreCommand } from './commands/store.js';
|
|
11
|
+
import { registerDoctorCommand } from './commands/doctor.js';
|
|
12
|
+
import { registerContextCommand } from './commands/context.js';
|
|
13
|
+
import { registerWorksetCommand } from './commands/workset.js';
|
|
14
|
+
import { DEFAULT_SCHEMA } from '../commands/workflow/default-schema.js';
|
|
30
15
|
import { COMMON_FLAGS } from '../core/completions/shared-flags.js';
|
|
31
|
-
|
|
16
|
+
// Startup cost: every command's implementation, and the packages it uses,
|
|
17
|
+
// loads with `await import()` inside its action. This module and
|
|
18
|
+
// ./commands/ only define commands (names, options, help), so `--version`,
|
|
19
|
+
// `--help`, and each command load no other command's implementation.
|
|
32
20
|
const STORE_OPTION_DESCRIPTION = COMMON_FLAGS.store.description;
|
|
33
21
|
// Deliberate rejection path: --store-path stays registered (hidden) so the
|
|
34
22
|
// resolver can explain that registering the path is the supported route,
|
|
@@ -37,14 +25,16 @@ const STORE_OPTION_DESCRIPTION = COMMON_FLAGS.store.description;
|
|
|
37
25
|
function hiddenStorePathOption() {
|
|
38
26
|
return new Option('--store-path <path>', 'Not supported; register the path with "openspec store register <path>" and use --store <id>').hideHelp();
|
|
39
27
|
}
|
|
40
|
-
function failWithError(error, json) {
|
|
28
|
+
async function failWithError(error, json) {
|
|
41
29
|
// The agent contract: every --json failure leaves exactly one JSON
|
|
42
30
|
// document on stdout (the command's null-shape plus a status array).
|
|
43
31
|
if (json?.enabled) {
|
|
32
|
+
const { asStatus } = await import('../commands/shared-output.js');
|
|
44
33
|
console.log(JSON.stringify({ ...(json.payload ?? {}), status: [asStatus(error, json.fallbackCode ?? 'command_error')] }, null, 2));
|
|
45
34
|
process.exitCode = 1;
|
|
46
35
|
return;
|
|
47
36
|
}
|
|
37
|
+
const { default: ora } = await import('ora');
|
|
48
38
|
ora().fail(`Error: ${error.message}`);
|
|
49
39
|
// Resolution and store errors carry a pasteable fix - never drop it.
|
|
50
40
|
const fix = error.diagnostic?.fix;
|
|
@@ -100,6 +90,13 @@ export function isJsonRun(command) {
|
|
|
100
90
|
export function isCompletionRun(commandPath) {
|
|
101
91
|
return commandPath.split(':')[0] === 'completion' || commandPath === '__complete';
|
|
102
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* True for the hidden `__complete` resolver alone. It runs on every Tab press,
|
|
95
|
+
* so the hooks skip telemetry and the completion tip for it entirely.
|
|
96
|
+
*/
|
|
97
|
+
export function isTabCompletionRun(commandPath) {
|
|
98
|
+
return commandPath === '__complete';
|
|
99
|
+
}
|
|
103
100
|
/**
|
|
104
101
|
* True when the first-run completions tip must be deferred rather than shown.
|
|
105
102
|
*
|
|
@@ -124,6 +121,7 @@ program
|
|
|
124
121
|
.option('--json', 'Output as JSON')
|
|
125
122
|
.option('--check', 'Check the registry for a newer version')
|
|
126
123
|
.action(async (options) => {
|
|
124
|
+
const { getCliInstallInfo, checkForCliUpdate, getCliUpdateCommand, canSelfUpgrade, buildVersionReportLines, } = await import('../core/version-check.js');
|
|
127
125
|
const install = getCliInstallInfo();
|
|
128
126
|
const update = options.check ? await checkForCliUpdate() : undefined;
|
|
129
127
|
const command = update?.status === 'available' ? getCliUpdateCommand(install) : null;
|
|
@@ -158,9 +156,16 @@ program.hook('preAction', async (thisCommand, actionCommand) => {
|
|
|
158
156
|
if (opts.color === false) {
|
|
159
157
|
process.env.NO_COLOR = '1';
|
|
160
158
|
}
|
|
159
|
+
// `__complete` runs on every Tab press, with stderr sent to /dev/null by the
|
|
160
|
+
// generated scripts. Tracking it would hold each press open for the request,
|
|
161
|
+
// and the first-run notice would be marked seen without anyone reading it.
|
|
162
|
+
if (isTabCompletionRun(getCommandPath(actionCommand))) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
161
165
|
// Show first-run telemetry notice (if not seen). It's written to stderr, so it
|
|
162
166
|
// never pollutes stdout — but --json runs still defer it (see isJsonRun) so the
|
|
163
167
|
// very first invocation stays free of any incidental output on either stream.
|
|
168
|
+
const { maybeShowTelemetryNotice, trackCommand } = await import('../telemetry/index.js');
|
|
164
169
|
await maybeShowTelemetryNotice({ silent: isJsonRun(actionCommand) });
|
|
165
170
|
// Track command execution (use actionCommand to get the actual subcommand)
|
|
166
171
|
const commandPath = getCommandPath(actionCommand);
|
|
@@ -168,6 +173,11 @@ program.hook('preAction', async (thisCommand, actionCommand) => {
|
|
|
168
173
|
});
|
|
169
174
|
// Shutdown telemetry after command completes
|
|
170
175
|
program.hook('postAction', async (_thisCommand, actionCommand) => {
|
|
176
|
+
// Nothing to flush (preAction tracked nothing), and the tip is always
|
|
177
|
+
// deferred for completion runs, so skip loading either module.
|
|
178
|
+
if (isTabCompletionRun(getCommandPath(actionCommand))) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
171
181
|
// Show the first-run shell-completions tip (on stderr, so piped stdout stays
|
|
172
182
|
// clean). postAction, not preAction: the tip trails the command's own output
|
|
173
183
|
// instead of pushing an error message or `init`'s setup summary down the
|
|
@@ -175,6 +185,7 @@ program.hook('postAction', async (_thisCommand, actionCommand) => {
|
|
|
175
185
|
// `openspec completion ...`, and a stderr that is not a terminal (agents and
|
|
176
186
|
// pipes would otherwise silently burn the user's one-shot tip).
|
|
177
187
|
try {
|
|
188
|
+
const { maybeShowCompletionTip } = await import('../core/completion-tip.js');
|
|
178
189
|
await maybeShowCompletionTip({
|
|
179
190
|
silent: shouldDeferCompletionTip(actionCommand, Boolean(process.stderr.isTTY)),
|
|
180
191
|
});
|
|
@@ -182,6 +193,7 @@ program.hook('postAction', async (_thisCommand, actionCommand) => {
|
|
|
182
193
|
finally {
|
|
183
194
|
// The flush runs even if the hint throws: parse() is synchronous, so a
|
|
184
195
|
// rejection here has no catch anywhere above it.
|
|
196
|
+
const { shutdown } = await import('../telemetry/index.js');
|
|
185
197
|
await shutdown();
|
|
186
198
|
}
|
|
187
199
|
});
|
|
@@ -236,7 +248,7 @@ program
|
|
|
236
248
|
await initCommand.execute(targetPath);
|
|
237
249
|
}
|
|
238
250
|
catch (error) {
|
|
239
|
-
failWithError(error);
|
|
251
|
+
await failWithError(error);
|
|
240
252
|
process.exit(1);
|
|
241
253
|
}
|
|
242
254
|
});
|
|
@@ -257,7 +269,7 @@ program
|
|
|
257
269
|
await initCommand.execute('.');
|
|
258
270
|
}
|
|
259
271
|
catch (error) {
|
|
260
|
-
failWithError(error);
|
|
272
|
+
await failWithError(error);
|
|
261
273
|
process.exit(1);
|
|
262
274
|
}
|
|
263
275
|
});
|
|
@@ -267,6 +279,11 @@ program
|
|
|
267
279
|
.option('--force', 'Force update even when tools are up to date')
|
|
268
280
|
.action(async (targetPath = '.', options) => {
|
|
269
281
|
try {
|
|
282
|
+
const [{ getInstallDir, isSourceCheckout, getAvailableCliUpdate, shouldOfferUpgrade, displayCliUpdateNote, offerCliUpgrade, rerunUpdateWithUpgradedCli, displayUpgradeCommand, }, { isInteractive }, { UpdateCommand },] = await Promise.all([
|
|
283
|
+
import('../core/version-check.js'),
|
|
284
|
+
import('../utils/interactive.js'),
|
|
285
|
+
import('../core/update.js'),
|
|
286
|
+
]);
|
|
270
287
|
const installDir = getInstallDir();
|
|
271
288
|
// Running from a clone: the version is whatever the branch says, so any
|
|
272
289
|
// upgrade advice would be noise. Decided before the request, so a
|
|
@@ -318,7 +335,7 @@ program
|
|
|
318
335
|
}
|
|
319
336
|
}
|
|
320
337
|
catch (error) {
|
|
321
|
-
failWithError(error);
|
|
338
|
+
await failWithError(error);
|
|
322
339
|
process.exit(1);
|
|
323
340
|
}
|
|
324
341
|
});
|
|
@@ -338,6 +355,10 @@ program
|
|
|
338
355
|
if (options?.specs && (options.archived || options.all)) {
|
|
339
356
|
throw new Error('--archived and --all can only be used when listing changes.');
|
|
340
357
|
}
|
|
358
|
+
const [{ resolveRootForCommand, toRootOutput }, { ListCommand }] = await Promise.all([
|
|
359
|
+
import('../core/root-selection.js'),
|
|
360
|
+
import('../core/list.js'),
|
|
361
|
+
]);
|
|
341
362
|
const root = await resolveRootForCommand(options ?? {}, {
|
|
342
363
|
json: options?.json,
|
|
343
364
|
failurePayload: options?.specs ? { specs: [], root: null } : { changes: [], root: null },
|
|
@@ -360,7 +381,7 @@ program
|
|
|
360
381
|
});
|
|
361
382
|
}
|
|
362
383
|
catch (error) {
|
|
363
|
-
failWithError(error, {
|
|
384
|
+
await failWithError(error, {
|
|
364
385
|
enabled: options?.json,
|
|
365
386
|
payload: options?.specs ? { specs: [], root: null } : { changes: [], root: null },
|
|
366
387
|
fallbackCode: 'list_error',
|
|
@@ -378,6 +399,10 @@ program
|
|
|
378
399
|
// Implicit cwd fallback stays enabled so `view` keeps accepting the same
|
|
379
400
|
// directories as `list`/`status` — notably pre-config.yaml `openspec/`
|
|
380
401
|
// dirs. ViewCommand still reports a missing openspec/ directory itself.
|
|
402
|
+
const [{ resolveRootForCommand }, { ViewCommand }] = await Promise.all([
|
|
403
|
+
import('../core/root-selection.js'),
|
|
404
|
+
import('../core/view.js'),
|
|
405
|
+
]);
|
|
381
406
|
const root = await resolveRootForCommand(options ?? {});
|
|
382
407
|
if (!root) {
|
|
383
408
|
return;
|
|
@@ -386,7 +411,7 @@ program
|
|
|
386
411
|
await viewCommand.execute(root.path);
|
|
387
412
|
}
|
|
388
413
|
catch (error) {
|
|
389
|
-
failWithError(error);
|
|
414
|
+
await failWithError(error);
|
|
390
415
|
process.exit(1);
|
|
391
416
|
}
|
|
392
417
|
});
|
|
@@ -408,6 +433,7 @@ changeCmd
|
|
|
408
433
|
.option('--no-interactive', 'Disable interactive prompts')
|
|
409
434
|
.action(async (changeName, options) => {
|
|
410
435
|
try {
|
|
436
|
+
const { ChangeCommand } = await import('../commands/change.js');
|
|
411
437
|
const changeCommand = new ChangeCommand();
|
|
412
438
|
await changeCommand.show(changeName, options);
|
|
413
439
|
}
|
|
@@ -424,6 +450,7 @@ changeCmd
|
|
|
424
450
|
.action(async (options) => {
|
|
425
451
|
try {
|
|
426
452
|
console.error('Warning: "openspec change list" is deprecated. Use "openspec list".');
|
|
453
|
+
const { ChangeCommand } = await import('../commands/change.js');
|
|
427
454
|
const changeCommand = new ChangeCommand();
|
|
428
455
|
await changeCommand.list(options);
|
|
429
456
|
}
|
|
@@ -440,6 +467,7 @@ changeCmd
|
|
|
440
467
|
.option('--no-interactive', 'Disable interactive prompts')
|
|
441
468
|
.action(async (changeName, options) => {
|
|
442
469
|
try {
|
|
470
|
+
const { ChangeCommand } = await import('../commands/change.js');
|
|
443
471
|
const changeCommand = new ChangeCommand();
|
|
444
472
|
// validate() already sets process.exitCode, and Node honours it at
|
|
445
473
|
// natural exit. Calling process.exit() here would skip commander's
|
|
@@ -464,11 +492,12 @@ program
|
|
|
464
492
|
.addOption(hiddenStorePathOption())
|
|
465
493
|
.action(async (changeName, options) => {
|
|
466
494
|
try {
|
|
495
|
+
const { ArchiveCommand } = await import('../core/archive.js');
|
|
467
496
|
const archiveCommand = new ArchiveCommand();
|
|
468
497
|
await archiveCommand.execute(changeName, options);
|
|
469
498
|
}
|
|
470
499
|
catch (error) {
|
|
471
|
-
failWithError(error);
|
|
500
|
+
await failWithError(error);
|
|
472
501
|
process.exit(1);
|
|
473
502
|
}
|
|
474
503
|
});
|
|
@@ -497,11 +526,12 @@ program
|
|
|
497
526
|
.addOption(hiddenStorePathOption())
|
|
498
527
|
.action(async (itemName, options) => {
|
|
499
528
|
try {
|
|
529
|
+
const { ValidateCommand } = await import('../commands/validate.js');
|
|
500
530
|
const validateCommand = new ValidateCommand();
|
|
501
531
|
await validateCommand.execute(itemName, options);
|
|
502
532
|
}
|
|
503
533
|
catch (error) {
|
|
504
|
-
failWithError(error, { enabled: options?.json, fallbackCode: 'validate_error' });
|
|
534
|
+
await failWithError(error, { enabled: options?.json, fallbackCode: 'validate_error' });
|
|
505
535
|
process.exit(1);
|
|
506
536
|
}
|
|
507
537
|
});
|
|
@@ -528,11 +558,12 @@ program
|
|
|
528
558
|
.allowUnknownOption(true)
|
|
529
559
|
.action(async (itemName, options) => {
|
|
530
560
|
try {
|
|
561
|
+
const { ShowCommand } = await import('../commands/show.js');
|
|
531
562
|
const showCommand = new ShowCommand();
|
|
532
563
|
await showCommand.execute(itemName, options ?? {});
|
|
533
564
|
}
|
|
534
565
|
catch (error) {
|
|
535
|
-
failWithError(error, { enabled: options?.json, fallbackCode: 'show_error' });
|
|
566
|
+
await failWithError(error, { enabled: options?.json, fallbackCode: 'show_error' });
|
|
536
567
|
process.exit(1);
|
|
537
568
|
}
|
|
538
569
|
});
|
|
@@ -543,11 +574,12 @@ program
|
|
|
543
574
|
.option('--body <text>', 'Detailed description for the feedback')
|
|
544
575
|
.action(async (message, options) => {
|
|
545
576
|
try {
|
|
577
|
+
const { FeedbackCommand } = await import('../commands/feedback.js');
|
|
546
578
|
const feedbackCommand = new FeedbackCommand();
|
|
547
579
|
await feedbackCommand.execute(message, options);
|
|
548
580
|
}
|
|
549
581
|
catch (error) {
|
|
550
|
-
failWithError(error);
|
|
582
|
+
await failWithError(error);
|
|
551
583
|
process.exit(1);
|
|
552
584
|
}
|
|
553
585
|
});
|
|
@@ -560,11 +592,12 @@ completionCmd
|
|
|
560
592
|
.description('Generate completion script for a shell (outputs to stdout)')
|
|
561
593
|
.action(async (shell) => {
|
|
562
594
|
try {
|
|
595
|
+
const { CompletionCommand } = await import('../commands/completion.js');
|
|
563
596
|
const completionCommand = new CompletionCommand();
|
|
564
597
|
await completionCommand.generate({ shell });
|
|
565
598
|
}
|
|
566
599
|
catch (error) {
|
|
567
|
-
failWithError(error);
|
|
600
|
+
await failWithError(error);
|
|
568
601
|
process.exit(1);
|
|
569
602
|
}
|
|
570
603
|
});
|
|
@@ -574,11 +607,12 @@ completionCmd
|
|
|
574
607
|
.option('--verbose', 'Show detailed installation output')
|
|
575
608
|
.action(async (shell, options) => {
|
|
576
609
|
try {
|
|
610
|
+
const { CompletionCommand } = await import('../commands/completion.js');
|
|
577
611
|
const completionCommand = new CompletionCommand();
|
|
578
612
|
await completionCommand.install({ shell, verbose: options?.verbose });
|
|
579
613
|
}
|
|
580
614
|
catch (error) {
|
|
581
|
-
failWithError(error);
|
|
615
|
+
await failWithError(error);
|
|
582
616
|
process.exit(1);
|
|
583
617
|
}
|
|
584
618
|
});
|
|
@@ -588,11 +622,12 @@ completionCmd
|
|
|
588
622
|
.option('-y, --yes', 'Skip confirmation prompts')
|
|
589
623
|
.action(async (shell, options) => {
|
|
590
624
|
try {
|
|
625
|
+
const { CompletionCommand } = await import('../commands/completion.js');
|
|
591
626
|
const completionCommand = new CompletionCommand();
|
|
592
627
|
await completionCommand.uninstall({ shell, yes: options?.yes });
|
|
593
628
|
}
|
|
594
629
|
catch (error) {
|
|
595
|
-
failWithError(error);
|
|
630
|
+
await failWithError(error);
|
|
596
631
|
process.exit(1);
|
|
597
632
|
}
|
|
598
633
|
});
|
|
@@ -602,6 +637,7 @@ program
|
|
|
602
637
|
.description('Output completion data in machine-readable format (internal use)')
|
|
603
638
|
.action(async (type) => {
|
|
604
639
|
try {
|
|
640
|
+
const { CompletionCommand } = await import('../commands/completion.js');
|
|
605
641
|
const completionCommand = new CompletionCommand();
|
|
606
642
|
await completionCommand.complete({ type });
|
|
607
643
|
}
|
|
@@ -625,14 +661,17 @@ program
|
|
|
625
661
|
.addOption(hiddenStorePathOption())
|
|
626
662
|
.action(async (options) => {
|
|
627
663
|
try {
|
|
664
|
+
const { statusCommand } = await import('../commands/workflow/status.js');
|
|
628
665
|
await statusCommand(options);
|
|
629
666
|
}
|
|
630
667
|
catch (error) {
|
|
631
|
-
failWithError(error, {
|
|
668
|
+
await failWithError(error, {
|
|
632
669
|
enabled: options.json,
|
|
633
670
|
// The batch null-shape; the single-change failure shape is
|
|
634
671
|
// pre-existing contract and stays payload-free.
|
|
635
|
-
payload: options.all
|
|
672
|
+
payload: options.all
|
|
673
|
+
? (await import('../commands/workflow/status.js')).BATCH_STATUS_FAILURE_PAYLOAD
|
|
674
|
+
: undefined,
|
|
636
675
|
fallbackCode: 'change_error',
|
|
637
676
|
});
|
|
638
677
|
process.exit(1);
|
|
@@ -649,6 +688,7 @@ program
|
|
|
649
688
|
.addOption(hiddenStorePathOption())
|
|
650
689
|
.action(async (artifactId, options) => {
|
|
651
690
|
try {
|
|
691
|
+
const { applyInstructionsCommand, archiveInstructionsCommand, instructionsCommand } = await import('../commands/workflow/instructions.js');
|
|
652
692
|
// Workflow instruction surfaces are reserved command branches, not artifacts.
|
|
653
693
|
if (artifactId === 'apply') {
|
|
654
694
|
await applyInstructionsCommand(options);
|
|
@@ -661,7 +701,7 @@ program
|
|
|
661
701
|
}
|
|
662
702
|
}
|
|
663
703
|
catch (error) {
|
|
664
|
-
failWithError(error, { enabled: options.json, fallbackCode: 'change_error' });
|
|
704
|
+
await failWithError(error, { enabled: options.json, fallbackCode: 'change_error' });
|
|
665
705
|
process.exit(1);
|
|
666
706
|
}
|
|
667
707
|
});
|
|
@@ -673,10 +713,11 @@ program
|
|
|
673
713
|
.option('--json', 'Output as JSON mapping artifact IDs to template paths')
|
|
674
714
|
.action(async (options) => {
|
|
675
715
|
try {
|
|
716
|
+
const { templatesCommand } = await import('../commands/workflow/templates.js');
|
|
676
717
|
await templatesCommand(options);
|
|
677
718
|
}
|
|
678
719
|
catch (error) {
|
|
679
|
-
failWithError(error);
|
|
720
|
+
await failWithError(error);
|
|
680
721
|
process.exit(1);
|
|
681
722
|
}
|
|
682
723
|
});
|
|
@@ -689,10 +730,11 @@ program
|
|
|
689
730
|
.addOption(hiddenStorePathOption())
|
|
690
731
|
.action(async (options) => {
|
|
691
732
|
try {
|
|
733
|
+
const { schemasCommand } = await import('../commands/workflow/schemas.js');
|
|
692
734
|
await schemasCommand(options);
|
|
693
735
|
}
|
|
694
736
|
catch (error) {
|
|
695
|
-
failWithError(error, {
|
|
737
|
+
await failWithError(error, {
|
|
696
738
|
enabled: options.json,
|
|
697
739
|
payload: { schemas: [], root: null },
|
|
698
740
|
fallbackCode: 'schemas_error',
|
|
@@ -717,10 +759,11 @@ newCmd
|
|
|
717
759
|
.addOption(new Option('--areas <names>', 'No longer supported').hideHelp())
|
|
718
760
|
.action(async (name, options) => {
|
|
719
761
|
try {
|
|
762
|
+
const { newChangeCommand } = await import('../commands/workflow/new-change.js');
|
|
720
763
|
await newChangeCommand(name, options);
|
|
721
764
|
}
|
|
722
765
|
catch (error) {
|
|
723
|
-
failWithError(error);
|
|
766
|
+
await failWithError(error);
|
|
724
767
|
process.exit(1);
|
|
725
768
|
}
|
|
726
769
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import ora from 'ora';
|
|
2
1
|
import { CompletionFactory } from '../core/completions/factory.js';
|
|
3
2
|
import { COMMAND_REGISTRY } from '../core/completions/command-registry.js';
|
|
4
3
|
import { detectShell } from '../utils/shell-detection.js';
|
|
@@ -93,6 +92,9 @@ export class CompletionCommand {
|
|
|
93
92
|
async installForShell(shell, verbose) {
|
|
94
93
|
const generator = CompletionFactory.createGenerator(shell);
|
|
95
94
|
const installer = CompletionFactory.createInstaller(shell);
|
|
95
|
+
// Loaded here, not at the top: `__complete` shares this module and runs on
|
|
96
|
+
// every Tab press, so it must not pay for the spinner.
|
|
97
|
+
const { default: ora } = await import('ora');
|
|
96
98
|
const spinner = ora(`Installing ${shell} completion script...`).start();
|
|
97
99
|
try {
|
|
98
100
|
// Generate the completion script
|
|
@@ -187,6 +189,7 @@ export class CompletionCommand {
|
|
|
187
189
|
return;
|
|
188
190
|
}
|
|
189
191
|
}
|
|
192
|
+
const { default: ora } = await import('ora');
|
|
190
193
|
const spinner = ora(`Uninstalling ${shell} completion script...`).start();
|
|
191
194
|
try {
|
|
192
195
|
const result = await installer.uninstall();
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
1
|
import { GlobalConfig } from '../core/global-config.js';
|
|
3
2
|
import type { Profile, Delivery } from '../core/global-config.js';
|
|
4
3
|
/**
|
|
@@ -40,11 +39,21 @@ export declare function formatWorkflowSummary(workflows: readonly string[], prof
|
|
|
40
39
|
* Build a user-facing diff summary between two profile states.
|
|
41
40
|
*/
|
|
42
41
|
export declare function diffProfileState(before: ProfileState, after: ProfileState): ProfileStateDiff;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
export declare function
|
|
42
|
+
export declare function configPathCommand(): void;
|
|
43
|
+
export declare function configListCommand(options: {
|
|
44
|
+
json?: boolean;
|
|
45
|
+
}): void;
|
|
46
|
+
export declare function configGetCommand(key: string): void;
|
|
47
|
+
export declare function configSetCommand(key: string, value: string, options: {
|
|
48
|
+
string?: boolean;
|
|
49
|
+
allowUnknown?: boolean;
|
|
50
|
+
}): void;
|
|
51
|
+
export declare function configUnsetCommand(key: string): void;
|
|
52
|
+
export declare function configResetCommand(options: {
|
|
53
|
+
all?: boolean;
|
|
54
|
+
yes?: boolean;
|
|
55
|
+
}): Promise<void>;
|
|
56
|
+
export declare function configEditCommand(): Promise<void>;
|
|
57
|
+
export declare function configProfileCommand(preset?: string): Promise<void>;
|
|
49
58
|
export {};
|
|
50
59
|
//# sourceMappingURL=config.d.ts.map
|