@fission-ai/openspec 1.4.0 → 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 +94 -76
- 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 -9
- package/dist/commands/workspace/selection.js +0 -115
- 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 -6
- package/dist/commands/workspace.js +0 -587
- 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 -119
- 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
package/README.md
CHANGED
|
@@ -47,6 +47,14 @@ Our philosophy:
|
|
|
47
47
|
## See it in action
|
|
48
48
|
|
|
49
49
|
```text
|
|
50
|
+
You: /opsx:explore
|
|
51
|
+
AI: What would you like to explore?
|
|
52
|
+
You: I want dark mode but I'm not sure how to do it cleanly.
|
|
53
|
+
AI: Let me look at your styling setup...
|
|
54
|
+
Cleanest path here: CSS variables + a small theme context,
|
|
55
|
+
with system-preference detection. No new dependencies. Scope it?
|
|
56
|
+
You: Yes, let's do it.
|
|
57
|
+
|
|
50
58
|
You: /opsx:propose add-dark-mode
|
|
51
59
|
AI: Created openspec/changes/add-dark-mode/
|
|
52
60
|
✓ proposal.md — why we're doing this, what's changing
|
|
@@ -94,9 +102,12 @@ cd your-project
|
|
|
94
102
|
openspec init
|
|
95
103
|
```
|
|
96
104
|
|
|
97
|
-
Now
|
|
105
|
+
Now talk to your AI:
|
|
106
|
+
|
|
107
|
+
- **Not sure what to build yet?** Start with `/opsx:explore`, a no-stakes thinking partner that reads your code, weighs options, and shapes a plan before anything is written. ([Explore guide](docs/explore.md))
|
|
108
|
+
- **Already know what you want?** Go straight to `/opsx:propose <what-you-want-to-build>`.
|
|
98
109
|
|
|
99
|
-
If you want the expanded workflow (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:bulk-archive`, `/opsx:onboard`), select it with `openspec config profile` and apply with `openspec update`.
|
|
110
|
+
Both are in the default profile. If you want the expanded workflow (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:bulk-archive`, `/opsx:onboard`), select it with `openspec config profile` and apply with `openspec update`.
|
|
100
111
|
|
|
101
112
|
> [!NOTE]
|
|
102
113
|
> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 25+ tools and growing.
|
|
@@ -105,14 +116,24 @@ If you want the expanded workflow (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/
|
|
|
105
116
|
|
|
106
117
|
## Docs
|
|
107
118
|
|
|
119
|
+
**Start here:** the **[Documentation Home](docs/README.md)** maps everything. New to OpenSpec? Read [Getting Started](docs/getting-started.md), then [How Commands Work](docs/how-commands-work.md) (where you actually type `/opsx:propose`).
|
|
120
|
+
|
|
108
121
|
→ **[Getting Started](docs/getting-started.md)**: first steps<br>
|
|
122
|
+
→ **[Explore First](docs/explore.md)**: think it through with `/opsx:explore` before you commit<br>
|
|
123
|
+
→ **[How Commands Work](docs/how-commands-work.md)**: where slash commands run vs the CLI<br>
|
|
124
|
+
→ **[Core Concepts at a Glance](docs/overview.md)**: the whole mental model, one page<br>
|
|
125
|
+
→ **[Examples & Recipes](docs/examples.md)**: real changes, start to finish<br>
|
|
109
126
|
→ **[Workflows](docs/workflows.md)**: combos and patterns<br>
|
|
127
|
+
→ **[Existing Projects](docs/existing-projects.md)**: adopt OpenSpec on a brownfield codebase<br>
|
|
128
|
+
→ **[Editing a Change](docs/editing-changes.md)**: update artifacts, go back, reconcile manual edits<br>
|
|
110
129
|
→ **[Commands](docs/commands.md)**: slash commands & skills<br>
|
|
111
130
|
→ **[CLI](docs/cli.md)**: terminal reference<br>
|
|
131
|
+
→ **[Stores](docs/stores-beta/user-guide.md)**: plan in a separate repo, shared across your team (beta)<br>
|
|
112
132
|
→ **[Supported Tools](docs/supported-tools.md)**: tool integrations & install paths<br>
|
|
113
133
|
→ **[Concepts](docs/concepts.md)**: how it all fits<br>
|
|
114
134
|
→ **[Multi-Language](docs/multi-language.md)**: multi-language support<br>
|
|
115
|
-
→ **[Customization](docs/customization.md)**: make it yours
|
|
135
|
+
→ **[Customization](docs/customization.md)**: make it yours<br>
|
|
136
|
+
→ **[FAQ](docs/faq.md)** · **[Troubleshooting](docs/troubleshooting.md)** · **[Glossary](docs/glossary.md)**: quick help
|
|
116
137
|
|
|
117
138
|
|
|
118
139
|
## Community schemas
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
declare const program: Command;
|
|
3
|
+
/**
|
|
4
|
+
* Get the full command path for nested commands.
|
|
5
|
+
* For example: 'change show' -> 'change:show'
|
|
6
|
+
*/
|
|
7
|
+
export declare function getCommandPath(command: Command): string;
|
|
3
8
|
export { program };
|
|
4
9
|
export declare function runCli(argv?: string[]): void;
|
|
5
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cli/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { asStatus } from '../commands/shared-output.js';
|
|
2
|
+
import { Command, Option } from 'commander';
|
|
2
3
|
import { createRequire } from 'module';
|
|
3
4
|
import ora from 'ora';
|
|
4
5
|
import path from 'path';
|
|
@@ -9,6 +10,7 @@ import { UpdateCommand } from '../core/update.js';
|
|
|
9
10
|
import { ListCommand } from '../core/list.js';
|
|
10
11
|
import { ArchiveCommand } from '../core/archive.js';
|
|
11
12
|
import { ViewCommand } from '../core/view.js';
|
|
13
|
+
import { resolveRootForCommand, toRootOutput } from '../core/root-selection.js';
|
|
12
14
|
import { registerSpecCommand } from '../commands/spec.js';
|
|
13
15
|
import { ChangeCommand } from '../commands/change.js';
|
|
14
16
|
import { ValidateCommand } from '../commands/validate.js';
|
|
@@ -17,12 +19,37 @@ import { CompletionCommand } from '../commands/completion.js';
|
|
|
17
19
|
import { FeedbackCommand } from '../commands/feedback.js';
|
|
18
20
|
import { registerConfigCommand } from '../commands/config.js';
|
|
19
21
|
import { registerSchemaCommand } from '../commands/schema.js';
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import { statusCommand, instructionsCommand, applyInstructionsCommand, templatesCommand, schemasCommand, newChangeCommand,
|
|
22
|
+
import { registerStoreCommand } from '../commands/store.js';
|
|
23
|
+
import { registerDoctorCommand } from '../commands/doctor.js';
|
|
24
|
+
import { registerContextCommand } from '../commands/context.js';
|
|
25
|
+
import { registerWorksetCommand } from '../commands/workset.js';
|
|
26
|
+
import { statusCommand, instructionsCommand, applyInstructionsCommand, templatesCommand, schemasCommand, newChangeCommand, DEFAULT_SCHEMA, } from '../commands/workflow/index.js';
|
|
25
27
|
import { maybeShowTelemetryNotice, trackCommand, shutdown } from '../telemetry/index.js';
|
|
28
|
+
import { COMMON_FLAGS } from '../core/completions/shared-flags.js';
|
|
29
|
+
const STORE_OPTION_DESCRIPTION = COMMON_FLAGS.store.description;
|
|
30
|
+
// Deliberate rejection path: --store-path stays registered (hidden) so the
|
|
31
|
+
// resolver can explain that registering the path is the supported route,
|
|
32
|
+
// instead of Commander emitting a generic unknown-option error (or, for
|
|
33
|
+
// `show`, silently ignoring it via allowUnknownOption).
|
|
34
|
+
function hiddenStorePathOption() {
|
|
35
|
+
return new Option('--store-path <path>', 'Not supported; register the path with "openspec store register <path>" and use --store <id>').hideHelp();
|
|
36
|
+
}
|
|
37
|
+
function failWithError(error, json) {
|
|
38
|
+
// The agent contract: every --json failure leaves exactly one JSON
|
|
39
|
+
// document on stdout (the command's null-shape plus a status array).
|
|
40
|
+
if (json?.enabled) {
|
|
41
|
+
console.log(JSON.stringify({ ...(json.payload ?? {}), status: [asStatus(error, json.fallbackCode ?? 'command_error')] }, null, 2));
|
|
42
|
+
process.exitCode = 1;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
ora().fail(`Error: ${error.message}`);
|
|
46
|
+
// Resolution and store errors carry a pasteable fix - never drop it.
|
|
47
|
+
const fix = error.diagnostic?.fix;
|
|
48
|
+
if (fix) {
|
|
49
|
+
console.error(`Fix: ${fix}`);
|
|
50
|
+
}
|
|
51
|
+
process.exitCode = process.exitCode ?? 1;
|
|
52
|
+
}
|
|
26
53
|
const program = new Command();
|
|
27
54
|
const require = createRequire(import.meta.url);
|
|
28
55
|
const { version } = require('../../package.json');
|
|
@@ -30,7 +57,7 @@ const { version } = require('../../package.json');
|
|
|
30
57
|
* Get the full command path for nested commands.
|
|
31
58
|
* For example: 'change show' -> 'change:show'
|
|
32
59
|
*/
|
|
33
|
-
function getCommandPath(command) {
|
|
60
|
+
export function getCommandPath(command) {
|
|
34
61
|
const names = [];
|
|
35
62
|
let current = command;
|
|
36
63
|
while (current) {
|
|
@@ -107,8 +134,7 @@ program
|
|
|
107
134
|
await initCommand.execute(targetPath);
|
|
108
135
|
}
|
|
109
136
|
catch (error) {
|
|
110
|
-
|
|
111
|
-
ora().fail(`Error: ${error.message}`);
|
|
137
|
+
failWithError(error);
|
|
112
138
|
process.exit(1);
|
|
113
139
|
}
|
|
114
140
|
});
|
|
@@ -129,8 +155,7 @@ program
|
|
|
129
155
|
await initCommand.execute('.');
|
|
130
156
|
}
|
|
131
157
|
catch (error) {
|
|
132
|
-
|
|
133
|
-
ora().fail(`Error: ${error.message}`);
|
|
158
|
+
failWithError(error);
|
|
134
159
|
process.exit(1);
|
|
135
160
|
}
|
|
136
161
|
});
|
|
@@ -140,18 +165,11 @@ program
|
|
|
140
165
|
.option('--force', 'Force update even when tools are up to date')
|
|
141
166
|
.action(async (targetPath = '.', options) => {
|
|
142
167
|
try {
|
|
143
|
-
const resolvedPath = path.resolve(targetPath);
|
|
144
|
-
const workspaceRoot = await findWorkspaceRoot(resolvedPath);
|
|
145
|
-
if (workspaceRoot) {
|
|
146
|
-
await runWorkspaceUpdateForRoot(workspaceRoot, { force: options?.force });
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
168
|
const updateCommand = new UpdateCommand({ force: options?.force });
|
|
150
|
-
await updateCommand.execute(
|
|
169
|
+
await updateCommand.execute(targetPath);
|
|
151
170
|
}
|
|
152
171
|
catch (error) {
|
|
153
|
-
|
|
154
|
-
ora().fail(`Error: ${error.message}`);
|
|
172
|
+
failWithError(error);
|
|
155
173
|
process.exit(1);
|
|
156
174
|
}
|
|
157
175
|
});
|
|
@@ -162,16 +180,32 @@ program
|
|
|
162
180
|
.option('--changes', 'List changes explicitly (default)')
|
|
163
181
|
.option('--sort <order>', 'Sort order: "recent" (default) or "name"', 'recent')
|
|
164
182
|
.option('--json', 'Output as JSON (for programmatic use)')
|
|
183
|
+
.option('--store <id>', STORE_OPTION_DESCRIPTION)
|
|
184
|
+
.addOption(hiddenStorePathOption())
|
|
165
185
|
.action(async (options) => {
|
|
166
186
|
try {
|
|
187
|
+
const root = await resolveRootForCommand(options ?? {}, {
|
|
188
|
+
json: options?.json,
|
|
189
|
+
failurePayload: options?.specs ? { specs: [], root: null } : { changes: [], root: null },
|
|
190
|
+
});
|
|
191
|
+
if (!root) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
167
194
|
const listCommand = new ListCommand();
|
|
168
195
|
const mode = options?.specs ? 'specs' : 'changes';
|
|
169
196
|
const sort = options?.sort === 'name' ? 'name' : 'recent';
|
|
170
|
-
await listCommand.execute(
|
|
197
|
+
await listCommand.execute(root.path, mode, {
|
|
198
|
+
sort,
|
|
199
|
+
json: options?.json,
|
|
200
|
+
...(options?.json ? { root: toRootOutput(root) } : {}),
|
|
201
|
+
});
|
|
171
202
|
}
|
|
172
203
|
catch (error) {
|
|
173
|
-
|
|
174
|
-
|
|
204
|
+
failWithError(error, {
|
|
205
|
+
enabled: options?.json,
|
|
206
|
+
payload: options?.specs ? { specs: [], root: null } : { changes: [], root: null },
|
|
207
|
+
fallbackCode: 'list_error',
|
|
208
|
+
});
|
|
175
209
|
process.exit(1);
|
|
176
210
|
}
|
|
177
211
|
});
|
|
@@ -184,8 +218,7 @@ program
|
|
|
184
218
|
await viewCommand.execute('.');
|
|
185
219
|
}
|
|
186
220
|
catch (error) {
|
|
187
|
-
|
|
188
|
-
ora().fail(`Error: ${error.message}`);
|
|
221
|
+
failWithError(error);
|
|
189
222
|
process.exit(1);
|
|
190
223
|
}
|
|
191
224
|
});
|
|
@@ -255,23 +288,26 @@ program
|
|
|
255
288
|
.option('-y, --yes', 'Skip confirmation prompts')
|
|
256
289
|
.option('--skip-specs', 'Skip spec update operations (useful for infrastructure, tooling, or doc-only changes)')
|
|
257
290
|
.option('--no-validate', 'Skip validation (not recommended, requires confirmation)')
|
|
291
|
+
.option('--json', 'Output as JSON (non-interactive)')
|
|
292
|
+
.option('--store <id>', STORE_OPTION_DESCRIPTION)
|
|
293
|
+
.addOption(hiddenStorePathOption())
|
|
258
294
|
.action(async (changeName, options) => {
|
|
259
295
|
try {
|
|
260
296
|
const archiveCommand = new ArchiveCommand();
|
|
261
297
|
await archiveCommand.execute(changeName, options);
|
|
262
298
|
}
|
|
263
299
|
catch (error) {
|
|
264
|
-
|
|
265
|
-
ora().fail(`Error: ${error.message}`);
|
|
300
|
+
failWithError(error);
|
|
266
301
|
process.exit(1);
|
|
267
302
|
}
|
|
268
303
|
});
|
|
269
304
|
registerSpecCommand(program);
|
|
270
305
|
registerConfigCommand(program);
|
|
271
306
|
registerSchemaCommand(program);
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
307
|
+
registerStoreCommand(program);
|
|
308
|
+
registerDoctorCommand(program);
|
|
309
|
+
registerContextCommand(program);
|
|
310
|
+
registerWorksetCommand(program);
|
|
275
311
|
// Top-level validate command
|
|
276
312
|
program
|
|
277
313
|
.command('validate [item-name]')
|
|
@@ -284,14 +320,15 @@ program
|
|
|
284
320
|
.option('--json', 'Output validation results as JSON')
|
|
285
321
|
.option('--concurrency <n>', 'Max concurrent validations (defaults to env OPENSPEC_CONCURRENCY or 6)')
|
|
286
322
|
.option('--no-interactive', 'Disable interactive prompts')
|
|
323
|
+
.option('--store <id>', STORE_OPTION_DESCRIPTION)
|
|
324
|
+
.addOption(hiddenStorePathOption())
|
|
287
325
|
.action(async (itemName, options) => {
|
|
288
326
|
try {
|
|
289
327
|
const validateCommand = new ValidateCommand();
|
|
290
328
|
await validateCommand.execute(itemName, options);
|
|
291
329
|
}
|
|
292
330
|
catch (error) {
|
|
293
|
-
|
|
294
|
-
ora().fail(`Error: ${error.message}`);
|
|
331
|
+
failWithError(error, { enabled: options?.json, fallbackCode: 'validate_error' });
|
|
295
332
|
process.exit(1);
|
|
296
333
|
}
|
|
297
334
|
});
|
|
@@ -309,6 +346,10 @@ program
|
|
|
309
346
|
.option('--requirements', 'JSON only: Show only requirements (exclude scenarios)')
|
|
310
347
|
.option('--no-scenarios', 'JSON only: Exclude scenario content')
|
|
311
348
|
.option('-r, --requirement <id>', 'JSON only: Show specific requirement by ID (1-based)')
|
|
349
|
+
.option('--store <id>', STORE_OPTION_DESCRIPTION)
|
|
350
|
+
// Explicit registration required: allowUnknownOption would otherwise
|
|
351
|
+
// silently swallow --store-path instead of rejecting it deliberately.
|
|
352
|
+
.addOption(hiddenStorePathOption())
|
|
312
353
|
// allow unknown options to pass-through to underlying command implementation
|
|
313
354
|
.allowUnknownOption(true)
|
|
314
355
|
.action(async (itemName, options) => {
|
|
@@ -317,8 +358,7 @@ program
|
|
|
317
358
|
await showCommand.execute(itemName, options ?? {});
|
|
318
359
|
}
|
|
319
360
|
catch (error) {
|
|
320
|
-
|
|
321
|
-
ora().fail(`Error: ${error.message}`);
|
|
361
|
+
failWithError(error, { enabled: options?.json, fallbackCode: 'show_error' });
|
|
322
362
|
process.exit(1);
|
|
323
363
|
}
|
|
324
364
|
});
|
|
@@ -333,8 +373,7 @@ program
|
|
|
333
373
|
await feedbackCommand.execute(message, options);
|
|
334
374
|
}
|
|
335
375
|
catch (error) {
|
|
336
|
-
|
|
337
|
-
ora().fail(`Error: ${error.message}`);
|
|
376
|
+
failWithError(error);
|
|
338
377
|
process.exit(1);
|
|
339
378
|
}
|
|
340
379
|
});
|
|
@@ -351,8 +390,7 @@ completionCmd
|
|
|
351
390
|
await completionCommand.generate({ shell });
|
|
352
391
|
}
|
|
353
392
|
catch (error) {
|
|
354
|
-
|
|
355
|
-
ora().fail(`Error: ${error.message}`);
|
|
393
|
+
failWithError(error);
|
|
356
394
|
process.exit(1);
|
|
357
395
|
}
|
|
358
396
|
});
|
|
@@ -366,8 +404,7 @@ completionCmd
|
|
|
366
404
|
await completionCommand.install({ shell, verbose: options?.verbose });
|
|
367
405
|
}
|
|
368
406
|
catch (error) {
|
|
369
|
-
|
|
370
|
-
ora().fail(`Error: ${error.message}`);
|
|
407
|
+
failWithError(error);
|
|
371
408
|
process.exit(1);
|
|
372
409
|
}
|
|
373
410
|
});
|
|
@@ -381,8 +418,7 @@ completionCmd
|
|
|
381
418
|
await completionCommand.uninstall({ shell, yes: options?.yes });
|
|
382
419
|
}
|
|
383
420
|
catch (error) {
|
|
384
|
-
|
|
385
|
-
ora().fail(`Error: ${error.message}`);
|
|
421
|
+
failWithError(error);
|
|
386
422
|
process.exit(1);
|
|
387
423
|
}
|
|
388
424
|
});
|
|
@@ -410,13 +446,14 @@ program
|
|
|
410
446
|
.option('--change <id>', 'Change name to show status for')
|
|
411
447
|
.option('--schema <name>', 'Schema override (auto-detected from config.yaml)')
|
|
412
448
|
.option('--json', 'Output as JSON')
|
|
449
|
+
.option('--store <id>', STORE_OPTION_DESCRIPTION)
|
|
450
|
+
.addOption(hiddenStorePathOption())
|
|
413
451
|
.action(async (options) => {
|
|
414
452
|
try {
|
|
415
453
|
await statusCommand(options);
|
|
416
454
|
}
|
|
417
455
|
catch (error) {
|
|
418
|
-
|
|
419
|
-
ora().fail(`Error: ${error.message}`);
|
|
456
|
+
failWithError(error, { enabled: options.json, fallbackCode: 'change_error' });
|
|
420
457
|
process.exit(1);
|
|
421
458
|
}
|
|
422
459
|
});
|
|
@@ -427,6 +464,8 @@ program
|
|
|
427
464
|
.option('--change <id>', 'Change name')
|
|
428
465
|
.option('--schema <name>', 'Schema override (auto-detected from config.yaml)')
|
|
429
466
|
.option('--json', 'Output as JSON')
|
|
467
|
+
.option('--store <id>', STORE_OPTION_DESCRIPTION)
|
|
468
|
+
.addOption(hiddenStorePathOption())
|
|
430
469
|
.action(async (artifactId, options) => {
|
|
431
470
|
try {
|
|
432
471
|
// Special case: "apply" is not an artifact, but a command to get apply instructions
|
|
@@ -438,8 +477,7 @@ program
|
|
|
438
477
|
}
|
|
439
478
|
}
|
|
440
479
|
catch (error) {
|
|
441
|
-
|
|
442
|
-
ora().fail(`Error: ${error.message}`);
|
|
480
|
+
failWithError(error, { enabled: options.json, fallbackCode: 'change_error' });
|
|
443
481
|
process.exit(1);
|
|
444
482
|
}
|
|
445
483
|
});
|
|
@@ -454,8 +492,7 @@ program
|
|
|
454
492
|
await templatesCommand(options);
|
|
455
493
|
}
|
|
456
494
|
catch (error) {
|
|
457
|
-
|
|
458
|
-
ora().fail(`Error: ${error.message}`);
|
|
495
|
+
failWithError(error);
|
|
459
496
|
process.exit(1);
|
|
460
497
|
}
|
|
461
498
|
});
|
|
@@ -469,8 +506,7 @@ program
|
|
|
469
506
|
await schemasCommand(options);
|
|
470
507
|
}
|
|
471
508
|
catch (error) {
|
|
472
|
-
|
|
473
|
-
ora().fail(`Error: ${error.message}`);
|
|
509
|
+
failWithError(error);
|
|
474
510
|
process.exit(1);
|
|
475
511
|
}
|
|
476
512
|
});
|
|
@@ -480,39 +516,21 @@ newCmd
|
|
|
480
516
|
.command('change <name>')
|
|
481
517
|
.description('Create a new change directory')
|
|
482
518
|
.option('--description <text>', 'Description to add to README.md')
|
|
483
|
-
.option('--goal <text>', '
|
|
484
|
-
.option('--areas <names>', 'Comma-separated affected workspace link names')
|
|
485
|
-
.option('--initiative <id>', 'Link the repo-local change to an initiative')
|
|
486
|
-
.option('--store <id>', 'Context store id for --initiative')
|
|
487
|
-
.option('--store-path <path>', 'Existing local context store root for --initiative')
|
|
519
|
+
.option('--goal <text>', 'Optional goal metadata to store with the change')
|
|
488
520
|
.option('--schema <name>', `Workflow schema to use (default: ${DEFAULT_SCHEMA})`)
|
|
489
521
|
.option('--json', 'Output as JSON')
|
|
522
|
+
.option('--store <id>', STORE_OPTION_DESCRIPTION)
|
|
523
|
+
.addOption(hiddenStorePathOption())
|
|
524
|
+
// Removed options kept registered (hidden) so users get a deliberate
|
|
525
|
+
// explanation instead of a generic unknown-option error.
|
|
526
|
+
.addOption(new Option('--initiative <id>', 'No longer supported').hideHelp())
|
|
527
|
+
.addOption(new Option('--areas <names>', 'No longer supported').hideHelp())
|
|
490
528
|
.action(async (name, options) => {
|
|
491
529
|
try {
|
|
492
530
|
await newChangeCommand(name, options);
|
|
493
531
|
}
|
|
494
532
|
catch (error) {
|
|
495
|
-
|
|
496
|
-
ora().fail(`Error: ${error.message}`);
|
|
497
|
-
process.exit(1);
|
|
498
|
-
}
|
|
499
|
-
});
|
|
500
|
-
// Set command group
|
|
501
|
-
const setCmd = program.command('set').description('Set checked-in OpenSpec metadata');
|
|
502
|
-
setCmd
|
|
503
|
-
.command('change <name>')
|
|
504
|
-
.description('Set repo-local change metadata')
|
|
505
|
-
.option('--initiative <id>', 'Link the repo-local change to an initiative')
|
|
506
|
-
.option('--store <id>', 'Context store id for --initiative')
|
|
507
|
-
.option('--store-path <path>', 'Existing local context store root for --initiative')
|
|
508
|
-
.option('--json', 'Output as JSON')
|
|
509
|
-
.action(async (name, options) => {
|
|
510
|
-
try {
|
|
511
|
-
await setChangeCommand(name, options);
|
|
512
|
-
}
|
|
513
|
-
catch (error) {
|
|
514
|
-
console.log();
|
|
515
|
-
ora().fail(`Error: ${error.message}`);
|
|
533
|
+
failWithError(error);
|
|
516
534
|
process.exit(1);
|
|
517
535
|
}
|
|
518
536
|
});
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import type { RootOutput } from '../core/root-selection.js';
|
|
1
2
|
export declare class ChangeCommand {
|
|
2
3
|
private converter;
|
|
3
|
-
|
|
4
|
+
private rootPath?;
|
|
5
|
+
constructor(rootPath?: string);
|
|
6
|
+
private getChangesPath;
|
|
4
7
|
/**
|
|
5
8
|
* Show a change proposal.
|
|
6
9
|
* - Text mode: raw markdown passthrough (no filters)
|
|
@@ -12,6 +15,7 @@ export declare class ChangeCommand {
|
|
|
12
15
|
requirementsOnly?: boolean;
|
|
13
16
|
deltasOnly?: boolean;
|
|
14
17
|
noInteractive?: boolean;
|
|
18
|
+
rootOutput?: RootOutput;
|
|
15
19
|
}): Promise<void>;
|
|
16
20
|
/**
|
|
17
21
|
* List active changes.
|
package/dist/commands/change.js
CHANGED
|
@@ -11,8 +11,15 @@ const TASK_PATTERN = /^[-*]\s+\[[\sx]\]/i;
|
|
|
11
11
|
const COMPLETED_TASK_PATTERN = /^[-*]\s+\[x\]/i;
|
|
12
12
|
export class ChangeCommand {
|
|
13
13
|
converter;
|
|
14
|
-
|
|
14
|
+
rootPath;
|
|
15
|
+
// rootPath is set only by root-aware callers (top-level `show`); the
|
|
16
|
+
// deprecated noun-form commands stay cwd-based.
|
|
17
|
+
constructor(rootPath) {
|
|
15
18
|
this.converter = new JsonConverter();
|
|
19
|
+
this.rootPath = rootPath;
|
|
20
|
+
}
|
|
21
|
+
getChangesPath() {
|
|
22
|
+
return path.join(this.rootPath ?? process.cwd(), 'openspec', 'changes');
|
|
16
23
|
}
|
|
17
24
|
/**
|
|
18
25
|
* Show a change proposal.
|
|
@@ -21,7 +28,7 @@ export class ChangeCommand {
|
|
|
21
28
|
* Note: --requirements-only is deprecated alias for --deltas-only
|
|
22
29
|
*/
|
|
23
30
|
async show(changeName, options) {
|
|
24
|
-
const changesPath =
|
|
31
|
+
const changesPath = this.getChangesPath();
|
|
25
32
|
if (!changeName) {
|
|
26
33
|
const canPrompt = isInteractive(options);
|
|
27
34
|
const changes = await this.getActiveChanges(changesPath);
|
|
@@ -62,19 +69,14 @@ export class ChangeCommand {
|
|
|
62
69
|
const title = this.extractTitle(contentForTitle, changeName);
|
|
63
70
|
const id = parsed.name;
|
|
64
71
|
const deltas = parsed.deltas || [];
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
deltaCount: deltas.length,
|
|
74
|
-
deltas,
|
|
75
|
-
};
|
|
76
|
-
console.log(JSON.stringify(output, null, 2));
|
|
77
|
-
}
|
|
72
|
+
const output = {
|
|
73
|
+
id,
|
|
74
|
+
title,
|
|
75
|
+
deltaCount: deltas.length,
|
|
76
|
+
deltas,
|
|
77
|
+
...(options.rootOutput ? { root: options.rootOutput } : {}),
|
|
78
|
+
};
|
|
79
|
+
console.log(JSON.stringify(output, null, 2));
|
|
78
80
|
}
|
|
79
81
|
else {
|
|
80
82
|
const content = await fs.readFile(proposalPath, 'utf-8');
|
package/dist/commands/config.js
CHANGED
|
@@ -6,7 +6,7 @@ import { getNestedValue, setNestedValue, deleteNestedValue, coerceValue, formatV
|
|
|
6
6
|
import { CORE_WORKFLOWS, ALL_WORKFLOWS, getProfileWorkflows } from '../core/profiles.js';
|
|
7
7
|
import { OPENSPEC_DIR_NAME } from '../core/config.js';
|
|
8
8
|
import { hasProjectConfigDrift } from '../core/profile-sync-drift.js';
|
|
9
|
-
import {
|
|
9
|
+
import { isPromptCancellationError } from './shared-output.js';
|
|
10
10
|
const WORKFLOW_PROMPT_META = {
|
|
11
11
|
propose: {
|
|
12
12
|
name: 'Propose change',
|
|
@@ -53,10 +53,6 @@ const WORKFLOW_PROMPT_META = {
|
|
|
53
53
|
description: 'Guided onboarding flow for OpenSpec',
|
|
54
54
|
},
|
|
55
55
|
};
|
|
56
|
-
function isPromptCancellationError(error) {
|
|
57
|
-
return (error instanceof Error &&
|
|
58
|
-
(error.name === 'ExitPromptError' || error.message.includes('force closed the prompt with SIGINT')));
|
|
59
|
-
}
|
|
60
56
|
/**
|
|
61
57
|
* Resolve the effective current profile state from global config defaults.
|
|
62
58
|
*/
|
|
@@ -133,16 +129,6 @@ export function diffProfileState(before, after) {
|
|
|
133
129
|
lines,
|
|
134
130
|
};
|
|
135
131
|
}
|
|
136
|
-
async function resolveWorkspaceConfigProfileContext(cwd = process.cwd()) {
|
|
137
|
-
const workspaceRoot = await findWorkspaceRoot(cwd);
|
|
138
|
-
if (!workspaceRoot) {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
return {
|
|
142
|
-
root: workspaceRoot,
|
|
143
|
-
commandCwd: cwd,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
132
|
function maybeWarnProjectConfigDrift(projectDir, state, colorize) {
|
|
147
133
|
const openspecDir = path.join(projectDir, OPENSPEC_DIR_NAME);
|
|
148
134
|
if (!fs.existsSync(openspecDir)) {
|
|
@@ -153,28 +139,7 @@ function maybeWarnProjectConfigDrift(projectDir, state, colorize) {
|
|
|
153
139
|
}
|
|
154
140
|
console.log(colorize('Warning: Global config is not applied to this project. Run `openspec update` to sync.'));
|
|
155
141
|
}
|
|
156
|
-
|
|
157
|
-
const workspaceContext = await resolveWorkspaceConfigProfileContext();
|
|
158
|
-
if (workspaceContext) {
|
|
159
|
-
let viewState = null;
|
|
160
|
-
try {
|
|
161
|
-
viewState = await readOptionalWorkspaceViewState(workspaceContext.root);
|
|
162
|
-
}
|
|
163
|
-
catch {
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
if (hasWorkspaceSkillProfileDrift(viewState)) {
|
|
167
|
-
console.log(colorize('Warning: Workspace-local agent skills are out of sync with the active global profile. Run `openspec workspace update` to sync.'));
|
|
168
|
-
}
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
maybeWarnProjectConfigDrift(process.cwd(), state, colorize);
|
|
172
|
-
}
|
|
173
|
-
function printConfigProfileApplyGuidance(workspaceContext) {
|
|
174
|
-
if (workspaceContext) {
|
|
175
|
-
console.log('Config updated. Run `openspec workspace update` to apply it to workspace-local skills.');
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
142
|
+
function printConfigProfileApplyGuidance() {
|
|
178
143
|
console.log('Config updated. Run `openspec update` in your projects to apply.');
|
|
179
144
|
}
|
|
180
145
|
/**
|
|
@@ -418,8 +383,7 @@ export function registerConfigCommand(program) {
|
|
|
418
383
|
config.workflows = [...CORE_WORKFLOWS];
|
|
419
384
|
// Preserve delivery setting
|
|
420
385
|
saveGlobalConfig(config);
|
|
421
|
-
|
|
422
|
-
printConfigProfileApplyGuidance(workspaceContext);
|
|
386
|
+
printConfigProfileApplyGuidance();
|
|
423
387
|
return;
|
|
424
388
|
}
|
|
425
389
|
if (preset) {
|
|
@@ -472,7 +436,7 @@ export function registerConfigCommand(program) {
|
|
|
472
436
|
});
|
|
473
437
|
if (action === 'keep') {
|
|
474
438
|
console.log('No config changes.');
|
|
475
|
-
|
|
439
|
+
maybeWarnProjectConfigDrift(process.cwd(), currentState, chalk.yellow);
|
|
476
440
|
return;
|
|
477
441
|
}
|
|
478
442
|
const nextState = {
|
|
@@ -541,7 +505,7 @@ export function registerConfigCommand(program) {
|
|
|
541
505
|
const diff = diffProfileState(currentState, nextState);
|
|
542
506
|
if (!diff.hasChanges) {
|
|
543
507
|
console.log('No config changes.');
|
|
544
|
-
|
|
508
|
+
maybeWarnProjectConfigDrift(process.cwd(), nextState, chalk.yellow);
|
|
545
509
|
return;
|
|
546
510
|
}
|
|
547
511
|
console.log(chalk.bold('\nConfig changes:'));
|
|
@@ -553,29 +517,6 @@ export function registerConfigCommand(program) {
|
|
|
553
517
|
config.delivery = nextState.delivery;
|
|
554
518
|
config.workflows = nextState.workflows;
|
|
555
519
|
saveGlobalConfig(config);
|
|
556
|
-
const workspaceContext = await resolveWorkspaceConfigProfileContext();
|
|
557
|
-
if (workspaceContext) {
|
|
558
|
-
const applyNow = await confirm({
|
|
559
|
-
message: 'Apply changes to this workspace now?',
|
|
560
|
-
default: true,
|
|
561
|
-
});
|
|
562
|
-
if (applyNow) {
|
|
563
|
-
try {
|
|
564
|
-
execSync('npx openspec workspace update', {
|
|
565
|
-
stdio: 'inherit',
|
|
566
|
-
cwd: workspaceContext.commandCwd,
|
|
567
|
-
});
|
|
568
|
-
console.log('Run `openspec workspace update` in your other workspaces to apply.');
|
|
569
|
-
}
|
|
570
|
-
catch {
|
|
571
|
-
console.error('`openspec workspace update` failed. Please run it manually to apply the profile changes.');
|
|
572
|
-
process.exitCode = 1;
|
|
573
|
-
}
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
|
-
printConfigProfileApplyGuidance(workspaceContext);
|
|
577
|
-
return;
|
|
578
|
-
}
|
|
579
520
|
// Check if inside an OpenSpec project
|
|
580
521
|
const projectDir = process.cwd();
|
|
581
522
|
const openspecDir = path.join(projectDir, OPENSPEC_DIR_NAME);
|
|
@@ -596,7 +537,7 @@ export function registerConfigCommand(program) {
|
|
|
596
537
|
return;
|
|
597
538
|
}
|
|
598
539
|
}
|
|
599
|
-
printConfigProfileApplyGuidance(
|
|
540
|
+
printConfigProfileApplyGuidance();
|
|
600
541
|
}
|
|
601
542
|
catch (error) {
|
|
602
543
|
if (isPromptCancellationError(error)) {
|