@fission-ai/openspec 1.3.0 → 1.4.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 +9 -6
- package/bin/openspec.js +3 -1
- package/dist/cli/index.d.ts +4 -1
- package/dist/cli/index.js +46 -2
- package/dist/commands/completion.js +7 -0
- package/dist/commands/config.js +64 -5
- package/dist/commands/context-store.d.ts +3 -0
- package/dist/commands/context-store.js +475 -0
- package/dist/commands/initiative.d.ts +13 -0
- package/dist/commands/initiative.js +318 -0
- package/dist/commands/workflow/index.d.ts +2 -0
- package/dist/commands/workflow/index.js +1 -0
- package/dist/commands/workflow/initiative-link.d.ts +24 -0
- package/dist/commands/workflow/initiative-link.js +47 -0
- package/dist/commands/workflow/instructions.d.ts +1 -1
- package/dist/commands/workflow/instructions.js +46 -83
- package/dist/commands/workflow/new-change.d.ts +6 -0
- package/dist/commands/workflow/new-change.js +114 -17
- package/dist/commands/workflow/set-change.d.ts +13 -0
- package/dist/commands/workflow/set-change.js +87 -0
- package/dist/commands/workflow/shared.d.ts +5 -3
- package/dist/commands/workflow/shared.js +6 -6
- package/dist/commands/workflow/status.js +24 -9
- package/dist/commands/workflow/templates.js +5 -4
- package/dist/commands/workspace/context-status.d.ts +4 -0
- package/dist/commands/workspace/context-status.js +59 -0
- package/dist/commands/workspace/open-target-selection.d.ts +13 -0
- package/dist/commands/workspace/open-target-selection.js +146 -0
- package/dist/commands/workspace/open-view.d.ts +62 -0
- package/dist/commands/workspace/open-view.js +249 -0
- package/dist/commands/workspace/open.d.ts +37 -0
- package/dist/commands/workspace/open.js +110 -0
- package/dist/commands/workspace/opener-selection.d.ts +11 -0
- package/dist/commands/workspace/opener-selection.js +98 -0
- package/dist/commands/workspace/operations.d.ts +29 -0
- package/dist/commands/workspace/operations.js +543 -0
- package/dist/commands/workspace/prompt-theme.d.ts +29 -0
- package/dist/commands/workspace/prompt-theme.js +24 -0
- package/dist/commands/workspace/registration.d.ts +13 -0
- package/dist/commands/workspace/registration.js +84 -0
- package/dist/commands/workspace/selection.d.ts +9 -0
- package/dist/commands/workspace/selection.js +115 -0
- package/dist/commands/workspace/setup-prompts.d.ts +13 -0
- package/dist/commands/workspace/setup-prompts.js +121 -0
- package/dist/commands/workspace/types.d.ts +103 -0
- package/dist/commands/workspace/types.js +36 -0
- package/dist/commands/workspace.d.ts +6 -0
- package/dist/commands/workspace.js +587 -0
- package/dist/core/artifact-graph/index.d.ts +3 -1
- package/dist/core/artifact-graph/index.js +1 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +41 -1
- package/dist/core/artifact-graph/instruction-loader.js +51 -9
- package/dist/core/artifact-graph/outputs.d.ts +14 -0
- package/dist/core/artifact-graph/outputs.js +39 -0
- package/dist/core/artifact-graph/state.js +2 -25
- package/dist/core/artifact-graph/types.d.ts +0 -5
- package/dist/core/artifact-graph/types.js +0 -14
- package/dist/core/change-metadata/index.d.ts +2 -0
- package/dist/core/change-metadata/index.js +2 -0
- package/dist/core/change-metadata/schema.d.ts +18 -0
- package/dist/core/change-metadata/schema.js +28 -0
- package/dist/core/change-status-policy.d.ts +50 -0
- package/dist/core/change-status-policy.js +70 -0
- package/dist/core/collections/index.d.ts +3 -0
- package/dist/core/collections/index.js +3 -0
- package/dist/core/collections/initiatives/collection.d.ts +4 -0
- package/dist/core/collections/initiatives/collection.js +17 -0
- package/dist/core/collections/initiatives/index.d.ts +6 -0
- package/dist/core/collections/initiatives/index.js +6 -0
- package/dist/core/collections/initiatives/operations.d.ts +49 -0
- package/dist/core/collections/initiatives/operations.js +175 -0
- package/dist/core/collections/initiatives/resolution.d.ts +87 -0
- package/dist/core/collections/initiatives/resolution.js +374 -0
- package/dist/core/collections/initiatives/schema.d.ts +41 -0
- package/dist/core/collections/initiatives/schema.js +134 -0
- package/dist/core/collections/initiatives/templates.d.ts +12 -0
- package/dist/core/collections/initiatives/templates.js +90 -0
- package/dist/core/collections/runtime.d.ts +46 -0
- package/dist/core/collections/runtime.js +194 -0
- package/dist/core/completions/command-registry.d.ts +1 -5
- package/dist/core/completions/command-registry.js +532 -32
- package/dist/core/completions/completion-provider.d.ts +11 -0
- package/dist/core/completions/completion-provider.js +27 -0
- package/dist/core/completions/generators/bash-generator.d.ts +3 -0
- package/dist/core/completions/generators/bash-generator.js +60 -4
- package/dist/core/completions/generators/fish-generator.js +3 -0
- package/dist/core/completions/generators/powershell-generator.d.ts +3 -0
- package/dist/core/completions/generators/powershell-generator.js +63 -4
- package/dist/core/completions/generators/zsh-generator.d.ts +3 -0
- package/dist/core/completions/generators/zsh-generator.js +46 -22
- package/dist/core/completions/installers/zsh-installer.d.ts +0 -8
- package/dist/core/completions/installers/zsh-installer.js +3 -31
- package/dist/core/completions/shared-flags.d.ts +12 -0
- package/dist/core/completions/shared-flags.js +28 -0
- package/dist/core/completions/templates/bash-templates.d.ts +1 -1
- package/dist/core/completions/templates/bash-templates.js +6 -0
- package/dist/core/completions/templates/fish-templates.d.ts +1 -1
- package/dist/core/completions/templates/fish-templates.js +6 -0
- package/dist/core/completions/templates/powershell-templates.d.ts +1 -1
- package/dist/core/completions/templates/powershell-templates.js +9 -0
- package/dist/core/completions/templates/zsh-templates.d.ts +1 -1
- package/dist/core/completions/templates/zsh-templates.js +9 -0
- package/dist/core/completions/types.d.ts +23 -1
- package/dist/core/config.js +3 -1
- package/dist/core/context-store/binding.d.ts +53 -0
- package/dist/core/context-store/binding.js +197 -0
- package/dist/core/context-store/errors.d.ts +20 -0
- package/dist/core/context-store/errors.js +22 -0
- package/dist/core/context-store/foundation.d.ts +55 -0
- package/dist/core/context-store/foundation.js +321 -0
- package/dist/core/context-store/index.d.ts +6 -0
- package/dist/core/context-store/index.js +6 -0
- package/dist/core/context-store/operations.d.ts +85 -0
- package/dist/core/context-store/operations.js +528 -0
- package/dist/core/context-store/registry.d.ts +45 -0
- package/dist/core/context-store/registry.js +229 -0
- package/dist/core/global-config.d.ts +6 -1
- package/dist/core/global-config.js +15 -16
- package/dist/core/index.d.ts +5 -1
- package/dist/core/index.js +4 -0
- package/dist/core/parsers/change-parser.js +7 -3
- package/dist/core/parsers/markdown-parser.d.ts +4 -0
- package/dist/core/parsers/markdown-parser.js +41 -1
- package/dist/core/parsers/requirement-blocks.js +5 -5
- package/dist/core/parsers/spec-structure.d.ts +9 -0
- package/dist/core/parsers/spec-structure.js +88 -0
- package/dist/core/planning-home.d.ts +21 -0
- package/dist/core/planning-home.js +108 -0
- package/dist/core/profiles.d.ts +1 -1
- package/dist/core/profiles.js +1 -1
- package/dist/core/specs-apply.js +9 -1
- package/dist/core/templates/workflows/apply-change.js +10 -4
- package/dist/core/templates/workflows/archive-change.js +21 -15
- package/dist/core/templates/workflows/bulk-archive-change.js +14 -10
- package/dist/core/templates/workflows/continue-change.js +6 -4
- package/dist/core/templates/workflows/explore.js +8 -10
- package/dist/core/templates/workflows/ff-change.js +8 -6
- package/dist/core/templates/workflows/new-change.js +6 -6
- package/dist/core/templates/workflows/onboard.js +13 -15
- package/dist/core/templates/workflows/propose.js +8 -6
- package/dist/core/templates/workflows/sync-specs.js +28 -10
- package/dist/core/templates/workflows/verify-change.js +16 -10
- package/dist/core/update.d.ts +5 -0
- package/dist/core/update.js +20 -0
- package/dist/core/validation/validator.d.ts +11 -0
- package/dist/core/validation/validator.js +28 -2
- package/dist/core/workspace/foundation.d.ts +67 -0
- package/dist/core/workspace/foundation.js +295 -0
- package/dist/core/workspace/index.d.ts +8 -0
- package/dist/core/workspace/index.js +8 -0
- package/dist/core/workspace/legacy-state.d.ts +28 -0
- package/dist/core/workspace/legacy-state.js +200 -0
- package/dist/core/workspace/link-input.d.ts +9 -0
- package/dist/core/workspace/link-input.js +32 -0
- package/dist/core/workspace/open-surface.d.ts +45 -0
- package/dist/core/workspace/open-surface.js +215 -0
- package/dist/core/workspace/openers.d.ts +21 -0
- package/dist/core/workspace/openers.js +124 -0
- package/dist/core/workspace/registry.d.ts +24 -0
- package/dist/core/workspace/registry.js +146 -0
- package/dist/core/workspace/skills.d.ts +57 -0
- package/dist/core/workspace/skills.js +334 -0
- package/dist/core/workspace/state-io.d.ts +10 -0
- package/dist/core/workspace/state-io.js +119 -0
- package/dist/telemetry/config.d.ts +7 -1
- package/dist/telemetry/config.js +87 -19
- package/dist/telemetry/index.js +19 -0
- package/dist/utils/change-metadata.d.ts +5 -2
- package/dist/utils/change-metadata.js +7 -13
- package/dist/utils/change-utils.d.ts +9 -0
- package/dist/utils/change-utils.js +7 -5
- package/dist/utils/file-system.d.ts +5 -0
- package/dist/utils/file-system.js +21 -1
- package/package.json +2 -1
- package/schemas/workspace-planning/schema.yaml +72 -0
- package/schemas/workspace-planning/templates/design.md +33 -0
- package/schemas/workspace-planning/templates/proposal.md +28 -0
- package/schemas/workspace-planning/templates/spec.md +9 -0
- package/schemas/workspace-planning/templates/tasks.md +15 -0
|
@@ -6,38 +6,135 @@
|
|
|
6
6
|
import ora from 'ora';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { createChange, validateChangeName } from '../../utils/change-utils.js';
|
|
9
|
+
import { formatChangeLocation, resolveCurrentPlanningHomeSync, } from '../../core/planning-home.js';
|
|
9
10
|
import { validateSchemaExists } from './shared.js';
|
|
11
|
+
import { resolveInitiativeLinkReference, } from '../../core/collections/initiatives/index.js';
|
|
12
|
+
import { assertInitiativeSelectorsHaveReference, assertRepoLocalInitiativeLinkPlanningHome, formatInitiativeLink, printJson, statusFromError, } from './initiative-link.js';
|
|
10
13
|
// -----------------------------------------------------------------------------
|
|
11
14
|
// Command Implementation
|
|
12
15
|
// -----------------------------------------------------------------------------
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
function parseAffectedAreas(value) {
|
|
17
|
+
return (value ?? '')
|
|
18
|
+
.split(',')
|
|
19
|
+
.map((area) => area.trim())
|
|
20
|
+
.filter((area) => area.length > 0);
|
|
21
|
+
}
|
|
22
|
+
function validateWorkspaceAffectedAreas(planningHome, affectedAreas) {
|
|
23
|
+
if (affectedAreas.length === 0) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (planningHome.kind !== 'workspace') {
|
|
27
|
+
throw new Error('--areas can only be used when creating a workspace-scoped change');
|
|
28
|
+
}
|
|
29
|
+
const validAreas = new Set(planningHome.workspace?.links ?? []);
|
|
30
|
+
const invalidAreas = affectedAreas.filter((area) => !validAreas.has(area));
|
|
31
|
+
if (invalidAreas.length > 0) {
|
|
32
|
+
const validList = [...validAreas].sort((a, b) => a.localeCompare(b));
|
|
33
|
+
const validMessage = validList.length > 0 ? validList.join(', ') : '(no registered links)';
|
|
34
|
+
throw new Error(`Invalid affected area${invalidAreas.length === 1 ? '' : 's'}: ${invalidAreas.join(', ')}. ` +
|
|
35
|
+
`Valid workspace link names: ${validMessage}`);
|
|
16
36
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
37
|
+
}
|
|
38
|
+
function outputForCreatedChange(id, changeDir, schema, initiative) {
|
|
39
|
+
return {
|
|
40
|
+
change: {
|
|
41
|
+
id,
|
|
42
|
+
path: changeDir,
|
|
43
|
+
metadataPath: path.join(changeDir, '.openspec.yaml'),
|
|
44
|
+
schema,
|
|
45
|
+
},
|
|
46
|
+
...(initiative ? { initiative } : {}),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function printCreatedChangeHuman(payload, planningHome) {
|
|
50
|
+
if (!payload.change) {
|
|
51
|
+
return;
|
|
20
52
|
}
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
53
|
+
const location = formatChangeLocation(planningHome, payload.change.id);
|
|
54
|
+
const scope = planningHome.kind === 'workspace' ? 'workspace change' : 'change';
|
|
55
|
+
console.log(`Created ${scope} '${payload.change.id}' at ${location}/`);
|
|
56
|
+
console.log(`Schema: ${payload.change.schema}`);
|
|
57
|
+
if (payload.initiative) {
|
|
58
|
+
console.log(`Initiative: ${formatInitiativeLink(payload.initiative)}`);
|
|
25
59
|
}
|
|
26
|
-
|
|
27
|
-
|
|
60
|
+
}
|
|
61
|
+
export async function newChangeCommand(name, options) {
|
|
62
|
+
const spinner = options.json ? undefined : ora();
|
|
28
63
|
try {
|
|
29
|
-
|
|
64
|
+
if (!name) {
|
|
65
|
+
throw new Error('Missing required argument <name>');
|
|
66
|
+
}
|
|
67
|
+
const validation = validateChangeName(name);
|
|
68
|
+
if (!validation.valid) {
|
|
69
|
+
throw new Error(validation.error);
|
|
70
|
+
}
|
|
71
|
+
assertInitiativeSelectorsHaveReference(options);
|
|
72
|
+
const planningHome = resolveCurrentPlanningHomeSync();
|
|
73
|
+
const projectRoot = planningHome.root;
|
|
74
|
+
const affectedAreas = parseAffectedAreas(options.areas);
|
|
75
|
+
validateWorkspaceAffectedAreas(planningHome, affectedAreas);
|
|
76
|
+
let initiative;
|
|
77
|
+
if (options.initiative !== undefined) {
|
|
78
|
+
assertRepoLocalInitiativeLinkPlanningHome(planningHome);
|
|
79
|
+
initiative = await resolveInitiativeLinkReference(options.initiative, {
|
|
80
|
+
store: options.store,
|
|
81
|
+
storePath: options.storePath,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// Validate schema if provided
|
|
85
|
+
if (options.schema) {
|
|
86
|
+
validateSchemaExists(options.schema, projectRoot);
|
|
87
|
+
}
|
|
88
|
+
const resolvedSchema = options.schema ?? planningHome.defaultSchema;
|
|
89
|
+
if (spinner) {
|
|
90
|
+
spinner.start(`Creating change '${name}' with schema '${resolvedSchema}'...`);
|
|
91
|
+
}
|
|
92
|
+
const workspaceGoal = planningHome.kind === 'workspace'
|
|
93
|
+
? options.goal ?? options.description
|
|
94
|
+
: options.goal;
|
|
95
|
+
const result = await createChange(projectRoot, name, {
|
|
96
|
+
schema: options.schema,
|
|
97
|
+
defaultSchema: planningHome.defaultSchema,
|
|
98
|
+
changesDir: planningHome.changesDir,
|
|
99
|
+
metadata: {
|
|
100
|
+
...(workspaceGoal ? { goal: workspaceGoal } : {}),
|
|
101
|
+
...(affectedAreas.length > 0 ? { affected_areas: affectedAreas } : {}),
|
|
102
|
+
...(initiative ? { initiative } : {}),
|
|
103
|
+
},
|
|
104
|
+
});
|
|
30
105
|
// If description provided, create README.md with description
|
|
31
106
|
if (options.description) {
|
|
32
107
|
const { promises: fs } = await import('fs');
|
|
33
|
-
const
|
|
34
|
-
const readmePath = path.join(changeDir, 'README.md');
|
|
108
|
+
const readmePath = path.join(result.changeDir, 'README.md');
|
|
35
109
|
await fs.writeFile(readmePath, `# ${name}\n\n${options.description}\n`, 'utf-8');
|
|
36
110
|
}
|
|
37
|
-
|
|
111
|
+
const payload = outputForCreatedChange(name, result.changeDir, result.schema, initiative);
|
|
112
|
+
if (options.json) {
|
|
113
|
+
printJson(payload);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
spinner?.stop();
|
|
117
|
+
printCreatedChangeHuman(payload, planningHome);
|
|
118
|
+
if (planningHome.kind === 'workspace' && !initiative) {
|
|
119
|
+
if (affectedAreas.length > 0) {
|
|
120
|
+
console.log(`Affected areas: ${affectedAreas.join(', ')}`);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
console.log('Affected areas: unresolved; identify them in change metadata or coordination tasks as planning continues.');
|
|
124
|
+
}
|
|
125
|
+
console.log('Next: run openspec status --change "' + name + '" to inspect workspace planning artifacts.');
|
|
126
|
+
}
|
|
38
127
|
}
|
|
39
128
|
catch (error) {
|
|
40
|
-
spinner
|
|
129
|
+
spinner?.stop();
|
|
130
|
+
if (options.json) {
|
|
131
|
+
printJson({
|
|
132
|
+
change: null,
|
|
133
|
+
status: [statusFromError(error)],
|
|
134
|
+
});
|
|
135
|
+
process.exitCode = 1;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
41
138
|
throw error;
|
|
42
139
|
}
|
|
43
140
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set Change Command
|
|
3
|
+
*
|
|
4
|
+
* Mutates checked-in repo-local change metadata.
|
|
5
|
+
*/
|
|
6
|
+
export interface SetChangeOptions {
|
|
7
|
+
initiative?: string;
|
|
8
|
+
store?: string;
|
|
9
|
+
storePath?: string;
|
|
10
|
+
json?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function setChangeCommand(name: string | undefined, options: SetChangeOptions): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=set-change.d.ts.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set Change Command
|
|
3
|
+
*
|
|
4
|
+
* Mutates checked-in repo-local change metadata.
|
|
5
|
+
*/
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { getChangeDir, resolveCurrentPlanningHomeSync, } from '../../core/planning-home.js';
|
|
8
|
+
import { readChangeMetadata, resolveSchemaForChange, writeChangeMetadata, } from '../../utils/change-metadata.js';
|
|
9
|
+
import { validateChangeExists } from './shared.js';
|
|
10
|
+
import { resolveInitiativeLinkReference, } from '../../core/collections/initiatives/index.js';
|
|
11
|
+
import { assertInitiativeReference, assertRepoLocalInitiativeLinkPlanningHome, formatInitiativeLink, printJson, sameInitiativeLink, statusFromError, } from './initiative-link.js';
|
|
12
|
+
function outputForSetChange(id, changeDir, schema, initiative, updated) {
|
|
13
|
+
return {
|
|
14
|
+
change: {
|
|
15
|
+
id,
|
|
16
|
+
path: changeDir,
|
|
17
|
+
metadataPath: path.join(changeDir, '.openspec.yaml'),
|
|
18
|
+
schema,
|
|
19
|
+
},
|
|
20
|
+
initiative,
|
|
21
|
+
updated,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function printSetChangeHuman(payload) {
|
|
25
|
+
if (!payload.change || !payload.initiative) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const verb = payload.updated ? 'Linked' : 'Change already linked';
|
|
29
|
+
console.log(`${verb}: ${payload.change.id}`);
|
|
30
|
+
console.log(`Initiative: ${formatInitiativeLink(payload.initiative)}`);
|
|
31
|
+
console.log(`Metadata: ${payload.change.metadataPath}`);
|
|
32
|
+
}
|
|
33
|
+
export async function setChangeCommand(name, options) {
|
|
34
|
+
try {
|
|
35
|
+
if (!name) {
|
|
36
|
+
throw new Error('Missing required argument <name>');
|
|
37
|
+
}
|
|
38
|
+
assertInitiativeReference(options.initiative);
|
|
39
|
+
const planningHome = resolveCurrentPlanningHomeSync();
|
|
40
|
+
assertRepoLocalInitiativeLinkPlanningHome(planningHome);
|
|
41
|
+
const projectRoot = planningHome.root;
|
|
42
|
+
const changeName = await validateChangeExists(name, projectRoot, planningHome.changesDir);
|
|
43
|
+
const changeDir = getChangeDir(planningHome, changeName);
|
|
44
|
+
const initiative = await resolveInitiativeLinkReference(options.initiative, {
|
|
45
|
+
store: options.store,
|
|
46
|
+
storePath: options.storePath,
|
|
47
|
+
});
|
|
48
|
+
const existingMetadata = readChangeMetadata(changeDir, projectRoot);
|
|
49
|
+
const metadata = existingMetadata ?? {
|
|
50
|
+
schema: resolveSchemaForChange(changeDir, undefined, projectRoot, { metadata: null }),
|
|
51
|
+
};
|
|
52
|
+
if (sameInitiativeLink(metadata.initiative, initiative)) {
|
|
53
|
+
const payload = outputForSetChange(changeName, changeDir, metadata.schema, initiative, false);
|
|
54
|
+
if (options.json) {
|
|
55
|
+
printJson(payload);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
printSetChangeHuman(payload);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (metadata.initiative) {
|
|
62
|
+
throw new Error(`Change '${changeName}' is already linked to initiative ${formatInitiativeLink(metadata.initiative)}.`);
|
|
63
|
+
}
|
|
64
|
+
writeChangeMetadata(changeDir, {
|
|
65
|
+
...metadata,
|
|
66
|
+
initiative,
|
|
67
|
+
}, projectRoot);
|
|
68
|
+
const payload = outputForSetChange(changeName, changeDir, metadata.schema, initiative, true);
|
|
69
|
+
if (options.json) {
|
|
70
|
+
printJson(payload);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
printSetChangeHuman(payload);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (options.json) {
|
|
77
|
+
printJson({
|
|
78
|
+
change: null,
|
|
79
|
+
status: [statusFromError(error)],
|
|
80
|
+
});
|
|
81
|
+
process.exitCode = 1;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=set-change.js.map
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* This module contains types, constants, and validation helpers used across
|
|
5
5
|
* multiple artifact workflow commands.
|
|
6
6
|
*/
|
|
7
|
+
import type { InitiativeLink } from '../../core/change-metadata/index.js';
|
|
7
8
|
export interface TaskItem {
|
|
8
9
|
id: string;
|
|
9
10
|
description: string;
|
|
@@ -13,7 +14,8 @@ export interface ApplyInstructions {
|
|
|
13
14
|
changeName: string;
|
|
14
15
|
changeDir: string;
|
|
15
16
|
schemaName: string;
|
|
16
|
-
|
|
17
|
+
initiative?: InitiativeLink;
|
|
18
|
+
contextFiles: Record<string, string[]>;
|
|
17
19
|
progress: {
|
|
18
20
|
total: number;
|
|
19
21
|
complete: number;
|
|
@@ -41,12 +43,12 @@ export declare function getStatusIndicator(status: 'done' | 'ready' | 'blocked')
|
|
|
41
43
|
* Returns the list of available change directory names under openspec/changes/.
|
|
42
44
|
* Excludes the archive directory and hidden directories.
|
|
43
45
|
*/
|
|
44
|
-
export declare function getAvailableChanges(projectRoot: string): Promise<string[]>;
|
|
46
|
+
export declare function getAvailableChanges(projectRoot: string, changesDir?: string): Promise<string[]>;
|
|
45
47
|
/**
|
|
46
48
|
* Validates that a change exists and returns available changes if not.
|
|
47
49
|
* Checks directory existence directly to support scaffolded changes (without proposal.md).
|
|
48
50
|
*/
|
|
49
|
-
export declare function validateChangeExists(changeName: string | undefined, projectRoot: string): Promise<string>;
|
|
51
|
+
export declare function validateChangeExists(changeName: string | undefined, projectRoot: string, changesDir?: string): Promise<string>;
|
|
50
52
|
/**
|
|
51
53
|
* Validates that a schema exists and returns available schemas if not.
|
|
52
54
|
*
|
|
@@ -56,8 +56,8 @@ export function getStatusIndicator(status) {
|
|
|
56
56
|
* Returns the list of available change directory names under openspec/changes/.
|
|
57
57
|
* Excludes the archive directory and hidden directories.
|
|
58
58
|
*/
|
|
59
|
-
export async function getAvailableChanges(projectRoot) {
|
|
60
|
-
const changesPath =
|
|
59
|
+
export async function getAvailableChanges(projectRoot, changesDir = path.join(projectRoot, 'openspec', 'changes')) {
|
|
60
|
+
const changesPath = changesDir;
|
|
61
61
|
try {
|
|
62
62
|
const entries = await fs.promises.readdir(changesPath, { withFileTypes: true });
|
|
63
63
|
return entries
|
|
@@ -74,9 +74,9 @@ export async function getAvailableChanges(projectRoot) {
|
|
|
74
74
|
* Validates that a change exists and returns available changes if not.
|
|
75
75
|
* Checks directory existence directly to support scaffolded changes (without proposal.md).
|
|
76
76
|
*/
|
|
77
|
-
export async function validateChangeExists(changeName, projectRoot) {
|
|
77
|
+
export async function validateChangeExists(changeName, projectRoot, changesDir = path.join(projectRoot, 'openspec', 'changes')) {
|
|
78
78
|
if (!changeName) {
|
|
79
|
-
const available = await getAvailableChanges(projectRoot);
|
|
79
|
+
const available = await getAvailableChanges(projectRoot, changesDir);
|
|
80
80
|
if (available.length === 0) {
|
|
81
81
|
throw new Error('No changes found. Create one with: openspec new change <name>');
|
|
82
82
|
}
|
|
@@ -88,10 +88,10 @@ export async function validateChangeExists(changeName, projectRoot) {
|
|
|
88
88
|
throw new Error(`Invalid change name '${changeName}': ${nameValidation.error}`);
|
|
89
89
|
}
|
|
90
90
|
// Check directory existence directly
|
|
91
|
-
const changePath = path.join(
|
|
91
|
+
const changePath = path.join(changesDir, changeName);
|
|
92
92
|
const exists = fs.existsSync(changePath) && fs.statSync(changePath).isDirectory();
|
|
93
93
|
if (!exists) {
|
|
94
|
-
const available = await getAvailableChanges(projectRoot);
|
|
94
|
+
const available = await getAvailableChanges(projectRoot, changesDir);
|
|
95
95
|
if (available.length === 0) {
|
|
96
96
|
throw new Error(`Change '${changeName}' not found. No changes exist. Create one with: openspec new change <name>`);
|
|
97
97
|
}
|
|
@@ -5,21 +5,23 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import ora from 'ora';
|
|
7
7
|
import chalk from 'chalk';
|
|
8
|
+
import { resolveCurrentPlanningHomeSync, getChangeDir } from '../../core/planning-home.js';
|
|
8
9
|
import { loadChangeContext, formatChangeStatus, } from '../../core/artifact-graph/index.js';
|
|
9
10
|
import { validateChangeExists, validateSchemaExists, getAvailableChanges, getStatusIndicator, getStatusColor, } from './shared.js';
|
|
10
11
|
// -----------------------------------------------------------------------------
|
|
11
12
|
// Command Implementation
|
|
12
13
|
// -----------------------------------------------------------------------------
|
|
13
14
|
export async function statusCommand(options) {
|
|
14
|
-
const spinner = ora('Loading change status...').start();
|
|
15
|
+
const spinner = options.json ? undefined : ora('Loading change status...').start();
|
|
15
16
|
try {
|
|
16
|
-
const
|
|
17
|
+
const planningHome = resolveCurrentPlanningHomeSync();
|
|
18
|
+
const projectRoot = planningHome.root;
|
|
17
19
|
// Handle no-changes case gracefully — status is informational,
|
|
18
20
|
// so "no changes" is a valid state, not an error.
|
|
19
21
|
if (!options.change) {
|
|
20
|
-
const available = await getAvailableChanges(projectRoot);
|
|
22
|
+
const available = await getAvailableChanges(projectRoot, planningHome.changesDir);
|
|
21
23
|
if (available.length === 0) {
|
|
22
|
-
spinner
|
|
24
|
+
spinner?.stop();
|
|
23
25
|
if (options.json) {
|
|
24
26
|
console.log(JSON.stringify({ changes: [], message: 'No active changes.' }, null, 2));
|
|
25
27
|
return;
|
|
@@ -28,18 +30,21 @@ export async function statusCommand(options) {
|
|
|
28
30
|
return;
|
|
29
31
|
}
|
|
30
32
|
// Changes exist but --change not provided
|
|
31
|
-
spinner
|
|
33
|
+
spinner?.stop();
|
|
32
34
|
throw new Error(`Missing required option --change. Available changes:\n ${available.join('\n ')}`);
|
|
33
35
|
}
|
|
34
|
-
const changeName = await validateChangeExists(options.change, projectRoot);
|
|
36
|
+
const changeName = await validateChangeExists(options.change, projectRoot, planningHome.changesDir);
|
|
35
37
|
// Validate schema if explicitly provided
|
|
36
38
|
if (options.schema) {
|
|
37
39
|
validateSchemaExists(options.schema, projectRoot);
|
|
38
40
|
}
|
|
39
41
|
// loadChangeContext will auto-detect schema from metadata if not provided
|
|
40
|
-
const context = loadChangeContext(projectRoot, changeName, options.schema
|
|
42
|
+
const context = loadChangeContext(projectRoot, changeName, options.schema, {
|
|
43
|
+
changeDir: getChangeDir(planningHome, changeName),
|
|
44
|
+
planningHome,
|
|
45
|
+
});
|
|
41
46
|
const status = formatChangeStatus(context);
|
|
42
|
-
spinner
|
|
47
|
+
spinner?.stop();
|
|
43
48
|
if (options.json) {
|
|
44
49
|
console.log(JSON.stringify(status, null, 2));
|
|
45
50
|
return;
|
|
@@ -47,7 +52,7 @@ export async function statusCommand(options) {
|
|
|
47
52
|
printStatusText(status);
|
|
48
53
|
}
|
|
49
54
|
catch (error) {
|
|
50
|
-
spinner
|
|
55
|
+
spinner?.stop();
|
|
51
56
|
throw error;
|
|
52
57
|
}
|
|
53
58
|
}
|
|
@@ -56,6 +61,16 @@ export function printStatusText(status) {
|
|
|
56
61
|
const total = status.artifacts.length;
|
|
57
62
|
console.log(`Change: ${status.changeName}`);
|
|
58
63
|
console.log(`Schema: ${status.schemaName}`);
|
|
64
|
+
if (status.initiative) {
|
|
65
|
+
console.log(`Initiative: ${status.initiative.store}/${status.initiative.id}`);
|
|
66
|
+
}
|
|
67
|
+
if (status.planningHome) {
|
|
68
|
+
const label = status.planningHome.kind === 'workspace'
|
|
69
|
+
? `workspace${status.planningHome.workspaceName ? ` (${status.planningHome.workspaceName})` : ''}`
|
|
70
|
+
: 'repo';
|
|
71
|
+
console.log(`Planning home: ${label}`);
|
|
72
|
+
console.log(`Change root: ${status.changeRoot}`);
|
|
73
|
+
}
|
|
59
74
|
console.log(`Progress: ${doneCount}/${total} artifacts complete`);
|
|
60
75
|
console.log();
|
|
61
76
|
for (const artifact of status.artifacts) {
|
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
import ora from 'ora';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { resolveSchema, getSchemaDir, ArtifactGraph, } from '../../core/artifact-graph/index.js';
|
|
9
|
+
import { FileSystemUtils } from '../../utils/file-system.js';
|
|
9
10
|
import { validateSchemaExists, DEFAULT_SCHEMA } from './shared.js';
|
|
10
11
|
// -----------------------------------------------------------------------------
|
|
11
12
|
// Command Implementation
|
|
12
13
|
// -----------------------------------------------------------------------------
|
|
13
14
|
export async function templatesCommand(options) {
|
|
14
|
-
const spinner = ora('Loading templates...').start();
|
|
15
|
+
const spinner = options.json ? undefined : ora('Loading templates...').start();
|
|
15
16
|
try {
|
|
16
17
|
const projectRoot = process.cwd();
|
|
17
18
|
const schemaName = validateSchemaExists(options.schema ?? DEFAULT_SCHEMA, projectRoot);
|
|
@@ -40,10 +41,10 @@ export async function templatesCommand(options) {
|
|
|
40
41
|
}
|
|
41
42
|
const templates = graph.getAllArtifacts().map((artifact) => ({
|
|
42
43
|
artifactId: artifact.id,
|
|
43
|
-
templatePath: path.join(schemaDir, 'templates', artifact.template),
|
|
44
|
+
templatePath: FileSystemUtils.canonicalizeExistingPath(path.join(schemaDir, 'templates', artifact.template)),
|
|
44
45
|
source,
|
|
45
46
|
}));
|
|
46
|
-
spinner
|
|
47
|
+
spinner?.stop();
|
|
47
48
|
if (options.json) {
|
|
48
49
|
const output = {};
|
|
49
50
|
for (const t of templates) {
|
|
@@ -61,7 +62,7 @@ export async function templatesCommand(options) {
|
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
catch (error) {
|
|
64
|
-
spinner
|
|
65
|
+
spinner?.stop();
|
|
65
66
|
throw error;
|
|
66
67
|
}
|
|
67
68
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type WorkspaceContextState } from '../../core/workspace/index.js';
|
|
2
|
+
import { WorkspaceStatus } from './types.js';
|
|
3
|
+
export declare function collectWorkspaceContextStatuses(context: WorkspaceContextState | null): Promise<WorkspaceStatus[]>;
|
|
4
|
+
//# sourceMappingURL=context-status.d.ts.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { mountInitiativesCollection, readInitiative, } from '../../core/collections/initiatives/index.js';
|
|
2
|
+
import { formatContextStoreBinding, formatContextStoreBindingSelector, resolveContextStoreBinding, } from '../../core/context-store/index.js';
|
|
3
|
+
import { getWorkspaceContextInitiativeId, } from '../../core/workspace/index.js';
|
|
4
|
+
import { asErrorMessage, makeStatus } from './types.js';
|
|
5
|
+
function contextStoreBindingWarningToStatus(warning) {
|
|
6
|
+
return makeStatus('warning', warning.code, warning.message, {
|
|
7
|
+
target: warning.target ? `workspace.context.store.${warning.target}` : 'workspace.context.store',
|
|
8
|
+
...(warning.fix ? { fix: warning.fix } : {}),
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export async function collectWorkspaceContextStatuses(context) {
|
|
12
|
+
if (!context) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
const initiativeId = getWorkspaceContextInitiativeId(context);
|
|
16
|
+
const contextStoreLabel = formatContextStoreBinding(context.store);
|
|
17
|
+
const selector = formatContextStoreBindingSelector(context.store);
|
|
18
|
+
let resolvedStore;
|
|
19
|
+
try {
|
|
20
|
+
resolvedStore = await resolveContextStoreBinding(context.store);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
return [
|
|
24
|
+
makeStatus('error', 'workspace_context_store_unavailable', `Workspace context store '${contextStoreLabel}' could not be read: ${asErrorMessage(error)}`, {
|
|
25
|
+
target: 'workspace.context.store',
|
|
26
|
+
fix: context.store.selector.kind === 'registry'
|
|
27
|
+
? 'openspec context-store doctor'
|
|
28
|
+
: `Check the path in workspace.yaml or run openspec initiative show ${initiativeId} ${selector}`,
|
|
29
|
+
}),
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
const statuses = resolvedStore.warnings.map(contextStoreBindingWarningToStatus);
|
|
33
|
+
try {
|
|
34
|
+
const initiative = await readInitiative({
|
|
35
|
+
collection: mountInitiativesCollection(resolvedStore.root),
|
|
36
|
+
id: initiativeId,
|
|
37
|
+
});
|
|
38
|
+
if (!initiative) {
|
|
39
|
+
return [
|
|
40
|
+
...statuses,
|
|
41
|
+
makeStatus('error', 'workspace_initiative_missing', `Workspace initiative '${contextStoreLabel}/${initiativeId}' was not found.`, {
|
|
42
|
+
target: 'workspace.context.initiative',
|
|
43
|
+
fix: `openspec initiative show ${initiativeId} ${selector}`,
|
|
44
|
+
}),
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
return statuses;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return [
|
|
51
|
+
...statuses,
|
|
52
|
+
makeStatus('error', 'workspace_initiative_unavailable', `Workspace initiative '${contextStoreLabel}/${initiativeId}' could not be read: ${asErrorMessage(error)}`, {
|
|
53
|
+
target: 'workspace.context.initiative',
|
|
54
|
+
fix: `openspec initiative show ${initiativeId} ${selector}`,
|
|
55
|
+
}),
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=context-status.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type InitiativeViewReference } from '../../core/collections/initiatives/index.js';
|
|
2
|
+
import { type SelectedWorkspace, type WorkspaceOpenOptions, type WorkspaceStatus } from './types.js';
|
|
3
|
+
export type WorkspaceOpenTarget = {
|
|
4
|
+
kind: 'workspace';
|
|
5
|
+
selected: SelectedWorkspace;
|
|
6
|
+
status: WorkspaceStatus[];
|
|
7
|
+
} | {
|
|
8
|
+
kind: 'initiative';
|
|
9
|
+
initiative: InitiativeViewReference;
|
|
10
|
+
status: WorkspaceStatus[];
|
|
11
|
+
};
|
|
12
|
+
export declare function selectWorkspaceOpenTarget(workspaceName: string | undefined, options: WorkspaceOpenOptions): Promise<WorkspaceOpenTarget>;
|
|
13
|
+
//# sourceMappingURL=open-target-selection.d.ts.map
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { InitiativeResolutionError, initiativeDiagnosticFromError, listInitiativeViewReferences, } from '../../core/collections/initiatives/index.js';
|
|
2
|
+
import { createRegisteredContextStoreBinding, sameContextStoreBinding, } from '../../core/context-store/index.js';
|
|
3
|
+
import { findWorkspaceRoot, getWorkspaceContextInitiativeId, listKnownWorkspaceEntries, readWorkspaceViewState, } from '../../core/workspace/index.js';
|
|
4
|
+
import { isInteractive, resolveNoInteractive } from '../../utils/interactive.js';
|
|
5
|
+
import { selectWorkspaceForCommand, selectedWorkspaceFromEntry, selectedWorkspaceFromRoot, } from './selection.js';
|
|
6
|
+
import { WorkspaceCliError, } from './types.js';
|
|
7
|
+
async function readKnownWorkspaceContexts(entries) {
|
|
8
|
+
return Promise.all(entries.map(async (entry) => {
|
|
9
|
+
try {
|
|
10
|
+
return (await readWorkspaceViewState(entry.workspaceRoot)).context;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// Broken workspaces are surfaced by list/doctor; open target selection
|
|
14
|
+
// should not hide otherwise openable initiatives behind unreadable views.
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
function workspaceContextMatchesInitiative(context, initiative) {
|
|
20
|
+
return (context !== null &&
|
|
21
|
+
sameContextStoreBinding(context.store, createRegisteredContextStoreBinding(initiative.store)) &&
|
|
22
|
+
getWorkspaceContextInitiativeId(context) === initiative.id);
|
|
23
|
+
}
|
|
24
|
+
function initiativeHasKnownWorkspace(contexts, initiative) {
|
|
25
|
+
return contexts.some((context) => workspaceContextMatchesInitiative(context, initiative));
|
|
26
|
+
}
|
|
27
|
+
function initiativeDiagnosticToWorkspaceStatus(diagnostic) {
|
|
28
|
+
return {
|
|
29
|
+
severity: diagnostic.severity,
|
|
30
|
+
code: diagnostic.code,
|
|
31
|
+
message: diagnostic.message,
|
|
32
|
+
target: diagnostic.target,
|
|
33
|
+
fix: diagnostic.fix,
|
|
34
|
+
details: diagnostic.details,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async function listOpenableInitiatives(entries) {
|
|
38
|
+
try {
|
|
39
|
+
const [result, contexts] = await Promise.all([
|
|
40
|
+
listInitiativeViewReferences(),
|
|
41
|
+
readKnownWorkspaceContexts(entries),
|
|
42
|
+
]);
|
|
43
|
+
const initiatives = [];
|
|
44
|
+
for (const initiative of result.initiatives) {
|
|
45
|
+
if (!initiativeHasKnownWorkspace(contexts, initiative)) {
|
|
46
|
+
initiatives.push(initiative);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
kind: 'listed',
|
|
51
|
+
initiatives,
|
|
52
|
+
status: result.status.map(initiativeDiagnosticToWorkspaceStatus),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
const diagnostic = error instanceof InitiativeResolutionError
|
|
57
|
+
? initiativeDiagnosticFromError(error)
|
|
58
|
+
: {
|
|
59
|
+
severity: 'error',
|
|
60
|
+
code: 'initiative_discovery_failed',
|
|
61
|
+
message: error instanceof Error ? error.message : String(error),
|
|
62
|
+
target: 'initiative',
|
|
63
|
+
fix: 'openspec context-store doctor',
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
kind: 'unavailable',
|
|
67
|
+
initiatives: [],
|
|
68
|
+
status: [initiativeDiagnosticToWorkspaceStatus(diagnostic)],
|
|
69
|
+
error: new WorkspaceCliError(diagnostic.message, diagnostic.code, {
|
|
70
|
+
target: diagnostic.target,
|
|
71
|
+
fix: diagnostic.fix,
|
|
72
|
+
details: diagnostic.details,
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export async function selectWorkspaceOpenTarget(workspaceName, options) {
|
|
78
|
+
if (workspaceName ||
|
|
79
|
+
options.json ||
|
|
80
|
+
resolveNoInteractive(options) ||
|
|
81
|
+
!isInteractive(options)) {
|
|
82
|
+
return {
|
|
83
|
+
kind: 'workspace',
|
|
84
|
+
selected: await selectWorkspaceForCommand({
|
|
85
|
+
...options,
|
|
86
|
+
workspace: workspaceName,
|
|
87
|
+
}, 'open', { preferPositionalName: true }),
|
|
88
|
+
status: [],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const entries = await listKnownWorkspaceEntries();
|
|
92
|
+
const currentWorkspaceRoot = await findWorkspaceRoot(process.cwd());
|
|
93
|
+
if (currentWorkspaceRoot) {
|
|
94
|
+
return {
|
|
95
|
+
kind: 'workspace',
|
|
96
|
+
selected: await selectedWorkspaceFromRoot(currentWorkspaceRoot, entries),
|
|
97
|
+
status: [],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const listed = await listOpenableInitiatives(entries);
|
|
101
|
+
if (listed.initiatives.length === 0) {
|
|
102
|
+
if (listed.kind === 'unavailable' && entries.length === 0) {
|
|
103
|
+
throw listed.error;
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
kind: 'workspace',
|
|
107
|
+
selected: await selectWorkspaceForCommand(options, 'open', {
|
|
108
|
+
preferPositionalName: true,
|
|
109
|
+
}),
|
|
110
|
+
status: listed.status,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const { select } = await import('@inquirer/prompts');
|
|
114
|
+
const selected = await select({
|
|
115
|
+
message: 'Select workspace or initiative:',
|
|
116
|
+
choices: [
|
|
117
|
+
...entries.map((entry) => ({
|
|
118
|
+
name: `Workspace: ${entry.name} (${entry.workspaceRoot})`,
|
|
119
|
+
value: {
|
|
120
|
+
kind: 'workspace',
|
|
121
|
+
entry,
|
|
122
|
+
},
|
|
123
|
+
})),
|
|
124
|
+
...listed.initiatives.map((initiative) => ({
|
|
125
|
+
name: `Initiative: ${initiative.store}/${initiative.id} - ${initiative.title} (create local workspace view)`,
|
|
126
|
+
value: {
|
|
127
|
+
kind: 'initiative',
|
|
128
|
+
initiative,
|
|
129
|
+
},
|
|
130
|
+
})),
|
|
131
|
+
],
|
|
132
|
+
});
|
|
133
|
+
if (selected.kind === 'workspace') {
|
|
134
|
+
return {
|
|
135
|
+
kind: 'workspace',
|
|
136
|
+
selected: selectedWorkspaceFromEntry(selected.entry),
|
|
137
|
+
status: listed.status,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
kind: 'initiative',
|
|
142
|
+
initiative: selected.initiative,
|
|
143
|
+
status: listed.status,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=open-target-selection.js.map
|