@codewalla_india/openspec 1.0.1
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 +225 -0
- package/bin/openspec.js +5 -0
- package/dist/cli/index.d.ts +10 -0
- package/dist/cli/index.js +548 -0
- package/dist/commands/change.d.ts +39 -0
- package/dist/commands/change.js +279 -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 +552 -0
- 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/feedback.d.ts +9 -0
- package/dist/commands/feedback.js +183 -0
- package/dist/commands/schema.d.ts +6 -0
- package/dist/commands/schema.js +869 -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 +19 -0
- package/dist/commands/show.js +177 -0
- package/dist/commands/spec.d.ts +19 -0
- package/dist/commands/spec.js +236 -0
- package/dist/commands/store.d.ts +3 -0
- package/dist/commands/store.js +547 -0
- package/dist/commands/validate.d.ts +26 -0
- package/dist/commands/validate.js +330 -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 +45 -0
- package/dist/commands/workflow/instructions.js +500 -0
- package/dist/commands/workflow/new-change.d.ts +20 -0
- package/dist/commands/workflow/new-change.js +106 -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 +84 -0
- package/dist/commands/workflow/shared.js +133 -0
- package/dist/commands/workflow/status.d.ts +16 -0
- package/dist/commands/workflow/status.js +92 -0
- package/dist/commands/workflow/templates.d.ts +16 -0
- package/dist/commands/workflow/templates.js +69 -0
- 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 +22 -0
- package/dist/core/archive.js +471 -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 +9 -0
- package/dist/core/artifact-graph/index.js +14 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +188 -0
- package/dist/core/artifact-graph/instruction-loader.js +233 -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 +40 -0
- package/dist/core/artifact-graph/types.js +29 -0
- package/dist/core/available-tools.d.ts +17 -0
- package/dist/core/available-tools.js +43 -0
- 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 +19 -0
- package/dist/core/change-metadata/schema.js +30 -0
- package/dist/core/change-status-policy.d.ts +37 -0
- package/dist/core/change-status-policy.js +35 -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 +32 -0
- package/dist/core/command-generation/adapters/claude.d.ts +13 -0
- package/dist/core/command-generation/adapters/claude.js +37 -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 +31 -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 +42 -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 +38 -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/command-generation/yaml.d.ts +22 -0
- package/dist/core/command-generation/yaml.js +38 -0
- package/dist/core/completions/command-registry.d.ts +3 -0
- package/dist/core/completions/command-registry.js +778 -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 +276 -0
- package/dist/core/completions/installers/bash-installer.d.ts +87 -0
- package/dist/core/completions/installers/bash-installer.js +321 -0
- package/dist/core/completions/installers/fish-installer.d.ts +43 -0
- package/dist/core/completions/installers/fish-installer.js +151 -0
- package/dist/core/completions/installers/powershell-installer.d.ts +102 -0
- package/dist/core/completions/installers/powershell-installer.js +415 -0
- package/dist/core/completions/installers/zsh-installer.d.ts +117 -0
- package/dist/core/completions/installers/zsh-installer.js +424 -0
- package/dist/core/completions/shared-flags.d.ts +13 -0
- package/dist/core/completions/shared-flags.js +33 -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/comprehension/config.d.ts +20 -0
- package/dist/core/comprehension/config.js +23 -0
- package/dist/core/comprehension/fingerprint.d.ts +5 -0
- package/dist/core/comprehension/fingerprint.js +25 -0
- package/dist/core/comprehension/index.d.ts +49 -0
- package/dist/core/comprehension/index.js +78 -0
- package/dist/core/comprehension/pass-record.d.ts +29 -0
- package/dist/core/comprehension/pass-record.js +64 -0
- package/dist/core/comprehension/stats.d.ts +18 -0
- package/dist/core/comprehension/stats.js +41 -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 +87 -0
- package/dist/core/config-schema.js +239 -0
- package/dist/core/config.d.ts +18 -0
- package/dist/core/config.js +39 -0
- package/dist/core/converters/json-converter.d.ts +6 -0
- package/dist/core/converters/json-converter.js +51 -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 +51 -0
- package/dist/core/global-config.js +124 -0
- package/dist/core/id.d.ts +17 -0
- package/dist/core/id.js +30 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.js +7 -0
- package/dist/core/init.d.ts +37 -0
- package/dist/core/init.js +613 -0
- package/dist/core/legacy-cleanup.d.ts +162 -0
- package/dist/core/legacy-cleanup.js +514 -0
- package/dist/core/list.d.ts +11 -0
- package/dist/core/list.js +185 -0
- package/dist/core/migration.d.ts +23 -0
- package/dist/core/migration.js +108 -0
- 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/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 +16 -0
- package/dist/core/planning-home.js +67 -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 +120 -0
- package/dist/core/project-config.js +406 -0
- 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/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 +78 -0
- package/dist/core/specs-apply.js +394 -0
- package/dist/core/store/errors.d.ts +20 -0
- package/dist/core/store/errors.js +22 -0
- 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/store/index.d.ts +5 -0
- package/dist/core/store/index.js +5 -0
- 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/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 +337 -0
- package/dist/core/templates/workflows/archive-change.d.ts +10 -0
- package/dist/core/templates/workflows/archive-change.js +278 -0
- package/dist/core/templates/workflows/bulk-archive-change.d.ts +10 -0
- package/dist/core/templates/workflows/bulk-archive-change.js +493 -0
- package/dist/core/templates/workflows/comprehension-guidance.d.ts +9 -0
- package/dist/core/templates/workflows/comprehension-guidance.js +58 -0
- package/dist/core/templates/workflows/continue-change.d.ts +10 -0
- package/dist/core/templates/workflows/continue-change.js +239 -0
- package/dist/core/templates/workflows/explore.d.ts +10 -0
- package/dist/core/templates/workflows/explore.js +464 -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 +205 -0
- package/dist/core/templates/workflows/mcp-guidance.d.ts +13 -0
- package/dist/core/templates/workflows/mcp-guidance.js +116 -0
- package/dist/core/templates/workflows/new-change.d.ts +10 -0
- package/dist/core/templates/workflows/new-change.js +148 -0
- package/dist/core/templates/workflows/onboard.d.ts +10 -0
- package/dist/core/templates/workflows/onboard.js +566 -0
- package/dist/core/templates/workflows/propose.d.ts +10 -0
- package/dist/core/templates/workflows/propose.js +228 -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.d.ts +10 -0
- package/dist/core/templates/workflows/sync-specs.js +291 -0
- package/dist/core/templates/workflows/verify-change.d.ts +10 -0
- package/dist/core/templates/workflows/verify-change.js +346 -0
- package/dist/core/update.d.ts +82 -0
- package/dist/core/update.js +557 -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 +44 -0
- package/dist/core/validation/validator.js +435 -0
- package/dist/core/view.d.ts +8 -0
- package/dist/core/view.js +168 -0
- 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/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 +55 -0
- package/dist/utils/change-metadata.js +141 -0
- package/dist/utils/change-utils.d.ts +71 -0
- package/dist/utils/change-utils.js +138 -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 +320 -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 +84 -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/scripts/postinstall.js +83 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared OpenSpec root resolution for normal commands.
|
|
3
|
+
*
|
|
4
|
+
* Normal commands (`new change`, `status`, `instructions`, `list`, `show`,
|
|
5
|
+
* `validate`, `archive`) resolve one OpenSpec root through this module:
|
|
6
|
+
*
|
|
7
|
+
* - `--store <id>` selects a registered store's root.
|
|
8
|
+
* - Without `--store`, the nearest ancestor containing `openspec/` wins.
|
|
9
|
+
* Leftover workspace view state is never considered a root here.
|
|
10
|
+
* - With no nearest root, registered stores produce a selection hint error;
|
|
11
|
+
* otherwise commands may treat the current directory as an implicit root.
|
|
12
|
+
*
|
|
13
|
+
* Diagnostic codes reuse the store taxonomy where an error passes
|
|
14
|
+
* through unchanged (`invalid_store_id`, metadata parse failures);
|
|
15
|
+
* resolver-specific failures use the normal-command codes below
|
|
16
|
+
* (`unknown_store`, `no_registered_stores`, `store_identity_mismatch`,
|
|
17
|
+
* `unhealthy_store_root`, `store_path_not_supported`,
|
|
18
|
+
* `invalid_store_pointer`, `no_root_with_registered_stores`,
|
|
19
|
+
* `no_openspec_root`).
|
|
20
|
+
*/
|
|
21
|
+
import * as fs from 'node:fs';
|
|
22
|
+
import * as path from 'node:path';
|
|
23
|
+
import { StoreError } from './store/errors.js';
|
|
24
|
+
import { getStoreMetadataPath, listStoreRegistryEntries, readStoreRegistryState, readOptionalStoreMetadataState, validateStoreId, } from './store/foundation.js';
|
|
25
|
+
import { getStoreRootForBackend } from './store/registry.js';
|
|
26
|
+
import { inspectOpenSpecRoot } from './openspec-root.js';
|
|
27
|
+
import { findRepoPlanningRootSync } from './planning-home.js';
|
|
28
|
+
import { classifyOpenSpecDir, storePointerProblem } from './project-config.js';
|
|
29
|
+
import { FileSystemUtils } from '../utils/file-system.js';
|
|
30
|
+
export class RootSelectionError extends Error {
|
|
31
|
+
diagnostic;
|
|
32
|
+
constructor(message, code, options = {}) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = 'RootSelectionError';
|
|
35
|
+
this.diagnostic = {
|
|
36
|
+
severity: 'error',
|
|
37
|
+
code,
|
|
38
|
+
message,
|
|
39
|
+
...options,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export function isRootSelectionError(error) {
|
|
44
|
+
return error instanceof RootSelectionError;
|
|
45
|
+
}
|
|
46
|
+
function fromStoreError(error) {
|
|
47
|
+
if (error instanceof StoreError) {
|
|
48
|
+
throw new RootSelectionError(error.message, error.diagnostic.code, {
|
|
49
|
+
...(error.diagnostic.target ? { target: error.diagnostic.target } : {}),
|
|
50
|
+
...(error.diagnostic.fix ? { fix: error.diagnostic.fix } : {}),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
function doctorFix(id) {
|
|
56
|
+
return `Run openspec store doctor ${id} to inspect it.`;
|
|
57
|
+
}
|
|
58
|
+
function makeRoot(rootPath, source, storeId) {
|
|
59
|
+
return {
|
|
60
|
+
path: rootPath,
|
|
61
|
+
changesDir: path.join(rootPath, 'openspec', 'changes'),
|
|
62
|
+
specsDir: path.join(rootPath, 'openspec', 'specs'),
|
|
63
|
+
archiveDir: path.join(rootPath, 'openspec', 'changes', 'archive'),
|
|
64
|
+
defaultSchema: 'spec-driven',
|
|
65
|
+
source,
|
|
66
|
+
...(storeId ? { storeId } : {}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function canonicalDirectory(startPath) {
|
|
70
|
+
const resolved = path.resolve(startPath);
|
|
71
|
+
try {
|
|
72
|
+
const stats = fs.statSync(resolved);
|
|
73
|
+
const dir = stats.isDirectory() ? resolved : path.dirname(resolved);
|
|
74
|
+
return FileSystemUtils.canonicalizeExistingPath(dir);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return resolved;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function resolveStoreRoot(id, globalDataDir, source = 'store') {
|
|
81
|
+
try {
|
|
82
|
+
validateStoreId(id);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
fromStoreError(error);
|
|
86
|
+
}
|
|
87
|
+
let registry;
|
|
88
|
+
try {
|
|
89
|
+
registry = await readStoreRegistryState(globalDataDir ? { globalDataDir } : {});
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
fromStoreError(error);
|
|
93
|
+
}
|
|
94
|
+
const entries = registry ? listStoreRegistryEntries(registry) : [];
|
|
95
|
+
const entry = entries.find((candidate) => candidate.id === id);
|
|
96
|
+
if (!entry) {
|
|
97
|
+
if (entries.length === 0) {
|
|
98
|
+
throw new RootSelectionError(`Unknown store '${id}'. No stores are registered.`, 'no_registered_stores', {
|
|
99
|
+
target: 'store.id',
|
|
100
|
+
fix: `Run openspec store setup ${id} or openspec store register <path> first.`,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
throw new RootSelectionError(`Unknown store '${id}'. Registered stores: ${entries
|
|
104
|
+
.map((candidate) => candidate.id)
|
|
105
|
+
.join(', ')}.`, 'unknown_store', {
|
|
106
|
+
target: 'store.id',
|
|
107
|
+
fix: 'Pass a registered store id, or run openspec store list.',
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const storeRoot = getStoreRootForBackend(entry.backend);
|
|
111
|
+
const inspection = await inspectRegisteredStore(id, storeRoot);
|
|
112
|
+
switch (inspection.kind) {
|
|
113
|
+
case 'metadata_error':
|
|
114
|
+
return fromStoreError(inspection.error);
|
|
115
|
+
case 'metadata_missing':
|
|
116
|
+
// The doctor pointer lives in the message because human-mode command
|
|
117
|
+
// wrappers print only the message, not the fix field.
|
|
118
|
+
throw new RootSelectionError(`Store '${id}' is missing identity metadata at ${inspection.metadataPath}. ${doctorFix(id)}`, 'store_identity_mismatch', { target: 'store.metadata', fix: doctorFix(id) });
|
|
119
|
+
case 'metadata_id_mismatch':
|
|
120
|
+
throw new RootSelectionError(`Store '${id}' metadata id '${inspection.actualId}' does not match its registered id. ${doctorFix(id)}`, 'store_identity_mismatch', { target: 'store.metadata', fix: doctorFix(id) });
|
|
121
|
+
case 'unhealthy_root':
|
|
122
|
+
throw new RootSelectionError(`Store '${id}' does not have a healthy OpenSpec root at ${storeRoot}: ${inspection.problems} ${doctorFix(id)}`, 'unhealthy_store_root', { target: 'openspec.root', fix: doctorFix(id) });
|
|
123
|
+
case 'ok':
|
|
124
|
+
return makeRoot(inspection.canonicalRoot, source, id);
|
|
125
|
+
default: {
|
|
126
|
+
// Exhaustiveness guard: a new inspection kind must be handled
|
|
127
|
+
// here explicitly, not fall through to an undefined root.
|
|
128
|
+
const unhandled = inspection;
|
|
129
|
+
throw new Error(`Unhandled store inspection kind: ${JSON.stringify(unhandled)}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export async function inspectRegisteredStore(id, storeRoot) {
|
|
134
|
+
// Identity (metadata) failures win before root-health diagnostics.
|
|
135
|
+
let metadata;
|
|
136
|
+
try {
|
|
137
|
+
metadata = await readOptionalStoreMetadataState(storeRoot);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
return { kind: 'metadata_error', error };
|
|
141
|
+
}
|
|
142
|
+
if (!metadata) {
|
|
143
|
+
return { kind: 'metadata_missing', metadataPath: getStoreMetadataPath(storeRoot) };
|
|
144
|
+
}
|
|
145
|
+
if (metadata.id !== id) {
|
|
146
|
+
return { kind: 'metadata_id_mismatch', actualId: metadata.id };
|
|
147
|
+
}
|
|
148
|
+
const inspection = await inspectOpenSpecRoot(storeRoot);
|
|
149
|
+
if (!inspection.healthy) {
|
|
150
|
+
const problems = inspection.diagnostics.map((diagnostic) => diagnostic.message).join(' ') ||
|
|
151
|
+
'OpenSpec root is missing or incomplete.';
|
|
152
|
+
return { kind: 'unhealthy_root', problems };
|
|
153
|
+
}
|
|
154
|
+
return { kind: 'ok', canonicalRoot: FileSystemUtils.canonicalizeExistingPath(storeRoot) };
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Classifies the nearest `openspec/` directory (slice 3.2): a planning
|
|
158
|
+
* shape (specs/ or changes/ directories) is a real root and wins —
|
|
159
|
+
* fallback never override. A config-only directory with a `store:`
|
|
160
|
+
* pointer resolves the declared store; without one, it stays a root
|
|
161
|
+
* (today's behavior for freshly initialized minimal roots).
|
|
162
|
+
*/
|
|
163
|
+
/**
|
|
164
|
+
* The nearest-root walk, qualified: an `openspec/` DIRECTORY alone is
|
|
165
|
+
* not a root — it must carry a planning shape or a config file.
|
|
166
|
+
* Without this, the recommended `~/openspec/<id>` store layout would
|
|
167
|
+
* make $HOME a phantom root that captures every command under the
|
|
168
|
+
* home tree.
|
|
169
|
+
*/
|
|
170
|
+
function findQualifyingRootSync(startPath) {
|
|
171
|
+
let candidate = findRepoPlanningRootSync(startPath);
|
|
172
|
+
while (candidate) {
|
|
173
|
+
const { hasPlanningShape, pointer } = classifyOpenSpecDir(candidate);
|
|
174
|
+
if (hasPlanningShape || pointer.filePath) {
|
|
175
|
+
return candidate;
|
|
176
|
+
}
|
|
177
|
+
const parent = path.dirname(candidate);
|
|
178
|
+
if (parent === candidate) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
candidate = findRepoPlanningRootSync(parent);
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
async function resolveNearestOrDeclaredRoot(nearestRoot, globalDataDir) {
|
|
186
|
+
const { hasPlanningShape, pointer } = classifyOpenSpecDir(nearestRoot);
|
|
187
|
+
if (hasPlanningShape) {
|
|
188
|
+
if (pointer.value !== undefined) {
|
|
189
|
+
console.error(`Warning: ${pointer.filePath} declares store '${pointer.value}', but this directory is a real OpenSpec root; the declaration is ignored.`);
|
|
190
|
+
}
|
|
191
|
+
return makeRoot(nearestRoot, 'nearest');
|
|
192
|
+
}
|
|
193
|
+
if (pointer.malformed) {
|
|
194
|
+
const problem = storePointerProblem(pointer.malformed);
|
|
195
|
+
throw new RootSelectionError(`Invalid store declaration in ${pointer.filePath}: ${problem}.`, 'invalid_store_pointer', {
|
|
196
|
+
target: 'store.pointer',
|
|
197
|
+
fix: pointer.malformed === 'unparseable'
|
|
198
|
+
? `Fix the YAML syntax in ${pointer.filePath}.`
|
|
199
|
+
: `Edit ${pointer.filePath} so the store key is a registered store id, or remove it.`,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (pointer.value === undefined) {
|
|
203
|
+
return makeRoot(nearestRoot, 'nearest');
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
return await resolveStoreRoot(pointer.value, globalDataDir, 'declared');
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
if (error instanceof RootSelectionError) {
|
|
210
|
+
// Rewrap with the declaration origin. The unknown-store fix is
|
|
211
|
+
// reshaped for the actual mistake: the user declared a pointer,
|
|
212
|
+
// they did not pass --store.
|
|
213
|
+
const declarationFix = error.diagnostic.code === 'unknown_store'
|
|
214
|
+
? `Register the store (openspec store register <path> --id ${pointer.value}) or edit ${pointer.filePath} to name a registered store.`
|
|
215
|
+
: error.diagnostic.fix;
|
|
216
|
+
throw new RootSelectionError(`Declared in ${pointer.filePath}: ${error.message}`, error.diagnostic.code, {
|
|
217
|
+
...(error.diagnostic.target ? { target: error.diagnostic.target } : {}),
|
|
218
|
+
...(declarationFix ? { fix: declarationFix } : {}),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
export async function resolveOpenSpecRoot(options = {}) {
|
|
225
|
+
if (options.storePath !== undefined) {
|
|
226
|
+
throw new RootSelectionError('--store-path is not supported. Register the path with openspec store register <path>, then select it with --store <id>.', 'store_path_not_supported', {
|
|
227
|
+
target: 'store.id',
|
|
228
|
+
fix: 'openspec store register <path>, then rerun with --store <id>.',
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
if (options.store !== undefined) {
|
|
232
|
+
return resolveStoreRoot(options.store, options.globalDataDir);
|
|
233
|
+
}
|
|
234
|
+
const startPath = options.startPath ?? process.cwd();
|
|
235
|
+
const nearestRoot = findQualifyingRootSync(startPath);
|
|
236
|
+
if (nearestRoot) {
|
|
237
|
+
return resolveNearestOrDeclaredRoot(nearestRoot, options.globalDataDir);
|
|
238
|
+
}
|
|
239
|
+
let registry;
|
|
240
|
+
try {
|
|
241
|
+
registry = await readStoreRegistryState(options.globalDataDir ? { globalDataDir: options.globalDataDir } : {});
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
fromStoreError(error);
|
|
245
|
+
}
|
|
246
|
+
const registeredIds = registry
|
|
247
|
+
? listStoreRegistryEntries(registry).map((entry) => entry.id)
|
|
248
|
+
: [];
|
|
249
|
+
if (registeredIds.length > 0) {
|
|
250
|
+
throw new RootSelectionError(`No OpenSpec root found in the current directory or its ancestors. Registered stores: ${registeredIds.join(', ')}. Pass --store <id> to use one, or run openspec init to create a local root.`, 'no_root_with_registered_stores', {
|
|
251
|
+
target: 'openspec.root',
|
|
252
|
+
fix: `Rerun with --store <id> (registered: ${registeredIds.join(', ')}) or run openspec init.`,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (options.allowImplicitRoot === false) {
|
|
256
|
+
throw new RootSelectionError('No OpenSpec root found from the current directory.', 'no_openspec_root', { target: 'openspec.root', fix: 'Run openspec init to create a root here.' });
|
|
257
|
+
}
|
|
258
|
+
return makeRoot(canonicalDirectory(startPath), 'implicit');
|
|
259
|
+
}
|
|
260
|
+
export function toRootOutput(root) {
|
|
261
|
+
return {
|
|
262
|
+
path: root.path,
|
|
263
|
+
source: root.source,
|
|
264
|
+
...(root.storeId ? { store_id: root.storeId } : {}),
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* A store-selected root — explicit `--store` or the declared fallback.
|
|
269
|
+
* Cross-root behavior (absolute paths, --store hints, suppressed
|
|
270
|
+
* noun-form suggestions) keys on this, never on `source` directly.
|
|
271
|
+
*/
|
|
272
|
+
export function isStoreSelectedRoot(root) {
|
|
273
|
+
return root.storeId !== undefined;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Human-mode verification signal for a selected store. Written to stderr so
|
|
277
|
+
* raw-Markdown and agent-consumed stdout payloads stay clean.
|
|
278
|
+
*/
|
|
279
|
+
export function emitStoreRootBanner(root) {
|
|
280
|
+
if (isStoreSelectedRoot(root)) {
|
|
281
|
+
console.error(`Using OpenSpec root: ${root.storeId} (${root.path})`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Keeps follow-up command hints inside the selected store: a hint a user can
|
|
286
|
+
* paste verbatim must carry `--store <id>` when a store was selected.
|
|
287
|
+
*/
|
|
288
|
+
export function withStoreFlag(root, command) {
|
|
289
|
+
return isStoreSelectedRoot(root)
|
|
290
|
+
? `${command} --store ${root.storeId}`
|
|
291
|
+
: command;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Compatibility bridge for workflow code that still expects a PlanningHome.
|
|
295
|
+
* The planning home is always repo-shaped.
|
|
296
|
+
*/
|
|
297
|
+
export function toPlanningHome(root) {
|
|
298
|
+
return {
|
|
299
|
+
kind: 'repo',
|
|
300
|
+
root: root.path,
|
|
301
|
+
changesDir: root.changesDir,
|
|
302
|
+
defaultSchema: root.defaultSchema,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* CLI adapter shared by the supported commands. In JSON mode a resolution
|
|
307
|
+
* failure is reported as a machine-readable payload on stdout (no human prose
|
|
308
|
+
* or blank lines) with a non-zero exit code; the caller must return when this
|
|
309
|
+
* resolves to null. In human mode the error propagates to the command's
|
|
310
|
+
* standard error handling so message text and exit behavior stay consistent.
|
|
311
|
+
*/
|
|
312
|
+
export async function resolveRootForCommand(selector, output = {}) {
|
|
313
|
+
try {
|
|
314
|
+
const root = await resolveOpenSpecRoot({
|
|
315
|
+
...(selector.store !== undefined ? { store: selector.store } : {}),
|
|
316
|
+
...(selector.storePath !== undefined ? { storePath: selector.storePath } : {}),
|
|
317
|
+
...(output.allowImplicitRoot !== undefined
|
|
318
|
+
? { allowImplicitRoot: output.allowImplicitRoot }
|
|
319
|
+
: {}),
|
|
320
|
+
});
|
|
321
|
+
// Emitted at resolution time so the banner survives command failures
|
|
322
|
+
// that happen after the root was successfully selected.
|
|
323
|
+
if (!output.json) {
|
|
324
|
+
emitStoreRootBanner(root);
|
|
325
|
+
}
|
|
326
|
+
return root;
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
if (output.json && isRootSelectionError(error)) {
|
|
330
|
+
console.log(JSON.stringify({ ...(output.failurePayload ?? {}), status: [error.diagnostic] }, null, 2));
|
|
331
|
+
process.exitCode = 1;
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
throw error;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=root-selection.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const ScenarioSchema: z.ZodObject<{
|
|
3
|
+
rawText: z.ZodString;
|
|
4
|
+
}, z.core.$strip>;
|
|
5
|
+
export declare const RequirementSchema: z.ZodObject<{
|
|
6
|
+
text: z.ZodString;
|
|
7
|
+
scenarios: z.ZodArray<z.ZodObject<{
|
|
8
|
+
rawText: z.ZodString;
|
|
9
|
+
}, z.core.$strip>>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type Scenario = z.infer<typeof ScenarioSchema>;
|
|
12
|
+
export type Requirement = z.infer<typeof RequirementSchema>;
|
|
13
|
+
//# sourceMappingURL=base.schema.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { VALIDATION_MESSAGES } from '../validation/constants.js';
|
|
3
|
+
export const ScenarioSchema = z.object({
|
|
4
|
+
rawText: z.string().min(1, VALIDATION_MESSAGES.SCENARIO_EMPTY),
|
|
5
|
+
});
|
|
6
|
+
export const RequirementSchema = z.object({
|
|
7
|
+
text: z.string()
|
|
8
|
+
.min(1, VALIDATION_MESSAGES.REQUIREMENT_EMPTY)
|
|
9
|
+
.refine((text) => text.includes('SHALL') || text.includes('MUST'), VALIDATION_MESSAGES.REQUIREMENT_NO_SHALL),
|
|
10
|
+
scenarios: z.array(ScenarioSchema)
|
|
11
|
+
.min(1, VALIDATION_MESSAGES.REQUIREMENT_NO_SCENARIOS),
|
|
12
|
+
});
|
|
13
|
+
//# sourceMappingURL=base.schema.js.map
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const DeltaOperationType: z.ZodEnum<{
|
|
3
|
+
ADDED: "ADDED";
|
|
4
|
+
MODIFIED: "MODIFIED";
|
|
5
|
+
REMOVED: "REMOVED";
|
|
6
|
+
RENAMED: "RENAMED";
|
|
7
|
+
}>;
|
|
8
|
+
export declare const DeltaSchema: z.ZodObject<{
|
|
9
|
+
spec: z.ZodString;
|
|
10
|
+
operation: z.ZodEnum<{
|
|
11
|
+
ADDED: "ADDED";
|
|
12
|
+
MODIFIED: "MODIFIED";
|
|
13
|
+
REMOVED: "REMOVED";
|
|
14
|
+
RENAMED: "RENAMED";
|
|
15
|
+
}>;
|
|
16
|
+
description: z.ZodString;
|
|
17
|
+
requirement: z.ZodOptional<z.ZodObject<{
|
|
18
|
+
text: z.ZodString;
|
|
19
|
+
scenarios: z.ZodArray<z.ZodObject<{
|
|
20
|
+
rawText: z.ZodString;
|
|
21
|
+
}, z.core.$strip>>;
|
|
22
|
+
}, z.core.$strip>>;
|
|
23
|
+
requirements: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
24
|
+
text: z.ZodString;
|
|
25
|
+
scenarios: z.ZodArray<z.ZodObject<{
|
|
26
|
+
rawText: z.ZodString;
|
|
27
|
+
}, z.core.$strip>>;
|
|
28
|
+
}, z.core.$strip>>>;
|
|
29
|
+
rename: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
from: z.ZodString;
|
|
31
|
+
to: z.ZodString;
|
|
32
|
+
}, z.core.$strip>>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
export declare const ChangeSchema: z.ZodObject<{
|
|
35
|
+
name: z.ZodString;
|
|
36
|
+
why: z.ZodString;
|
|
37
|
+
whatChanges: z.ZodString;
|
|
38
|
+
deltas: z.ZodArray<z.ZodObject<{
|
|
39
|
+
spec: z.ZodString;
|
|
40
|
+
operation: z.ZodEnum<{
|
|
41
|
+
ADDED: "ADDED";
|
|
42
|
+
MODIFIED: "MODIFIED";
|
|
43
|
+
REMOVED: "REMOVED";
|
|
44
|
+
RENAMED: "RENAMED";
|
|
45
|
+
}>;
|
|
46
|
+
description: z.ZodString;
|
|
47
|
+
requirement: z.ZodOptional<z.ZodObject<{
|
|
48
|
+
text: z.ZodString;
|
|
49
|
+
scenarios: z.ZodArray<z.ZodObject<{
|
|
50
|
+
rawText: z.ZodString;
|
|
51
|
+
}, z.core.$strip>>;
|
|
52
|
+
}, z.core.$strip>>;
|
|
53
|
+
requirements: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
54
|
+
text: z.ZodString;
|
|
55
|
+
scenarios: z.ZodArray<z.ZodObject<{
|
|
56
|
+
rawText: z.ZodString;
|
|
57
|
+
}, z.core.$strip>>;
|
|
58
|
+
}, z.core.$strip>>>;
|
|
59
|
+
rename: z.ZodOptional<z.ZodObject<{
|
|
60
|
+
from: z.ZodString;
|
|
61
|
+
to: z.ZodString;
|
|
62
|
+
}, z.core.$strip>>;
|
|
63
|
+
}, z.core.$strip>>;
|
|
64
|
+
metadata: z.ZodOptional<z.ZodObject<{
|
|
65
|
+
version: z.ZodDefault<z.ZodString>;
|
|
66
|
+
format: z.ZodLiteral<"openspec-change">;
|
|
67
|
+
sourcePath: z.ZodOptional<z.ZodString>;
|
|
68
|
+
}, z.core.$strip>>;
|
|
69
|
+
}, z.core.$strip>;
|
|
70
|
+
export type DeltaOperation = z.infer<typeof DeltaOperationType>;
|
|
71
|
+
export type Delta = z.infer<typeof DeltaSchema>;
|
|
72
|
+
export type Change = z.infer<typeof ChangeSchema>;
|
|
73
|
+
//# sourceMappingURL=change.schema.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { RequirementSchema } from './base.schema.js';
|
|
3
|
+
import { MIN_WHY_SECTION_LENGTH, MAX_WHY_SECTION_LENGTH, MAX_DELTAS_PER_CHANGE, VALIDATION_MESSAGES } from '../validation/constants.js';
|
|
4
|
+
export const DeltaOperationType = z.enum(['ADDED', 'MODIFIED', 'REMOVED', 'RENAMED']);
|
|
5
|
+
export const DeltaSchema = z.object({
|
|
6
|
+
spec: z.string().min(1, VALIDATION_MESSAGES.DELTA_SPEC_EMPTY),
|
|
7
|
+
operation: DeltaOperationType,
|
|
8
|
+
description: z.string().min(1, VALIDATION_MESSAGES.DELTA_DESCRIPTION_EMPTY),
|
|
9
|
+
requirement: RequirementSchema.optional(),
|
|
10
|
+
requirements: z.array(RequirementSchema).optional(),
|
|
11
|
+
rename: z.object({
|
|
12
|
+
from: z.string(),
|
|
13
|
+
to: z.string(),
|
|
14
|
+
}).optional(),
|
|
15
|
+
});
|
|
16
|
+
export const ChangeSchema = z.object({
|
|
17
|
+
name: z.string().min(1, VALIDATION_MESSAGES.CHANGE_NAME_EMPTY),
|
|
18
|
+
why: z.string()
|
|
19
|
+
.min(MIN_WHY_SECTION_LENGTH, VALIDATION_MESSAGES.CHANGE_WHY_TOO_SHORT)
|
|
20
|
+
.max(MAX_WHY_SECTION_LENGTH, VALIDATION_MESSAGES.CHANGE_WHY_TOO_LONG),
|
|
21
|
+
whatChanges: z.string().min(1, VALIDATION_MESSAGES.CHANGE_WHAT_EMPTY),
|
|
22
|
+
deltas: z.array(DeltaSchema)
|
|
23
|
+
.min(1, VALIDATION_MESSAGES.CHANGE_NO_DELTAS)
|
|
24
|
+
.max(MAX_DELTAS_PER_CHANGE, VALIDATION_MESSAGES.CHANGE_TOO_MANY_DELTAS),
|
|
25
|
+
metadata: z.object({
|
|
26
|
+
version: z.string().default('1.0.0'),
|
|
27
|
+
format: z.literal('openspec-change'),
|
|
28
|
+
sourcePath: z.string().optional(),
|
|
29
|
+
}).optional(),
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=change.schema.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { ScenarioSchema, RequirementSchema, type Scenario, type Requirement, } from './base.schema.js';
|
|
2
|
+
export { SpecSchema, type Spec, } from './spec.schema.js';
|
|
3
|
+
export { DeltaOperationType, DeltaSchema, ChangeSchema, type DeltaOperation, type Delta, type Change, } from './change.schema.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const SpecSchema: z.ZodObject<{
|
|
3
|
+
name: z.ZodString;
|
|
4
|
+
overview: z.ZodString;
|
|
5
|
+
requirements: z.ZodArray<z.ZodObject<{
|
|
6
|
+
text: z.ZodString;
|
|
7
|
+
scenarios: z.ZodArray<z.ZodObject<{
|
|
8
|
+
rawText: z.ZodString;
|
|
9
|
+
}, z.core.$strip>>;
|
|
10
|
+
}, z.core.$strip>>;
|
|
11
|
+
metadata: z.ZodOptional<z.ZodObject<{
|
|
12
|
+
version: z.ZodDefault<z.ZodString>;
|
|
13
|
+
format: z.ZodLiteral<"openspec">;
|
|
14
|
+
sourcePath: z.ZodOptional<z.ZodString>;
|
|
15
|
+
}, z.core.$strip>>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
export type Spec = z.infer<typeof SpecSchema>;
|
|
18
|
+
//# sourceMappingURL=spec.schema.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { RequirementSchema } from './base.schema.js';
|
|
3
|
+
import { VALIDATION_MESSAGES } from '../validation/constants.js';
|
|
4
|
+
export const SpecSchema = z.object({
|
|
5
|
+
name: z.string().min(1, VALIDATION_MESSAGES.SPEC_NAME_EMPTY),
|
|
6
|
+
overview: z.string().min(1, VALIDATION_MESSAGES.SPEC_PURPOSE_EMPTY),
|
|
7
|
+
requirements: z.array(RequirementSchema)
|
|
8
|
+
.min(1, VALIDATION_MESSAGES.SPEC_NO_REQUIREMENTS),
|
|
9
|
+
metadata: z.object({
|
|
10
|
+
version: z.string().default('1.0.0'),
|
|
11
|
+
format: z.literal('openspec'),
|
|
12
|
+
sourcePath: z.string().optional(),
|
|
13
|
+
}).optional(),
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=spec.schema.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Utilities
|
|
3
|
+
*
|
|
4
|
+
* Common code shared between init and update commands.
|
|
5
|
+
*/
|
|
6
|
+
export { SKILL_NAMES, type SkillName, COMMAND_IDS, type CommandId, type ToolSkillStatus, type ToolVersionStatus, getToolsWithSkillsDir, getToolSkillStatus, getToolStates, extractGeneratedByVersion, getToolVersionStatus, getConfiguredTools, getAllToolVersionStatus, } from './tool-detection.js';
|
|
7
|
+
export { type SkillTemplateEntry, type CommandTemplateEntry, getSkillTemplates, getCommandTemplates, getCommandContents, generateSkillContent, } from './skill-generation.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Utilities
|
|
3
|
+
*
|
|
4
|
+
* Common code shared between init and update commands.
|
|
5
|
+
*/
|
|
6
|
+
export { SKILL_NAMES, COMMAND_IDS, getToolsWithSkillsDir, getToolSkillStatus, getToolStates, extractGeneratedByVersion, getToolVersionStatus, getConfiguredTools, getAllToolVersionStatus, } from './tool-detection.js';
|
|
7
|
+
export { getSkillTemplates, getCommandTemplates, getCommandContents, generateSkillContent, } from './skill-generation.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill Generation Utilities
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities for generating skill and command files.
|
|
5
|
+
*/
|
|
6
|
+
import { getOpsxExploreCommandTemplate, type SkillTemplate } from '../templates/skill-templates.js';
|
|
7
|
+
import type { CommandContent } from '../command-generation/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Skill template with directory name and workflow ID mapping.
|
|
10
|
+
*/
|
|
11
|
+
export interface SkillTemplateEntry {
|
|
12
|
+
template: SkillTemplate;
|
|
13
|
+
dirName: string;
|
|
14
|
+
workflowId: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Command template with ID mapping.
|
|
18
|
+
*/
|
|
19
|
+
export interface CommandTemplateEntry {
|
|
20
|
+
template: ReturnType<typeof getOpsxExploreCommandTemplate>;
|
|
21
|
+
id: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Gets skill templates with their directory names, optionally filtered by workflow IDs.
|
|
25
|
+
*
|
|
26
|
+
* @param workflowFilter - If provided, only return templates whose workflowId is in this array
|
|
27
|
+
*/
|
|
28
|
+
export declare function getSkillTemplates(workflowFilter?: readonly string[]): SkillTemplateEntry[];
|
|
29
|
+
/**
|
|
30
|
+
* Gets command templates with their IDs, optionally filtered by workflow IDs.
|
|
31
|
+
*
|
|
32
|
+
* @param workflowFilter - If provided, only return templates whose id is in this array
|
|
33
|
+
*/
|
|
34
|
+
export declare function getCommandTemplates(workflowFilter?: readonly string[]): CommandTemplateEntry[];
|
|
35
|
+
/**
|
|
36
|
+
* Converts command templates to CommandContent array, optionally filtered by workflow IDs.
|
|
37
|
+
*
|
|
38
|
+
* @param workflowFilter - If provided, only return contents whose id is in this array
|
|
39
|
+
*/
|
|
40
|
+
export declare function getCommandContents(workflowFilter?: readonly string[]): CommandContent[];
|
|
41
|
+
/**
|
|
42
|
+
* Generates skill file content with YAML frontmatter.
|
|
43
|
+
*
|
|
44
|
+
* @param template - The skill template
|
|
45
|
+
* @param generatedByVersion - The OpenSpec version to embed in the file
|
|
46
|
+
* @param transformInstructions - Optional callback to transform the instructions content
|
|
47
|
+
*/
|
|
48
|
+
export declare function generateSkillContent(template: SkillTemplate, generatedByVersion: string, transformInstructions?: (instructions: string) => string): string;
|
|
49
|
+
//# sourceMappingURL=skill-generation.d.ts.map
|