@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
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
export const INITIATIVE_COLLECTION_ID = 'initiatives';
|
|
4
|
-
export const INITIATIVE_FILE_NAME = 'initiative.yaml';
|
|
5
|
-
export const INITIATIVE_REQUIREMENTS_FILE_NAME = 'requirements.md';
|
|
6
|
-
export const INITIATIVE_DESIGN_FILE_NAME = 'design.md';
|
|
7
|
-
export const INITIATIVE_DECISIONS_FILE_NAME = 'decisions.md';
|
|
8
|
-
export const INITIATIVE_QUESTIONS_FILE_NAME = 'questions.md';
|
|
9
|
-
export const INITIATIVE_TASKS_FILE_NAME = 'tasks.md';
|
|
10
|
-
export const INITIATIVE_MARKDOWN_FILE_NAMES = [
|
|
11
|
-
INITIATIVE_REQUIREMENTS_FILE_NAME,
|
|
12
|
-
INITIATIVE_DESIGN_FILE_NAME,
|
|
13
|
-
INITIATIVE_DECISIONS_FILE_NAME,
|
|
14
|
-
INITIATIVE_QUESTIONS_FILE_NAME,
|
|
15
|
-
INITIATIVE_TASKS_FILE_NAME,
|
|
16
|
-
];
|
|
17
|
-
export const INITIATIVE_FILE_NAMES = [
|
|
18
|
-
INITIATIVE_FILE_NAME,
|
|
19
|
-
...INITIATIVE_MARKDOWN_FILE_NAMES,
|
|
20
|
-
];
|
|
21
|
-
export const INITIATIVE_STATUSES = [
|
|
22
|
-
'exploring',
|
|
23
|
-
'active',
|
|
24
|
-
'complete',
|
|
25
|
-
'archived',
|
|
26
|
-
];
|
|
27
|
-
const INITIATIVE_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/u;
|
|
28
|
-
function assertNoNul(value, label) {
|
|
29
|
-
if (value.includes('\0')) {
|
|
30
|
-
throw new Error(`${label} must not contain NUL bytes`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function nonBlankString(label) {
|
|
34
|
-
return z.string().refine((value) => value.trim().length > 0, {
|
|
35
|
-
message: `${label} must not be empty`,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
const InitiativeMetadataValueSchema = z.lazy(() => z.union([
|
|
39
|
-
z.string(),
|
|
40
|
-
z.number().finite(),
|
|
41
|
-
z.boolean(),
|
|
42
|
-
z.null(),
|
|
43
|
-
z.array(InitiativeMetadataValueSchema),
|
|
44
|
-
z.record(z.string(), InitiativeMetadataValueSchema),
|
|
45
|
-
]));
|
|
46
|
-
const InitiativeMetadataSchema = z.record(z.string(), InitiativeMetadataValueSchema);
|
|
47
|
-
const InitiativeStateSchema = z.object({
|
|
48
|
-
version: z.literal(1),
|
|
49
|
-
id: z.string(),
|
|
50
|
-
title: nonBlankString('title'),
|
|
51
|
-
summary: nonBlankString('summary'),
|
|
52
|
-
status: z.enum(INITIATIVE_STATUSES),
|
|
53
|
-
created: z.string().regex(INITIATIVE_DATE_PATTERN, {
|
|
54
|
-
message: 'created must be YYYY-MM-DD format',
|
|
55
|
-
}),
|
|
56
|
-
owners: z.array(nonBlankString('owner')).default([]),
|
|
57
|
-
metadata: InitiativeMetadataSchema.default({}),
|
|
58
|
-
}).strict();
|
|
59
|
-
function formatZodIssues(error) {
|
|
60
|
-
return error.issues
|
|
61
|
-
.map((issue) => {
|
|
62
|
-
const location = issue.path.length > 0 ? issue.path.join('.') : 'root';
|
|
63
|
-
return `${location}: ${issue.message}`;
|
|
64
|
-
})
|
|
65
|
-
.join('; ');
|
|
66
|
-
}
|
|
67
|
-
function parseYamlObject(content, label) {
|
|
68
|
-
try {
|
|
69
|
-
return parseYaml(content);
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
73
|
-
throw new Error(`Invalid ${label}: ${message}`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
export function validateInitiativeId(id) {
|
|
77
|
-
assertNoNul(id, 'Initiative id');
|
|
78
|
-
if (id.length === 0) {
|
|
79
|
-
throw new Error('Initiative id must not be empty');
|
|
80
|
-
}
|
|
81
|
-
if (id === '.' || id === '..') {
|
|
82
|
-
throw new Error(`Initiative id must not be '${id}'`);
|
|
83
|
-
}
|
|
84
|
-
if (/[\\/]/u.test(id)) {
|
|
85
|
-
throw new Error('Initiative id must not contain path separators');
|
|
86
|
-
}
|
|
87
|
-
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(id)) {
|
|
88
|
-
throw new Error('Initiative id must be kebab-case with lowercase letters, numbers, and single hyphen separators');
|
|
89
|
-
}
|
|
90
|
-
return id;
|
|
91
|
-
}
|
|
92
|
-
export function isValidInitiativeId(id) {
|
|
93
|
-
try {
|
|
94
|
-
validateInitiativeId(id);
|
|
95
|
-
return true;
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
function parseInitiativeStateInput(raw) {
|
|
102
|
-
const result = InitiativeStateSchema.safeParse(raw);
|
|
103
|
-
if (!result.success) {
|
|
104
|
-
throw new Error(`Invalid initiative state: ${formatZodIssues(result.error)}`);
|
|
105
|
-
}
|
|
106
|
-
validateInitiativeId(result.data.id);
|
|
107
|
-
return {
|
|
108
|
-
version: 1,
|
|
109
|
-
id: result.data.id,
|
|
110
|
-
title: result.data.title,
|
|
111
|
-
summary: result.data.summary,
|
|
112
|
-
status: result.data.status,
|
|
113
|
-
created: result.data.created,
|
|
114
|
-
owners: result.data.owners,
|
|
115
|
-
metadata: result.data.metadata,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
export function parseInitiativeState(content) {
|
|
119
|
-
return parseInitiativeStateInput(parseYamlObject(content, 'initiative state'));
|
|
120
|
-
}
|
|
121
|
-
export function serializeInitiativeState(state) {
|
|
122
|
-
const parsedState = parseInitiativeStateInput(state);
|
|
123
|
-
return stringifyYaml({
|
|
124
|
-
version: 1,
|
|
125
|
-
id: parsedState.id,
|
|
126
|
-
title: parsedState.title,
|
|
127
|
-
summary: parsedState.summary,
|
|
128
|
-
status: parsedState.status,
|
|
129
|
-
created: parsedState.created,
|
|
130
|
-
owners: parsedState.owners,
|
|
131
|
-
metadata: parsedState.metadata,
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
//# sourceMappingURL=schema.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { type InitiativeMarkdownFileName, type InitiativeState } from './schema.js';
|
|
2
|
-
export interface InitiativeTemplateFile {
|
|
3
|
-
fileName: InitiativeMarkdownFileName;
|
|
4
|
-
content: string;
|
|
5
|
-
}
|
|
6
|
-
export declare function buildInitiativeRequirementsTemplate(state: InitiativeState): string;
|
|
7
|
-
export declare function buildInitiativeDesignTemplate(state: InitiativeState): string;
|
|
8
|
-
export declare function buildInitiativeDecisionsTemplate(state: InitiativeState): string;
|
|
9
|
-
export declare function buildInitiativeQuestionsTemplate(): string;
|
|
10
|
-
export declare function buildInitiativeTasksTemplate(): string;
|
|
11
|
-
export declare function buildDefaultInitiativeFiles(state: InitiativeState): InitiativeTemplateFile[];
|
|
12
|
-
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { INITIATIVE_DECISIONS_FILE_NAME, INITIATIVE_DESIGN_FILE_NAME, INITIATIVE_MARKDOWN_FILE_NAMES, INITIATIVE_QUESTIONS_FILE_NAME, INITIATIVE_REQUIREMENTS_FILE_NAME, INITIATIVE_TASKS_FILE_NAME, } from './schema.js';
|
|
2
|
-
function withTrailingNewline(content) {
|
|
3
|
-
return content.endsWith('\n') ? content : `${content}\n`;
|
|
4
|
-
}
|
|
5
|
-
export function buildInitiativeRequirementsTemplate(state) {
|
|
6
|
-
return withTrailingNewline(`# Requirements
|
|
7
|
-
|
|
8
|
-
## Product Intent
|
|
9
|
-
|
|
10
|
-
${state.summary}
|
|
11
|
-
|
|
12
|
-
## Accepted Requirements
|
|
13
|
-
|
|
14
|
-
- TBD
|
|
15
|
-
|
|
16
|
-
## Out Of Scope
|
|
17
|
-
|
|
18
|
-
- TBD
|
|
19
|
-
`);
|
|
20
|
-
}
|
|
21
|
-
export function buildInitiativeDesignTemplate(state) {
|
|
22
|
-
return withTrailingNewline(`# Design
|
|
23
|
-
|
|
24
|
-
## Context
|
|
25
|
-
|
|
26
|
-
${state.summary}
|
|
27
|
-
|
|
28
|
-
## Approach
|
|
29
|
-
|
|
30
|
-
TBD
|
|
31
|
-
|
|
32
|
-
## Affected Areas
|
|
33
|
-
|
|
34
|
-
- TBD
|
|
35
|
-
|
|
36
|
-
## Dependencies
|
|
37
|
-
|
|
38
|
-
- TBD
|
|
39
|
-
|
|
40
|
-
## Risks
|
|
41
|
-
|
|
42
|
-
- TBD
|
|
43
|
-
`);
|
|
44
|
-
}
|
|
45
|
-
export function buildInitiativeDecisionsTemplate(state) {
|
|
46
|
-
return withTrailingNewline(`# Decisions
|
|
47
|
-
|
|
48
|
-
## Accepted Decisions
|
|
49
|
-
|
|
50
|
-
### ${state.created}: ${state.title}
|
|
51
|
-
|
|
52
|
-
- Decision: TBD
|
|
53
|
-
- Why: TBD
|
|
54
|
-
- Implications: TBD
|
|
55
|
-
`);
|
|
56
|
-
}
|
|
57
|
-
export function buildInitiativeQuestionsTemplate() {
|
|
58
|
-
return withTrailingNewline(`# Questions
|
|
59
|
-
|
|
60
|
-
## Open Questions
|
|
61
|
-
|
|
62
|
-
- TBD
|
|
63
|
-
|
|
64
|
-
## Resolved Questions
|
|
65
|
-
|
|
66
|
-
- TBD
|
|
67
|
-
`);
|
|
68
|
-
}
|
|
69
|
-
export function buildInitiativeTasksTemplate() {
|
|
70
|
-
return withTrailingNewline(`# Tasks
|
|
71
|
-
|
|
72
|
-
## Coordination Tasks
|
|
73
|
-
|
|
74
|
-
- [ ] TBD
|
|
75
|
-
`);
|
|
76
|
-
}
|
|
77
|
-
export function buildDefaultInitiativeFiles(state) {
|
|
78
|
-
const templates = {
|
|
79
|
-
[INITIATIVE_REQUIREMENTS_FILE_NAME]: buildInitiativeRequirementsTemplate(state),
|
|
80
|
-
[INITIATIVE_DESIGN_FILE_NAME]: buildInitiativeDesignTemplate(state),
|
|
81
|
-
[INITIATIVE_DECISIONS_FILE_NAME]: buildInitiativeDecisionsTemplate(state),
|
|
82
|
-
[INITIATIVE_QUESTIONS_FILE_NAME]: buildInitiativeQuestionsTemplate(),
|
|
83
|
-
[INITIATIVE_TASKS_FILE_NAME]: buildInitiativeTasksTemplate(),
|
|
84
|
-
};
|
|
85
|
-
return INITIATIVE_MARKDOWN_FILE_NAMES.map((fileName) => ({
|
|
86
|
-
fileName,
|
|
87
|
-
content: templates[fileName],
|
|
88
|
-
}));
|
|
89
|
-
}
|
|
90
|
-
//# sourceMappingURL=templates.js.map
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
export type CollectionMetadata = Readonly<Record<string, unknown>>;
|
|
2
|
-
export type CollectionHooks = Readonly<Record<string, unknown>>;
|
|
3
|
-
export interface CollectionDefinition<THandle = unknown> {
|
|
4
|
-
id: string;
|
|
5
|
-
mount: string;
|
|
6
|
-
metadata?: CollectionMetadata;
|
|
7
|
-
hooks?: CollectionHooks;
|
|
8
|
-
createHandle?: (context: MountedCollectionContext) => THandle;
|
|
9
|
-
}
|
|
10
|
-
export interface CollectionRegistry {
|
|
11
|
-
list(): readonly CollectionDefinition[];
|
|
12
|
-
get<THandle = unknown>(collectionId: string): CollectionDefinition<THandle> | undefined;
|
|
13
|
-
require<THandle = unknown>(collectionId: string): CollectionDefinition<THandle>;
|
|
14
|
-
}
|
|
15
|
-
export interface MountedCollectionContext {
|
|
16
|
-
storeRoot: string;
|
|
17
|
-
collectionId: string;
|
|
18
|
-
mount: string;
|
|
19
|
-
mountRoot: string;
|
|
20
|
-
resolvePath(relativePath?: string): string;
|
|
21
|
-
toStorePath(relativePath?: string): string;
|
|
22
|
-
}
|
|
23
|
-
export interface MountedCollection<THandle = unknown> {
|
|
24
|
-
collectionId: string;
|
|
25
|
-
mount: string;
|
|
26
|
-
mountRoot: string;
|
|
27
|
-
context: MountedCollectionContext;
|
|
28
|
-
handle: THandle | undefined;
|
|
29
|
-
resolvePath(relativePath?: string): string;
|
|
30
|
-
toStorePath(relativePath?: string): string;
|
|
31
|
-
}
|
|
32
|
-
export interface MountedCollectionRegistry {
|
|
33
|
-
list(): readonly MountedCollection[];
|
|
34
|
-
get<THandle = unknown>(collectionId: string): MountedCollection<THandle> | undefined;
|
|
35
|
-
require<THandle = unknown>(collectionId: string): MountedCollection<THandle>;
|
|
36
|
-
}
|
|
37
|
-
export interface MountCollectionsInput {
|
|
38
|
-
storeRoot: string;
|
|
39
|
-
collections: CollectionRegistry;
|
|
40
|
-
}
|
|
41
|
-
export declare function validateCollectionId(id: string): string;
|
|
42
|
-
export declare function validateMount(mount: string): string;
|
|
43
|
-
export declare function parseCollectionPath(input?: string): string;
|
|
44
|
-
export declare function createCollectionRegistry(definitions: readonly CollectionDefinition[]): CollectionRegistry;
|
|
45
|
-
export declare function mountCollections(input: MountCollectionsInput): MountedCollectionRegistry;
|
|
46
|
-
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import * as path from 'node:path';
|
|
2
|
-
import { FileSystemUtils } from '../../utils/file-system.js';
|
|
3
|
-
function assertNoNul(value, label) {
|
|
4
|
-
if (value.includes('\0')) {
|
|
5
|
-
throw new Error(`${label} must not contain NUL bytes`);
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
function validateKebabSegment(value, label) {
|
|
9
|
-
assertNoNul(value, label);
|
|
10
|
-
if (value.length === 0) {
|
|
11
|
-
throw new Error(`${label} must not be empty`);
|
|
12
|
-
}
|
|
13
|
-
if (value === '.' || value === '..') {
|
|
14
|
-
throw new Error(`${label} must not be '${value}'`);
|
|
15
|
-
}
|
|
16
|
-
if (/[\\/]/u.test(value)) {
|
|
17
|
-
throw new Error(`${label} must not contain path separators`);
|
|
18
|
-
}
|
|
19
|
-
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(value)) {
|
|
20
|
-
throw new Error(`${label} must be kebab-case with lowercase letters, numbers, and single hyphen separators`);
|
|
21
|
-
}
|
|
22
|
-
return value;
|
|
23
|
-
}
|
|
24
|
-
export function validateCollectionId(id) {
|
|
25
|
-
return validateKebabSegment(id, 'Collection id');
|
|
26
|
-
}
|
|
27
|
-
export function validateMount(mount) {
|
|
28
|
-
assertNoNul(mount, 'Collection mount');
|
|
29
|
-
if (mount.startsWith('.')) {
|
|
30
|
-
throw new Error(`Collection mount '${mount}' is reserved`);
|
|
31
|
-
}
|
|
32
|
-
return validateKebabSegment(mount, 'Collection mount');
|
|
33
|
-
}
|
|
34
|
-
function isWindowsDrivePath(value) {
|
|
35
|
-
return /^[A-Za-z]:/u.test(value);
|
|
36
|
-
}
|
|
37
|
-
function isUncPath(value) {
|
|
38
|
-
return value.startsWith('\\\\') || value.startsWith('//');
|
|
39
|
-
}
|
|
40
|
-
export function parseCollectionPath(input = '') {
|
|
41
|
-
assertNoNul(input, 'Collection path');
|
|
42
|
-
if (input.length === 0) {
|
|
43
|
-
return '';
|
|
44
|
-
}
|
|
45
|
-
if (input.includes('\\')) {
|
|
46
|
-
throw new Error('Collection path must use forward slashes');
|
|
47
|
-
}
|
|
48
|
-
if (isWindowsDrivePath(input)) {
|
|
49
|
-
throw new Error('Collection path must not be a Windows drive path');
|
|
50
|
-
}
|
|
51
|
-
if (isUncPath(input) || path.posix.isAbsolute(input)) {
|
|
52
|
-
throw new Error('Collection path must be relative');
|
|
53
|
-
}
|
|
54
|
-
const segments = input.split('/');
|
|
55
|
-
for (const segment of segments) {
|
|
56
|
-
if (segment.length === 0) {
|
|
57
|
-
throw new Error('Collection path must not contain empty segments');
|
|
58
|
-
}
|
|
59
|
-
if (segment === '.' || segment === '..') {
|
|
60
|
-
throw new Error('Collection path must not contain dot segments');
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return segments.join('/');
|
|
64
|
-
}
|
|
65
|
-
function compareCollectionDefinitions(a, b) {
|
|
66
|
-
return a.id.localeCompare(b.id);
|
|
67
|
-
}
|
|
68
|
-
export function createCollectionRegistry(definitions) {
|
|
69
|
-
const byId = new Map();
|
|
70
|
-
const mountOwners = new Map();
|
|
71
|
-
for (const definition of definitions) {
|
|
72
|
-
const id = validateCollectionId(definition.id);
|
|
73
|
-
const mount = validateMount(definition.mount);
|
|
74
|
-
if (byId.has(id)) {
|
|
75
|
-
throw new Error(`Duplicate collection id '${id}'`);
|
|
76
|
-
}
|
|
77
|
-
const existingMountOwner = mountOwners.get(mount);
|
|
78
|
-
if (existingMountOwner) {
|
|
79
|
-
throw new Error(`Duplicate collection mount '${mount}' for '${existingMountOwner}' and '${id}'`);
|
|
80
|
-
}
|
|
81
|
-
const normalizedDefinition = {
|
|
82
|
-
...definition,
|
|
83
|
-
id,
|
|
84
|
-
mount,
|
|
85
|
-
};
|
|
86
|
-
byId.set(id, normalizedDefinition);
|
|
87
|
-
mountOwners.set(mount, id);
|
|
88
|
-
}
|
|
89
|
-
const sortedDefinitions = Array.from(byId.values()).sort(compareCollectionDefinitions);
|
|
90
|
-
return {
|
|
91
|
-
list() {
|
|
92
|
-
return [...sortedDefinitions];
|
|
93
|
-
},
|
|
94
|
-
get(collectionId) {
|
|
95
|
-
const id = validateCollectionId(collectionId);
|
|
96
|
-
return byId.get(id);
|
|
97
|
-
},
|
|
98
|
-
require(collectionId) {
|
|
99
|
-
const definition = this.get(collectionId);
|
|
100
|
-
if (!definition) {
|
|
101
|
-
throw new Error(`Unknown collection '${collectionId}'`);
|
|
102
|
-
}
|
|
103
|
-
return definition;
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
function isWindowsLikePath(candidatePath) {
|
|
108
|
-
return /^[A-Za-z]:[\\/]/u.test(candidatePath) || candidatePath.startsWith('\\\\');
|
|
109
|
-
}
|
|
110
|
-
function relativePath(fromPath, toPath) {
|
|
111
|
-
if (isWindowsLikePath(fromPath) || isWindowsLikePath(toPath)) {
|
|
112
|
-
return path.win32.relative(path.win32.normalize(fromPath), path.win32.normalize(toPath));
|
|
113
|
-
}
|
|
114
|
-
return path.posix.relative(fromPath.replace(/\\/g, '/'), toPath.replace(/\\/g, '/'));
|
|
115
|
-
}
|
|
116
|
-
function isRelativePathAbsolute(value, windowsLike) {
|
|
117
|
-
return windowsLike ? path.win32.isAbsolute(value) : path.posix.isAbsolute(value);
|
|
118
|
-
}
|
|
119
|
-
function isSameOrDescendant(rootPath, candidatePath) {
|
|
120
|
-
const windowsLike = isWindowsLikePath(rootPath) || isWindowsLikePath(candidatePath);
|
|
121
|
-
const relative = relativePath(rootPath, candidatePath);
|
|
122
|
-
const escapesRoot = /^\.\.(?:[\\/]|$)/u.test(relative);
|
|
123
|
-
return (relative === '' ||
|
|
124
|
-
(!escapesRoot && !isRelativePathAbsolute(relative, windowsLike)));
|
|
125
|
-
}
|
|
126
|
-
function getMountRoot(storeRoot, mount) {
|
|
127
|
-
return FileSystemUtils.joinPath(storeRoot, validateMount(mount));
|
|
128
|
-
}
|
|
129
|
-
function resolvePathInsideMount(mountRoot, relativePath) {
|
|
130
|
-
const collectionPath = parseCollectionPath(relativePath);
|
|
131
|
-
const resolvedPath = collectionPath.length > 0
|
|
132
|
-
? FileSystemUtils.joinPath(mountRoot, collectionPath)
|
|
133
|
-
: mountRoot;
|
|
134
|
-
if (!isSameOrDescendant(mountRoot, resolvedPath)) {
|
|
135
|
-
throw new Error(`Collection path escapes mount: ${relativePath ?? ''}`);
|
|
136
|
-
}
|
|
137
|
-
return resolvedPath;
|
|
138
|
-
}
|
|
139
|
-
function toStorePath(mount, relativePath) {
|
|
140
|
-
const collectionPath = parseCollectionPath(relativePath);
|
|
141
|
-
return collectionPath.length > 0
|
|
142
|
-
? `${validateMount(mount)}/${collectionPath}`
|
|
143
|
-
: validateMount(mount);
|
|
144
|
-
}
|
|
145
|
-
function createMountedCollection(storeRoot, definition) {
|
|
146
|
-
const mountRoot = getMountRoot(storeRoot, definition.mount);
|
|
147
|
-
const resolveMountedPath = (relativePath) => resolvePathInsideMount(mountRoot, relativePath);
|
|
148
|
-
const resolveStorePath = (relativePath) => toStorePath(definition.mount, relativePath);
|
|
149
|
-
const context = {
|
|
150
|
-
storeRoot,
|
|
151
|
-
collectionId: definition.id,
|
|
152
|
-
mount: definition.mount,
|
|
153
|
-
mountRoot,
|
|
154
|
-
resolvePath: resolveMountedPath,
|
|
155
|
-
toStorePath: resolveStorePath,
|
|
156
|
-
};
|
|
157
|
-
return {
|
|
158
|
-
collectionId: definition.id,
|
|
159
|
-
mount: definition.mount,
|
|
160
|
-
mountRoot,
|
|
161
|
-
context,
|
|
162
|
-
handle: definition.createHandle?.(context),
|
|
163
|
-
resolvePath: resolveMountedPath,
|
|
164
|
-
toStorePath: resolveStorePath,
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
export function mountCollections(input) {
|
|
168
|
-
if (input.storeRoot.length === 0) {
|
|
169
|
-
throw new Error('Context store root must not be empty');
|
|
170
|
-
}
|
|
171
|
-
const byId = new Map();
|
|
172
|
-
for (const definition of input.collections.list()) {
|
|
173
|
-
const mountedCollection = createMountedCollection(input.storeRoot, definition);
|
|
174
|
-
byId.set(mountedCollection.collectionId, mountedCollection);
|
|
175
|
-
}
|
|
176
|
-
const sortedCollections = Array.from(byId.values()).sort((a, b) => a.collectionId.localeCompare(b.collectionId));
|
|
177
|
-
return {
|
|
178
|
-
list() {
|
|
179
|
-
return [...sortedCollections];
|
|
180
|
-
},
|
|
181
|
-
get(collectionId) {
|
|
182
|
-
const id = validateCollectionId(collectionId);
|
|
183
|
-
return byId.get(id);
|
|
184
|
-
},
|
|
185
|
-
require(collectionId) {
|
|
186
|
-
const mountedCollection = this.get(collectionId);
|
|
187
|
-
if (!mountedCollection) {
|
|
188
|
-
throw new Error(`Unknown mounted collection '${collectionId}'`);
|
|
189
|
-
}
|
|
190
|
-
return mountedCollection;
|
|
191
|
-
},
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
//# sourceMappingURL=runtime.js.map
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { type ContextStorePathOptions } from './foundation.js';
|
|
2
|
-
import { type ResolvedContextStore } from './registry.js';
|
|
3
|
-
export type ContextStoreSelector = {
|
|
4
|
-
kind: 'registry';
|
|
5
|
-
id: string;
|
|
6
|
-
} | {
|
|
7
|
-
kind: 'path';
|
|
8
|
-
path: string;
|
|
9
|
-
observed_id?: string;
|
|
10
|
-
};
|
|
11
|
-
export type ContextStoreSelectorSource = 'registry' | 'path';
|
|
12
|
-
export interface ContextStoreSelectorOptions {
|
|
13
|
-
store?: string;
|
|
14
|
-
storePath?: string;
|
|
15
|
-
}
|
|
16
|
-
export interface SelectedContextStore {
|
|
17
|
-
id: string;
|
|
18
|
-
root: string;
|
|
19
|
-
source: ContextStoreSelectorSource;
|
|
20
|
-
}
|
|
21
|
-
export interface ContextStoreBinding {
|
|
22
|
-
id: string;
|
|
23
|
-
selector: ContextStoreSelector;
|
|
24
|
-
}
|
|
25
|
-
export interface ContextStoreBindingWarning {
|
|
26
|
-
code: string;
|
|
27
|
-
message: string;
|
|
28
|
-
target?: string;
|
|
29
|
-
fix?: string;
|
|
30
|
-
}
|
|
31
|
-
export interface ResolvedContextStoreBinding {
|
|
32
|
-
binding: ContextStoreBinding;
|
|
33
|
-
id: string;
|
|
34
|
-
root: string;
|
|
35
|
-
source: 'registry' | 'path';
|
|
36
|
-
registered?: ResolvedContextStore;
|
|
37
|
-
warnings: ContextStoreBindingWarning[];
|
|
38
|
-
}
|
|
39
|
-
export declare function createRegisteredContextStoreBinding(id: string): ContextStoreBinding;
|
|
40
|
-
export declare function createPathContextStoreBinding(input: {
|
|
41
|
-
id: string;
|
|
42
|
-
path: string;
|
|
43
|
-
}): ContextStoreBinding;
|
|
44
|
-
export declare function normalizeContextStoreBinding(binding: ContextStoreBinding): ContextStoreBinding;
|
|
45
|
-
export declare function sameContextStoreBinding(left: ContextStoreBinding, right: ContextStoreBinding): boolean;
|
|
46
|
-
export declare function formatContextStoreBinding(binding: ContextStoreBinding): string;
|
|
47
|
-
export declare function formatContextStoreBindingSelector(binding: ContextStoreBinding): string;
|
|
48
|
-
export declare function formatContextStoreSelector(selected: SelectedContextStore): string;
|
|
49
|
-
export declare function createContextStoreBindingFromSelected(selected: SelectedContextStore): ContextStoreBinding;
|
|
50
|
-
export declare function requireContextStoreSelector(options: ContextStoreSelectorOptions, commandName: string): void;
|
|
51
|
-
export declare function resolveSelectedContextStore(options: ContextStoreSelectorOptions, commandName: string, pathOptions?: ContextStorePathOptions): Promise<SelectedContextStore>;
|
|
52
|
-
export declare function resolveContextStoreBinding(binding: ContextStoreBinding, options?: ContextStorePathOptions): Promise<ResolvedContextStoreBinding>;
|
|
53
|
-
//# sourceMappingURL=binding.d.ts.map
|