@thiagodiogo/pastelsdd 1.0.0-beta.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 +3 -0
- package/bin/pastelsdd.js +5 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.js +526 -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/context-store.d.ts +3 -0
- package/dist/commands/context-store.js +282 -0
- package/dist/commands/feedback.d.ts +9 -0
- package/dist/commands/feedback.js +183 -0
- package/dist/commands/initiative.d.ts +13 -0
- package/dist/commands/initiative.js +318 -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 +19 -0
- package/dist/commands/workflow/index.js +13 -0
- package/dist/commands/workflow/initiative-link.d.ts +24 -0
- package/dist/commands/workflow/initiative-link.js +47 -0
- package/dist/commands/workflow/instructions.d.ts +29 -0
- package/dist/commands/workflow/instructions.js +344 -0
- package/dist/commands/workflow/new-change.d.ts +17 -0
- package/dist/commands/workflow/new-change.js +141 -0
- package/dist/commands/workflow/schemas.d.ts +10 -0
- package/dist/commands/workflow/schemas.js +34 -0
- package/dist/commands/workflow/set-change.d.ts +13 -0
- package/dist/commands/workflow/set-change.js +87 -0
- package/dist/commands/workflow/shared.d.ts +59 -0
- package/dist/commands/workflow/shared.js +116 -0
- package/dist/commands/workflow/status.d.ts +14 -0
- package/dist/commands/workflow/status.js +90 -0
- package/dist/commands/workflow/templates.d.ts +16 -0
- package/dist/commands/workflow/templates.js +69 -0
- package/dist/commands/workspace/context-status.d.ts +4 -0
- package/dist/commands/workspace/context-status.js +59 -0
- package/dist/commands/workspace/open-view.d.ts +62 -0
- package/dist/commands/workspace/open-view.js +228 -0
- package/dist/commands/workspace/open.d.ts +37 -0
- package/dist/commands/workspace/open.js +102 -0
- package/dist/commands/workspace/opener-selection.d.ts +11 -0
- package/dist/commands/workspace/opener-selection.js +93 -0
- package/dist/commands/workspace/operations.d.ts +28 -0
- package/dist/commands/workspace/operations.js +543 -0
- package/dist/commands/workspace/prompt-theme.d.ts +29 -0
- package/dist/commands/workspace/prompt-theme.js +24 -0
- package/dist/commands/workspace/registration.d.ts +13 -0
- package/dist/commands/workspace/registration.js +84 -0
- package/dist/commands/workspace/selection.d.ts +6 -0
- package/dist/commands/workspace/selection.js +122 -0
- package/dist/commands/workspace/types.d.ts +103 -0
- package/dist/commands/workspace/types.js +36 -0
- package/dist/commands/workspace.d.ts +6 -0
- package/dist/commands/workspace.js +678 -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 +9 -0
- package/dist/core/artifact-graph/index.js +14 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +183 -0
- package/dist/core/artifact-graph/instruction-loader.js +256 -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 +18 -0
- package/dist/core/change-metadata/schema.js +28 -0
- package/dist/core/change-status-policy.d.ts +50 -0
- package/dist/core/change-status-policy.js +70 -0
- package/dist/core/collections/index.d.ts +3 -0
- package/dist/core/collections/index.js +3 -0
- package/dist/core/collections/initiatives/collection.d.ts +4 -0
- package/dist/core/collections/initiatives/collection.js +17 -0
- package/dist/core/collections/initiatives/index.d.ts +6 -0
- package/dist/core/collections/initiatives/index.js +6 -0
- package/dist/core/collections/initiatives/operations.d.ts +49 -0
- package/dist/core/collections/initiatives/operations.js +175 -0
- package/dist/core/collections/initiatives/resolution.d.ts +87 -0
- package/dist/core/collections/initiatives/resolution.js +374 -0
- package/dist/core/collections/initiatives/schema.d.ts +41 -0
- package/dist/core/collections/initiatives/schema.js +134 -0
- package/dist/core/collections/initiatives/templates.d.ts +12 -0
- package/dist/core/collections/initiatives/templates.js +90 -0
- package/dist/core/collections/runtime.d.ts +46 -0
- package/dist/core/collections/runtime.js +194 -0
- package/dist/core/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 +3 -0
- package/dist/core/completions/command-registry.js +939 -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/shared-flags.d.ts +12 -0
- package/dist/core/completions/shared-flags.js +28 -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/context-store/binding.d.ts +53 -0
- package/dist/core/context-store/binding.js +197 -0
- package/dist/core/context-store/errors.d.ts +20 -0
- package/dist/core/context-store/errors.js +22 -0
- package/dist/core/context-store/foundation.d.ts +54 -0
- package/dist/core/context-store/foundation.js +318 -0
- package/dist/core/context-store/index.d.ts +6 -0
- package/dist/core/context-store/index.js +6 -0
- package/dist/core/context-store/operations.d.ts +62 -0
- package/dist/core/context-store/operations.js +352 -0
- package/dist/core/context-store/registry.d.ts +35 -0
- package/dist/core/context-store/registry.js +158 -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 +6 -0
- package/dist/core/index.js +7 -0
- package/dist/core/init.d.ts +37 -0
- package/dist/core/init.js +593 -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 +108 -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 +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 +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 +62 -0
- package/dist/core/workspace/foundation.js +274 -0
- package/dist/core/workspace/index.d.ts +8 -0
- package/dist/core/workspace/index.js +8 -0
- package/dist/core/workspace/legacy-state.d.ts +28 -0
- package/dist/core/workspace/legacy-state.js +200 -0
- package/dist/core/workspace/link-input.d.ts +9 -0
- package/dist/core/workspace/link-input.js +32 -0
- package/dist/core/workspace/open-surface.d.ts +43 -0
- package/dist/core/workspace/open-surface.js +214 -0
- package/dist/core/workspace/openers.d.ts +21 -0
- package/dist/core/workspace/openers.js +119 -0
- package/dist/core/workspace/registry.d.ts +24 -0
- package/dist/core/workspace/registry.js +146 -0
- package/dist/core/workspace/skills.d.ts +57 -0
- package/dist/core/workspace/skills.js +334 -0
- package/dist/core/workspace/state-io.d.ts +10 -0
- package/dist/core/workspace/state-io.js +119 -0
- package/dist/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 +54 -0
- package/dist/utils/change-metadata.js +141 -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 +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/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,374 @@
|
|
|
1
|
+
import { ContextStoreError, formatContextStoreSelector, listRegisteredContextStores, resolveSelectedContextStore, } from '../../context-store/index.js';
|
|
2
|
+
import { mountInitiativesCollection } from './collection.js';
|
|
3
|
+
import { listInitiatives, readInitiative } from './operations.js';
|
|
4
|
+
import { INITIATIVE_FILE_NAME } from './schema.js';
|
|
5
|
+
export { formatContextStoreSelector };
|
|
6
|
+
export class InitiativeResolutionError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
target;
|
|
9
|
+
fix;
|
|
10
|
+
details;
|
|
11
|
+
constructor(message, code, options = {}) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.target = options.target;
|
|
15
|
+
this.fix = options.fix;
|
|
16
|
+
this.details = options.details;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function asErrorMessage(error) {
|
|
20
|
+
return error instanceof Error ? error.message : String(error);
|
|
21
|
+
}
|
|
22
|
+
function makeDiagnostic(severity, code, message, options = {}) {
|
|
23
|
+
return {
|
|
24
|
+
severity,
|
|
25
|
+
code,
|
|
26
|
+
message,
|
|
27
|
+
...options,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const INITIATIVE_ALREADY_EXISTS_PREFIX = "Initiative '";
|
|
31
|
+
const INITIATIVE_ALREADY_EXISTS_MARKER = "' already exists";
|
|
32
|
+
export function initiativeDiagnosticFromError(error) {
|
|
33
|
+
if (error instanceof InitiativeResolutionError) {
|
|
34
|
+
return makeDiagnostic('error', error.code, error.message, {
|
|
35
|
+
target: error.target,
|
|
36
|
+
fix: error.fix,
|
|
37
|
+
details: error.details,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
const message = asErrorMessage(error);
|
|
41
|
+
if (message.startsWith(INITIATIVE_ALREADY_EXISTS_PREFIX) &&
|
|
42
|
+
message.includes(INITIATIVE_ALREADY_EXISTS_MARKER, INITIATIVE_ALREADY_EXISTS_PREFIX.length)) {
|
|
43
|
+
return makeDiagnostic('error', 'initiative_already_exists', message, {
|
|
44
|
+
target: 'initiative.id',
|
|
45
|
+
fix: 'Choose a new initiative id or list existing initiatives first.',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (message.startsWith('Initiative id ')) {
|
|
49
|
+
return makeDiagnostic('error', 'invalid_initiative_id', message, {
|
|
50
|
+
target: 'initiative.id',
|
|
51
|
+
fix: 'Use kebab-case with lowercase letters, numbers, and single hyphen separators.',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (message.startsWith('Invalid initiative')) {
|
|
55
|
+
return makeDiagnostic('error', 'invalid_initiative', message, {
|
|
56
|
+
target: 'initiative',
|
|
57
|
+
fix: 'Fix the initiative folder state and retry.',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return makeDiagnostic('error', 'initiative_error', message);
|
|
61
|
+
}
|
|
62
|
+
function requireInitiativeId(id, commandName) {
|
|
63
|
+
if (id === undefined || id.trim().length === 0) {
|
|
64
|
+
throw new InitiativeResolutionError('Pass an initiative id.', 'initiative_id_required', {
|
|
65
|
+
target: 'initiative.id',
|
|
66
|
+
fix: `pastelsdd initiative ${commandName} <id>`,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return id.trim();
|
|
70
|
+
}
|
|
71
|
+
export function parseInitiativeReference(reference, options) {
|
|
72
|
+
const initiativeId = requireInitiativeId(reference, 'show');
|
|
73
|
+
const parts = initiativeId.split('/');
|
|
74
|
+
if (parts.length === 1) {
|
|
75
|
+
return { initiativeId, options };
|
|
76
|
+
}
|
|
77
|
+
if (parts.length !== 2 || parts[0].length === 0 || parts[1].length === 0) {
|
|
78
|
+
throw new InitiativeResolutionError(`Invalid initiative reference '${initiativeId}'.`, 'invalid_initiative_reference', {
|
|
79
|
+
target: 'initiative.id',
|
|
80
|
+
fix: 'Use <initiative-id>, <store>/<initiative-id>, or <initiative-id> --store <store>.',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (options.store !== undefined || options.storePath !== undefined) {
|
|
84
|
+
throw new InitiativeResolutionError('Pass either --initiative <store>/<id> or a context store selector, not both.', 'context_store_selector_conflict', {
|
|
85
|
+
target: 'context_store',
|
|
86
|
+
fix: 'Use --initiative <store>/<id> or --initiative <id> --store <store>.',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
initiativeId: parts[1],
|
|
91
|
+
options: {
|
|
92
|
+
...options,
|
|
93
|
+
store: parts[0],
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function contextStoreErrorAsInitiativeError(error) {
|
|
98
|
+
if (error instanceof ContextStoreError) {
|
|
99
|
+
return new InitiativeResolutionError(error.message, error.diagnostic.code, {
|
|
100
|
+
target: error.diagnostic.target,
|
|
101
|
+
fix: error.diagnostic.fix,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const message = asErrorMessage(error);
|
|
105
|
+
if (message.startsWith('Context store id ')) {
|
|
106
|
+
return new InitiativeResolutionError(message, 'invalid_context_store_id', {
|
|
107
|
+
target: 'context_store.id',
|
|
108
|
+
fix: 'Use kebab-case with lowercase letters, numbers, and single hyphen separators.',
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return new InitiativeResolutionError(message, 'invalid_context_store', {
|
|
112
|
+
target: 'context_store',
|
|
113
|
+
fix: 'Fix the context store registry or pass --store-path <path>.',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
export async function resolveRegisteredInitiativeContextStore(storeId) {
|
|
117
|
+
return selectContextStoreForInitiative({ store: storeId }, 'show');
|
|
118
|
+
}
|
|
119
|
+
export async function resolvePathInitiativeContextStore(storePath) {
|
|
120
|
+
return selectContextStoreForInitiative({ storePath }, 'show');
|
|
121
|
+
}
|
|
122
|
+
export async function selectContextStoreForInitiative(options, commandName) {
|
|
123
|
+
try {
|
|
124
|
+
return await resolveSelectedContextStore(options, `initiative ${commandName}`);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
throw contextStoreErrorAsInitiativeError(error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function toInitiativeViewReference(selected, state) {
|
|
131
|
+
const collection = mountInitiativesCollection(selected.root);
|
|
132
|
+
return {
|
|
133
|
+
store: selected.id,
|
|
134
|
+
storeSource: selected.source,
|
|
135
|
+
storeRoot: selected.root,
|
|
136
|
+
id: state.id,
|
|
137
|
+
title: state.title,
|
|
138
|
+
summary: state.summary,
|
|
139
|
+
created: state.created,
|
|
140
|
+
root: collection.resolvePath(state.id),
|
|
141
|
+
storePath: collection.toStorePath(state.id),
|
|
142
|
+
metadataPath: collection.resolvePath(`${state.id}/${INITIATIVE_FILE_NAME}`),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function toResolutionMatch(selected, state) {
|
|
146
|
+
const reference = toInitiativeViewReference(selected, state);
|
|
147
|
+
return {
|
|
148
|
+
context_store: {
|
|
149
|
+
id: reference.store,
|
|
150
|
+
root: reference.storeRoot,
|
|
151
|
+
},
|
|
152
|
+
initiative: {
|
|
153
|
+
id: reference.id,
|
|
154
|
+
title: reference.title,
|
|
155
|
+
root: reference.root,
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function toListedInitiativeReference(selected, state) {
|
|
160
|
+
return {
|
|
161
|
+
...toInitiativeViewReference(selected, state),
|
|
162
|
+
status: state.status,
|
|
163
|
+
owners: state.owners,
|
|
164
|
+
metadata: state.metadata,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
async function readSelectedInitiative(selected, initiativeId) {
|
|
168
|
+
return readInitiative({
|
|
169
|
+
collection: mountInitiativesCollection(selected.root),
|
|
170
|
+
id: initiativeId,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
export async function resolveSelectedInitiativeViewReference(selected, initiativeId) {
|
|
174
|
+
const state = await readSelectedInitiative(selected, initiativeId);
|
|
175
|
+
if (!state) {
|
|
176
|
+
throw new InitiativeResolutionError(`Initiative '${initiativeId}' was not found in context store '${selected.id}'.`, 'initiative_not_found', {
|
|
177
|
+
target: 'initiative.id',
|
|
178
|
+
fix: `pastelsdd initiative list ${formatContextStoreSelector(selected)}`,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return toInitiativeViewReference(selected, state);
|
|
182
|
+
}
|
|
183
|
+
export async function listSelectedInitiativeViewReferences(selected) {
|
|
184
|
+
const collection = mountInitiativesCollection(selected.root);
|
|
185
|
+
const initiatives = await listInitiatives({ collection });
|
|
186
|
+
return {
|
|
187
|
+
contextStore: selected,
|
|
188
|
+
initiatives: initiatives.map((initiative) => toListedInitiativeReference(selected, initiative)),
|
|
189
|
+
status: [],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
async function scanRegisteredStoreForInitiativeList(entryId) {
|
|
193
|
+
let selected;
|
|
194
|
+
try {
|
|
195
|
+
selected = await resolveRegisteredInitiativeContextStore(entryId);
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
return {
|
|
199
|
+
kind: 'store_unreadable',
|
|
200
|
+
entryId,
|
|
201
|
+
error,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
return {
|
|
206
|
+
kind: 'listed',
|
|
207
|
+
listed: await listSelectedInitiativeViewReferences(selected),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
return {
|
|
212
|
+
kind: 'initiative_collection_invalid',
|
|
213
|
+
selected,
|
|
214
|
+
error,
|
|
215
|
+
diagnostic: initiativeDiagnosticFromError(error),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async function scanRegisteredStoreForInitiative(entryId, initiativeId) {
|
|
220
|
+
let selected;
|
|
221
|
+
try {
|
|
222
|
+
selected = await resolveRegisteredInitiativeContextStore(entryId);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
return {
|
|
226
|
+
kind: 'store_unreadable',
|
|
227
|
+
entryId,
|
|
228
|
+
error,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
const state = await readSelectedInitiative(selected, initiativeId);
|
|
233
|
+
if (!state) {
|
|
234
|
+
return {
|
|
235
|
+
kind: 'missing',
|
|
236
|
+
selected,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
kind: 'match',
|
|
241
|
+
selected,
|
|
242
|
+
state,
|
|
243
|
+
diagnostic: toResolutionMatch(selected, state),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
return {
|
|
248
|
+
kind: 'initiative_invalid',
|
|
249
|
+
selected,
|
|
250
|
+
error,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async function scanRegisteredStoresForInitiativeLists() {
|
|
255
|
+
const registeredStores = await listRegisteredContextStores();
|
|
256
|
+
return Promise.all(registeredStores.map((entry) => scanRegisteredStoreForInitiativeList(entry.id)));
|
|
257
|
+
}
|
|
258
|
+
async function scanRegisteredStoresForInitiative(initiativeId) {
|
|
259
|
+
const registeredStores = await listRegisteredContextStores();
|
|
260
|
+
return Promise.all(registeredStores.map((entry) => scanRegisteredStoreForInitiative(entry.id, initiativeId)));
|
|
261
|
+
}
|
|
262
|
+
export async function listInitiativeViewReferences(options = {}) {
|
|
263
|
+
if (options.store !== undefined || options.storePath !== undefined) {
|
|
264
|
+
const selected = await selectContextStoreForInitiative(options, 'list');
|
|
265
|
+
const listed = await listSelectedInitiativeViewReferences(selected);
|
|
266
|
+
return {
|
|
267
|
+
contextStore: listed.contextStore,
|
|
268
|
+
contextStores: [listed],
|
|
269
|
+
initiatives: listed.initiatives,
|
|
270
|
+
status: [],
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
const outcomes = await scanRegisteredStoresForInitiativeLists();
|
|
274
|
+
if (outcomes.length === 0) {
|
|
275
|
+
return {
|
|
276
|
+
contextStore: null,
|
|
277
|
+
contextStores: [],
|
|
278
|
+
initiatives: [],
|
|
279
|
+
status: [],
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
const contextStores = outcomes
|
|
283
|
+
.filter((outcome) => outcome.kind === 'listed')
|
|
284
|
+
.map((outcome) => outcome.listed);
|
|
285
|
+
const invalidCollections = outcomes.filter((outcome) => outcome.kind === 'initiative_collection_invalid');
|
|
286
|
+
const unreadable = outcomes.filter((outcome) => outcome.kind === 'store_unreadable');
|
|
287
|
+
const contextStoreResults = [
|
|
288
|
+
...contextStores,
|
|
289
|
+
...invalidCollections.map((outcome) => ({
|
|
290
|
+
contextStore: outcome.selected,
|
|
291
|
+
initiatives: [],
|
|
292
|
+
status: [outcome.diagnostic],
|
|
293
|
+
})),
|
|
294
|
+
];
|
|
295
|
+
if (contextStores.length === 0 && invalidCollections.length > 0) {
|
|
296
|
+
throw new InitiativeResolutionError('No initiatives could be read because registered context stores contain invalid initiatives.', 'initiative_collections_invalid', {
|
|
297
|
+
target: 'initiative',
|
|
298
|
+
fix: 'Fix the invalid initiative folder state and retry.',
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
if (contextStoreResults.length === 0) {
|
|
302
|
+
throw new InitiativeResolutionError('No initiatives could be read from registered context stores.', 'context_stores_unreadable', {
|
|
303
|
+
target: 'context_store',
|
|
304
|
+
fix: 'pastelsdd context-store doctor',
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
const status = [];
|
|
308
|
+
if (unreadable.length > 0) {
|
|
309
|
+
status.push(makeDiagnostic('warning', 'context_stores_partially_unreadable', 'Some registered context stores could not be read.', {
|
|
310
|
+
target: 'context_store',
|
|
311
|
+
fix: 'pastelsdd context-store doctor',
|
|
312
|
+
}));
|
|
313
|
+
}
|
|
314
|
+
if (invalidCollections.length > 0) {
|
|
315
|
+
status.push(makeDiagnostic('warning', 'initiative_collections_partially_invalid', 'Some registered context stores contain invalid initiatives.', {
|
|
316
|
+
target: 'initiative',
|
|
317
|
+
fix: 'Fix the invalid initiative folder state and retry.',
|
|
318
|
+
}));
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
contextStore: null,
|
|
322
|
+
contextStores: contextStoreResults,
|
|
323
|
+
initiatives: contextStoreResults
|
|
324
|
+
.flatMap((store) => store.initiatives)
|
|
325
|
+
.sort((left, right) => left.store.localeCompare(right.store) || left.id.localeCompare(right.id)),
|
|
326
|
+
status,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
export async function resolveInitiativeViewReference(reference, options = {}) {
|
|
330
|
+
const parsed = parseInitiativeReference(reference, options);
|
|
331
|
+
if (parsed.options.store !== undefined || parsed.options.storePath !== undefined) {
|
|
332
|
+
const selected = await selectContextStoreForInitiative(parsed.options, 'show');
|
|
333
|
+
return resolveSelectedInitiativeViewReference(selected, parsed.initiativeId);
|
|
334
|
+
}
|
|
335
|
+
const outcomes = await scanRegisteredStoresForInitiative(parsed.initiativeId);
|
|
336
|
+
const matches = outcomes.filter((outcome) => outcome.kind === 'match');
|
|
337
|
+
const unreadable = outcomes.filter((outcome) => outcome.kind === 'store_unreadable');
|
|
338
|
+
const invalidInitiatives = outcomes.filter((outcome) => outcome.kind === 'initiative_invalid');
|
|
339
|
+
if (invalidInitiatives.length > 0) {
|
|
340
|
+
throw invalidInitiatives[0].error;
|
|
341
|
+
}
|
|
342
|
+
if (unreadable.length > 0) {
|
|
343
|
+
throw new InitiativeResolutionError(`Initiative lookup for '${parsed.initiativeId}' is incomplete because some context stores could not be read.`, 'initiative_lookup_incomplete', {
|
|
344
|
+
target: 'context_store',
|
|
345
|
+
fix: 'pastelsdd context-store doctor',
|
|
346
|
+
...(matches.length > 0
|
|
347
|
+
? { details: { matches: matches.map((match) => match.diagnostic) } }
|
|
348
|
+
: {}),
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
if (matches.length === 0) {
|
|
352
|
+
throw new InitiativeResolutionError(`Initiative '${parsed.initiativeId}' was not found in registered context stores.`, 'initiative_not_found', {
|
|
353
|
+
target: 'initiative.id',
|
|
354
|
+
fix: 'pastelsdd initiative list',
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
if (matches.length > 1) {
|
|
358
|
+
throw new InitiativeResolutionError(`Initiative '${parsed.initiativeId}' exists in multiple context stores.`, 'initiative_ambiguous', {
|
|
359
|
+
target: 'initiative.id',
|
|
360
|
+
fix: `pastelsdd initiative show ${parsed.initiativeId} --store <store>`,
|
|
361
|
+
details: { matches: matches.map((match) => match.diagnostic) },
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
const [match] = matches;
|
|
365
|
+
return toInitiativeViewReference(match.selected, match.state);
|
|
366
|
+
}
|
|
367
|
+
export async function resolveInitiativeLinkReference(reference, options = {}) {
|
|
368
|
+
const initiative = await resolveInitiativeViewReference(reference, options);
|
|
369
|
+
return {
|
|
370
|
+
store: initiative.store,
|
|
371
|
+
id: initiative.id,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
//# sourceMappingURL=resolution.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const INITIATIVE_COLLECTION_ID = "initiatives";
|
|
3
|
+
export declare const INITIATIVE_FILE_NAME = "initiative.yaml";
|
|
4
|
+
export declare const INITIATIVE_REQUIREMENTS_FILE_NAME = "requirements.md";
|
|
5
|
+
export declare const INITIATIVE_DESIGN_FILE_NAME = "design.md";
|
|
6
|
+
export declare const INITIATIVE_DECISIONS_FILE_NAME = "decisions.md";
|
|
7
|
+
export declare const INITIATIVE_QUESTIONS_FILE_NAME = "questions.md";
|
|
8
|
+
export declare const INITIATIVE_TASKS_FILE_NAME = "tasks.md";
|
|
9
|
+
export declare const INITIATIVE_MARKDOWN_FILE_NAMES: readonly ["requirements.md", "design.md", "decisions.md", "questions.md", "tasks.md"];
|
|
10
|
+
export declare const INITIATIVE_FILE_NAMES: readonly ["initiative.yaml", "requirements.md", "design.md", "decisions.md", "questions.md", "tasks.md"];
|
|
11
|
+
export type InitiativeMarkdownFileName = typeof INITIATIVE_MARKDOWN_FILE_NAMES[number];
|
|
12
|
+
export type InitiativeFileName = typeof INITIATIVE_FILE_NAMES[number];
|
|
13
|
+
export declare const INITIATIVE_STATUSES: readonly ["exploring", "active", "complete", "archived"];
|
|
14
|
+
export type InitiativeStatus = typeof INITIATIVE_STATUSES[number];
|
|
15
|
+
export type InitiativeMetadataValue = string | number | boolean | null | InitiativeMetadataValue[] | {
|
|
16
|
+
[key: string]: InitiativeMetadataValue;
|
|
17
|
+
};
|
|
18
|
+
export type InitiativeMetadata = Record<string, InitiativeMetadataValue>;
|
|
19
|
+
declare const InitiativeStateSchema: z.ZodObject<{
|
|
20
|
+
version: z.ZodLiteral<1>;
|
|
21
|
+
id: z.ZodString;
|
|
22
|
+
title: z.ZodString;
|
|
23
|
+
summary: z.ZodString;
|
|
24
|
+
status: z.ZodEnum<{
|
|
25
|
+
complete: "complete";
|
|
26
|
+
active: "active";
|
|
27
|
+
exploring: "exploring";
|
|
28
|
+
archived: "archived";
|
|
29
|
+
}>;
|
|
30
|
+
created: z.ZodString;
|
|
31
|
+
owners: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
32
|
+
metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<InitiativeMetadataValue, unknown, z.core.$ZodTypeInternals<InitiativeMetadataValue, unknown>>>>;
|
|
33
|
+
}, z.core.$strict>;
|
|
34
|
+
export type InitiativeStateInput = z.input<typeof InitiativeStateSchema>;
|
|
35
|
+
export type InitiativeState = z.output<typeof InitiativeStateSchema>;
|
|
36
|
+
export declare function validateInitiativeId(id: string): string;
|
|
37
|
+
export declare function isValidInitiativeId(id: string): boolean;
|
|
38
|
+
export declare function parseInitiativeState(content: string): InitiativeState;
|
|
39
|
+
export declare function serializeInitiativeState(state: InitiativeStateInput): string;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export const INITIATIVE_COLLECTION_ID = 'initiatives';
|
|
4
|
+
export const INITIATIVE_FILE_NAME = 'initiative.yaml';
|
|
5
|
+
export const INITIATIVE_REQUIREMENTS_FILE_NAME = 'requirements.md';
|
|
6
|
+
export const INITIATIVE_DESIGN_FILE_NAME = 'design.md';
|
|
7
|
+
export const INITIATIVE_DECISIONS_FILE_NAME = 'decisions.md';
|
|
8
|
+
export const INITIATIVE_QUESTIONS_FILE_NAME = 'questions.md';
|
|
9
|
+
export const INITIATIVE_TASKS_FILE_NAME = 'tasks.md';
|
|
10
|
+
export const INITIATIVE_MARKDOWN_FILE_NAMES = [
|
|
11
|
+
INITIATIVE_REQUIREMENTS_FILE_NAME,
|
|
12
|
+
INITIATIVE_DESIGN_FILE_NAME,
|
|
13
|
+
INITIATIVE_DECISIONS_FILE_NAME,
|
|
14
|
+
INITIATIVE_QUESTIONS_FILE_NAME,
|
|
15
|
+
INITIATIVE_TASKS_FILE_NAME,
|
|
16
|
+
];
|
|
17
|
+
export const INITIATIVE_FILE_NAMES = [
|
|
18
|
+
INITIATIVE_FILE_NAME,
|
|
19
|
+
...INITIATIVE_MARKDOWN_FILE_NAMES,
|
|
20
|
+
];
|
|
21
|
+
export const INITIATIVE_STATUSES = [
|
|
22
|
+
'exploring',
|
|
23
|
+
'active',
|
|
24
|
+
'complete',
|
|
25
|
+
'archived',
|
|
26
|
+
];
|
|
27
|
+
const INITIATIVE_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/u;
|
|
28
|
+
function assertNoNul(value, label) {
|
|
29
|
+
if (value.includes('\0')) {
|
|
30
|
+
throw new Error(`${label} must not contain NUL bytes`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function nonBlankString(label) {
|
|
34
|
+
return z.string().refine((value) => value.trim().length > 0, {
|
|
35
|
+
message: `${label} must not be empty`,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const InitiativeMetadataValueSchema = z.lazy(() => z.union([
|
|
39
|
+
z.string(),
|
|
40
|
+
z.number().finite(),
|
|
41
|
+
z.boolean(),
|
|
42
|
+
z.null(),
|
|
43
|
+
z.array(InitiativeMetadataValueSchema),
|
|
44
|
+
z.record(z.string(), InitiativeMetadataValueSchema),
|
|
45
|
+
]));
|
|
46
|
+
const InitiativeMetadataSchema = z.record(z.string(), InitiativeMetadataValueSchema);
|
|
47
|
+
const InitiativeStateSchema = z.object({
|
|
48
|
+
version: z.literal(1),
|
|
49
|
+
id: z.string(),
|
|
50
|
+
title: nonBlankString('title'),
|
|
51
|
+
summary: nonBlankString('summary'),
|
|
52
|
+
status: z.enum(INITIATIVE_STATUSES),
|
|
53
|
+
created: z.string().regex(INITIATIVE_DATE_PATTERN, {
|
|
54
|
+
message: 'created must be YYYY-MM-DD format',
|
|
55
|
+
}),
|
|
56
|
+
owners: z.array(nonBlankString('owner')).default([]),
|
|
57
|
+
metadata: InitiativeMetadataSchema.default({}),
|
|
58
|
+
}).strict();
|
|
59
|
+
function formatZodIssues(error) {
|
|
60
|
+
return error.issues
|
|
61
|
+
.map((issue) => {
|
|
62
|
+
const location = issue.path.length > 0 ? issue.path.join('.') : 'root';
|
|
63
|
+
return `${location}: ${issue.message}`;
|
|
64
|
+
})
|
|
65
|
+
.join('; ');
|
|
66
|
+
}
|
|
67
|
+
function parseYamlObject(content, label) {
|
|
68
|
+
try {
|
|
69
|
+
return parseYaml(content);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
73
|
+
throw new Error(`Invalid ${label}: ${message}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function validateInitiativeId(id) {
|
|
77
|
+
assertNoNul(id, 'Initiative id');
|
|
78
|
+
if (id.length === 0) {
|
|
79
|
+
throw new Error('Initiative id must not be empty');
|
|
80
|
+
}
|
|
81
|
+
if (id === '.' || id === '..') {
|
|
82
|
+
throw new Error(`Initiative id must not be '${id}'`);
|
|
83
|
+
}
|
|
84
|
+
if (/[\\/]/u.test(id)) {
|
|
85
|
+
throw new Error('Initiative id must not contain path separators');
|
|
86
|
+
}
|
|
87
|
+
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(id)) {
|
|
88
|
+
throw new Error('Initiative id must be kebab-case with lowercase letters, numbers, and single hyphen separators');
|
|
89
|
+
}
|
|
90
|
+
return id;
|
|
91
|
+
}
|
|
92
|
+
export function isValidInitiativeId(id) {
|
|
93
|
+
try {
|
|
94
|
+
validateInitiativeId(id);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function parseInitiativeStateInput(raw) {
|
|
102
|
+
const result = InitiativeStateSchema.safeParse(raw);
|
|
103
|
+
if (!result.success) {
|
|
104
|
+
throw new Error(`Invalid initiative state: ${formatZodIssues(result.error)}`);
|
|
105
|
+
}
|
|
106
|
+
validateInitiativeId(result.data.id);
|
|
107
|
+
return {
|
|
108
|
+
version: 1,
|
|
109
|
+
id: result.data.id,
|
|
110
|
+
title: result.data.title,
|
|
111
|
+
summary: result.data.summary,
|
|
112
|
+
status: result.data.status,
|
|
113
|
+
created: result.data.created,
|
|
114
|
+
owners: result.data.owners,
|
|
115
|
+
metadata: result.data.metadata,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export function parseInitiativeState(content) {
|
|
119
|
+
return parseInitiativeStateInput(parseYamlObject(content, 'initiative state'));
|
|
120
|
+
}
|
|
121
|
+
export function serializeInitiativeState(state) {
|
|
122
|
+
const parsedState = parseInitiativeStateInput(state);
|
|
123
|
+
return stringifyYaml({
|
|
124
|
+
version: 1,
|
|
125
|
+
id: parsedState.id,
|
|
126
|
+
title: parsedState.title,
|
|
127
|
+
summary: parsedState.summary,
|
|
128
|
+
status: parsedState.status,
|
|
129
|
+
created: parsedState.created,
|
|
130
|
+
owners: parsedState.owners,
|
|
131
|
+
metadata: parsedState.metadata,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type InitiativeMarkdownFileName, type InitiativeState } from './schema.js';
|
|
2
|
+
export interface InitiativeTemplateFile {
|
|
3
|
+
fileName: InitiativeMarkdownFileName;
|
|
4
|
+
content: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function buildInitiativeRequirementsTemplate(state: InitiativeState): string;
|
|
7
|
+
export declare function buildInitiativeDesignTemplate(state: InitiativeState): string;
|
|
8
|
+
export declare function buildInitiativeDecisionsTemplate(state: InitiativeState): string;
|
|
9
|
+
export declare function buildInitiativeQuestionsTemplate(): string;
|
|
10
|
+
export declare function buildInitiativeTasksTemplate(): string;
|
|
11
|
+
export declare function buildDefaultInitiativeFiles(state: InitiativeState): InitiativeTemplateFile[];
|
|
12
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { INITIATIVE_DECISIONS_FILE_NAME, INITIATIVE_DESIGN_FILE_NAME, INITIATIVE_MARKDOWN_FILE_NAMES, INITIATIVE_QUESTIONS_FILE_NAME, INITIATIVE_REQUIREMENTS_FILE_NAME, INITIATIVE_TASKS_FILE_NAME, } from './schema.js';
|
|
2
|
+
function withTrailingNewline(content) {
|
|
3
|
+
return content.endsWith('\n') ? content : `${content}\n`;
|
|
4
|
+
}
|
|
5
|
+
export function buildInitiativeRequirementsTemplate(state) {
|
|
6
|
+
return withTrailingNewline(`# Requirements
|
|
7
|
+
|
|
8
|
+
## Product Intent
|
|
9
|
+
|
|
10
|
+
${state.summary}
|
|
11
|
+
|
|
12
|
+
## Accepted Requirements
|
|
13
|
+
|
|
14
|
+
- TBD
|
|
15
|
+
|
|
16
|
+
## Out Of Scope
|
|
17
|
+
|
|
18
|
+
- TBD
|
|
19
|
+
`);
|
|
20
|
+
}
|
|
21
|
+
export function buildInitiativeDesignTemplate(state) {
|
|
22
|
+
return withTrailingNewline(`# Design
|
|
23
|
+
|
|
24
|
+
## Context
|
|
25
|
+
|
|
26
|
+
${state.summary}
|
|
27
|
+
|
|
28
|
+
## Approach
|
|
29
|
+
|
|
30
|
+
TBD
|
|
31
|
+
|
|
32
|
+
## Affected Areas
|
|
33
|
+
|
|
34
|
+
- TBD
|
|
35
|
+
|
|
36
|
+
## Dependencies
|
|
37
|
+
|
|
38
|
+
- TBD
|
|
39
|
+
|
|
40
|
+
## Risks
|
|
41
|
+
|
|
42
|
+
- TBD
|
|
43
|
+
`);
|
|
44
|
+
}
|
|
45
|
+
export function buildInitiativeDecisionsTemplate(state) {
|
|
46
|
+
return withTrailingNewline(`# Decisions
|
|
47
|
+
|
|
48
|
+
## Accepted Decisions
|
|
49
|
+
|
|
50
|
+
### ${state.created}: ${state.title}
|
|
51
|
+
|
|
52
|
+
- Decision: TBD
|
|
53
|
+
- Why: TBD
|
|
54
|
+
- Implications: TBD
|
|
55
|
+
`);
|
|
56
|
+
}
|
|
57
|
+
export function buildInitiativeQuestionsTemplate() {
|
|
58
|
+
return withTrailingNewline(`# Questions
|
|
59
|
+
|
|
60
|
+
## Open Questions
|
|
61
|
+
|
|
62
|
+
- TBD
|
|
63
|
+
|
|
64
|
+
## Resolved Questions
|
|
65
|
+
|
|
66
|
+
- TBD
|
|
67
|
+
`);
|
|
68
|
+
}
|
|
69
|
+
export function buildInitiativeTasksTemplate() {
|
|
70
|
+
return withTrailingNewline(`# Tasks
|
|
71
|
+
|
|
72
|
+
## Coordination Tasks
|
|
73
|
+
|
|
74
|
+
- [ ] TBD
|
|
75
|
+
`);
|
|
76
|
+
}
|
|
77
|
+
export function buildDefaultInitiativeFiles(state) {
|
|
78
|
+
const templates = {
|
|
79
|
+
[INITIATIVE_REQUIREMENTS_FILE_NAME]: buildInitiativeRequirementsTemplate(state),
|
|
80
|
+
[INITIATIVE_DESIGN_FILE_NAME]: buildInitiativeDesignTemplate(state),
|
|
81
|
+
[INITIATIVE_DECISIONS_FILE_NAME]: buildInitiativeDecisionsTemplate(state),
|
|
82
|
+
[INITIATIVE_QUESTIONS_FILE_NAME]: buildInitiativeQuestionsTemplate(),
|
|
83
|
+
[INITIATIVE_TASKS_FILE_NAME]: buildInitiativeTasksTemplate(),
|
|
84
|
+
};
|
|
85
|
+
return INITIATIVE_MARKDOWN_FILE_NAMES.map((fileName) => ({
|
|
86
|
+
fileName,
|
|
87
|
+
content: templates[fileName],
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=templates.js.map
|