gmc-openspec 1.0.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/LICENSE +22 -0
- package/README.md +207 -0
- package/bin/openspec.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +494 -0
- package/dist/commands/change.d.ts +35 -0
- package/dist/commands/change.js +277 -0
- package/dist/commands/completion.d.ts +72 -0
- package/dist/commands/completion.js +264 -0
- package/dist/commands/config.d.ts +36 -0
- package/dist/commands/config.js +611 -0
- package/dist/commands/feedback.d.ts +9 -0
- package/dist/commands/feedback.js +183 -0
- package/dist/commands/jira.d.ts +3 -0
- package/dist/commands/jira.js +249 -0
- package/dist/commands/schema.d.ts +6 -0
- package/dist/commands/schema.js +869 -0
- package/dist/commands/show.d.ts +14 -0
- package/dist/commands/show.js +132 -0
- package/dist/commands/spec.d.ts +15 -0
- package/dist/commands/spec.js +225 -0
- package/dist/commands/validate.d.ts +24 -0
- package/dist/commands/validate.js +294 -0
- package/dist/commands/workflow/index.d.ts +17 -0
- package/dist/commands/workflow/index.js +12 -0
- package/dist/commands/workflow/instructions.d.ts +29 -0
- package/dist/commands/workflow/instructions.js +336 -0
- package/dist/commands/workflow/new-change.d.ts +13 -0
- package/dist/commands/workflow/new-change.js +92 -0
- package/dist/commands/workflow/schemas.d.ts +10 -0
- package/dist/commands/workflow/schemas.js +34 -0
- package/dist/commands/workflow/shared.d.ts +57 -0
- package/dist/commands/workflow/shared.js +116 -0
- package/dist/commands/workflow/status.d.ts +14 -0
- package/dist/commands/workflow/status.js +87 -0
- package/dist/commands/workflow/templates.d.ts +16 -0
- package/dist/commands/workflow/templates.js +69 -0
- package/dist/commands/workspace/open.d.ts +29 -0
- package/dist/commands/workspace/open.js +84 -0
- package/dist/commands/workspace/operations.d.ts +23 -0
- package/dist/commands/workspace/operations.js +475 -0
- package/dist/commands/workspace/selection.d.ts +6 -0
- package/dist/commands/workspace/selection.js +113 -0
- package/dist/commands/workspace/types.d.ts +88 -0
- package/dist/commands/workspace/types.js +36 -0
- package/dist/commands/workspace.d.ts +6 -0
- package/dist/commands/workspace.js +868 -0
- package/dist/core/archive.d.ts +11 -0
- package/dist/core/archive.js +318 -0
- package/dist/core/artifact-graph/graph.d.ts +56 -0
- package/dist/core/artifact-graph/graph.js +141 -0
- package/dist/core/artifact-graph/index.d.ts +8 -0
- package/dist/core/artifact-graph/index.js +14 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +196 -0
- package/dist/core/artifact-graph/instruction-loader.js +317 -0
- package/dist/core/artifact-graph/outputs.d.ts +14 -0
- package/dist/core/artifact-graph/outputs.js +39 -0
- package/dist/core/artifact-graph/resolver.d.ts +81 -0
- package/dist/core/artifact-graph/resolver.js +257 -0
- package/dist/core/artifact-graph/schema.d.ts +13 -0
- package/dist/core/artifact-graph/schema.js +108 -0
- package/dist/core/artifact-graph/state.d.ts +12 -0
- package/dist/core/artifact-graph/state.js +31 -0
- package/dist/core/artifact-graph/types.d.ts +47 -0
- package/dist/core/artifact-graph/types.js +48 -0
- package/dist/core/available-tools.d.ts +17 -0
- package/dist/core/available-tools.js +43 -0
- package/dist/core/command-generation/adapters/amazon-q.d.ts +13 -0
- package/dist/core/command-generation/adapters/amazon-q.js +26 -0
- package/dist/core/command-generation/adapters/antigravity.d.ts +13 -0
- package/dist/core/command-generation/adapters/antigravity.js +26 -0
- package/dist/core/command-generation/adapters/auggie.d.ts +13 -0
- package/dist/core/command-generation/adapters/auggie.js +27 -0
- package/dist/core/command-generation/adapters/bob.d.ts +14 -0
- package/dist/core/command-generation/adapters/bob.js +45 -0
- package/dist/core/command-generation/adapters/claude.d.ts +13 -0
- package/dist/core/command-generation/adapters/claude.js +50 -0
- package/dist/core/command-generation/adapters/cline.d.ts +14 -0
- package/dist/core/command-generation/adapters/cline.js +27 -0
- package/dist/core/command-generation/adapters/codebuddy.d.ts +13 -0
- package/dist/core/command-generation/adapters/codebuddy.js +28 -0
- package/dist/core/command-generation/adapters/codex.d.ts +16 -0
- package/dist/core/command-generation/adapters/codex.js +39 -0
- package/dist/core/command-generation/adapters/continue.d.ts +13 -0
- package/dist/core/command-generation/adapters/continue.js +28 -0
- package/dist/core/command-generation/adapters/costrict.d.ts +13 -0
- package/dist/core/command-generation/adapters/costrict.js +27 -0
- package/dist/core/command-generation/adapters/crush.d.ts +13 -0
- package/dist/core/command-generation/adapters/crush.js +30 -0
- package/dist/core/command-generation/adapters/cursor.d.ts +14 -0
- package/dist/core/command-generation/adapters/cursor.js +44 -0
- package/dist/core/command-generation/adapters/factory.d.ts +13 -0
- package/dist/core/command-generation/adapters/factory.js +27 -0
- package/dist/core/command-generation/adapters/gemini.d.ts +13 -0
- package/dist/core/command-generation/adapters/gemini.js +26 -0
- package/dist/core/command-generation/adapters/github-copilot.d.ts +13 -0
- package/dist/core/command-generation/adapters/github-copilot.js +26 -0
- package/dist/core/command-generation/adapters/iflow.d.ts +13 -0
- package/dist/core/command-generation/adapters/iflow.js +29 -0
- package/dist/core/command-generation/adapters/index.d.ts +32 -0
- package/dist/core/command-generation/adapters/index.js +32 -0
- package/dist/core/command-generation/adapters/junie.d.ts +13 -0
- package/dist/core/command-generation/adapters/junie.js +26 -0
- package/dist/core/command-generation/adapters/kilocode.d.ts +14 -0
- package/dist/core/command-generation/adapters/kilocode.js +23 -0
- package/dist/core/command-generation/adapters/kiro.d.ts +13 -0
- package/dist/core/command-generation/adapters/kiro.js +26 -0
- package/dist/core/command-generation/adapters/lingma.d.ts +13 -0
- package/dist/core/command-generation/adapters/lingma.js +30 -0
- package/dist/core/command-generation/adapters/opencode.d.ts +13 -0
- package/dist/core/command-generation/adapters/opencode.js +29 -0
- package/dist/core/command-generation/adapters/pi.d.ts +18 -0
- package/dist/core/command-generation/adapters/pi.js +55 -0
- package/dist/core/command-generation/adapters/qoder.d.ts +13 -0
- package/dist/core/command-generation/adapters/qoder.js +30 -0
- package/dist/core/command-generation/adapters/qwen.d.ts +13 -0
- package/dist/core/command-generation/adapters/qwen.js +26 -0
- package/dist/core/command-generation/adapters/roocode.d.ts +14 -0
- package/dist/core/command-generation/adapters/roocode.js +27 -0
- package/dist/core/command-generation/adapters/windsurf.d.ts +14 -0
- package/dist/core/command-generation/adapters/windsurf.js +51 -0
- package/dist/core/command-generation/generator.d.ts +21 -0
- package/dist/core/command-generation/generator.js +27 -0
- package/dist/core/command-generation/index.d.ts +22 -0
- package/dist/core/command-generation/index.js +24 -0
- package/dist/core/command-generation/registry.d.ts +36 -0
- package/dist/core/command-generation/registry.js +98 -0
- package/dist/core/command-generation/types.d.ts +56 -0
- package/dist/core/command-generation/types.js +8 -0
- package/dist/core/completions/command-registry.d.ts +7 -0
- package/dist/core/completions/command-registry.js +626 -0
- package/dist/core/completions/completion-provider.d.ts +71 -0
- package/dist/core/completions/completion-provider.js +129 -0
- package/dist/core/completions/factory.d.ts +64 -0
- package/dist/core/completions/factory.js +75 -0
- package/dist/core/completions/generators/bash-generator.d.ts +35 -0
- package/dist/core/completions/generators/bash-generator.js +230 -0
- package/dist/core/completions/generators/fish-generator.d.ts +32 -0
- package/dist/core/completions/generators/fish-generator.js +160 -0
- package/dist/core/completions/generators/powershell-generator.d.ts +36 -0
- package/dist/core/completions/generators/powershell-generator.js +266 -0
- package/dist/core/completions/generators/zsh-generator.d.ts +47 -0
- package/dist/core/completions/generators/zsh-generator.js +274 -0
- package/dist/core/completions/installers/bash-installer.d.ts +87 -0
- package/dist/core/completions/installers/bash-installer.js +318 -0
- package/dist/core/completions/installers/fish-installer.d.ts +43 -0
- package/dist/core/completions/installers/fish-installer.js +143 -0
- package/dist/core/completions/installers/powershell-installer.d.ts +102 -0
- package/dist/core/completions/installers/powershell-installer.js +387 -0
- package/dist/core/completions/installers/zsh-installer.d.ts +117 -0
- package/dist/core/completions/installers/zsh-installer.js +421 -0
- package/dist/core/completions/templates/bash-templates.d.ts +6 -0
- package/dist/core/completions/templates/bash-templates.js +30 -0
- package/dist/core/completions/templates/fish-templates.d.ts +7 -0
- package/dist/core/completions/templates/fish-templates.js +45 -0
- package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
- package/dist/core/completions/templates/powershell-templates.js +34 -0
- package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
- package/dist/core/completions/templates/zsh-templates.js +45 -0
- package/dist/core/completions/types.d.ts +101 -0
- package/dist/core/completions/types.js +2 -0
- package/dist/core/config-prompts.d.ts +9 -0
- package/dist/core/config-prompts.js +34 -0
- package/dist/core/config-schema.d.ts +86 -0
- package/dist/core/config-schema.js +213 -0
- package/dist/core/config.d.ts +18 -0
- package/dist/core/config.js +38 -0
- package/dist/core/converters/json-converter.d.ts +6 -0
- package/dist/core/converters/json-converter.js +51 -0
- package/dist/core/global-config.d.ts +49 -0
- package/dist/core/global-config.js +124 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +6 -0
- package/dist/core/init.d.ts +37 -0
- package/dist/core/init.js +593 -0
- package/dist/core/jira/config.d.ts +35 -0
- package/dist/core/jira/config.js +151 -0
- package/dist/core/jira/constants.d.ts +20 -0
- package/dist/core/jira/constants.js +49 -0
- package/dist/core/jira/doctor.d.ts +19 -0
- package/dist/core/jira/doctor.js +173 -0
- package/dist/core/jira/hash.d.ts +3 -0
- package/dist/core/jira/hash.js +9 -0
- package/dist/core/jira/index.d.ts +11 -0
- package/dist/core/jira/index.js +11 -0
- package/dist/core/jira/intake.d.ts +40 -0
- package/dist/core/jira/intake.js +54 -0
- package/dist/core/jira/mcp-config.d.ts +13 -0
- package/dist/core/jira/mcp-config.js +259 -0
- package/dist/core/jira/paths.d.ts +12 -0
- package/dist/core/jira/paths.js +66 -0
- package/dist/core/jira/setup.d.ts +30 -0
- package/dist/core/jira/setup.js +99 -0
- package/dist/core/jira/templates.d.ts +12 -0
- package/dist/core/jira/templates.js +204 -0
- package/dist/core/jira/validation.d.ts +17 -0
- package/dist/core/jira/validation.js +341 -0
- package/dist/core/legacy-cleanup.d.ts +162 -0
- package/dist/core/legacy-cleanup.js +514 -0
- package/dist/core/list.d.ts +9 -0
- package/dist/core/list.js +171 -0
- package/dist/core/migration.d.ts +23 -0
- package/dist/core/migration.js +108 -0
- package/dist/core/parsers/change-parser.d.ts +13 -0
- package/dist/core/parsers/change-parser.js +197 -0
- package/dist/core/parsers/markdown-parser.d.ts +26 -0
- package/dist/core/parsers/markdown-parser.js +227 -0
- package/dist/core/parsers/requirement-blocks.d.ts +37 -0
- package/dist/core/parsers/requirement-blocks.js +201 -0
- 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 +124 -0
- package/dist/core/profile-sync-drift.d.ts +38 -0
- package/dist/core/profile-sync-drift.js +200 -0
- package/dist/core/profiles.d.ts +26 -0
- package/dist/core/profiles.js +40 -0
- package/dist/core/project-config.d.ts +64 -0
- package/dist/core/project-config.js +223 -0
- package/dist/core/schemas/base.schema.d.ts +13 -0
- package/dist/core/schemas/base.schema.js +13 -0
- package/dist/core/schemas/change.schema.d.ts +73 -0
- package/dist/core/schemas/change.schema.js +31 -0
- package/dist/core/schemas/index.d.ts +4 -0
- package/dist/core/schemas/index.js +4 -0
- package/dist/core/schemas/spec.schema.d.ts +18 -0
- package/dist/core/schemas/spec.schema.js +15 -0
- package/dist/core/shared/index.d.ts +8 -0
- package/dist/core/shared/index.js +8 -0
- package/dist/core/shared/skill-generation.d.ts +49 -0
- package/dist/core/shared/skill-generation.js +96 -0
- package/dist/core/shared/tool-detection.d.ts +71 -0
- package/dist/core/shared/tool-detection.js +158 -0
- package/dist/core/specs-apply.d.ts +73 -0
- package/dist/core/specs-apply.js +392 -0
- package/dist/core/styles/palette.d.ts +7 -0
- package/dist/core/styles/palette.js +8 -0
- package/dist/core/templates/index.d.ts +8 -0
- package/dist/core/templates/index.js +9 -0
- package/dist/core/templates/skill-templates.d.ts +19 -0
- package/dist/core/templates/skill-templates.js +18 -0
- package/dist/core/templates/types.d.ts +19 -0
- package/dist/core/templates/types.js +5 -0
- package/dist/core/templates/workflows/apply-change.d.ts +10 -0
- package/dist/core/templates/workflows/apply-change.js +314 -0
- package/dist/core/templates/workflows/archive-change.d.ts +10 -0
- package/dist/core/templates/workflows/archive-change.js +277 -0
- package/dist/core/templates/workflows/bulk-archive-change.d.ts +10 -0
- package/dist/core/templates/workflows/bulk-archive-change.js +492 -0
- package/dist/core/templates/workflows/continue-change.d.ts +10 -0
- package/dist/core/templates/workflows/continue-change.js +234 -0
- package/dist/core/templates/workflows/explore.d.ts +10 -0
- package/dist/core/templates/workflows/explore.js +459 -0
- package/dist/core/templates/workflows/feedback.d.ts +9 -0
- package/dist/core/templates/workflows/feedback.js +108 -0
- package/dist/core/templates/workflows/ff-change.d.ts +10 -0
- package/dist/core/templates/workflows/ff-change.js +200 -0
- package/dist/core/templates/workflows/new-change.d.ts +10 -0
- package/dist/core/templates/workflows/new-change.js +143 -0
- package/dist/core/templates/workflows/onboard.d.ts +10 -0
- package/dist/core/templates/workflows/onboard.js +563 -0
- package/dist/core/templates/workflows/propose.d.ts +10 -0
- package/dist/core/templates/workflows/propose.js +218 -0
- package/dist/core/templates/workflows/sync-specs.d.ts +10 -0
- package/dist/core/templates/workflows/sync-specs.js +290 -0
- package/dist/core/templates/workflows/verify-change.d.ts +10 -0
- package/dist/core/templates/workflows/verify-change.js +338 -0
- package/dist/core/update.d.ts +83 -0
- package/dist/core/update.js +573 -0
- package/dist/core/validation/constants.d.ts +34 -0
- package/dist/core/validation/constants.js +40 -0
- package/dist/core/validation/types.d.ts +18 -0
- package/dist/core/validation/types.js +2 -0
- package/dist/core/validation/validator.d.ts +33 -0
- package/dist/core/validation/validator.js +418 -0
- package/dist/core/view.d.ts +8 -0
- package/dist/core/view.js +168 -0
- package/dist/core/workspace/foundation.d.ts +87 -0
- package/dist/core/workspace/foundation.js +379 -0
- package/dist/core/workspace/index.d.ts +6 -0
- package/dist/core/workspace/index.js +6 -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 +24 -0
- package/dist/core/workspace/open-surface.js +137 -0
- package/dist/core/workspace/openers.d.ts +21 -0
- package/dist/core/workspace/openers.js +119 -0
- package/dist/core/workspace/skills.d.ts +55 -0
- package/dist/core/workspace/skills.js +334 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/prompts/searchable-multi-select.d.ts +28 -0
- package/dist/prompts/searchable-multi-select.js +159 -0
- package/dist/telemetry/config.d.ts +38 -0
- package/dist/telemetry/config.js +136 -0
- package/dist/telemetry/index.d.ts +31 -0
- package/dist/telemetry/index.js +164 -0
- package/dist/ui/ascii-patterns.d.ts +16 -0
- package/dist/ui/ascii-patterns.js +133 -0
- package/dist/ui/welcome-screen.d.ts +10 -0
- package/dist/ui/welcome-screen.js +146 -0
- package/dist/utils/change-metadata.d.ts +51 -0
- package/dist/utils/change-metadata.js +147 -0
- package/dist/utils/change-utils.d.ts +71 -0
- package/dist/utils/change-utils.js +123 -0
- package/dist/utils/command-references.d.ts +18 -0
- package/dist/utils/command-references.js +20 -0
- package/dist/utils/file-system.d.ts +41 -0
- package/dist/utils/file-system.js +301 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/interactive.d.ts +18 -0
- package/dist/utils/interactive.js +21 -0
- package/dist/utils/item-discovery.d.ts +4 -0
- package/dist/utils/item-discovery.js +72 -0
- package/dist/utils/match.d.ts +3 -0
- package/dist/utils/match.js +22 -0
- package/dist/utils/shell-detection.d.ts +20 -0
- package/dist/utils/shell-detection.js +41 -0
- package/dist/utils/task-progress.d.ts +8 -0
- package/dist/utils/task-progress.js +36 -0
- package/package.json +79 -0
- package/schemas/spec-driven/schema.yaml +153 -0
- package/schemas/spec-driven/templates/design.md +19 -0
- package/schemas/spec-driven/templates/proposal.md +23 -0
- package/schemas/spec-driven/templates/spec.md +8 -0
- package/schemas/spec-driven/templates/tasks.md +9 -0
- 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
- package/scripts/postinstall.js +83 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { ArtifactGraph } from './graph.js';
|
|
2
|
+
import type { PlanningHome } from '../planning-home.js';
|
|
3
|
+
import type { CompletedSet } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Error thrown when loading a template fails.
|
|
6
|
+
*/
|
|
7
|
+
export declare class TemplateLoadError extends Error {
|
|
8
|
+
readonly templatePath: string;
|
|
9
|
+
constructor(message: string, templatePath: string);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Change context containing graph, completion state, and metadata.
|
|
13
|
+
*/
|
|
14
|
+
export interface ChangeContext {
|
|
15
|
+
/** The artifact dependency graph */
|
|
16
|
+
graph: ArtifactGraph;
|
|
17
|
+
/** Set of completed artifact IDs */
|
|
18
|
+
completed: CompletedSet;
|
|
19
|
+
/** Schema name being used */
|
|
20
|
+
schemaName: string;
|
|
21
|
+
/** Change name */
|
|
22
|
+
changeName: string;
|
|
23
|
+
/** Path to the change directory */
|
|
24
|
+
changeDir: string;
|
|
25
|
+
/** Project root directory */
|
|
26
|
+
projectRoot: string;
|
|
27
|
+
/** Resolved planning home for this change */
|
|
28
|
+
planningHome?: PlanningHome;
|
|
29
|
+
}
|
|
30
|
+
export interface LoadChangeContextOptions {
|
|
31
|
+
changeDir?: string;
|
|
32
|
+
planningHome?: PlanningHome;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Enriched instructions for creating an artifact.
|
|
36
|
+
*/
|
|
37
|
+
export interface ArtifactInstructions {
|
|
38
|
+
/** Change name */
|
|
39
|
+
changeName: string;
|
|
40
|
+
/** Artifact ID */
|
|
41
|
+
artifactId: string;
|
|
42
|
+
/** Schema name */
|
|
43
|
+
schemaName: string;
|
|
44
|
+
/** Full path to change directory */
|
|
45
|
+
changeDir: string;
|
|
46
|
+
/** Resolved planning home for this change */
|
|
47
|
+
planningHome?: PlanningHomeSummary;
|
|
48
|
+
/** Output path pattern (e.g., "proposal.md") */
|
|
49
|
+
outputPath: string;
|
|
50
|
+
/** Absolute output path or glob pattern resolved under the change directory */
|
|
51
|
+
resolvedOutputPath: string;
|
|
52
|
+
/** Existing concrete output files for this artifact */
|
|
53
|
+
existingOutputPaths: string[];
|
|
54
|
+
/** Artifact description */
|
|
55
|
+
description: string;
|
|
56
|
+
/** Guidance on how to create this artifact (from schema instruction field) */
|
|
57
|
+
instruction: string | undefined;
|
|
58
|
+
/** Project context from config (constraints/background for AI, not to be included in output) */
|
|
59
|
+
context: string | undefined;
|
|
60
|
+
/** Artifact-specific rules from config (constraints for AI, not to be included in output) */
|
|
61
|
+
rules: string[] | undefined;
|
|
62
|
+
/** Template content (structure to follow - this IS the output format) */
|
|
63
|
+
template: string;
|
|
64
|
+
/** Dependencies with completion status and paths */
|
|
65
|
+
dependencies: DependencyInfo[];
|
|
66
|
+
/** Artifacts that become available after completing this one */
|
|
67
|
+
unlocks: string[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Dependency information including path and description.
|
|
71
|
+
*/
|
|
72
|
+
export interface DependencyInfo {
|
|
73
|
+
/** Artifact ID */
|
|
74
|
+
id: string;
|
|
75
|
+
/** Whether the dependency is completed */
|
|
76
|
+
done: boolean;
|
|
77
|
+
/** Relative output path of the dependency (e.g., "proposal.md") */
|
|
78
|
+
path: string;
|
|
79
|
+
/** Description of the dependency artifact */
|
|
80
|
+
description: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Status of a single artifact in the workflow.
|
|
84
|
+
*/
|
|
85
|
+
export interface ArtifactStatus {
|
|
86
|
+
/** Artifact ID */
|
|
87
|
+
id: string;
|
|
88
|
+
/** Output path pattern */
|
|
89
|
+
outputPath: string;
|
|
90
|
+
/** Status: done, ready, or blocked */
|
|
91
|
+
status: 'done' | 'ready' | 'blocked';
|
|
92
|
+
/** Missing dependencies (only for blocked) */
|
|
93
|
+
missingDeps?: string[];
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Formatted change status.
|
|
97
|
+
*/
|
|
98
|
+
export interface ChangeStatus {
|
|
99
|
+
/** Change name */
|
|
100
|
+
changeName: string;
|
|
101
|
+
/** Schema name */
|
|
102
|
+
schemaName: string;
|
|
103
|
+
/** Resolved planning home for this change */
|
|
104
|
+
planningHome?: PlanningHomeSummary;
|
|
105
|
+
/** Full path to the change root */
|
|
106
|
+
changeRoot: string;
|
|
107
|
+
/** Absolute artifact path details keyed by artifact ID */
|
|
108
|
+
artifactPaths: Record<string, ArtifactPathSummary>;
|
|
109
|
+
/** Workspace affected-area summary, when available */
|
|
110
|
+
affectedAreas?: AffectedAreasSummary;
|
|
111
|
+
/** Plain-language next steps for users and agents */
|
|
112
|
+
nextSteps: string[];
|
|
113
|
+
/** Machine-readable action constraints for agents */
|
|
114
|
+
actionContext: ActionContext;
|
|
115
|
+
/** Whether all artifacts are complete */
|
|
116
|
+
isComplete: boolean;
|
|
117
|
+
/** Artifact IDs required before apply phase (from schema's apply.requires) */
|
|
118
|
+
applyRequires: string[];
|
|
119
|
+
/** Status of each artifact */
|
|
120
|
+
artifacts: ArtifactStatus[];
|
|
121
|
+
}
|
|
122
|
+
export interface ArtifactPathSummary {
|
|
123
|
+
outputPath: string;
|
|
124
|
+
resolvedOutputPath: string;
|
|
125
|
+
existingOutputPaths: string[];
|
|
126
|
+
}
|
|
127
|
+
export interface PlanningHomeSummary {
|
|
128
|
+
kind: 'repo' | 'workspace';
|
|
129
|
+
root: string;
|
|
130
|
+
changesDir: string;
|
|
131
|
+
defaultSchema: string;
|
|
132
|
+
workspaceName?: string;
|
|
133
|
+
}
|
|
134
|
+
export interface AffectedAreasSummary {
|
|
135
|
+
known: string[];
|
|
136
|
+
unresolved: boolean;
|
|
137
|
+
invalid: string[];
|
|
138
|
+
}
|
|
139
|
+
export interface ActionContext {
|
|
140
|
+
mode: 'repo-local' | 'workspace-planning';
|
|
141
|
+
sourceOfTruth: 'repo' | 'workspace';
|
|
142
|
+
planningArtifacts: string[];
|
|
143
|
+
linkedContext: Array<{
|
|
144
|
+
name: string;
|
|
145
|
+
}>;
|
|
146
|
+
allowedEditRoots: string[];
|
|
147
|
+
requiresAffectedAreaSelection: boolean;
|
|
148
|
+
constraints: string[];
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Loads a template from a schema's templates directory.
|
|
152
|
+
*
|
|
153
|
+
* @param schemaName - Schema name (e.g., "spec-driven")
|
|
154
|
+
* @param templatePath - Relative path within the templates directory (e.g., "proposal.md")
|
|
155
|
+
* @param projectRoot - Optional project root for project-local schema resolution
|
|
156
|
+
* @returns The template content
|
|
157
|
+
* @throws TemplateLoadError if the template cannot be loaded
|
|
158
|
+
*/
|
|
159
|
+
export declare function loadTemplate(schemaName: string, templatePath: string, projectRoot?: string): string;
|
|
160
|
+
/**
|
|
161
|
+
* Loads change context combining graph and completion state.
|
|
162
|
+
*
|
|
163
|
+
* Schema resolution order:
|
|
164
|
+
* 1. Explicit schemaName parameter (if provided)
|
|
165
|
+
* 2. Schema from .openspec.yaml metadata (if exists in change directory)
|
|
166
|
+
* 3. Default 'spec-driven'
|
|
167
|
+
*
|
|
168
|
+
* @param projectRoot - Project root directory
|
|
169
|
+
* @param changeName - Change name
|
|
170
|
+
* @param schemaName - Optional schema name override. If not provided, auto-detected from metadata.
|
|
171
|
+
* @returns Change context with graph, completed set, and metadata
|
|
172
|
+
*/
|
|
173
|
+
export declare function loadChangeContext(projectRoot: string, changeName: string, schemaName?: string, options?: LoadChangeContextOptions): ChangeContext;
|
|
174
|
+
/**
|
|
175
|
+
* Generates enriched instructions for creating an artifact.
|
|
176
|
+
*
|
|
177
|
+
* Instruction injection order:
|
|
178
|
+
* 1. <context> - Project context from config (if present)
|
|
179
|
+
* 2. <rules> - Artifact-specific rules from config (if present)
|
|
180
|
+
* 3. <template> - Schema's template content
|
|
181
|
+
*
|
|
182
|
+
* @param context - Change context
|
|
183
|
+
* @param artifactId - Artifact ID to generate instructions for
|
|
184
|
+
* @param projectRoot - Project root directory (for reading config)
|
|
185
|
+
* @returns Enriched artifact instructions
|
|
186
|
+
* @throws Error if artifact not found
|
|
187
|
+
*/
|
|
188
|
+
export declare function generateInstructions(context: ChangeContext, artifactId: string, projectRoot?: string): ArtifactInstructions;
|
|
189
|
+
/**
|
|
190
|
+
* Formats the status of all artifacts in a change.
|
|
191
|
+
*
|
|
192
|
+
* @param context - Change context
|
|
193
|
+
* @returns Formatted change status
|
|
194
|
+
*/
|
|
195
|
+
export declare function formatChangeStatus(context: ChangeContext): ChangeStatus;
|
|
196
|
+
//# sourceMappingURL=instruction-loader.d.ts.map
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { getSchemaDir, resolveSchema } from './resolver.js';
|
|
4
|
+
import { ArtifactGraph } from './graph.js';
|
|
5
|
+
import { detectCompleted } from './state.js';
|
|
6
|
+
import { resolveArtifactOutputs } from './outputs.js';
|
|
7
|
+
import { readChangeMetadata, resolveSchemaForChange } from '../../utils/change-metadata.js';
|
|
8
|
+
import { FileSystemUtils } from '../../utils/file-system.js';
|
|
9
|
+
import { readProjectConfig, validateConfigRules } from '../project-config.js';
|
|
10
|
+
// Session-level cache for validation warnings (avoid repeating same warnings)
|
|
11
|
+
const shownWarnings = new Set();
|
|
12
|
+
/**
|
|
13
|
+
* Error thrown when loading a template fails.
|
|
14
|
+
*/
|
|
15
|
+
export class TemplateLoadError extends Error {
|
|
16
|
+
templatePath;
|
|
17
|
+
constructor(message, templatePath) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.templatePath = templatePath;
|
|
20
|
+
this.name = 'TemplateLoadError';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Loads a template from a schema's templates directory.
|
|
25
|
+
*
|
|
26
|
+
* @param schemaName - Schema name (e.g., "spec-driven")
|
|
27
|
+
* @param templatePath - Relative path within the templates directory (e.g., "proposal.md")
|
|
28
|
+
* @param projectRoot - Optional project root for project-local schema resolution
|
|
29
|
+
* @returns The template content
|
|
30
|
+
* @throws TemplateLoadError if the template cannot be loaded
|
|
31
|
+
*/
|
|
32
|
+
export function loadTemplate(schemaName, templatePath, projectRoot) {
|
|
33
|
+
const schemaDir = getSchemaDir(schemaName, projectRoot);
|
|
34
|
+
if (!schemaDir) {
|
|
35
|
+
throw new TemplateLoadError(`Schema '${schemaName}' not found`, templatePath);
|
|
36
|
+
}
|
|
37
|
+
const templatePathOnDisk = path.join(schemaDir, 'templates', templatePath);
|
|
38
|
+
if (!fs.existsSync(templatePathOnDisk)) {
|
|
39
|
+
throw new TemplateLoadError(`Template not found: ${templatePathOnDisk}`, templatePathOnDisk);
|
|
40
|
+
}
|
|
41
|
+
const fullPath = FileSystemUtils.canonicalizeExistingPath(templatePathOnDisk);
|
|
42
|
+
try {
|
|
43
|
+
return fs.readFileSync(fullPath, 'utf-8');
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
const ioError = err instanceof Error ? err : new Error(String(err));
|
|
47
|
+
throw new TemplateLoadError(`Failed to read template: ${ioError.message}`, fullPath);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Loads change context combining graph and completion state.
|
|
52
|
+
*
|
|
53
|
+
* Schema resolution order:
|
|
54
|
+
* 1. Explicit schemaName parameter (if provided)
|
|
55
|
+
* 2. Schema from .openspec.yaml metadata (if exists in change directory)
|
|
56
|
+
* 3. Default 'spec-driven'
|
|
57
|
+
*
|
|
58
|
+
* @param projectRoot - Project root directory
|
|
59
|
+
* @param changeName - Change name
|
|
60
|
+
* @param schemaName - Optional schema name override. If not provided, auto-detected from metadata.
|
|
61
|
+
* @returns Change context with graph, completed set, and metadata
|
|
62
|
+
*/
|
|
63
|
+
export function loadChangeContext(projectRoot, changeName, schemaName, options = {}) {
|
|
64
|
+
const changeDir = FileSystemUtils.canonicalizeExistingPath(options.changeDir ?? path.join(projectRoot, 'openspec', 'changes', changeName));
|
|
65
|
+
// Resolve schema: explicit > metadata > default
|
|
66
|
+
const resolvedSchemaName = resolveSchemaForChange(changeDir, schemaName, projectRoot);
|
|
67
|
+
const schema = resolveSchema(resolvedSchemaName, projectRoot);
|
|
68
|
+
const graph = ArtifactGraph.fromSchema(schema);
|
|
69
|
+
const completed = detectCompleted(graph, changeDir);
|
|
70
|
+
return {
|
|
71
|
+
graph,
|
|
72
|
+
completed,
|
|
73
|
+
schemaName: resolvedSchemaName,
|
|
74
|
+
changeName,
|
|
75
|
+
changeDir,
|
|
76
|
+
projectRoot,
|
|
77
|
+
...(options.planningHome ? { planningHome: options.planningHome } : {}),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Generates enriched instructions for creating an artifact.
|
|
82
|
+
*
|
|
83
|
+
* Instruction injection order:
|
|
84
|
+
* 1. <context> - Project context from config (if present)
|
|
85
|
+
* 2. <rules> - Artifact-specific rules from config (if present)
|
|
86
|
+
* 3. <template> - Schema's template content
|
|
87
|
+
*
|
|
88
|
+
* @param context - Change context
|
|
89
|
+
* @param artifactId - Artifact ID to generate instructions for
|
|
90
|
+
* @param projectRoot - Project root directory (for reading config)
|
|
91
|
+
* @returns Enriched artifact instructions
|
|
92
|
+
* @throws Error if artifact not found
|
|
93
|
+
*/
|
|
94
|
+
export function generateInstructions(context, artifactId, projectRoot) {
|
|
95
|
+
const artifact = context.graph.getArtifact(artifactId);
|
|
96
|
+
if (!artifact) {
|
|
97
|
+
throw new Error(`Artifact '${artifactId}' not found in schema '${context.schemaName}'`);
|
|
98
|
+
}
|
|
99
|
+
const templateContent = loadTemplate(context.schemaName, artifact.template, context.projectRoot);
|
|
100
|
+
const dependencies = getDependencyInfo(artifact, context.graph, context.completed);
|
|
101
|
+
const unlocks = getUnlockedArtifacts(context.graph, artifactId);
|
|
102
|
+
// Use projectRoot from context if not explicitly provided
|
|
103
|
+
const effectiveProjectRoot = projectRoot ?? context.projectRoot;
|
|
104
|
+
// Try to read project config for context and rules
|
|
105
|
+
let projectConfig = null;
|
|
106
|
+
if (effectiveProjectRoot) {
|
|
107
|
+
try {
|
|
108
|
+
projectConfig = readProjectConfig(effectiveProjectRoot);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// If config read fails, continue without config
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Validate rules artifact IDs if config has rules (only once per session)
|
|
115
|
+
if (projectConfig?.rules) {
|
|
116
|
+
const validArtifactIds = new Set(context.graph.getAllArtifacts().map((a) => a.id));
|
|
117
|
+
const warnings = validateConfigRules(projectConfig.rules, validArtifactIds, context.schemaName);
|
|
118
|
+
// Show each unique warning only once per session
|
|
119
|
+
for (const warning of warnings) {
|
|
120
|
+
if (!shownWarnings.has(warning)) {
|
|
121
|
+
console.warn(warning);
|
|
122
|
+
shownWarnings.add(warning);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Extract context and rules as separate fields (not prepended to template)
|
|
127
|
+
const configContext = projectConfig?.context?.trim() || undefined;
|
|
128
|
+
const rulesForArtifact = projectConfig?.rules?.[artifactId];
|
|
129
|
+
const configRules = rulesForArtifact && rulesForArtifact.length > 0 ? rulesForArtifact : undefined;
|
|
130
|
+
return {
|
|
131
|
+
changeName: context.changeName,
|
|
132
|
+
artifactId: artifact.id,
|
|
133
|
+
schemaName: context.schemaName,
|
|
134
|
+
changeDir: context.changeDir,
|
|
135
|
+
planningHome: summarizePlanningHome(context.planningHome),
|
|
136
|
+
outputPath: artifact.generates,
|
|
137
|
+
resolvedOutputPath: path.join(context.changeDir, artifact.generates),
|
|
138
|
+
existingOutputPaths: resolveArtifactOutputs(context.changeDir, artifact.generates),
|
|
139
|
+
description: artifact.description,
|
|
140
|
+
instruction: artifact.instruction,
|
|
141
|
+
context: configContext,
|
|
142
|
+
rules: configRules,
|
|
143
|
+
template: templateContent,
|
|
144
|
+
dependencies,
|
|
145
|
+
unlocks,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Gets dependency info including paths and descriptions.
|
|
150
|
+
*/
|
|
151
|
+
function getDependencyInfo(artifact, graph, completed) {
|
|
152
|
+
return artifact.requires.map(id => {
|
|
153
|
+
const depArtifact = graph.getArtifact(id);
|
|
154
|
+
return {
|
|
155
|
+
id,
|
|
156
|
+
done: completed.has(id),
|
|
157
|
+
path: depArtifact?.generates ?? id,
|
|
158
|
+
description: depArtifact?.description ?? '',
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Gets artifacts that become available after completing the given artifact.
|
|
164
|
+
*/
|
|
165
|
+
function getUnlockedArtifacts(graph, artifactId) {
|
|
166
|
+
const unlocks = [];
|
|
167
|
+
for (const artifact of graph.getAllArtifacts()) {
|
|
168
|
+
if (artifact.requires.includes(artifactId)) {
|
|
169
|
+
unlocks.push(artifact.id);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return unlocks.sort();
|
|
173
|
+
}
|
|
174
|
+
function summarizePlanningHome(planningHome) {
|
|
175
|
+
if (!planningHome) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
kind: planningHome.kind,
|
|
180
|
+
root: planningHome.root,
|
|
181
|
+
changesDir: planningHome.changesDir,
|
|
182
|
+
defaultSchema: planningHome.defaultSchema,
|
|
183
|
+
...(planningHome.workspace ? { workspaceName: planningHome.workspace.name } : {}),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function getWorkspaceSpecAreaSegments(context) {
|
|
187
|
+
if (context.planningHome?.kind !== 'workspace') {
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
const specArtifact = context.graph.getArtifact('specs');
|
|
191
|
+
if (!specArtifact) {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
return resolveArtifactOutputs(context.changeDir, specArtifact.generates)
|
|
195
|
+
.map((outputPath) => path.relative(path.join(context.changeDir, 'specs'), outputPath))
|
|
196
|
+
.filter((relativePath) => relativePath.length > 0 && !relativePath.startsWith('..'))
|
|
197
|
+
.map((relativePath) => relativePath.split(path.sep)[0])
|
|
198
|
+
.filter((areaName) => areaName.length > 0);
|
|
199
|
+
}
|
|
200
|
+
function getAffectedAreasSummary(context) {
|
|
201
|
+
if (context.planningHome?.kind !== 'workspace') {
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
const metadata = readChangeMetadata(context.changeDir, context.projectRoot);
|
|
205
|
+
const known = Array.from(new Set([...(metadata?.affected_areas ?? []), ...getWorkspaceSpecAreaSegments(context)])).sort((a, b) => a.localeCompare(b));
|
|
206
|
+
const validAreas = new Set(context.planningHome.workspace?.links ?? []);
|
|
207
|
+
const invalid = known.filter((areaName) => validAreas.size > 0 && !validAreas.has(areaName));
|
|
208
|
+
return {
|
|
209
|
+
known,
|
|
210
|
+
unresolved: known.length === 0,
|
|
211
|
+
invalid,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function buildActionContext(context, artifactIds) {
|
|
215
|
+
if (context.planningHome?.kind === 'workspace') {
|
|
216
|
+
return {
|
|
217
|
+
mode: 'workspace-planning',
|
|
218
|
+
sourceOfTruth: 'workspace',
|
|
219
|
+
planningArtifacts: artifactIds,
|
|
220
|
+
linkedContext: (context.planningHome.workspace?.links ?? []).map((name) => ({ name })),
|
|
221
|
+
allowedEditRoots: [],
|
|
222
|
+
requiresAffectedAreaSelection: true,
|
|
223
|
+
constraints: [
|
|
224
|
+
'Use workspace-level planning artifacts as the source of truth.',
|
|
225
|
+
'Treat linked repos and folders as exploration context until an affected area is selected.',
|
|
226
|
+
'Do not make implementation edits without an explicit allowed edit root.',
|
|
227
|
+
],
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
mode: 'repo-local',
|
|
232
|
+
sourceOfTruth: 'repo',
|
|
233
|
+
planningArtifacts: artifactIds,
|
|
234
|
+
linkedContext: [],
|
|
235
|
+
allowedEditRoots: [context.projectRoot],
|
|
236
|
+
requiresAffectedAreaSelection: false,
|
|
237
|
+
constraints: ['Repo-local change artifacts and implementation edits are scoped to this project.'],
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function buildNextSteps(context, artifactStatuses, affectedAreas) {
|
|
241
|
+
const readyArtifact = artifactStatuses.find((artifact) => artifact.status === 'ready');
|
|
242
|
+
const steps = [];
|
|
243
|
+
if (readyArtifact) {
|
|
244
|
+
steps.push(`Run openspec instructions ${readyArtifact.id} --change "${context.changeName}" --json before writing that artifact.`);
|
|
245
|
+
}
|
|
246
|
+
else if (context.graph.isComplete(context.completed)) {
|
|
247
|
+
steps.push('All planning artifacts are complete; review tasks before implementation.');
|
|
248
|
+
}
|
|
249
|
+
if (context.planningHome?.kind === 'workspace') {
|
|
250
|
+
if (affectedAreas?.unresolved) {
|
|
251
|
+
steps.push('Identify affected areas in workspace specs or coordination tasks as planning continues.');
|
|
252
|
+
}
|
|
253
|
+
steps.push('Select an affected area and allowed edit root before implementation edits.');
|
|
254
|
+
}
|
|
255
|
+
return steps;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Formats the status of all artifacts in a change.
|
|
259
|
+
*
|
|
260
|
+
* @param context - Change context
|
|
261
|
+
* @returns Formatted change status
|
|
262
|
+
*/
|
|
263
|
+
export function formatChangeStatus(context) {
|
|
264
|
+
// Load schema to get apply phase configuration
|
|
265
|
+
const schema = resolveSchema(context.schemaName, context.projectRoot);
|
|
266
|
+
const applyRequires = schema.apply?.requires ?? schema.artifacts.map(a => a.id);
|
|
267
|
+
const artifacts = context.graph.getAllArtifacts();
|
|
268
|
+
const ready = new Set(context.graph.getNextArtifacts(context.completed));
|
|
269
|
+
const blocked = context.graph.getBlocked(context.completed);
|
|
270
|
+
const artifactPaths = {};
|
|
271
|
+
const artifactStatuses = artifacts.map(artifact => {
|
|
272
|
+
artifactPaths[artifact.id] = {
|
|
273
|
+
outputPath: artifact.generates,
|
|
274
|
+
resolvedOutputPath: path.join(context.changeDir, artifact.generates),
|
|
275
|
+
existingOutputPaths: resolveArtifactOutputs(context.changeDir, artifact.generates),
|
|
276
|
+
};
|
|
277
|
+
if (context.completed.has(artifact.id)) {
|
|
278
|
+
return {
|
|
279
|
+
id: artifact.id,
|
|
280
|
+
outputPath: artifact.generates,
|
|
281
|
+
status: 'done',
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
if (ready.has(artifact.id)) {
|
|
285
|
+
return {
|
|
286
|
+
id: artifact.id,
|
|
287
|
+
outputPath: artifact.generates,
|
|
288
|
+
status: 'ready',
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
id: artifact.id,
|
|
293
|
+
outputPath: artifact.generates,
|
|
294
|
+
status: 'blocked',
|
|
295
|
+
missingDeps: blocked[artifact.id] ?? [],
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
// Sort by build order for consistent output
|
|
299
|
+
const buildOrder = context.graph.getBuildOrder();
|
|
300
|
+
const orderMap = new Map(buildOrder.map((id, idx) => [id, idx]));
|
|
301
|
+
artifactStatuses.sort((a, b) => (orderMap.get(a.id) ?? 0) - (orderMap.get(b.id) ?? 0));
|
|
302
|
+
const affectedAreas = getAffectedAreasSummary(context);
|
|
303
|
+
return {
|
|
304
|
+
changeName: context.changeName,
|
|
305
|
+
schemaName: context.schemaName,
|
|
306
|
+
planningHome: summarizePlanningHome(context.planningHome),
|
|
307
|
+
changeRoot: context.changeDir,
|
|
308
|
+
artifactPaths,
|
|
309
|
+
affectedAreas,
|
|
310
|
+
isComplete: context.graph.isComplete(context.completed),
|
|
311
|
+
applyRequires,
|
|
312
|
+
nextSteps: buildNextSteps(context, artifactStatuses, affectedAreas),
|
|
313
|
+
actionContext: buildActionContext(context, artifactStatuses.map((artifact) => artifact.id)),
|
|
314
|
+
artifacts: artifactStatuses,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=instruction-loader.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if a path contains glob pattern characters.
|
|
3
|
+
*/
|
|
4
|
+
export declare function isGlobPattern(pattern: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Resolves an artifact's output path(s) to concrete files that currently exist.
|
|
7
|
+
* Returns absolute file paths. Glob matches are sorted for deterministic output.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveArtifactOutputs(changeDir: string, generates: string): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Checks if an artifact has at least one resolved output file.
|
|
12
|
+
*/
|
|
13
|
+
export declare function artifactOutputExists(changeDir: string, generates: string): boolean;
|
|
14
|
+
//# sourceMappingURL=outputs.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import fg from 'fast-glob';
|
|
4
|
+
import { FileSystemUtils } from '../../utils/file-system.js';
|
|
5
|
+
/**
|
|
6
|
+
* Checks if a path contains glob pattern characters.
|
|
7
|
+
*/
|
|
8
|
+
export function isGlobPattern(pattern) {
|
|
9
|
+
return pattern.includes('*') || pattern.includes('?') || pattern.includes('[');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Resolves an artifact's output path(s) to concrete files that currently exist.
|
|
13
|
+
* Returns absolute file paths. Glob matches are sorted for deterministic output.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveArtifactOutputs(changeDir, generates) {
|
|
16
|
+
if (!isGlobPattern(generates)) {
|
|
17
|
+
const fullPath = path.join(changeDir, generates);
|
|
18
|
+
try {
|
|
19
|
+
return fs.statSync(fullPath).isFile()
|
|
20
|
+
? [FileSystemUtils.canonicalizeExistingPath(fullPath)]
|
|
21
|
+
: [];
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const normalizedPattern = FileSystemUtils.toPosixPath(generates);
|
|
28
|
+
const matches = fg
|
|
29
|
+
.sync(normalizedPattern, { cwd: changeDir, onlyFiles: true, absolute: true })
|
|
30
|
+
.map((match) => FileSystemUtils.canonicalizeExistingPath(path.normalize(match)));
|
|
31
|
+
return Array.from(new Set(matches)).sort();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Checks if an artifact has at least one resolved output file.
|
|
35
|
+
*/
|
|
36
|
+
export function artifactOutputExists(changeDir, generates) {
|
|
37
|
+
return resolveArtifactOutputs(changeDir, generates).length > 0;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=outputs.js.map
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { SchemaYaml } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Error thrown when loading a schema fails.
|
|
4
|
+
*/
|
|
5
|
+
export declare class SchemaLoadError extends Error {
|
|
6
|
+
readonly schemaPath: string;
|
|
7
|
+
readonly cause?: Error | undefined;
|
|
8
|
+
constructor(message: string, schemaPath: string, cause?: Error | undefined);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Gets the package's built-in schemas directory path.
|
|
12
|
+
* Uses import.meta.url to resolve relative to the current module.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getPackageSchemasDir(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Gets the user's schema override directory path.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getUserSchemasDir(): string;
|
|
19
|
+
/**
|
|
20
|
+
* Gets the project-local schemas directory path.
|
|
21
|
+
* @param projectRoot - The project root directory
|
|
22
|
+
* @returns The path to the project's schemas directory
|
|
23
|
+
*/
|
|
24
|
+
export declare function getProjectSchemasDir(projectRoot: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Resolves a schema name to its directory path.
|
|
27
|
+
*
|
|
28
|
+
* Resolution order (when projectRoot is provided):
|
|
29
|
+
* 1. Project-local: <projectRoot>/openspec/schemas/<name>/schema.yaml
|
|
30
|
+
* 2. User override: ${XDG_DATA_HOME}/openspec/schemas/<name>/schema.yaml
|
|
31
|
+
* 3. Package built-in: <package>/schemas/<name>/schema.yaml
|
|
32
|
+
*
|
|
33
|
+
* When projectRoot is not provided, only user override and package built-in are checked
|
|
34
|
+
* (backward compatible behavior).
|
|
35
|
+
*
|
|
36
|
+
* @param name - Schema name (e.g., "spec-driven")
|
|
37
|
+
* @param projectRoot - Optional project root directory for project-local schema resolution
|
|
38
|
+
* @returns The path to the schema directory, or null if not found
|
|
39
|
+
*/
|
|
40
|
+
export declare function getSchemaDir(name: string, projectRoot?: string): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Resolves a schema name to a SchemaYaml object.
|
|
43
|
+
*
|
|
44
|
+
* Resolution order (when projectRoot is provided):
|
|
45
|
+
* 1. Project-local: <projectRoot>/openspec/schemas/<name>/schema.yaml
|
|
46
|
+
* 2. User override: ${XDG_DATA_HOME}/openspec/schemas/<name>/schema.yaml
|
|
47
|
+
* 3. Package built-in: <package>/schemas/<name>/schema.yaml
|
|
48
|
+
*
|
|
49
|
+
* When projectRoot is not provided, only user override and package built-in are checked
|
|
50
|
+
* (backward compatible behavior).
|
|
51
|
+
*
|
|
52
|
+
* @param name - Schema name (e.g., "spec-driven")
|
|
53
|
+
* @param projectRoot - Optional project root directory for project-local schema resolution
|
|
54
|
+
* @returns The resolved schema object
|
|
55
|
+
* @throws Error if schema is not found in any location
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveSchema(name: string, projectRoot?: string): SchemaYaml;
|
|
58
|
+
/**
|
|
59
|
+
* Lists all available schema names.
|
|
60
|
+
* Combines project-local, user override, and package built-in schemas.
|
|
61
|
+
*
|
|
62
|
+
* @param projectRoot - Optional project root directory for project-local schema resolution
|
|
63
|
+
*/
|
|
64
|
+
export declare function listSchemas(projectRoot?: string): string[];
|
|
65
|
+
/**
|
|
66
|
+
* Schema info with metadata (name, description, artifacts).
|
|
67
|
+
*/
|
|
68
|
+
export interface SchemaInfo {
|
|
69
|
+
name: string;
|
|
70
|
+
description: string;
|
|
71
|
+
artifacts: string[];
|
|
72
|
+
source: 'project' | 'user' | 'package';
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Lists all available schemas with their descriptions and artifact lists.
|
|
76
|
+
* Useful for agent skills to present schema selection to users.
|
|
77
|
+
*
|
|
78
|
+
* @param projectRoot - Optional project root directory for project-local schema resolution
|
|
79
|
+
*/
|
|
80
|
+
export declare function listSchemasWithInfo(projectRoot?: string): SchemaInfo[];
|
|
81
|
+
//# sourceMappingURL=resolver.d.ts.map
|