@seanmars/tospec 0.19.0-beta.1 → 0.19.0-beta.13
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/CHANGELOG.md +530 -0
- package/README.md +71 -77
- package/assets/dashboard/app.js +14 -3
- package/assets/dashboard/style.css +7 -0
- package/assets/rules/tospec/decision.md +3 -0
- package/assets/rules/tospec/single-source-of-truth.md +19 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +254 -83
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/config.d.ts +9 -17
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +374 -98
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/dashboard.d.ts +64 -81
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +346 -230
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/decision.d.ts +41 -19
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +400 -70
- package/dist/commands/decision.js.map +1 -1
- package/dist/commands/metrics.d.ts +28 -51
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +69 -85
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/shared-output.d.ts +18 -21
- package/dist/commands/shared-output.d.ts.map +1 -1
- package/dist/commands/shared-output.js +49 -23
- package/dist/commands/shared-output.js.map +1 -1
- package/dist/commands/show.d.ts +7 -0
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +39 -8
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/validate.d.ts +47 -30
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +282 -108
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/workflow/index.d.ts +6 -10
- package/dist/commands/workflow/index.d.ts.map +1 -1
- package/dist/commands/workflow/index.js +6 -10
- package/dist/commands/workflow/index.js.map +1 -1
- package/dist/commands/workflow/instructions.d.ts +21 -8
- package/dist/commands/workflow/instructions.d.ts.map +1 -1
- package/dist/commands/workflow/instructions.js +254 -95
- package/dist/commands/workflow/instructions.js.map +1 -1
- package/dist/commands/workflow/new-change.d.ts +4 -5
- package/dist/commands/workflow/new-change.d.ts.map +1 -1
- package/dist/commands/workflow/new-change.js +90 -25
- package/dist/commands/workflow/new-change.js.map +1 -1
- package/dist/commands/workflow/schemas.d.ts +3 -5
- package/dist/commands/workflow/schemas.d.ts.map +1 -1
- package/dist/commands/workflow/schemas.js +37 -11
- package/dist/commands/workflow/schemas.js.map +1 -1
- package/dist/commands/workflow/shared.d.ts +48 -21
- package/dist/commands/workflow/shared.d.ts.map +1 -1
- package/dist/commands/workflow/shared.js +36 -33
- package/dist/commands/workflow/shared.js.map +1 -1
- package/dist/commands/workflow/status.d.ts +10 -6
- package/dist/commands/workflow/status.d.ts.map +1 -1
- package/dist/commands/workflow/status.js +84 -42
- package/dist/commands/workflow/status.js.map +1 -1
- package/dist/commands/workflow/templates.d.ts +10 -3
- package/dist/commands/workflow/templates.d.ts.map +1 -1
- package/dist/commands/workflow/templates.js +39 -40
- package/dist/commands/workflow/templates.js.map +1 -1
- package/dist/core/archive.d.ts +26 -21
- package/dist/core/archive.d.ts.map +1 -1
- package/dist/core/archive.js +386 -205
- package/dist/core/archive.js.map +1 -1
- package/dist/core/artifact-graph/graph.d.ts +29 -36
- package/dist/core/artifact-graph/graph.d.ts.map +1 -1
- package/dist/core/artifact-graph/graph.js +50 -58
- package/dist/core/artifact-graph/graph.js.map +1 -1
- package/dist/core/artifact-graph/index.d.ts +1 -1
- package/dist/core/artifact-graph/index.d.ts.map +1 -1
- package/dist/core/artifact-graph/index.js +1 -1
- package/dist/core/artifact-graph/index.js.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.d.ts +105 -100
- package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.js +176 -110
- package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
- package/dist/core/artifact-graph/outputs.d.ts +11 -14
- package/dist/core/artifact-graph/outputs.d.ts.map +1 -1
- package/dist/core/artifact-graph/outputs.js +47 -29
- package/dist/core/artifact-graph/outputs.js.map +1 -1
- package/dist/core/artifact-graph/resolver.d.ts +44 -63
- package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
- package/dist/core/artifact-graph/resolver.js +85 -86
- package/dist/core/artifact-graph/resolver.js.map +1 -1
- package/dist/core/artifact-graph/schema.d.ts +0 -6
- package/dist/core/artifact-graph/schema.d.ts.map +1 -1
- package/dist/core/artifact-graph/schema.js +7 -32
- package/dist/core/artifact-graph/schema.js.map +1 -1
- package/dist/core/artifact-graph/state.d.ts +1 -8
- package/dist/core/artifact-graph/state.d.ts.map +1 -1
- package/dist/core/artifact-graph/state.js +2 -17
- package/dist/core/artifact-graph/state.js.map +1 -1
- package/dist/core/artifact-graph/stub-detection.d.ts +12 -0
- package/dist/core/artifact-graph/stub-detection.d.ts.map +1 -0
- package/dist/core/artifact-graph/stub-detection.js +39 -0
- package/dist/core/artifact-graph/stub-detection.js.map +1 -0
- package/dist/core/artifact-graph/types.d.ts +4 -0
- package/dist/core/artifact-graph/types.d.ts.map +1 -1
- package/dist/core/artifact-graph/types.js +30 -10
- package/dist/core/artifact-graph/types.js.map +1 -1
- package/dist/core/available-tools.d.ts +3 -12
- package/dist/core/available-tools.d.ts.map +1 -1
- package/dist/core/available-tools.js +4 -13
- package/dist/core/available-tools.js.map +1 -1
- package/dist/core/change-metadata/schema.d.ts +1 -1
- package/dist/core/change-metadata/schema.d.ts.map +1 -1
- package/dist/core/change-metadata/schema.js +10 -7
- package/dist/core/change-metadata/schema.js.map +1 -1
- package/dist/core/change-presenter.d.ts +23 -18
- package/dist/core/change-presenter.d.ts.map +1 -1
- package/dist/core/change-presenter.js +102 -43
- package/dist/core/change-presenter.js.map +1 -1
- package/dist/core/change-status-policy.d.ts +8 -1
- package/dist/core/change-status-policy.d.ts.map +1 -1
- package/dist/core/change-status-policy.js +25 -1
- package/dist/core/change-status-policy.js.map +1 -1
- package/dist/core/codex-metrics.d.ts +25 -45
- package/dist/core/codex-metrics.d.ts.map +1 -1
- package/dist/core/codex-metrics.js +44 -88
- package/dist/core/codex-metrics.js.map +1 -1
- package/dist/core/codex-residue.d.ts +22 -0
- package/dist/core/codex-residue.d.ts.map +1 -0
- package/dist/core/codex-residue.js +61 -0
- package/dist/core/codex-residue.js.map +1 -0
- package/dist/core/command-generation/adapters/claude.d.ts +2 -9
- package/dist/core/command-generation/adapters/claude.d.ts.map +1 -1
- package/dist/core/command-generation/adapters/claude.js +2 -12
- package/dist/core/command-generation/adapters/claude.js.map +1 -1
- package/dist/core/command-generation/adapters/index.d.ts +1 -9
- package/dist/core/command-generation/adapters/index.d.ts.map +1 -1
- package/dist/core/command-generation/adapters/index.js +1 -9
- package/dist/core/command-generation/adapters/index.js.map +1 -1
- package/dist/core/command-generation/generator.d.ts +0 -17
- package/dist/core/command-generation/generator.d.ts.map +1 -1
- package/dist/core/command-generation/generator.js +0 -17
- package/dist/core/command-generation/generator.js.map +1 -1
- package/dist/core/command-generation/index.d.ts +2 -5
- package/dist/core/command-generation/index.d.ts.map +1 -1
- package/dist/core/command-generation/index.js +0 -9
- package/dist/core/command-generation/index.js.map +1 -1
- package/dist/core/command-generation/types.d.ts +10 -36
- package/dist/core/command-generation/types.d.ts.map +1 -1
- package/dist/core/command-generation/types.js +0 -6
- package/dist/core/command-generation/types.js.map +1 -1
- package/dist/core/command-generation/yaml.d.ts +3 -18
- package/dist/core/command-generation/yaml.d.ts.map +1 -1
- package/dist/core/command-generation/yaml.js +5 -23
- package/dist/core/command-generation/yaml.js.map +1 -1
- package/dist/core/config-prompts.d.ts +2 -4
- package/dist/core/config-prompts.d.ts.map +1 -1
- package/dist/core/config-prompts.js +2 -7
- package/dist/core/config-prompts.js.map +1 -1
- package/dist/core/config-schema.d.ts +8 -53
- package/dist/core/config-schema.d.ts.map +1 -1
- package/dist/core/config-schema.js +49 -62
- package/dist/core/config-schema.js.map +1 -1
- package/dist/core/config.d.ts +56 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +73 -2
- package/dist/core/config.js.map +1 -1
- package/dist/core/converters/json-converter.d.ts.map +1 -1
- package/dist/core/dashboard-activity.d.ts +7 -9
- package/dist/core/dashboard-activity.d.ts.map +1 -1
- package/dist/core/dashboard-activity.js +26 -24
- package/dist/core/dashboard-activity.js.map +1 -1
- package/dist/core/dashboard-data.d.ts +40 -22
- package/dist/core/dashboard-data.d.ts.map +1 -1
- package/dist/core/dashboard-data.js +62 -70
- package/dist/core/dashboard-data.js.map +1 -1
- package/dist/core/global-config.d.ts +24 -53
- package/dist/core/global-config.d.ts.map +1 -1
- package/dist/core/global-config.js +38 -67
- package/dist/core/global-config.js.map +1 -1
- package/dist/core/init.d.ts +29 -11
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +232 -164
- package/dist/core/init.js.map +1 -1
- package/dist/core/list.d.ts +1 -1
- package/dist/core/list.d.ts.map +1 -1
- package/dist/core/list.js +121 -28
- package/dist/core/list.js.map +1 -1
- package/dist/core/local-server.d.ts +60 -50
- package/dist/core/local-server.d.ts.map +1 -1
- package/dist/core/local-server.js +94 -66
- package/dist/core/local-server.js.map +1 -1
- package/dist/core/markdown-render.d.ts +25 -0
- package/dist/core/markdown-render.d.ts.map +1 -0
- package/dist/core/markdown-render.js +94 -0
- package/dist/core/markdown-render.js.map +1 -0
- package/dist/core/migrate.d.ts +32 -15
- package/dist/core/migrate.d.ts.map +1 -1
- package/dist/core/migrate.js +220 -108
- package/dist/core/migrate.js.map +1 -1
- package/dist/core/parsers/change-parser.d.ts +7 -10
- package/dist/core/parsers/change-parser.d.ts.map +1 -1
- package/dist/core/parsers/change-parser.js +48 -56
- package/dist/core/parsers/change-parser.js.map +1 -1
- package/dist/core/parsers/markdown-parser.d.ts +8 -9
- package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
- package/dist/core/parsers/markdown-parser.js +31 -22
- package/dist/core/parsers/markdown-parser.js.map +1 -1
- package/dist/core/parsers/requirement-blocks.d.ts +43 -15
- package/dist/core/parsers/requirement-blocks.d.ts.map +1 -1
- package/dist/core/parsers/requirement-blocks.js +169 -54
- package/dist/core/parsers/requirement-blocks.js.map +1 -1
- package/dist/core/parsers/requirement-text.d.ts +73 -79
- package/dist/core/parsers/requirement-text.d.ts.map +1 -1
- package/dist/core/parsers/requirement-text.js +137 -79
- package/dist/core/parsers/requirement-text.js.map +1 -1
- package/dist/core/parsers/spec-structure.d.ts.map +1 -1
- package/dist/core/parsers/spec-structure.js +10 -6
- package/dist/core/parsers/spec-structure.js.map +1 -1
- package/dist/core/planning-home.js.map +1 -1
- package/dist/core/profiles.d.ts +3 -10
- package/dist/core/profiles.d.ts.map +1 -1
- package/dist/core/profiles.js +5 -12
- package/dist/core/profiles.js.map +1 -1
- package/dist/core/project-config.d.ts +43 -44
- package/dist/core/project-config.d.ts.map +1 -1
- package/dist/core/project-config.js +107 -82
- package/dist/core/project-config.js.map +1 -1
- package/dist/core/project-layout.d.ts +10 -18
- package/dist/core/project-layout.d.ts.map +1 -1
- package/dist/core/project-layout.js +16 -26
- package/dist/core/project-layout.js.map +1 -1
- package/dist/core/root-selection.d.ts +11 -7
- package/dist/core/root-selection.d.ts.map +1 -1
- package/dist/core/root-selection.js +7 -8
- package/dist/core/root-selection.js.map +1 -1
- package/dist/core/rules.d.ts +10 -0
- package/dist/core/rules.d.ts.map +1 -0
- package/dist/core/rules.js +43 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/schema-names.d.ts +16 -0
- package/dist/core/schema-names.d.ts.map +1 -0
- package/dist/core/schema-names.js +16 -0
- package/dist/core/schema-names.js.map +1 -0
- package/dist/core/schemas/base.schema.d.ts +3 -0
- package/dist/core/schemas/base.schema.d.ts.map +1 -1
- package/dist/core/schemas/base.schema.js +22 -6
- package/dist/core/schemas/base.schema.js.map +1 -1
- package/dist/core/schemas/change.schema.d.ts +16 -0
- package/dist/core/schemas/change.schema.d.ts.map +1 -1
- package/dist/core/schemas/change.schema.js +41 -10
- package/dist/core/schemas/change.schema.js.map +1 -1
- package/dist/core/schemas/spec.schema.d.ts +2 -0
- package/dist/core/schemas/spec.schema.d.ts.map +1 -1
- package/dist/core/shared/index.d.ts +3 -8
- package/dist/core/shared/index.d.ts.map +1 -1
- package/dist/core/shared/index.js +3 -8
- package/dist/core/shared/index.js.map +1 -1
- package/dist/core/shared/rules-generation.d.ts +27 -8
- package/dist/core/shared/rules-generation.d.ts.map +1 -1
- package/dist/core/shared/rules-generation.js +151 -16
- package/dist/core/shared/rules-generation.js.map +1 -1
- package/dist/core/shared/skill-generation.d.ts +38 -53
- package/dist/core/shared/skill-generation.d.ts.map +1 -1
- package/dist/core/shared/skill-generation.js +82 -51
- package/dist/core/shared/skill-generation.js.map +1 -1
- package/dist/core/shared/tool-detection.d.ts +40 -62
- package/dist/core/shared/tool-detection.d.ts.map +1 -1
- package/dist/core/shared/tool-detection.js +88 -80
- package/dist/core/shared/tool-detection.js.map +1 -1
- package/dist/core/skill-metrics.d.ts +36 -63
- package/dist/core/skill-metrics.d.ts.map +1 -1
- package/dist/core/skill-metrics.js +34 -73
- package/dist/core/skill-metrics.js.map +1 -1
- package/dist/core/spec-presenter.d.ts.map +1 -1
- package/dist/core/spec-presenter.js +6 -6
- package/dist/core/spec-presenter.js.map +1 -1
- package/dist/core/specs-apply.d.ts +22 -23
- package/dist/core/specs-apply.d.ts.map +1 -1
- package/dist/core/specs-apply.js +166 -193
- package/dist/core/specs-apply.js.map +1 -1
- package/dist/core/templates/fragments/interview.d.ts +2 -6
- package/dist/core/templates/fragments/interview.d.ts.map +1 -1
- package/dist/core/templates/fragments/interview.js +2 -6
- package/dist/core/templates/fragments/interview.js.map +1 -1
- package/dist/core/templates/fragments/next-step.d.ts +4 -8
- package/dist/core/templates/fragments/next-step.d.ts.map +1 -1
- package/dist/core/templates/fragments/next-step.js +4 -8
- package/dist/core/templates/fragments/next-step.js.map +1 -1
- package/dist/core/templates/fragments/verify.d.ts +9 -12
- package/dist/core/templates/fragments/verify.d.ts.map +1 -1
- package/dist/core/templates/fragments/verify.js +9 -12
- package/dist/core/templates/fragments/verify.js.map +1 -1
- package/dist/core/templates/index.d.ts +0 -6
- package/dist/core/templates/index.d.ts.map +1 -1
- package/dist/core/templates/index.js +0 -7
- package/dist/core/templates/index.js.map +1 -1
- package/dist/core/templates/skill-templates.d.ts +1 -5
- package/dist/core/templates/skill-templates.d.ts.map +1 -1
- package/dist/core/templates/skill-templates.js +0 -5
- package/dist/core/templates/skill-templates.js.map +1 -1
- package/dist/core/templates/types.d.ts +3 -7
- package/dist/core/templates/types.d.ts.map +1 -1
- package/dist/core/templates/types.js +0 -3
- package/dist/core/templates/types.js.map +1 -1
- package/dist/core/templates/workflows/apply.d.ts +3 -9
- package/dist/core/templates/workflows/apply.d.ts.map +1 -1
- package/dist/core/templates/workflows/apply.js +9 -12
- package/dist/core/templates/workflows/apply.js.map +1 -1
- package/dist/core/templates/workflows/archive.d.ts +0 -6
- package/dist/core/templates/workflows/archive.d.ts.map +1 -1
- package/dist/core/templates/workflows/archive.js +7 -5
- package/dist/core/templates/workflows/archive.js.map +1 -1
- package/dist/core/templates/workflows/decision.js +4 -4
- package/dist/core/templates/workflows/decision.js.map +1 -1
- package/dist/core/templates/workflows/explore.js +1 -1
- package/dist/core/templates/workflows/grill.d.ts.map +1 -1
- package/dist/core/templates/workflows/grill.js +0 -2
- package/dist/core/templates/workflows/grill.js.map +1 -1
- package/dist/core/templates/workflows/issue.d.ts +0 -6
- package/dist/core/templates/workflows/issue.d.ts.map +1 -1
- package/dist/core/templates/workflows/issue.js +3 -0
- package/dist/core/templates/workflows/issue.js.map +1 -1
- package/dist/core/templates/workflows/propose.d.ts +0 -6
- package/dist/core/templates/workflows/propose.d.ts.map +1 -1
- package/dist/core/templates/workflows/propose.js +0 -1
- package/dist/core/templates/workflows/propose.js.map +1 -1
- package/dist/core/templates/workflows/sync.d.ts +2 -8
- package/dist/core/templates/workflows/sync.d.ts.map +1 -1
- package/dist/core/templates/workflows/sync.js +2 -2
- package/dist/core/templates/workflows/sync.js.map +1 -1
- package/dist/core/templates/workflows/update.d.ts +0 -6
- package/dist/core/templates/workflows/update.d.ts.map +1 -1
- package/dist/core/templates/workflows/update.js.map +1 -1
- package/dist/core/update.d.ts +26 -21
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +165 -116
- package/dist/core/update.js.map +1 -1
- package/dist/core/user-state-migration.d.ts +13 -15
- package/dist/core/user-state-migration.d.ts.map +1 -1
- package/dist/core/user-state-migration.js +16 -20
- package/dist/core/user-state-migration.js.map +1 -1
- package/dist/core/validation/constants.d.ts +19 -25
- package/dist/core/validation/constants.d.ts.map +1 -1
- package/dist/core/validation/constants.js +25 -20
- package/dist/core/validation/constants.js.map +1 -1
- package/dist/core/validation/prose-length.d.ts +15 -0
- package/dist/core/validation/prose-length.d.ts.map +1 -0
- package/dist/core/validation/prose-length.js +29 -0
- package/dist/core/validation/prose-length.js.map +1 -0
- package/dist/core/validation/purpose-placeholder.d.ts +9 -16
- package/dist/core/validation/purpose-placeholder.d.ts.map +1 -1
- package/dist/core/validation/purpose-placeholder.js +30 -44
- package/dist/core/validation/purpose-placeholder.js.map +1 -1
- package/dist/core/validation/section-validator.d.ts +4 -4
- package/dist/core/validation/section-validator.d.ts.map +1 -1
- package/dist/core/validation/section-validator.js +43 -7
- package/dist/core/validation/section-validator.js.map +1 -1
- package/dist/core/validation/task-numbering.d.ts +6 -3
- package/dist/core/validation/task-numbering.d.ts.map +1 -1
- package/dist/core/validation/task-numbering.js +23 -11
- package/dist/core/validation/task-numbering.js.map +1 -1
- package/dist/core/validation/types.d.ts +18 -0
- package/dist/core/validation/types.d.ts.map +1 -1
- package/dist/core/validation/types.js +12 -1
- package/dist/core/validation/types.js.map +1 -1
- package/dist/core/validation/validator.d.ts +50 -51
- package/dist/core/validation/validator.d.ts.map +1 -1
- package/dist/core/validation/validator.js +478 -269
- package/dist/core/validation/validator.js.map +1 -1
- package/dist/prompts/searchable-multi-select.d.ts +3 -8
- package/dist/prompts/searchable-multi-select.d.ts.map +1 -1
- package/dist/prompts/searchable-multi-select.js +16 -39
- package/dist/prompts/searchable-multi-select.js.map +1 -1
- package/dist/utils/change-metadata.d.ts +11 -50
- package/dist/utils/change-metadata.d.ts.map +1 -1
- package/dist/utils/change-metadata.js +48 -67
- package/dist/utils/change-metadata.js.map +1 -1
- package/dist/utils/change-utils.d.ts +31 -54
- package/dist/utils/change-utils.d.ts.map +1 -1
- package/dist/utils/change-utils.js +143 -100
- package/dist/utils/change-utils.js.map +1 -1
- package/dist/utils/file-lock.d.ts +39 -0
- package/dist/utils/file-lock.d.ts.map +1 -0
- package/dist/utils/file-lock.js +149 -0
- package/dist/utils/file-lock.js.map +1 -0
- package/dist/utils/file-system.d.ts +12 -32
- package/dist/utils/file-system.d.ts.map +1 -1
- package/dist/utils/file-system.js +16 -40
- package/dist/utils/file-system.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +7 -11
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +11 -11
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/interactive.d.ts +4 -9
- package/dist/utils/interactive.d.ts.map +1 -1
- package/dist/utils/interactive.js +2 -4
- package/dist/utils/interactive.js.map +1 -1
- package/dist/utils/item-discovery.d.ts +15 -10
- package/dist/utils/item-discovery.d.ts.map +1 -1
- package/dist/utils/item-discovery.js +42 -47
- package/dist/utils/item-discovery.js.map +1 -1
- package/dist/utils/link.d.ts +13 -4
- package/dist/utils/link.d.ts.map +1 -1
- package/dist/utils/link.js +13 -4
- package/dist/utils/link.js.map +1 -1
- package/dist/utils/match.js.map +1 -1
- package/dist/utils/requirement-diff.d.ts +13 -23
- package/dist/utils/requirement-diff.d.ts.map +1 -1
- package/dist/utils/requirement-diff.js +13 -23
- package/dist/utils/requirement-diff.js.map +1 -1
- package/dist/utils/spec-files.d.ts +10 -11
- package/dist/utils/spec-files.d.ts.map +1 -1
- package/dist/utils/spec-files.js +31 -22
- package/dist/utils/spec-files.js.map +1 -1
- package/dist/utils/task-progress.d.ts +11 -9
- package/dist/utils/task-progress.d.ts.map +1 -1
- package/dist/utils/task-progress.js +53 -32
- package/dist/utils/task-progress.js.map +1 -1
- package/dist/utils/timestamp.d.ts +5 -8
- package/dist/utils/timestamp.d.ts.map +1 -1
- package/dist/utils/timestamp.js +5 -8
- package/dist/utils/timestamp.js.map +1 -1
- package/package.json +9 -10
- package/schemas/decision/templates/decision.md +3 -1
- package/schemas/decision/templates/index.md +2 -2
- package/schemas/issue/schema.yaml +11 -2
- package/schemas/issue/templates/spec.md +37 -3
- package/schemas/sdd/schema.yaml +24 -1
- package/schemas/sdd/templates/spec.md +37 -3
|
@@ -2,131 +2,143 @@ import { existsSync, readFileSync } from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { parse as parseYaml } from 'yaml';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
/**
|
|
6
|
-
* Zod schema for project configuration.
|
|
7
|
-
*
|
|
8
|
-
* Purpose:
|
|
9
|
-
* 1. Documentation - clearly defines the config file structure
|
|
10
|
-
* 2. Type safety - TypeScript infers ProjectConfig type from schema
|
|
11
|
-
* 3. Runtime validation - uses safeParse() for resilient field-by-field validation
|
|
12
|
-
*
|
|
13
|
-
* Why Zod over manual validation:
|
|
14
|
-
* - Helps understand Tospec's data interfaces at a glance
|
|
15
|
-
* - Single source of truth for type and validation
|
|
16
|
-
* - Consistent with other Tospec schemas
|
|
17
|
-
*/
|
|
5
|
+
/** Single source of truth for both `ProjectConfig` and its runtime validation. */
|
|
18
6
|
export const ProjectConfigSchema = z.object({
|
|
19
|
-
// Required: which schema to use (e.g., "sdd", or project-local schema name)
|
|
20
7
|
schema: z
|
|
21
8
|
.string()
|
|
22
9
|
.min(1)
|
|
23
10
|
.describe('The workflow schema to use (e.g., "sdd")'),
|
|
24
|
-
//
|
|
25
|
-
// Max size: 50KB (enforced during parsing)
|
|
11
|
+
// Capped at MAX_CONTEXT_SIZE during parsing.
|
|
26
12
|
context: z
|
|
27
13
|
.string()
|
|
28
14
|
.optional()
|
|
29
15
|
.describe('Project context injected into all artifact instructions'),
|
|
30
|
-
//
|
|
16
|
+
// Additive to the schema's built-in guidance.
|
|
31
17
|
rules: z
|
|
32
|
-
.record(z.string(),
|
|
33
|
-
z.array(z.string()) // list of rules
|
|
34
|
-
)
|
|
18
|
+
.record(z.string(), z.array(z.string()))
|
|
35
19
|
.optional()
|
|
36
20
|
.describe('Per-artifact rules, keyed by artifact ID'),
|
|
37
|
-
//
|
|
38
|
-
//
|
|
21
|
+
// ADR 001. staleDays: days without a file change before an active change is
|
|
22
|
+
// flagged stale (default 14).
|
|
39
23
|
dashboard: z
|
|
40
24
|
.object({
|
|
41
25
|
staleDays: z.number().int().positive().optional(),
|
|
42
26
|
})
|
|
43
27
|
.optional()
|
|
44
28
|
.describe('Dashboard settings (staleDays: stale-change threshold in days)'),
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
// simply ignored, never an error.
|
|
29
|
+
// The retired `agentsLinkMode` field is absent on purpose: config files still
|
|
30
|
+
// carrying it are ignored, never an error.
|
|
48
31
|
});
|
|
49
32
|
export const MAX_CONTEXT_SIZE = 50 * 1024; // 50KB hard limit on inlined context
|
|
50
33
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* Returns partial config if some fields are invalid (with warnings).
|
|
34
|
+
* Reads `tospec/config.yaml`, validating each field independently so one bad
|
|
35
|
+
* field does not discard the rest. Uncached on purpose: ~0.5 ms for a typical
|
|
36
|
+
* config and 1-2 reads per command, so mtime invalidation would buy nothing.
|
|
55
37
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* - Typical config (1KB): ~0.5ms per read
|
|
59
|
-
* - Large config (50KB): ~1.6ms per read
|
|
60
|
-
* - Missing config: ~0.01ms per read
|
|
61
|
-
* Config is read 1-2 times per command (schema resolution + instruction loading),
|
|
62
|
-
* adding ~1-3ms total overhead. Caching would add complexity (mtime checks,
|
|
63
|
-
* invalidation logic) for negligible benefit. Direct reads also ensure config
|
|
64
|
-
* changes are reflected immediately without stale cache issues.
|
|
65
|
-
*
|
|
66
|
-
* @param projectRoot - The root directory of the project (where `tospec/` lives)
|
|
67
|
-
* @returns Parsed config or null if file doesn't exist
|
|
38
|
+
* Diagnostics go to stderr here, for callers with no envelope to carry them;
|
|
39
|
+
* the ones that have an envelope call the variant below.
|
|
68
40
|
*/
|
|
69
41
|
export function readProjectConfig(projectRoot) {
|
|
42
|
+
const { config, diagnostics } = readProjectConfigWithDiagnostics(projectRoot);
|
|
43
|
+
for (const diagnostic of diagnostics) {
|
|
44
|
+
console.warn(diagnostic.message);
|
|
45
|
+
}
|
|
46
|
+
return config;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Stderr copy of the config diagnostics, for commands that never read the
|
|
50
|
+
* config themselves. `list` and `status` resolve each change's schema from its
|
|
51
|
+
* own `.tospec.yaml` and consult the project config only when that field is
|
|
52
|
+
* absent, so a config that no longer parses went unmentioned by exactly the
|
|
53
|
+
* commands a user runs to look around. Stderr in both modes: a `--json` stdout
|
|
54
|
+
* stays one document, and a warning is not a failed command.
|
|
55
|
+
*/
|
|
56
|
+
export function printProjectConfigDiagnostics(projectRoot) {
|
|
57
|
+
for (const diagnostic of readProjectConfigWithDiagnostics(projectRoot).diagnostics) {
|
|
58
|
+
console.error(diagnostic.message.startsWith('Warning:') ? diagnostic.message : `Warning: ${diagnostic.message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** The same read, with the dropped fields handed back instead of printed. */
|
|
62
|
+
export function readProjectConfigWithDiagnostics(projectRoot) {
|
|
70
63
|
const configPath = resolveConfigFilePath(projectRoot);
|
|
71
64
|
if (configPath === null) {
|
|
72
|
-
return null; // No config is OK
|
|
65
|
+
return { config: null, diagnostics: [] }; // No config is OK
|
|
73
66
|
}
|
|
67
|
+
const diagnostics = [];
|
|
68
|
+
const where = configPath;
|
|
74
69
|
try {
|
|
75
70
|
const content = readFileSync(configPath, 'utf-8');
|
|
76
71
|
const raw = parseYaml(content);
|
|
77
72
|
if (!raw || typeof raw !== 'object') {
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
return {
|
|
74
|
+
config: null,
|
|
75
|
+
diagnostics: [
|
|
76
|
+
{
|
|
77
|
+
code: 'config_not_a_mapping',
|
|
78
|
+
message: `${where} is not a YAML mapping; ignoring it.`,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
};
|
|
80
82
|
}
|
|
81
83
|
const config = {};
|
|
82
|
-
// Parse schema field using Zod
|
|
83
84
|
const schemaField = z.string().min(1);
|
|
84
85
|
const schemaResult = schemaField.safeParse(raw.schema);
|
|
85
86
|
if (schemaResult.success) {
|
|
86
87
|
config.schema = schemaResult.data;
|
|
87
88
|
}
|
|
88
89
|
else if (raw.schema !== undefined) {
|
|
89
|
-
|
|
90
|
+
diagnostics.push({
|
|
91
|
+
code: 'config_field_invalid',
|
|
92
|
+
message: `Invalid 'schema' field in ${where} (must be a non-empty string); ignoring it.`,
|
|
93
|
+
});
|
|
90
94
|
}
|
|
91
|
-
// Parse context field with size limit
|
|
92
95
|
if (raw.context !== undefined) {
|
|
93
96
|
const contextField = z.string();
|
|
94
97
|
const contextResult = contextField.safeParse(raw.context);
|
|
95
98
|
if (contextResult.success) {
|
|
96
99
|
const contextSize = Buffer.byteLength(contextResult.data, 'utf-8');
|
|
97
100
|
if (contextSize > MAX_CONTEXT_SIZE) {
|
|
98
|
-
|
|
99
|
-
|
|
101
|
+
diagnostics.push({
|
|
102
|
+
code: 'config_context_too_large',
|
|
103
|
+
message: `Context too large (${(contextSize / 1024).toFixed(1)}KB, limit: ${MAX_CONTEXT_SIZE / 1024}KB); ignoring the context field in ${where}.`,
|
|
104
|
+
});
|
|
100
105
|
}
|
|
101
106
|
else {
|
|
102
107
|
config.context = contextResult.data;
|
|
103
108
|
}
|
|
104
109
|
}
|
|
105
110
|
else {
|
|
106
|
-
|
|
111
|
+
diagnostics.push({
|
|
112
|
+
code: 'config_field_invalid',
|
|
113
|
+
message: `Invalid 'context' field in ${where} (must be a string); ignoring it.`,
|
|
114
|
+
});
|
|
107
115
|
}
|
|
108
116
|
}
|
|
109
|
-
// Parse rules field using Zod
|
|
110
117
|
if (raw.rules !== undefined) {
|
|
111
|
-
//
|
|
118
|
+
// The null guard matters: typeof null === 'object'.
|
|
112
119
|
if (typeof raw.rules === 'object' && raw.rules !== null && !Array.isArray(raw.rules)) {
|
|
113
120
|
const parsedRules = {};
|
|
114
121
|
let hasValidRules = false;
|
|
115
122
|
for (const [artifactId, rules] of Object.entries(raw.rules)) {
|
|
116
123
|
const rulesArrayResult = z.array(z.string()).safeParse(rules);
|
|
117
124
|
if (rulesArrayResult.success) {
|
|
118
|
-
// Filter out empty strings
|
|
119
125
|
const validRules = rulesArrayResult.data.filter((r) => r.length > 0);
|
|
120
126
|
if (validRules.length > 0) {
|
|
121
127
|
parsedRules[artifactId] = validRules;
|
|
122
128
|
hasValidRules = true;
|
|
123
129
|
}
|
|
124
130
|
if (validRules.length < rulesArrayResult.data.length) {
|
|
125
|
-
|
|
131
|
+
diagnostics.push({
|
|
132
|
+
code: 'config_rules_empty_entries',
|
|
133
|
+
message: `Some rules for '${artifactId}' in ${where} are empty strings, ignoring them`,
|
|
134
|
+
});
|
|
126
135
|
}
|
|
127
136
|
}
|
|
128
137
|
else {
|
|
129
|
-
|
|
138
|
+
diagnostics.push({
|
|
139
|
+
code: 'config_field_invalid',
|
|
140
|
+
message: `Rules for '${artifactId}' in ${where} must be an array of strings, ignoring this artifact's rules`,
|
|
141
|
+
});
|
|
130
142
|
}
|
|
131
143
|
}
|
|
132
144
|
if (hasValidRules) {
|
|
@@ -134,10 +146,12 @@ export function readProjectConfig(projectRoot) {
|
|
|
134
146
|
}
|
|
135
147
|
}
|
|
136
148
|
else {
|
|
137
|
-
|
|
149
|
+
diagnostics.push({
|
|
150
|
+
code: 'config_field_invalid',
|
|
151
|
+
message: `Invalid 'rules' field in ${where} (must be a mapping); ignoring it.`,
|
|
152
|
+
});
|
|
138
153
|
}
|
|
139
154
|
}
|
|
140
|
-
// Parse dashboard field using Zod
|
|
141
155
|
if (raw.dashboard !== undefined) {
|
|
142
156
|
const dashboardField = z.object({ staleDays: z.number().int().positive().optional() });
|
|
143
157
|
const dashboardResult = dashboardField.safeParse(raw.dashboard);
|
|
@@ -145,40 +159,51 @@ export function readProjectConfig(projectRoot) {
|
|
|
145
159
|
config.dashboard = dashboardResult.data;
|
|
146
160
|
}
|
|
147
161
|
else {
|
|
148
|
-
|
|
162
|
+
diagnostics.push({
|
|
163
|
+
code: 'config_field_invalid',
|
|
164
|
+
message: `Invalid 'dashboard' field in ${where} (staleDays must be a positive integer); ignoring it.`,
|
|
165
|
+
});
|
|
149
166
|
}
|
|
150
167
|
}
|
|
151
|
-
//
|
|
152
|
-
return
|
|
168
|
+
// A partial config, even when some fields failed.
|
|
169
|
+
return {
|
|
170
|
+
config: Object.keys(config).length > 0 ? config : null,
|
|
171
|
+
diagnostics,
|
|
172
|
+
};
|
|
153
173
|
}
|
|
154
174
|
catch (error) {
|
|
155
|
-
|
|
156
|
-
|
|
175
|
+
return {
|
|
176
|
+
config: null,
|
|
177
|
+
diagnostics: [
|
|
178
|
+
{
|
|
179
|
+
code: 'config_unparseable',
|
|
180
|
+
// First line only, minus the colon that introduces the yaml
|
|
181
|
+
// library's code frame on the lines that follow.
|
|
182
|
+
message: `Warning: could not parse ${where} (${error instanceof Error ? error.message.split('\n')[0].replace(/:\s*$/, '') : String(error)}); ignoring it.`,
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
};
|
|
157
186
|
}
|
|
158
187
|
}
|
|
159
|
-
function configPathForWarnings(projectRoot) {
|
|
160
|
-
return resolveConfigFilePath(projectRoot) ?? path.join(projectRoot, 'tospec', 'config.yaml');
|
|
161
|
-
}
|
|
162
188
|
/**
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
*
|
|
170
|
-
*
|
|
189
|
+
* The one `rules:` key that is not an artifact: every other names a document to
|
|
190
|
+
* write, this one the phase that writes code. Without it a project can say how
|
|
191
|
+
* to write tasks.md but not how to implement it.
|
|
192
|
+
*/
|
|
193
|
+
export const APPLY_RULES_KEY = 'apply';
|
|
194
|
+
/**
|
|
195
|
+
* Checks rule keys against the artifacts of *every* available schema. `rules:`
|
|
196
|
+
* is one global map but a change loads under one schema, so checking against
|
|
197
|
+
* that schema alone warns about real, correctly-spelled artifacts.
|
|
171
198
|
*
|
|
172
|
-
* @param
|
|
173
|
-
* @param validArtifactIds - Union of artifact IDs across all available schemas
|
|
174
|
-
* (see collectAllArtifactIds)
|
|
175
|
-
* @returns Array of warning messages for artifact IDs that match no schema
|
|
199
|
+
* @param validArtifactIds Union across all schemas; see collectAllArtifactIds.
|
|
176
200
|
*/
|
|
177
201
|
export function validateConfigRules(rules, validArtifactIds) {
|
|
178
202
|
const warnings = [];
|
|
203
|
+
const validKeys = new Set([...validArtifactIds, APPLY_RULES_KEY]);
|
|
179
204
|
for (const artifactId of Object.keys(rules)) {
|
|
180
|
-
if (!
|
|
181
|
-
const validIds = Array.from(
|
|
205
|
+
if (!validKeys.has(artifactId)) {
|
|
206
|
+
const validIds = Array.from(validKeys).sort().join(', ');
|
|
182
207
|
warnings.push(`Unknown artifact ID in rules: "${artifactId}". ` +
|
|
183
208
|
`Valid IDs across all available schemas: ${validIds}`);
|
|
184
209
|
}
|
|
@@ -186,9 +211,9 @@ export function validateConfigRules(rules, validArtifactIds) {
|
|
|
186
211
|
return warnings;
|
|
187
212
|
}
|
|
188
213
|
/**
|
|
189
|
-
* Shared .yaml/.yml probe over an existing `tospec/` directory
|
|
190
|
-
* that decides which config file a root has
|
|
191
|
-
*
|
|
214
|
+
* Shared .yaml/.yml probe over an existing `tospec/` directory: the one place
|
|
215
|
+
* that decides which config file a root has, so init cannot report "created"
|
|
216
|
+
* next to a config the reader is already using.
|
|
192
217
|
*/
|
|
193
218
|
export function resolveConfigFileInDir(tospecDir) {
|
|
194
219
|
const yamlPath = path.join(tospecDir, 'config.yaml');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-config.js","sourceRoot":"","sources":["../../src/core/project-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB
|
|
1
|
+
{"version":3,"file":"project-config.js","sourceRoot":"","sources":["../../src/core/project-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The directory layout `tospec init` creates, and the anchors that make it
|
|
3
|
-
* survive version control.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* the first command that looks for one reports the project as uninitialized.
|
|
8
|
-
* Nothing is lost — every writer creates the directory it needs on demand — but
|
|
9
|
-
* a diagnostic that sends the reader to re-run a command that will change
|
|
10
|
-
* nothing is worse than a crash.
|
|
3
|
+
* survive version control. Git does not track an empty directory, so without
|
|
4
|
+
* them a collaborator clones a layout whose directories are gone and the first
|
|
5
|
+
* command reports the project as uninitialized — nothing is lost, but the
|
|
6
|
+
* diagnostic sends the reader to re-run a command that changes nothing.
|
|
11
7
|
*/
|
|
12
8
|
/**
|
|
13
|
-
* Relative to `tospec/`, in creation order.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* whether it ends up empty, and `changes/` never does because it holds
|
|
17
|
-
* `archive/`. A name asserting the property would be wrong for the next
|
|
18
|
-
* directory that ships with content.
|
|
9
|
+
* Relative to `tospec/`, in creation order. Not named for anchoring: whether a
|
|
10
|
+
* directory gets an anchor is computed from whether it ends up empty, and
|
|
11
|
+
* `changes/` never does because it holds `archive/`.
|
|
19
12
|
*/
|
|
20
|
-
export declare const TOSPEC_LAYOUT_DIRS: readonly [
|
|
13
|
+
export declare const TOSPEC_LAYOUT_DIRS: readonly ['specs', 'changes', 'changes/archive', 'decisions'];
|
|
21
14
|
/** The layout as absolute paths, so callers never re-derive the join. */
|
|
22
15
|
export declare function tospecLayoutDirs(tospecPath: string): string[];
|
|
23
16
|
/**
|
|
24
|
-
* Anchor `directory` if it is empty.
|
|
25
|
-
*
|
|
26
|
-
* and adding one beside real content leaves a file nobody asked for.
|
|
17
|
+
* Anchor `directory` if it is empty. An anchor exists to make an empty directory
|
|
18
|
+
* representable, so adding one beside real content leaves a file nobody wanted.
|
|
27
19
|
*/
|
|
28
20
|
export declare function ensureDirectoryAnchor(directory: string): Promise<void>;
|
|
29
21
|
//# sourceMappingURL=project-layout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-layout.d.ts","sourceRoot":"","sources":["../../src/core/project-layout.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"project-layout.d.ts","sourceRoot":"","sources":["../../src/core/project-layout.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,YAC7B,OAAO,EACP,SAAS,EACT,iBAAiB,EAGjB,WAAW,CACH,CAAC;AAIX,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAE7D;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB5E"}
|
|
@@ -1,30 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The directory layout `tospec init` creates, and the anchors that make it
|
|
3
|
-
* survive version control.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* the first command that looks for one reports the project as uninitialized.
|
|
8
|
-
* Nothing is lost — every writer creates the directory it needs on demand — but
|
|
9
|
-
* a diagnostic that sends the reader to re-run a command that will change
|
|
10
|
-
* nothing is worse than a crash.
|
|
3
|
+
* survive version control. Git does not track an empty directory, so without
|
|
4
|
+
* them a collaborator clones a layout whose directories are gone and the first
|
|
5
|
+
* command reports the project as uninitialized — nothing is lost, but the
|
|
6
|
+
* diagnostic sends the reader to re-run a command that changes nothing.
|
|
11
7
|
*/
|
|
12
8
|
import path from 'path';
|
|
13
9
|
import { promises as fs } from 'fs';
|
|
14
10
|
/**
|
|
15
|
-
* Relative to `tospec/`, in creation order.
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* whether it ends up empty, and `changes/` never does because it holds
|
|
19
|
-
* `archive/`. A name asserting the property would be wrong for the next
|
|
20
|
-
* directory that ships with content.
|
|
11
|
+
* Relative to `tospec/`, in creation order. Not named for anchoring: whether a
|
|
12
|
+
* directory gets an anchor is computed from whether it ends up empty, and
|
|
13
|
+
* `changes/` never does because it holds `archive/`.
|
|
21
14
|
*/
|
|
22
15
|
export const TOSPEC_LAYOUT_DIRS = [
|
|
23
16
|
'specs',
|
|
24
17
|
'changes',
|
|
25
18
|
'changes/archive',
|
|
26
|
-
// Permanent decision records (`tospec decision new`)
|
|
27
|
-
// layout is visible from the start
|
|
19
|
+
// Permanent decision records (`tospec decision new`), scaffolded here so the
|
|
20
|
+
// layout is visible from the start rather than appearing on first use.
|
|
28
21
|
'decisions',
|
|
29
22
|
];
|
|
30
23
|
const DIRECTORY_ANCHOR_FILE_NAME = '.gitkeep';
|
|
@@ -33,27 +26,24 @@ export function tospecLayoutDirs(tospecPath) {
|
|
|
33
26
|
return TOSPEC_LAYOUT_DIRS.map((relative) => path.join(tospecPath, relative));
|
|
34
27
|
}
|
|
35
28
|
/**
|
|
36
|
-
* Anchor `directory` if it is empty.
|
|
37
|
-
*
|
|
38
|
-
* and adding one beside real content leaves a file nobody asked for.
|
|
29
|
+
* Anchor `directory` if it is empty. An anchor exists to make an empty directory
|
|
30
|
+
* representable, so adding one beside real content leaves a file nobody wanted.
|
|
39
31
|
*/
|
|
40
32
|
export async function ensureDirectoryAnchor(directory) {
|
|
41
33
|
if ((await fs.readdir(directory)).length > 0)
|
|
42
34
|
return;
|
|
43
35
|
try {
|
|
44
|
-
// Exclusive create
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
// content the anchor never owned, or write *through* a link into a path
|
|
48
|
-
// outside the project entirely.
|
|
36
|
+
// Exclusive create, closing the window after the emptiness check where a
|
|
37
|
+
// file or link can appear at the anchor's path: an ordinary write would
|
|
38
|
+
// overwrite content the anchor never owned, or write *through* a link.
|
|
49
39
|
await fs.writeFile(path.join(directory, DIRECTORY_ANCHOR_FILE_NAME), '', {
|
|
50
40
|
encoding: 'utf-8',
|
|
51
41
|
flag: 'wx',
|
|
52
42
|
});
|
|
53
43
|
}
|
|
54
44
|
catch (error) {
|
|
55
|
-
// Something is already there, so the directory
|
|
56
|
-
//
|
|
45
|
+
// Something is already there, so the directory needs no anchor: done, not
|
|
46
|
+
// a failure.
|
|
57
47
|
if (error?.code === 'EEXIST')
|
|
58
48
|
return;
|
|
59
49
|
throw error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-layout.js","sourceRoot":"","sources":["../../src/core/project-layout.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"project-layout.js","sourceRoot":"","sources":["../../src/core/project-layout.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,OAAO;IACP,SAAS;IACT,iBAAiB;IACjB,6EAA6E;IAC7E,uEAAuE;IACvE,WAAW;CACH,CAAC;AAEX,MAAM,0BAA0B,GAAG,UAAU,CAAC;AAE9C,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,SAAiB;IAC3D,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO;IAErD,IAAI,CAAC;QACH,yEAAyE;QACzE,wEAAwE;QACxE,uEAAuE;QACvE,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,0BAA0B,CAAC,EAAE,EAAE,EAAE;YACvE,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0EAA0E;QAC1E,aAAa;QACb,IAAK,KAA+B,EAAE,IAAI,KAAK,QAAQ;YAAE,OAAO;QAChE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* rule: walk up from the start path to the nearest ancestor that contains a
|
|
6
|
-
* `tospec/` directory; if none is found, treat the current directory as an
|
|
7
|
-
* implicit root (unless the caller forbids it).
|
|
2
|
+
* Root resolution: walk up from the start path to the nearest ancestor holding
|
|
3
|
+
* a `tospec/` directory, else treat the current directory as an implicit root
|
|
4
|
+
* unless the caller forbids it.
|
|
8
5
|
*/
|
|
9
6
|
import { type PlanningHome } from './planning-home.js';
|
|
10
|
-
|
|
7
|
+
/**
|
|
8
|
+
* How a command arrived at the root it reports. `nearest` and `implicit` are the
|
|
9
|
+
* two outcomes of *searching*; `explicit` is the install layer (`init`,
|
|
10
|
+
* `update`, `rules`, `migrate`), which operates on the path it was handed.
|
|
11
|
+
* Naming that case keeps the key present: `JSON.stringify` drops an omitted
|
|
12
|
+
* one, leaving a caller unable to tell it from a renamed field.
|
|
13
|
+
*/
|
|
14
|
+
export type TospecRootSource = 'nearest' | 'implicit' | 'explicit';
|
|
11
15
|
export interface ResolveTospecRootOptions {
|
|
12
16
|
startPath?: string;
|
|
13
17
|
allowImplicitRoot?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root-selection.d.ts","sourceRoot":"","sources":["../../src/core/root-selection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"root-selection.d.ts","sourceRoot":"","sources":["../../src/core/root-selection.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAG5B;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAEnE,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,KAAK,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,UAAU,EAAE,uBAAuB,CAAC;IAE7C,YACE,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAO,EAUhD;CACF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAEhF;AAaD,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,kBAAkB,CAAC,CAgB7B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB,GAAG,UAAU,CAKjE;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,YAAY,CAOrE;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,OAAO,EAClB,MAAM,GAAE;IACN,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACxB,GACL,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAgBpC"}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* rule: walk up from the start path to the nearest ancestor that contains a
|
|
6
|
-
* `tospec/` directory; if none is found, treat the current directory as an
|
|
7
|
-
* implicit root (unless the caller forbids it).
|
|
2
|
+
* Root resolution: walk up from the start path to the nearest ancestor holding
|
|
3
|
+
* a `tospec/` directory, else treat the current directory as an implicit root
|
|
4
|
+
* unless the caller forbids it.
|
|
8
5
|
*/
|
|
9
6
|
import * as path from 'node:path';
|
|
10
7
|
import { findRepoPlanningRootSync, getSearchStartDirectory, } from './planning-home.js';
|
|
11
|
-
import { emitFailureStatus } from '../commands/shared-output.js';
|
|
8
|
+
import { emitFailureStatus, recordResolvedRoot } from '../commands/shared-output.js';
|
|
12
9
|
export class RootSelectionError extends Error {
|
|
13
10
|
diagnostic;
|
|
14
11
|
constructor(message, code, options = {}) {
|
|
@@ -68,11 +65,13 @@ export function toPlanningHome(root) {
|
|
|
68
65
|
*/
|
|
69
66
|
export async function resolveRootForCommand(_selector, output = {}) {
|
|
70
67
|
try {
|
|
71
|
-
|
|
68
|
+
const root = await resolveTospecRoot({
|
|
72
69
|
...(output.allowImplicitRoot !== undefined
|
|
73
70
|
? { allowImplicitRoot: output.allowImplicitRoot }
|
|
74
71
|
: {}),
|
|
75
72
|
});
|
|
73
|
+
recordResolvedRoot(toRootOutput(root));
|
|
74
|
+
return root;
|
|
76
75
|
}
|
|
77
76
|
catch (error) {
|
|
78
77
|
if (output.json && isRootSelectionError(error)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root-selection.js","sourceRoot":"","sources":["../../src/core/root-selection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"root-selection.js","sourceRoot":"","sources":["../../src/core/root-selection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface RulesCommandOptions {
|
|
2
|
+
json?: boolean;
|
|
3
|
+
}
|
|
4
|
+
/** The `--json` null-shape; mirrors the success payload with `rules` nulled. */
|
|
5
|
+
export declare const RULES_FAILURE_PAYLOAD: Record<string, unknown>;
|
|
6
|
+
/** Refresh only the workflow rule files of agents already configured for tospec. */
|
|
7
|
+
export declare class RulesCommand {
|
|
8
|
+
execute(targetPath: string, options?: RulesCommandOptions): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/core/rules.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAA+B,CAAC;AAE1F,oFAAoF;AACpF,qBAAa,YAAY;IACjB,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkClF;CACF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { FileSystemUtils } from '../utils/file-system.js';
|
|
3
|
+
import { TOSPEC_DIR_NAME } from './config.js';
|
|
4
|
+
import { getConfiguredTools } from './shared/tool-detection.js';
|
|
5
|
+
import { planWorkflowRules, writeWorkflowRules } from './shared/rules-generation.js';
|
|
6
|
+
import { emitSuccess } from '../commands/shared-output.js';
|
|
7
|
+
/** The `--json` null-shape; mirrors the success payload with `rules` nulled. */
|
|
8
|
+
export const RULES_FAILURE_PAYLOAD = { rules: null, root: null };
|
|
9
|
+
/** Refresh only the workflow rule files of agents already configured for tospec. */
|
|
10
|
+
export class RulesCommand {
|
|
11
|
+
async execute(targetPath, options = {}) {
|
|
12
|
+
const projectPath = path.resolve(targetPath);
|
|
13
|
+
if (!await FileSystemUtils.directoryExists(path.join(projectPath, TOSPEC_DIR_NAME))) {
|
|
14
|
+
throw new Error("No Tospec directory found. Run 'tospec init' first.");
|
|
15
|
+
}
|
|
16
|
+
const tools = getConfiguredTools(projectPath);
|
|
17
|
+
if (tools.length === 0) {
|
|
18
|
+
// Not an error: a project can legitimately have no agent configured. The
|
|
19
|
+
// JSON form says so with an empty list, so a caller need not read English
|
|
20
|
+
// to tell "nothing to do" from "something went wrong".
|
|
21
|
+
if (options.json) {
|
|
22
|
+
emitSuccess({ rules: [], message: 'No configured tools found.' }, { path: projectPath, source: 'explicit' });
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
console.log('No configured tools found. Run "tospec init" to set up tools.');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const plan = await planWorkflowRules(projectPath, tools);
|
|
29
|
+
await writeWorkflowRules(plan, { silent: options.json });
|
|
30
|
+
if (options.json) {
|
|
31
|
+
emitSuccess({
|
|
32
|
+
rules: plan.map((entry) => ({
|
|
33
|
+
tool: entry.toolId,
|
|
34
|
+
rule: entry.rule,
|
|
35
|
+
path: entry.destination,
|
|
36
|
+
action: entry.action,
|
|
37
|
+
...(entry.retire ? { retiredPath: entry.retire } : {}),
|
|
38
|
+
})),
|
|
39
|
+
}, { path: projectPath, source: 'explicit' });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/core/rules.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAM3D,gFAAgF;AAChF,MAAM,CAAC,MAAM,qBAAqB,GAA4B,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAE1F,oFAAoF;AACpF,MAAM,OAAO,YAAY;IACvB,KAAK,CAAC,OAAO,CAAC,UAAkB,EAAE,OAAO,GAAwB,EAAE;QACjE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,eAAe,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC;YACpF,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,KAAK,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,yEAAyE;YACzE,0EAA0E;YAC1E,uDAAuD;YACvD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,4BAA4B,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC7G,OAAO;YACT,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;YAC7E,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACzD,MAAM,kBAAkB,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAEzD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,WAAW,CACT;gBACE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBAC1B,IAAI,EAAE,KAAK,CAAC,MAAM;oBAClB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,IAAI,EAAE,KAAK,CAAC,WAAW;oBACvB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACvD,CAAC,CAAC;aACJ,EACD,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,CAC1C,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|