@seanmars/tospec 0.19.0-beta.7 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -231
- package/README.md +69 -82
- package/assets/dashboard/app.js +14 -3
- package/assets/dashboard/style.css +7 -0
- package/assets/rules/tospec/decision.md +3 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +227 -86
- 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 +366 -107
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/dashboard.d.ts +57 -99
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +224 -282
- 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 +385 -79
- 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 +62 -93
- 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 +29 -7
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/validate.d.ts +43 -45
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +262 -129
- 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 +81 -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 +378 -235
- package/dist/core/archive.js.map +1 -1
- package/dist/core/artifact-graph/graph.d.ts +25 -42
- package/dist/core/artifact-graph/graph.d.ts.map +1 -1
- package/dist/core/artifact-graph/graph.js +45 -63
- 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 +97 -103
- package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.js +146 -119
- package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
- package/dist/core/artifact-graph/outputs.d.ts +9 -23
- package/dist/core/artifact-graph/outputs.d.ts.map +1 -1
- package/dist/core/artifact-graph/outputs.js +45 -38
- 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 +14 -15
- package/dist/core/codex-residue.d.ts.map +1 -1
- package/dist/core/codex-residue.js +18 -22
- package/dist/core/codex-residue.js.map +1 -1
- 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 +39 -26
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +36 -22
- package/dist/core/config.js.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 +25 -19
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +168 -181
- 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 +41 -83
- package/dist/core/local-server.d.ts.map +1 -1
- package/dist/core/local-server.js +53 -98
- 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 +29 -14
- package/dist/core/migrate.d.ts.map +1 -1
- package/dist/core/migrate.js +184 -122
- 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 +142 -70
- 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/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 +9 -17
- 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 +6 -1
- package/dist/core/rules.d.ts.map +1 -1
- package/dist/core/rules.js +23 -2
- package/dist/core/rules.js.map +1 -1
- 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 +19 -8
- package/dist/core/shared/rules-generation.d.ts.map +1 -1
- package/dist/core/shared/rules-generation.js +117 -50
- package/dist/core/shared/rules-generation.js.map +1 -1
- package/dist/core/shared/skill-generation.d.ts +28 -43
- 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 +39 -61
- 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.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/validate.d.ts +13 -0
- package/dist/core/templates/fragments/validate.d.ts.map +1 -0
- package/dist/core/templates/fragments/validate.js +13 -0
- package/dist/core/templates/fragments/validate.js.map +1 -0
- 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 +11 -13
- 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 +19 -6
- 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 -2
- 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 +2 -2
- 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 +4 -3
- 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 +9 -2
- package/dist/core/templates/workflows/update.js.map +1 -1
- package/dist/core/update.d.ts +23 -23
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +139 -118
- 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 +4 -10
- 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 +43 -63
- package/dist/core/validation/validator.d.ts.map +1 -1
- package/dist/core/validation/validator.js +500 -267
- 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 +30 -54
- package/dist/utils/change-utils.d.ts.map +1 -1
- package/dist/utils/change-utils.js +133 -91
- 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 +9 -18
- package/dist/utils/link.d.ts.map +1 -1
- package/dist/utils/link.js +9 -18
- package/dist/utils/link.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 +7 -20
- package/dist/utils/spec-files.d.ts.map +1 -1
- package/dist/utils/spec-files.js +26 -51
- 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 +2 -3
- package/schemas/decision/templates/decision.md +3 -1
- package/schemas/decision/templates/index.md +2 -2
- package/schemas/issue/schema.yaml +8 -1
- package/schemas/issue/templates/spec.md +27 -2
- package/schemas/sdd/schema.yaml +20 -1
- package/schemas/sdd/templates/spec.md +27 -2
- /package/assets/rules/tospec/{single-sourc-of-truth.md → single-source-of-truth.md} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"change-metadata.js","sourceRoot":"","sources":["../../src/utils/change-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"change-metadata.js","sourceRoot":"","sources":["../../src/utils/change-metadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,79 +1,55 @@
|
|
|
1
1
|
import type { ChangeMetadata } from '../core/change-metadata/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Options for creating a change.
|
|
4
|
-
*/
|
|
5
2
|
export interface CreateChangeOptions {
|
|
6
|
-
/** The workflow schema to use (default: 'sdd') */
|
|
7
3
|
schema?: string;
|
|
8
|
-
/**
|
|
4
|
+
/** Used when there is no explicit schema and no project config. */
|
|
9
5
|
defaultSchema?: string;
|
|
10
|
-
/** Directory
|
|
6
|
+
/** Directory holding the change directories. */
|
|
11
7
|
changesDir?: string;
|
|
12
|
-
/** Additional metadata to persist in the change's .tospec.yaml */
|
|
13
8
|
metadata?: Partial<Pick<ChangeMetadata, 'goal' | 'decisions'>>;
|
|
14
|
-
/**
|
|
9
|
+
/** Fills the ticket stub's `## Summary`; absent leaves the placeholder. */
|
|
15
10
|
description?: string;
|
|
16
11
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Result of creating a change.
|
|
19
|
-
*/
|
|
20
12
|
export interface CreateChangeResult {
|
|
21
|
-
/**
|
|
13
|
+
/** Resolved from options, config, or default. */
|
|
22
14
|
schema: string;
|
|
23
|
-
/** Absolute path to the created change directory */
|
|
24
15
|
changeDir: string;
|
|
16
|
+
/** Absent for a schema that ships no `ticket.md`, and so uses no index. */
|
|
17
|
+
ticketPath?: string;
|
|
18
|
+
/** `--description` dropped: the reused ticket already had a written Summary. */
|
|
19
|
+
ticketSummaryKept?: boolean;
|
|
20
|
+
/** `--description` dropped: the schema ships no `ticket.md` to carry it. */
|
|
21
|
+
ticketsUnsupported?: boolean;
|
|
25
22
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Result of validating a change name.
|
|
28
|
-
*/
|
|
29
23
|
export interface ValidationResult {
|
|
30
24
|
valid: boolean;
|
|
31
25
|
error?: string;
|
|
32
26
|
}
|
|
33
27
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* @param name - The kebab-case identifier to validate
|
|
47
|
-
* @param noun - The user-facing name for the identifier in validation errors
|
|
48
|
-
* @returns Validation result with `valid: true` or `valid: false` with an error message
|
|
28
|
+
* Deliberately generous: a kebab-case summary runs well under this, so the limit
|
|
29
|
+
* only catches input that was never a name.
|
|
30
|
+
*/
|
|
31
|
+
export declare const MAX_CHANGE_NAME_LENGTH = 100;
|
|
32
|
+
/**
|
|
33
|
+
* The one directory under `tospec/changes/` that is not a change. Named once so
|
|
34
|
+
* what `completeRootStructure` creates and what `createChange` refuses agree.
|
|
35
|
+
*/
|
|
36
|
+
export declare const ARCHIVE_DIR_NAME = "archive";
|
|
37
|
+
/**
|
|
38
|
+
* The shared kebab-id grammar. A leading digit is allowed so orderings like
|
|
39
|
+
* `100-add-feature` work.
|
|
49
40
|
*
|
|
50
|
-
* @
|
|
51
|
-
* validateChangeName('add-auth') // { valid: true }
|
|
52
|
-
* validateChangeName('100-add-feature') // { valid: true }
|
|
53
|
-
* validateChangeName('Add-Auth') // { valid: false, error: '...' }
|
|
41
|
+
* @param noun User-facing name for the identifier in validation errors.
|
|
54
42
|
*/
|
|
55
43
|
export declare function validateChangeName(name: string, noun?: string): ValidationResult;
|
|
56
44
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* @param projectRoot - The root directory of the project (where `tospec/` lives)
|
|
60
|
-
* @param name - The change name (must be valid kebab-case)
|
|
61
|
-
* @param options - Optional settings for the change
|
|
62
|
-
* @throws Error if the change name is invalid
|
|
63
|
-
* @throws Error if the schema name is invalid
|
|
64
|
-
* @throws Error if the change directory already exists
|
|
65
|
-
*
|
|
66
|
-
* @returns Result containing the resolved schema name
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* // Creates tospec/changes/add-auth/ with default schema
|
|
70
|
-
* const result = await createChange('/path/to/project', 'add-auth')
|
|
71
|
-
* console.log(result.schema) // 'sdd' or value from config
|
|
45
|
+
* Bring a tospec root up to the full layout every command expects.
|
|
72
46
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
47
|
+
* A command that creates only the subdirectory it needs leaves a half-root that
|
|
48
|
+
* still resolves as a project, so `validate --all` answers "0 items, all fine"
|
|
49
|
+
* about somewhere that was never one. Shared because `new change` and
|
|
50
|
+
* `decision new` can each be the command that creates the root.
|
|
77
51
|
*/
|
|
52
|
+
export declare function completeRootStructure(projectRoot: string, defaultSchema: string): Promise<void>;
|
|
53
|
+
/** Creates `tospec/changes/<name>/` with its metadata file and ticket stub. */
|
|
78
54
|
export declare function createChange(projectRoot: string, name: string, options?: CreateChangeOptions): Promise<CreateChangeResult>;
|
|
79
55
|
//# sourceMappingURL=change-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"change-utils.d.ts","sourceRoot":"","sources":["../../src/utils/change-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"change-utils.d.ts","sourceRoot":"","sources":["../../src/utils/change-utils.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAYvE,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC;IAC/D,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAgB,GAAG,gBAAgB,CA2CvF;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASrG;AAED,+EAA+E;AAC/E,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAyE7B"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import { promises as fsPromises } from 'fs';
|
|
2
3
|
import { FileSystemUtils } from './file-system.js';
|
|
3
4
|
import { formatTimestamp, formatLocalDate } from './timestamp.js';
|
|
4
5
|
import { writeChangeMetadata, validateSchemaName } from './change-metadata.js';
|
|
5
6
|
import { readProjectConfig, resolveConfigFileInDir } from '../core/project-config.js';
|
|
6
7
|
import { isKebabId } from '../core/id.js';
|
|
7
8
|
import { resolveSchema, loadTemplate } from '../core/artifact-graph/index.js';
|
|
9
|
+
import { findTicketPath } from './item-discovery.js';
|
|
10
|
+
import { stripBom } from '../core/parsers/requirement-text.js';
|
|
8
11
|
const DEFAULT_SCHEMA = 'sdd';
|
|
9
12
|
// sdd → requirement, issue → issue; custom schemas leave type unset.
|
|
10
13
|
const SCHEMA_TO_CHANGE_TYPE = {
|
|
@@ -12,33 +15,26 @@ const SCHEMA_TO_CHANGE_TYPE = {
|
|
|
12
15
|
issue: 'issue',
|
|
13
16
|
};
|
|
14
17
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* @param name - The kebab-case identifier to validate
|
|
28
|
-
* @param noun - The user-facing name for the identifier in validation errors
|
|
29
|
-
* @returns Validation result with `valid: true` or `valid: false` with an error message
|
|
18
|
+
* Deliberately generous: a kebab-case summary runs well under this, so the limit
|
|
19
|
+
* only catches input that was never a name.
|
|
20
|
+
*/
|
|
21
|
+
export const MAX_CHANGE_NAME_LENGTH = 100;
|
|
22
|
+
/**
|
|
23
|
+
* The one directory under `tospec/changes/` that is not a change. Named once so
|
|
24
|
+
* what `completeRootStructure` creates and what `createChange` refuses agree.
|
|
25
|
+
*/
|
|
26
|
+
export const ARCHIVE_DIR_NAME = 'archive';
|
|
27
|
+
/**
|
|
28
|
+
* The shared kebab-id grammar. A leading digit is allowed so orderings like
|
|
29
|
+
* `100-add-feature` work.
|
|
30
30
|
*
|
|
31
|
-
* @
|
|
32
|
-
* validateChangeName('add-auth') // { valid: true }
|
|
33
|
-
* validateChangeName('100-add-feature') // { valid: true }
|
|
34
|
-
* validateChangeName('Add-Auth') // { valid: false, error: '...' }
|
|
31
|
+
* @param noun User-facing name for the identifier in validation errors.
|
|
35
32
|
*/
|
|
36
33
|
export function validateChangeName(name, noun = 'Change name') {
|
|
37
34
|
if (!name) {
|
|
38
35
|
return { valid: false, error: `${noun} cannot be empty` };
|
|
39
36
|
}
|
|
40
37
|
if (!isKebabId(name)) {
|
|
41
|
-
// Provide specific error messages for common mistakes
|
|
42
38
|
if (/[A-Z]/.test(name)) {
|
|
43
39
|
return { valid: false, error: `${noun} must be lowercase (use kebab-case)` };
|
|
44
40
|
}
|
|
@@ -62,96 +58,108 @@ export function validateChangeName(name, noun = 'Change name') {
|
|
|
62
58
|
}
|
|
63
59
|
return { valid: false, error: `${noun} must follow kebab-case convention (e.g., add-auth, refactor-db)` };
|
|
64
60
|
}
|
|
61
|
+
// Checked last so a malformed name still gets the specific message above.
|
|
62
|
+
// Without a cap, an over-long name overflows the platform path limit (archive
|
|
63
|
+
// adds `<yyyyMMdd_HHmmss>-`) as a raw ENOENT. No cap can guarantee the write
|
|
64
|
+
// succeeds, so this is a legibility bound.
|
|
65
|
+
if (name.length > MAX_CHANGE_NAME_LENGTH) {
|
|
66
|
+
return {
|
|
67
|
+
valid: false,
|
|
68
|
+
error: `${noun} is ${name.length} characters; the maximum is ${MAX_CHANGE_NAME_LENGTH}`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
65
71
|
return { valid: true };
|
|
66
72
|
}
|
|
67
73
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* @param projectRoot - The root directory of the project (where `tospec/` lives)
|
|
71
|
-
* @param name - The change name (must be valid kebab-case)
|
|
72
|
-
* @param options - Optional settings for the change
|
|
73
|
-
* @throws Error if the change name is invalid
|
|
74
|
-
* @throws Error if the schema name is invalid
|
|
75
|
-
* @throws Error if the change directory already exists
|
|
76
|
-
*
|
|
77
|
-
* @returns Result containing the resolved schema name
|
|
74
|
+
* Bring a tospec root up to the full layout every command expects.
|
|
78
75
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* @example
|
|
85
|
-
* // Creates tospec/changes/add-auth/ with custom schema
|
|
86
|
-
* const result = await createChange('/path/to/project', 'add-auth', { schema: 'my-workflow' })
|
|
87
|
-
* console.log(result.schema) // 'my-workflow'
|
|
76
|
+
* A command that creates only the subdirectory it needs leaves a half-root that
|
|
77
|
+
* still resolves as a project, so `validate --all` answers "0 items, all fine"
|
|
78
|
+
* about somewhere that was never one. Shared because `new change` and
|
|
79
|
+
* `decision new` can each be the command that creates the root.
|
|
88
80
|
*/
|
|
81
|
+
export async function completeRootStructure(projectRoot, defaultSchema) {
|
|
82
|
+
const tospecDir = path.join(projectRoot, 'tospec');
|
|
83
|
+
await FileSystemUtils.createDirectory(path.join(tospecDir, 'specs'));
|
|
84
|
+
await FileSystemUtils.createDirectory(path.join(tospecDir, 'changes', ARCHIVE_DIR_NAME));
|
|
85
|
+
// The config records the project default schema, never a one-off override,
|
|
86
|
+
// and is written only when none exists.
|
|
87
|
+
if (!resolveConfigFileInDir(tospecDir)) {
|
|
88
|
+
await FileSystemUtils.writeFile(path.join(tospecDir, 'config.yaml'), `schema: ${defaultSchema}\n`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** Creates `tospec/changes/<name>/` with its metadata file and ticket stub. */
|
|
89
92
|
export async function createChange(projectRoot, name, options = {}) {
|
|
90
|
-
// Validate the name first
|
|
91
93
|
const validation = validateChangeName(name);
|
|
92
94
|
if (!validation.valid) {
|
|
93
95
|
throw new Error(validation.error);
|
|
94
96
|
}
|
|
95
97
|
const defaultSchema = options.defaultSchema ?? DEFAULT_SCHEMA;
|
|
96
|
-
//
|
|
98
|
+
// Schema: explicit option → project config → supplied default.
|
|
97
99
|
let schemaName;
|
|
98
100
|
if (options.schema) {
|
|
99
101
|
schemaName = options.schema;
|
|
100
102
|
}
|
|
101
103
|
else {
|
|
102
|
-
// Try to read from project config
|
|
103
104
|
try {
|
|
104
105
|
const config = readProjectConfig(projectRoot);
|
|
105
106
|
schemaName = config?.schema ?? defaultSchema;
|
|
106
107
|
}
|
|
107
108
|
catch {
|
|
108
|
-
// If config read fails, use default
|
|
109
109
|
schemaName = defaultSchema;
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
// Validate the resolved schema
|
|
113
112
|
validateSchemaName(schemaName, projectRoot);
|
|
114
|
-
// Build the change directory path
|
|
115
113
|
const changeDir = path.join(options.changesDir ?? path.join(projectRoot, 'tospec', 'changes'), name);
|
|
116
|
-
//
|
|
114
|
+
// Before the existence test below, which would otherwise answer "Change
|
|
115
|
+
// 'archive' already exists" and send the reader to delete every archived
|
|
116
|
+
// change. Not in validateChangeName: that is shared with decision topics,
|
|
117
|
+
// where the name is fine.
|
|
118
|
+
if (name === ARCHIVE_DIR_NAME) {
|
|
119
|
+
throw new Error(`'${ARCHIVE_DIR_NAME}' is a reserved directory name under tospec/changes/ — it holds every archived change. Pick another change name.`);
|
|
120
|
+
}
|
|
117
121
|
if (await FileSystemUtils.directoryExists(changeDir)) {
|
|
118
122
|
throw new Error(`Change '${name}' already exists at ${changeDir}`);
|
|
119
123
|
}
|
|
120
|
-
// Creating a change may scaffold or complete the root itself (an
|
|
121
|
-
// implicit root, or a config-only/incomplete clone). Never leave a
|
|
122
|
-
// half-root behind that doctor immediately calls unhealthy: ensure
|
|
123
|
-
// specs/ and changes/archive/ exist, and write a config only when
|
|
124
|
-
// none exists. The config records the PROJECT default schema, never
|
|
125
|
-
// a one-change --schema override.
|
|
126
|
-
const tospecDir = path.join(projectRoot, 'tospec');
|
|
127
|
-
// Create the directory (including parent directories if needed)
|
|
128
124
|
await FileSystemUtils.createDirectory(changeDir);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
125
|
+
// Creation is several writes across two trees, and a failure partway leaves a
|
|
126
|
+
// change directory with no ticket that `list` and `status --all` treat as
|
|
127
|
+
// real. Only the change directory is rolled back — the root scaffolding stays
|
|
128
|
+
// valid for every other change.
|
|
129
|
+
try {
|
|
130
|
+
await completeRootStructure(projectRoot, defaultSchema);
|
|
131
|
+
const today = formatLocalDate();
|
|
132
|
+
writeChangeMetadata(changeDir, {
|
|
133
|
+
schema: schemaName,
|
|
134
|
+
type: SCHEMA_TO_CHANGE_TYPE[schemaName],
|
|
135
|
+
created: today,
|
|
136
|
+
...options.metadata,
|
|
137
|
+
}, projectRoot);
|
|
138
|
+
// The stamped filename is CLI-generated and recorded nowhere an agent reads,
|
|
139
|
+
// so the path has to come back or filling in the Summary means globbing for
|
|
140
|
+
// a filename the CLI just chose.
|
|
141
|
+
const ticket = await writeTicketStub(projectRoot, name, schemaName, options.description);
|
|
142
|
+
return {
|
|
143
|
+
schema: schemaName,
|
|
144
|
+
changeDir,
|
|
145
|
+
...(ticket?.path ? { ticketPath: ticket.path } : {}),
|
|
146
|
+
...(ticket?.summaryKept ? { ticketSummaryKept: true } : {}),
|
|
147
|
+
...(ticket?.ticketsUnsupported ? { ticketsUnsupported: true } : {}),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
// Best effort: a failed rollback must not mask the original failure.
|
|
152
|
+
await fsPromises.rm(changeDir, { recursive: true, force: true }).catch(() => { });
|
|
153
|
+
throw error;
|
|
133
154
|
}
|
|
134
|
-
// Write metadata file with schema and creation date
|
|
135
|
-
const today = formatLocalDate();
|
|
136
|
-
writeChangeMetadata(changeDir, {
|
|
137
|
-
schema: schemaName,
|
|
138
|
-
type: SCHEMA_TO_CHANGE_TYPE[schemaName],
|
|
139
|
-
created: today,
|
|
140
|
-
...options.metadata,
|
|
141
|
-
}, projectRoot);
|
|
142
|
-
// Generate the ticket stub. The timestamped filename (and its `date` header)
|
|
143
|
-
// are CLI-generated — agents can't reliably reproduce the timestamp.
|
|
144
|
-
await writeTicketStub(projectRoot, name, schemaName, options.description);
|
|
145
|
-
return { schema: schemaName, changeDir };
|
|
146
155
|
}
|
|
156
|
+
/** `## Summary` followed by the template's `[...]` placeholder. */
|
|
157
|
+
const PLACEHOLDER_SUMMARY = /(##[ \t]*Summary[ \t]*\r?\n)\[[^\]]*\]/;
|
|
147
158
|
/**
|
|
148
|
-
* Writes a
|
|
149
|
-
* index
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* template body. `change:` links the ticket back to its change; `ref` points
|
|
153
|
-
* from tospec/tickets/ at where the change's detail lives (proposal.md or task.md).
|
|
154
|
-
* When `description` is given it replaces the template's `## Summary` placeholder.
|
|
159
|
+
* Writes a stub into the global `tospec/tickets/<yyyyMMdd_HHmmss>-<name>.md`
|
|
160
|
+
* index: a yaml header generated here plus the schema's `ticket.md` body.
|
|
161
|
+
* `change:` links back to the change; `ref` points at where its detail lives. A
|
|
162
|
+
* schema without a `ticket.md` template opts out of the index.
|
|
155
163
|
*/
|
|
156
164
|
async function writeTicketStub(projectRoot, name, schemaName, description) {
|
|
157
165
|
let schema;
|
|
@@ -159,7 +167,7 @@ async function writeTicketStub(projectRoot, name, schemaName, description) {
|
|
|
159
167
|
schema = resolveSchema(schemaName, projectRoot);
|
|
160
168
|
}
|
|
161
169
|
catch {
|
|
162
|
-
return; // schema unresolvable — nothing to scaffold
|
|
170
|
+
return undefined; // schema unresolvable — nothing to scaffold
|
|
163
171
|
}
|
|
164
172
|
// A schema opts into the global ticket index by shipping a ticket.md template.
|
|
165
173
|
let body;
|
|
@@ -167,26 +175,60 @@ async function writeTicketStub(projectRoot, name, schemaName, description) {
|
|
|
167
175
|
body = loadTemplate(schemaName, 'ticket.md', projectRoot);
|
|
168
176
|
}
|
|
169
177
|
catch {
|
|
170
|
-
|
|
178
|
+
// No ticket template, and .tospec.yaml has no field for it, so a
|
|
179
|
+
// `--description` has nowhere to land. Report the drop.
|
|
180
|
+
return description?.trim() ? { ticketsUnsupported: true } : undefined;
|
|
171
181
|
}
|
|
172
|
-
//
|
|
173
|
-
// replacer keeps `$`-sequences in the text literal. No description → the
|
|
174
|
-
// placeholder stays for the workflow agent to edit.
|
|
182
|
+
// A function replacer keeps `$`-sequences in the description literal.
|
|
175
183
|
const summary = description?.trim();
|
|
176
184
|
if (summary) {
|
|
177
|
-
body = body.replace(
|
|
185
|
+
body = body.replace(PLACEHOLDER_SUMMARY, (_m, head) => head + summary);
|
|
186
|
+
}
|
|
187
|
+
// The index holds one active ticket per change. `rm -rf` on a change leaves
|
|
188
|
+
// its ticket behind, and recreating the name would otherwise write a second:
|
|
189
|
+
// archive files under the older, and the newer stays active forever naming a
|
|
190
|
+
// dead path.
|
|
191
|
+
const existing = await findTicketPath(projectRoot, name);
|
|
192
|
+
if (existing) {
|
|
193
|
+
// Filled in only when the Summary is still the placeholder. A written
|
|
194
|
+
// Summary is kept and reported rather than overwritten.
|
|
195
|
+
if (summary) {
|
|
196
|
+
// Stripped before the rewrite: the BOM would otherwise survive into a
|
|
197
|
+
// file tospec is re-emitting, which ships UTF-8 without one.
|
|
198
|
+
const current = await fsPromises
|
|
199
|
+
.readFile(existing, 'utf-8')
|
|
200
|
+
.then(stripBom)
|
|
201
|
+
.catch(() => null);
|
|
202
|
+
if (current !== null && PLACEHOLDER_SUMMARY.test(current)) {
|
|
203
|
+
await FileSystemUtils.writeFile(existing, current.replace(PLACEHOLDER_SUMMARY, (_m, head) => head + summary));
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
return { path: existing, summaryKept: true };
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return { path: existing };
|
|
178
210
|
}
|
|
179
211
|
const stamp = formatTimestamp(new Date());
|
|
180
212
|
const ticketPath = path.join(projectRoot, 'tospec', 'tickets', `${stamp}-${name}.md`);
|
|
181
|
-
//
|
|
182
|
-
//
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
|
|
213
|
+
// Root-relative so it stays stable once the ticket moves to tospec/tickets/archive/.
|
|
214
|
+
//
|
|
215
|
+
// The schema's own first non-glob artifact, not a hardcoded proposal.md /
|
|
216
|
+
// task.md pair: a project-local schema (`<project>/tospec/schemas/`) may name
|
|
217
|
+
// neither, and the pair then pointed the ticket at a task.md that never
|
|
218
|
+
// exists. `tospec archive` rewrites only the path prefix, so that basename
|
|
219
|
+
// survived into tospec/tickets/archive/. A glob artifact is skipped for the
|
|
220
|
+
// same reason findMainArtifact skips it — `specs/*/spec.md` is a set of
|
|
221
|
+
// documents, not the change's narrative.
|
|
222
|
+
const mainArtifact = schema.artifacts.find((a) => !a.generates.includes('*'));
|
|
223
|
+
const ref = `tospec/changes/${name}/${mainArtifact?.generates ?? 'task.md'}`;
|
|
224
|
+
// `date` is quoted so yaml keeps it a string (bare yyyyMMdd_HHmmss parses as
|
|
225
|
+
// an underscore-separated integer under yaml 1.1). `type` is the change type,
|
|
226
|
+
// the same vocabulary as .tospec.yaml and `list --json`; the schema name has
|
|
227
|
+
// its own key so neither means two things.
|
|
228
|
+
const changeType = SCHEMA_TO_CHANGE_TYPE[schemaName] ?? schemaName;
|
|
229
|
+
const header = `---\ntitle: ${name}\ndate: "${stamp}"\ntype: ${changeType}\nschema: ${schemaName}\nchange: ${name}\nref: ${ref}\n---\n\n`;
|
|
189
230
|
await FileSystemUtils.createDirectory(path.join(projectRoot, 'tospec', 'tickets'));
|
|
190
231
|
await FileSystemUtils.writeFile(ticketPath, header + body);
|
|
232
|
+
return { path: ticketPath };
|
|
191
233
|
}
|
|
192
234
|
//# sourceMappingURL=change-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"change-utils.js","sourceRoot":"","sources":["../../src/utils/change-utils.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"change-utils.js","sourceRoot":"","sources":["../../src/utils/change-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A cross-process advisory lock for read-compute-write sequences.
|
|
3
|
+
*
|
|
4
|
+
* `tospec archive` is one: it reads every target spec, merges in memory, then
|
|
5
|
+
* writes. Two overlapping archives both read the pre-merge text, so the second
|
|
6
|
+
* write erases the first one's requirement while both report success — measured
|
|
7
|
+
* at roughly one in five overlapping pairs.
|
|
8
|
+
*
|
|
9
|
+
* Advisory, not mandatory: it stops two of *our* merges from interleaving, not
|
|
10
|
+
* arbitrary writers.
|
|
11
|
+
*/
|
|
12
|
+
/** What a held lock records, so a stale one can be told from a live one. */
|
|
13
|
+
interface LockRecord {
|
|
14
|
+
pid: number;
|
|
15
|
+
host: string;
|
|
16
|
+
startedAt: string;
|
|
17
|
+
/** Human-readable note about what holds it, echoed in the timeout message. */
|
|
18
|
+
operation: string;
|
|
19
|
+
}
|
|
20
|
+
export interface LockOptions {
|
|
21
|
+
/** How long to keep retrying before giving up. */
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
/** A lock older than this is presumed abandoned and taken over. */
|
|
24
|
+
staleMs?: number;
|
|
25
|
+
/** Named in the error a waiter eventually gets. */
|
|
26
|
+
operation?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare class LockTimeoutError extends Error {
|
|
29
|
+
readonly holder: LockRecord | null;
|
|
30
|
+
constructor(message: string, holder: LockRecord | null);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Runs `fn` while holding an exclusive lock at `lockPath`. Released in a
|
|
34
|
+
* `finally`, so a throwing `fn` leaves nothing behind; a killed process is
|
|
35
|
+
* covered by the staleness rules above.
|
|
36
|
+
*/
|
|
37
|
+
export declare function withFileLock<T>(lockPath: string, fn: () => Promise<T>, options?: LockOptions): Promise<T>;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=file-lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-lock.d.ts","sourceRoot":"","sources":["../../src/utils/file-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,4EAA4E;AAC5E,UAAU,UAAU;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwBD,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAFpC,YACE,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,UAAU,GAAG,IAAI,EAInC;CACF;AAsCD;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,CAAC,CAAC,CAiEZ"}
|