@seanmars/tospec 0.24.0 → 0.26.0-beta
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 +241 -0
- package/README.md +10 -6
- package/assets/dashboard/lib/derive.js +11 -5
- package/assets/dashboard/lib/store.js +4 -2
- package/assets/dashboard/views/change.js +5 -3
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +42 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +213 -100
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/dashboard.d.ts +9 -0
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +77 -21
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/decision.d.ts +38 -1
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +303 -27
- package/dist/commands/decision.js.map +1 -1
- package/dist/commands/metrics.d.ts +3 -4
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +3 -5
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/shared-output.d.ts +24 -0
- package/dist/commands/shared-output.d.ts.map +1 -1
- package/dist/commands/shared-output.js +21 -2
- package/dist/commands/shared-output.js.map +1 -1
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +12 -9
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/validate.d.ts +19 -0
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +243 -64
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/workflow/instructions.d.ts +7 -1
- package/dist/commands/workflow/instructions.d.ts.map +1 -1
- package/dist/commands/workflow/instructions.js +299 -81
- package/dist/commands/workflow/instructions.js.map +1 -1
- package/dist/commands/workflow/new-change.d.ts.map +1 -1
- package/dist/commands/workflow/new-change.js +26 -17
- package/dist/commands/workflow/new-change.js.map +1 -1
- package/dist/commands/workflow/prompt-escape.d.ts +25 -0
- package/dist/commands/workflow/prompt-escape.d.ts.map +1 -0
- package/dist/commands/workflow/prompt-escape.js +62 -0
- package/dist/commands/workflow/prompt-escape.js.map +1 -0
- package/dist/commands/workflow/schemas.d.ts.map +1 -1
- package/dist/commands/workflow/schemas.js +34 -16
- package/dist/commands/workflow/schemas.js.map +1 -1
- package/dist/commands/workflow/shared.d.ts +46 -10
- package/dist/commands/workflow/shared.d.ts.map +1 -1
- package/dist/commands/workflow/shared.js +66 -30
- package/dist/commands/workflow/shared.js.map +1 -1
- package/dist/commands/workflow/status.d.ts +5 -2
- package/dist/commands/workflow/status.d.ts.map +1 -1
- package/dist/commands/workflow/status.js +62 -28
- package/dist/commands/workflow/status.js.map +1 -1
- package/dist/core/archive.d.ts +38 -0
- package/dist/core/archive.d.ts.map +1 -1
- package/dist/core/archive.js +492 -75
- package/dist/core/archive.js.map +1 -1
- package/dist/core/artifact-graph/index.d.ts +2 -2
- package/dist/core/artifact-graph/index.d.ts.map +1 -1
- package/dist/core/artifact-graph/index.js +2 -2
- package/dist/core/artifact-graph/index.js.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.d.ts +8 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.js +58 -36
- package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
- package/dist/core/artifact-graph/resolver.d.ts +39 -12
- package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
- package/dist/core/artifact-graph/resolver.js +82 -36
- package/dist/core/artifact-graph/resolver.js.map +1 -1
- package/dist/core/artifact-graph/schema.d.ts +24 -0
- package/dist/core/artifact-graph/schema.d.ts.map +1 -1
- package/dist/core/artifact-graph/schema.js +32 -1
- package/dist/core/artifact-graph/schema.js.map +1 -1
- package/dist/core/artifact-graph/stub-detection.d.ts +10 -2
- package/dist/core/artifact-graph/stub-detection.d.ts.map +1 -1
- package/dist/core/artifact-graph/stub-detection.js +18 -11
- package/dist/core/artifact-graph/stub-detection.js.map +1 -1
- package/dist/core/artifact-graph/types.d.ts +2 -2
- package/dist/core/artifact-graph/types.d.ts.map +1 -1
- package/dist/core/artifact-graph/types.js +10 -1
- package/dist/core/artifact-graph/types.js.map +1 -1
- package/dist/core/change-metadata/schema.d.ts.map +1 -1
- package/dist/core/change-metadata/schema.js +18 -4
- package/dist/core/change-metadata/schema.js.map +1 -1
- package/dist/core/change-presenter.d.ts.map +1 -1
- package/dist/core/change-presenter.js +13 -8
- package/dist/core/change-presenter.js.map +1 -1
- package/dist/core/change-status-policy.d.ts.map +1 -1
- package/dist/core/change-status-policy.js +3 -1
- package/dist/core/change-status-policy.js.map +1 -1
- package/dist/core/codex-metrics.d.ts +1 -1
- package/dist/core/codex-metrics.js +1 -1
- package/dist/core/config-schema.d.ts +8 -0
- package/dist/core/config-schema.d.ts.map +1 -1
- package/dist/core/config-schema.js +10 -0
- package/dist/core/config-schema.js.map +1 -1
- package/dist/core/dashboard-activity.d.ts +4 -4
- package/dist/core/dashboard-activity.js +4 -4
- package/dist/core/dashboard-data.d.ts +11 -5
- package/dist/core/dashboard-data.d.ts.map +1 -1
- package/dist/core/dashboard-data.js +54 -28
- package/dist/core/dashboard-data.js.map +1 -1
- package/dist/core/dashboard-hub.d.ts +3 -3
- package/dist/core/dashboard-hub.d.ts.map +1 -1
- package/dist/core/dashboard-hub.js +16 -4
- package/dist/core/dashboard-hub.js.map +1 -1
- package/dist/core/dashboard-routes.d.ts +2 -1
- package/dist/core/dashboard-routes.d.ts.map +1 -1
- package/dist/core/dashboard-routes.js +102 -33
- package/dist/core/dashboard-routes.js.map +1 -1
- package/dist/core/global-config.d.ts +71 -2
- package/dist/core/global-config.d.ts.map +1 -1
- package/dist/core/global-config.js +149 -4
- package/dist/core/global-config.js.map +1 -1
- package/dist/core/id.d.ts +9 -0
- package/dist/core/id.d.ts.map +1 -1
- package/dist/core/id.js +37 -0
- package/dist/core/id.js.map +1 -1
- package/dist/core/init.d.ts +9 -2
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +116 -33
- package/dist/core/init.js.map +1 -1
- package/dist/core/list.d.ts.map +1 -1
- package/dist/core/list.js +69 -45
- package/dist/core/list.js.map +1 -1
- package/dist/core/local-server.d.ts +9 -2
- package/dist/core/local-server.d.ts.map +1 -1
- package/dist/core/local-server.js +24 -4
- package/dist/core/local-server.js.map +1 -1
- package/dist/core/markdown-render.d.ts.map +1 -1
- package/dist/core/markdown-render.js +7 -2
- package/dist/core/markdown-render.js.map +1 -1
- package/dist/core/migrate.d.ts +24 -2
- package/dist/core/migrate.d.ts.map +1 -1
- package/dist/core/migrate.js +335 -59
- package/dist/core/migrate.js.map +1 -1
- package/dist/core/parsers/change-parser.d.ts +20 -1
- package/dist/core/parsers/change-parser.d.ts.map +1 -1
- package/dist/core/parsers/change-parser.js +76 -73
- package/dist/core/parsers/change-parser.js.map +1 -1
- package/dist/core/parsers/markdown-parser.d.ts +24 -0
- package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
- package/dist/core/parsers/markdown-parser.js +65 -10
- package/dist/core/parsers/markdown-parser.js.map +1 -1
- package/dist/core/parsers/requirement-blocks.d.ts +127 -6
- package/dist/core/parsers/requirement-blocks.d.ts.map +1 -1
- package/dist/core/parsers/requirement-blocks.js +349 -56
- package/dist/core/parsers/requirement-blocks.js.map +1 -1
- package/dist/core/parsers/requirement-text.d.ts +25 -1
- package/dist/core/parsers/requirement-text.d.ts.map +1 -1
- package/dist/core/parsers/requirement-text.js +62 -6
- 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 +36 -24
- package/dist/core/parsers/spec-structure.js.map +1 -1
- package/dist/core/project-config.d.ts +9 -2
- package/dist/core/project-config.d.ts.map +1 -1
- package/dist/core/project-config.js +30 -7
- package/dist/core/project-config.js.map +1 -1
- package/dist/core/project-layout.d.ts +26 -0
- package/dist/core/project-layout.d.ts.map +1 -1
- package/dist/core/project-layout.js +51 -1
- package/dist/core/project-layout.js.map +1 -1
- package/dist/core/schema-names.d.ts +17 -0
- package/dist/core/schema-names.d.ts.map +1 -1
- package/dist/core/schema-names.js +24 -0
- package/dist/core/schema-names.js.map +1 -1
- package/dist/core/shared/index.d.ts +1 -1
- package/dist/core/shared/index.d.ts.map +1 -1
- package/dist/core/shared/index.js +1 -1
- package/dist/core/shared/index.js.map +1 -1
- package/dist/core/shared/rules-generation.d.ts +12 -0
- package/dist/core/shared/rules-generation.d.ts.map +1 -1
- package/dist/core/shared/rules-generation.js +26 -2
- package/dist/core/shared/rules-generation.js.map +1 -1
- package/dist/core/shared/skill-generation.d.ts +7 -0
- package/dist/core/shared/skill-generation.d.ts.map +1 -1
- package/dist/core/shared/skill-generation.js +19 -0
- package/dist/core/shared/skill-generation.js.map +1 -1
- package/dist/core/shared/tool-detection.d.ts +10 -1
- package/dist/core/shared/tool-detection.d.ts.map +1 -1
- package/dist/core/shared/tool-detection.js +37 -6
- package/dist/core/shared/tool-detection.js.map +1 -1
- package/dist/core/spec-presenter.d.ts.map +1 -1
- package/dist/core/spec-presenter.js +23 -1
- package/dist/core/spec-presenter.js.map +1 -1
- package/dist/core/specs-apply.d.ts +98 -1
- package/dist/core/specs-apply.d.ts.map +1 -1
- package/dist/core/specs-apply.js +426 -63
- package/dist/core/specs-apply.js.map +1 -1
- package/dist/core/templates/fragments/change-diff.d.ts +37 -0
- package/dist/core/templates/fragments/change-diff.d.ts.map +1 -0
- package/dist/core/templates/fragments/change-diff.js +37 -0
- package/dist/core/templates/fragments/change-diff.js.map +1 -0
- package/dist/core/templates/fragments/sync-fail.d.ts +8 -0
- package/dist/core/templates/fragments/sync-fail.d.ts.map +1 -0
- package/dist/core/templates/fragments/sync-fail.js +8 -0
- package/dist/core/templates/fragments/sync-fail.js.map +1 -0
- package/dist/core/templates/fragments/validate.d.ts +14 -1
- package/dist/core/templates/fragments/validate.d.ts.map +1 -1
- package/dist/core/templates/fragments/validate.js +14 -1
- package/dist/core/templates/fragments/validate.js.map +1 -1
- package/dist/core/templates/fragments/verify.d.ts +2 -2
- package/dist/core/templates/fragments/verify.d.ts.map +1 -1
- package/dist/core/templates/fragments/verify.js +8 -5
- package/dist/core/templates/fragments/verify.js.map +1 -1
- package/dist/core/templates/workflows/apply.d.ts +1 -1
- package/dist/core/templates/workflows/apply.d.ts.map +1 -1
- package/dist/core/templates/workflows/apply.js +29 -10
- package/dist/core/templates/workflows/apply.js.map +1 -1
- package/dist/core/templates/workflows/archive.d.ts.map +1 -1
- package/dist/core/templates/workflows/archive.js +27 -9
- package/dist/core/templates/workflows/archive.js.map +1 -1
- package/dist/core/templates/workflows/decision.d.ts.map +1 -1
- package/dist/core/templates/workflows/decision.js +10 -4
- package/dist/core/templates/workflows/decision.js.map +1 -1
- package/dist/core/templates/workflows/explore.d.ts +2 -2
- package/dist/core/templates/workflows/explore.d.ts.map +1 -1
- package/dist/core/templates/workflows/explore.js +7 -3
- package/dist/core/templates/workflows/explore.js.map +1 -1
- package/dist/core/templates/workflows/grill.d.ts +2 -2
- package/dist/core/templates/workflows/grill.d.ts.map +1 -1
- package/dist/core/templates/workflows/grill.js +5 -4
- package/dist/core/templates/workflows/grill.js.map +1 -1
- package/dist/core/templates/workflows/issue.d.ts.map +1 -1
- package/dist/core/templates/workflows/issue.js +9 -3
- package/dist/core/templates/workflows/issue.js.map +1 -1
- package/dist/core/templates/workflows/propose.d.ts.map +1 -1
- package/dist/core/templates/workflows/propose.js +4 -1
- package/dist/core/templates/workflows/propose.js.map +1 -1
- package/dist/core/templates/workflows/sync.d.ts.map +1 -1
- package/dist/core/templates/workflows/sync.js +25 -11
- package/dist/core/templates/workflows/sync.js.map +1 -1
- package/dist/core/templates/workflows/update.d.ts.map +1 -1
- package/dist/core/templates/workflows/update.js +17 -10
- package/dist/core/templates/workflows/update.js.map +1 -1
- package/dist/core/update.d.ts +5 -0
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +66 -29
- package/dist/core/update.js.map +1 -1
- package/dist/core/validation/constants.d.ts +7 -1
- package/dist/core/validation/constants.d.ts.map +1 -1
- package/dist/core/validation/constants.js +16 -2
- package/dist/core/validation/constants.js.map +1 -1
- package/dist/core/validation/purpose-placeholder.d.ts.map +1 -1
- package/dist/core/validation/purpose-placeholder.js +35 -11
- package/dist/core/validation/purpose-placeholder.js.map +1 -1
- package/dist/core/validation/section-validator.d.ts +7 -0
- package/dist/core/validation/section-validator.d.ts.map +1 -1
- package/dist/core/validation/section-validator.js +22 -2
- package/dist/core/validation/section-validator.js.map +1 -1
- package/dist/core/validation/sister-changes.d.ts +93 -0
- package/dist/core/validation/sister-changes.d.ts.map +1 -0
- package/dist/core/validation/sister-changes.js +180 -0
- package/dist/core/validation/sister-changes.js.map +1 -0
- package/dist/core/validation/task-markers.d.ts +9 -0
- package/dist/core/validation/task-markers.d.ts.map +1 -0
- package/dist/core/validation/task-markers.js +71 -0
- package/dist/core/validation/task-markers.js.map +1 -0
- package/dist/core/validation/types.d.ts +58 -0
- package/dist/core/validation/types.d.ts.map +1 -1
- package/dist/core/validation/types.js +22 -0
- package/dist/core/validation/types.js.map +1 -1
- package/dist/core/validation/validator.d.ts +79 -2
- package/dist/core/validation/validator.d.ts.map +1 -1
- package/dist/core/validation/validator.js +565 -84
- package/dist/core/validation/validator.js.map +1 -1
- package/dist/utils/change-metadata.d.ts +62 -5
- package/dist/utils/change-metadata.d.ts.map +1 -1
- package/dist/utils/change-metadata.js +193 -31
- package/dist/utils/change-metadata.js.map +1 -1
- package/dist/utils/change-utils.d.ts +21 -0
- package/dist/utils/change-utils.d.ts.map +1 -1
- package/dist/utils/change-utils.js +168 -53
- package/dist/utils/change-utils.js.map +1 -1
- package/dist/utils/command-line.d.ts +11 -0
- package/dist/utils/command-line.d.ts.map +1 -0
- package/dist/utils/command-line.js +43 -0
- package/dist/utils/command-line.js.map +1 -0
- package/dist/utils/display-width.d.ts +10 -0
- package/dist/utils/display-width.d.ts.map +1 -0
- package/dist/utils/display-width.js +15 -0
- package/dist/utils/display-width.js.map +1 -0
- package/dist/utils/file-system.d.ts +16 -0
- package/dist/utils/file-system.d.ts.map +1 -1
- package/dist/utils/file-system.js +49 -2
- package/dist/utils/file-system.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +11 -5
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/interactive.d.ts.map +1 -1
- package/dist/utils/interactive.js +3 -1
- package/dist/utils/interactive.js.map +1 -1
- package/dist/utils/item-discovery.d.ts +3 -2
- package/dist/utils/item-discovery.d.ts.map +1 -1
- package/dist/utils/item-discovery.js +34 -16
- package/dist/utils/item-discovery.js.map +1 -1
- package/dist/utils/link.d.ts +0 -1
- package/dist/utils/link.d.ts.map +1 -1
- package/dist/utils/link.js +0 -1
- package/dist/utils/link.js.map +1 -1
- package/dist/utils/match.d.ts.map +1 -1
- package/dist/utils/match.js +10 -1
- package/dist/utils/match.js.map +1 -1
- package/dist/utils/option-flags.d.ts +9 -0
- package/dist/utils/option-flags.d.ts.map +1 -0
- package/dist/utils/option-flags.js +12 -0
- package/dist/utils/option-flags.js.map +1 -0
- package/dist/utils/sentence.d.ts +9 -0
- package/dist/utils/sentence.d.ts.map +1 -0
- package/dist/utils/sentence.js +12 -0
- package/dist/utils/sentence.js.map +1 -0
- package/dist/utils/spec-files.d.ts +84 -1
- package/dist/utils/spec-files.d.ts.map +1 -1
- package/dist/utils/spec-files.js +192 -3
- package/dist/utils/spec-files.js.map +1 -1
- package/dist/utils/task-progress.d.ts.map +1 -1
- package/dist/utils/task-progress.js +32 -9
- package/dist/utils/task-progress.js.map +1 -1
- package/dist/utils/timestamp.d.ts +27 -0
- package/dist/utils/timestamp.d.ts.map +1 -1
- package/dist/utils/timestamp.js +37 -0
- package/dist/utils/timestamp.js.map +1 -1
- package/package.json +4 -1
- package/schemas/decision/templates/decision.md +2 -2
- package/schemas/issue/schema.yaml +12 -6
- package/schemas/issue/templates/task.md +1 -1
- package/schemas/sdd/schema.yaml +21 -10
- package/schemas/sdd/templates/proposal.md +1 -1
|
@@ -15,12 +15,26 @@
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function normalizeDocument(content: string): string;
|
|
17
17
|
/**
|
|
18
|
-
* Strip a leading UTF-8 BOM, leaving line endings untouched
|
|
18
|
+
* Strip a leading UTF-8 BOM, leaving line endings untouched — for readers that
|
|
19
19
|
* write the file back and so must preserve its endings, which rules out
|
|
20
20
|
* `normalizeDocument`. Writing the stripped text back is deliberate: every
|
|
21
21
|
* document tospec produces is UTF-8 *without* a BOM.
|
|
22
22
|
*/
|
|
23
23
|
export declare function stripBom(content: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* A flag value meant as one line, with each line break and the blanks around
|
|
26
|
+
* it collapsed to one space. Folded rather than refused, as the decision ledger
|
|
27
|
+
* always did: a value spliced under a heading or after `# ` otherwise wrote its
|
|
28
|
+
* second line as markdown of its own, so `\n## Injected` became a section.
|
|
29
|
+
*/
|
|
30
|
+
export declare function toSingleLine(text: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* The characters `.` refuses to match. A capture written `(.[\s\S]*)$`, so
|
|
33
|
+
* that no blank run can be re-split, is refused in code when it holds one, as
|
|
34
|
+
* `(.+)$` refused it in the regex. Not global, so `test` and `search` keep no
|
|
35
|
+
* state between calls.
|
|
36
|
+
*/
|
|
37
|
+
export declare const LINE_TERMINATOR: RegExp;
|
|
24
38
|
export interface CodeFenceScan {
|
|
25
39
|
/** True for every line inside a fenced code block, fence lines included. */
|
|
26
40
|
mask: boolean[];
|
|
@@ -43,6 +57,16 @@ export declare function buildCodeFenceMask(lines: string[]): boolean[];
|
|
|
43
57
|
* check shares it: it once carried its own, subtly different copy.
|
|
44
58
|
*/
|
|
45
59
|
export declare const SCENARIO_HEADER: RegExp;
|
|
60
|
+
/**
|
|
61
|
+
* A heading's text without its optional closing `#` sequence (CommonMark:
|
|
62
|
+
* `### Late Fees ###` names `Late Fees`). Kept as part of the name, a REMOVED
|
|
63
|
+
* `Late Fees ###` matched nothing and the requirement silently stayed.
|
|
64
|
+
*
|
|
65
|
+
* The run must follow a space or tab, so `Support C#` keeps its `#`. A scan
|
|
66
|
+
* rather than `/[ \t]+#+$/`, which backtracks quadratically on a long run of
|
|
67
|
+
* blanks or `#`.
|
|
68
|
+
*/
|
|
69
|
+
export declare function stripClosingHashes(text: string): string;
|
|
46
70
|
/**
|
|
47
71
|
* The scenario name from a `#### Scenario:` header line, or null when the line
|
|
48
72
|
* is not one. The single place the name is peeled off, so every reader agrees.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requirement-text.d.ts","sourceRoot":"","sources":["../../../src/core/parsers/requirement-text.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,aAAa,CAsB7D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAE7D;AAgCD;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAAuB,CAAC;AAEpD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG5D;AAKD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAoBlE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAEvF;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAQ1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAUhE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBtF;
|
|
1
|
+
{"version":3,"file":"requirement-text.d.ts","sourceRoot":"","sources":["../../../src/core/parsers/requirement-text.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QAAuB,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,aAAa,CAsB7D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAE7D;AAgCD;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAAuB,CAAC;AAEpD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG5D;AAKD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAoBlE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAEvF;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAQ1D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAUhE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBtF;AAuBD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAoBzF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BpF;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,KAAK,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,mEAAmE;QACnE,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAAC;IACH,yEAAyE;IACzE,kBAAkB,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,gBAAgB,CA+BlE"}
|
|
@@ -17,7 +17,7 @@ export function normalizeDocument(content) {
|
|
|
17
17
|
return stripBom(content).replace(/\r\n?/g, '\n');
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
* Strip a leading UTF-8 BOM, leaving line endings untouched
|
|
20
|
+
* Strip a leading UTF-8 BOM, leaving line endings untouched — for readers that
|
|
21
21
|
* write the file back and so must preserve its endings, which rules out
|
|
22
22
|
* `normalizeDocument`. Writing the stripped text back is deliberate: every
|
|
23
23
|
* document tospec produces is UTF-8 *without* a BOM.
|
|
@@ -25,6 +25,22 @@ export function normalizeDocument(content) {
|
|
|
25
25
|
export function stripBom(content) {
|
|
26
26
|
return content.replace(/^\uFEFF/, '');
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* A flag value meant as one line, with each line break and the blanks around
|
|
30
|
+
* it collapsed to one space. Folded rather than refused, as the decision ledger
|
|
31
|
+
* always did: a value spliced under a heading or after `# ` otherwise wrote its
|
|
32
|
+
* second line as markdown of its own, so `\n## Injected` became a section.
|
|
33
|
+
*/
|
|
34
|
+
export function toSingleLine(text) {
|
|
35
|
+
return text.replace(/\s*[\r\n]\s*/g, ' ').trim();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The characters `.` refuses to match. A capture written `(.[\s\S]*)$`, so
|
|
39
|
+
* that no blank run can be re-split, is refused in code when it holds one, as
|
|
40
|
+
* `(.+)$` refused it in the regex. Not global, so `test` and `search` keep no
|
|
41
|
+
* state between calls.
|
|
42
|
+
*/
|
|
43
|
+
export const LINE_TERMINATOR = /[\n\r\u2028\u2029]/;
|
|
28
44
|
/**
|
|
29
45
|
* Mask the lines inside fenced code blocks, mirroring markdown's own rules: a
|
|
30
46
|
* fence opens on a ```` ``` ````/`~~~` run of length >= 3 and closes on the same
|
|
@@ -81,6 +97,27 @@ const HEADER_LINE = /^#{1,6}\s/;
|
|
|
81
97
|
* check shares it: it once carried its own, subtly different copy.
|
|
82
98
|
*/
|
|
83
99
|
export const SCENARIO_HEADER = /^####\s+Scenario:/i;
|
|
100
|
+
/**
|
|
101
|
+
* A heading's text without its optional closing `#` sequence (CommonMark:
|
|
102
|
+
* `### Late Fees ###` names `Late Fees`). Kept as part of the name, a REMOVED
|
|
103
|
+
* `Late Fees ###` matched nothing and the requirement silently stayed.
|
|
104
|
+
*
|
|
105
|
+
* The run must follow a space or tab, so `Support C#` keeps its `#`. A scan
|
|
106
|
+
* rather than `/[ \t]+#+$/`, which backtracks quadratically on a long run of
|
|
107
|
+
* blanks or `#`.
|
|
108
|
+
*/
|
|
109
|
+
export function stripClosingHashes(text) {
|
|
110
|
+
const trimmed = text.trim();
|
|
111
|
+
let end = trimmed.length;
|
|
112
|
+
while (end > 0 && trimmed[end - 1] === '#')
|
|
113
|
+
end--;
|
|
114
|
+
if (end === trimmed.length || end === 0)
|
|
115
|
+
return trimmed;
|
|
116
|
+
const before = trimmed[end - 1];
|
|
117
|
+
if (before !== ' ' && before !== '\t')
|
|
118
|
+
return trimmed;
|
|
119
|
+
return trimmed.slice(0, end).trimEnd();
|
|
120
|
+
}
|
|
84
121
|
/**
|
|
85
122
|
* The scenario name from a `#### Scenario:` header line, or null when the line
|
|
86
123
|
* is not one. The single place the name is peeled off, so every reader agrees.
|
|
@@ -88,7 +125,7 @@ export const SCENARIO_HEADER = /^####\s+Scenario:/i;
|
|
|
88
125
|
export function scenarioNameFrom(line) {
|
|
89
126
|
if (!SCENARIO_HEADER.test(line))
|
|
90
127
|
return null;
|
|
91
|
-
return line.replace(SCENARIO_HEADER, '')
|
|
128
|
+
return stripClosingHashes(line.replace(SCENARIO_HEADER, ''));
|
|
92
129
|
}
|
|
93
130
|
/** Any level-4 header — used to detect non-scenario `####` headers. */
|
|
94
131
|
const ANY_H4_HEADER = /^####\s+/;
|
|
@@ -198,8 +235,26 @@ export function findMissingScenarios(currentRaw, incomingRaw) {
|
|
|
198
235
|
}
|
|
199
236
|
return missing;
|
|
200
237
|
}
|
|
201
|
-
/**
|
|
202
|
-
|
|
238
|
+
/**
|
|
239
|
+
* A `- ...` / `* ...` bullet, with its marker and leading space removed; the
|
|
240
|
+
* trailing blanks go in `bulletText`. As `(.+?)[ \t]*$` the lazy capture
|
|
241
|
+
* retried the tail at every position of a blank run, and a bullet holding 80k
|
|
242
|
+
* blanks took ~2 s.
|
|
243
|
+
*/
|
|
244
|
+
const BULLET_LINE = /^[ \t]*[-*][ \t]+(.[\s\S]*)$/;
|
|
245
|
+
/**
|
|
246
|
+
* The text `(.+?)[ \t]*$` would have captured. Not `trimNameTail`: only spaces
|
|
247
|
+
* and tabs go and a backtick stays. One character always stays, as `.+?`
|
|
248
|
+
* required, so `- ` still reads as a one-blank bullet. `.` refused a line
|
|
249
|
+
* terminator, so a bullet holding one is still no match.
|
|
250
|
+
*/
|
|
251
|
+
function bulletText(captured) {
|
|
252
|
+
let end = captured.length;
|
|
253
|
+
while (end > 1 && (captured[end - 1] === ' ' || captured[end - 1] === '\t'))
|
|
254
|
+
end--;
|
|
255
|
+
const text = captured.slice(0, end);
|
|
256
|
+
return LINE_TERMINATOR.test(text) ? null : text;
|
|
257
|
+
}
|
|
203
258
|
/**
|
|
204
259
|
* A requirement block with the named scenarios cut out, header and body. Takes
|
|
205
260
|
* declared removals out of the "current" side before comparing: a scenario
|
|
@@ -254,10 +309,11 @@ export function findDroppedBullets(currentRaw, incomingRaw) {
|
|
|
254
309
|
if (mask[i])
|
|
255
310
|
continue;
|
|
256
311
|
const match = BULLET_LINE.exec(lines[i]);
|
|
312
|
+
const text = match ? bulletText(match[1]) : null;
|
|
257
313
|
// Interior whitespace collapses so a re-indented or re-spaced bullet
|
|
258
314
|
// still matches itself.
|
|
259
|
-
if (
|
|
260
|
-
bullets.push(
|
|
315
|
+
if (text !== null)
|
|
316
|
+
bullets.push(text.replace(/\s+/g, ' '));
|
|
261
317
|
}
|
|
262
318
|
return bullets;
|
|
263
319
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requirement-text.js","sourceRoot":"","sources":["../../../src/core/parsers/requirement-text.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AACxC,CAAC;
|
|
1
|
+
{"version":3,"file":"requirement-text.js","sourceRoot":"","sources":["../../../src/core/parsers/requirement-text.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-structure.d.ts","sourceRoot":"","sources":["../../../src/core/parsers/spec-structure.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"spec-structure.d.ts","sourceRoot":"","sources":["../../../src/core/parsers/spec-structure.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,cAAc,GAAG,kCAAkC,GAAG,uBAAuB,CAAC;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,sBAAsB,EAAE,CAyGrF;AAED,wBAAgB,oCAAoC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI5E"}
|
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import { buildCodeFenceMask, normalizeDocument } from './requirement-text.js';
|
|
2
|
-
import { normalizeRequirementName,
|
|
3
|
-
const REQUIREMENTS_SECTION_HEADER = /^##\s+Requirements\s*$/i;
|
|
4
|
-
const TOP_LEVEL_SECTION_HEADER = /^##\s+/;
|
|
5
|
-
const DELTA_HEADER = /^##\s+(ADDED|MODIFIED|REMOVED|RENAMED)\s+Requirements\s*$/i;
|
|
6
|
-
// Shared with the merge, not a local `\s+` copy: this guard exists to report
|
|
7
|
-
// every pair that collides in buildUpdatedSpec's Map, so it must read headers
|
|
8
|
-
// exactly as the merge does — `###Requirement: A` beside `### Requirement: A`
|
|
9
|
-
// passed the stricter copy and then lost one body on archive.
|
|
10
|
-
const REQUIREMENT_HEADER = REQUIREMENT_HEADER_REGEX;
|
|
2
|
+
import { endsRequirementsSection, foldRequirementName, isDeltaSectionHeader, matchRequirementHeader, normalizeRequirementName, sectionHeaderKey, } from './requirement-blocks.js';
|
|
11
3
|
export function findMainSpecStructureIssues(content) {
|
|
12
4
|
const normalized = normalizeDocument(content);
|
|
13
5
|
const stripped = stripFencedCodeBlocksPreservingLines(normalized);
|
|
14
6
|
const lines = stripped.split('\n');
|
|
15
7
|
const issues = [];
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
8
|
+
// Folded, so wider than buildUpdatedSpec's exact-name Map: every pair that
|
|
9
|
+
// would collide there is reported (or this guard passes a spec the merge
|
|
10
|
+
// corrupts), and so is a case/spacing variant the merge refuses to create.
|
|
19
11
|
const firstSeenAt = new Map();
|
|
20
|
-
|
|
12
|
+
// Keyed as the spec parser and the merge key it: once the parser read
|
|
13
|
+
// `## Requirements ##` as the section, a regex of its own here would report
|
|
14
|
+
// every requirement under it as outside.
|
|
15
|
+
const requirementsHeaderIndex = lines.findIndex(line => sectionHeaderKey(line) === 'requirements');
|
|
21
16
|
let requirementsEndIndex = lines.length;
|
|
17
|
+
// Ended where the merge ends it, at a `#` heading too: ending at `##` only
|
|
18
|
+
// passed a requirement under a `#` heading below the section, which the
|
|
19
|
+
// merge read and the spec parser did not.
|
|
22
20
|
if (requirementsHeaderIndex !== -1) {
|
|
23
21
|
for (let i = requirementsHeaderIndex + 1; i < lines.length; i++) {
|
|
24
|
-
if (
|
|
22
|
+
if (endsRequirementsSection(lines[i])) {
|
|
25
23
|
requirementsEndIndex = i;
|
|
26
24
|
break;
|
|
27
25
|
}
|
|
@@ -33,7 +31,13 @@ export function findMainSpecStructureIssues(content) {
|
|
|
33
31
|
if (!trimmed) {
|
|
34
32
|
continue;
|
|
35
33
|
}
|
|
36
|
-
|
|
34
|
+
// The delta parser's own section list, not a local regex: the copy kept here
|
|
35
|
+
// lacked `## REMOVED Scenarios` and the closing `#` peel, so a main spec
|
|
36
|
+
// still holding either passed validate and archive. Blank runs are folded
|
|
37
|
+
// first, as foldRequirementName does, because this guard reads looser than
|
|
38
|
+
// the parser on purpose: `## ADDED Requirements` is no section to the
|
|
39
|
+
// parser, but in a main spec it is still a delta header left behind.
|
|
40
|
+
if (isDeltaSectionHeader(line.replace(/\s+/g, ' '))) {
|
|
37
41
|
issues.push({
|
|
38
42
|
kind: 'delta-header',
|
|
39
43
|
line: i + 1,
|
|
@@ -44,8 +48,12 @@ export function findMainSpecStructureIssues(content) {
|
|
|
44
48
|
});
|
|
45
49
|
continue;
|
|
46
50
|
}
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
// Shared with the merge, not a local `\s+` copy: this guard exists to report
|
|
52
|
+
// every pair that collides in buildUpdatedSpec's Map, so it must read headers
|
|
53
|
+
// exactly as the merge does — `###Requirement: A` beside `### Requirement: A`
|
|
54
|
+
// passed the stricter copy and then lost one body on archive.
|
|
55
|
+
const requirementName = matchRequirementHeader(line);
|
|
56
|
+
if (requirementName === null) {
|
|
49
57
|
continue;
|
|
50
58
|
}
|
|
51
59
|
const insideRequirements = requirementsHeaderIndex !== -1 &&
|
|
@@ -64,19 +72,23 @@ export function findMainSpecStructureIssues(content) {
|
|
|
64
72
|
// Duplicate names are only a merge hazard for requirements the merge sees,
|
|
65
73
|
// so this runs on the ones inside the section — the ones just reported as
|
|
66
74
|
// outside it are already fatal for a different reason.
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
const name = normalizeRequirementName(requirementName);
|
|
76
|
+
// Folded, the same rule the merge refuses a new spelling by: `Late Fees`
|
|
77
|
+
// beside `late fees` is two requirements no reader can tell apart.
|
|
78
|
+
const key = foldRequirementName(name);
|
|
79
|
+
const first = firstSeenAt.get(key);
|
|
80
|
+
if (first === undefined) {
|
|
81
|
+
firstSeenAt.set(key, { line: i + 1, name });
|
|
71
82
|
continue;
|
|
72
83
|
}
|
|
84
|
+
const spelling = first.name === name ? '' : ` (as "${first.name}")`;
|
|
73
85
|
issues.push({
|
|
74
86
|
kind: 'duplicate-requirement',
|
|
75
87
|
line: i + 1,
|
|
76
88
|
header: trimmed,
|
|
77
|
-
message: `Requirement "${
|
|
78
|
-
'
|
|
79
|
-
'the earlier body
|
|
89
|
+
message: `Requirement "${name}" is defined more than once (first at line ${first.line}${spelling}, again at line ${i + 1}). ` +
|
|
90
|
+
'Names that differ only in case or spacing count as the same requirement: merging a change into this spec ' +
|
|
91
|
+
'could not tell them apart, and the earlier body could be lost. Rename one or merge them.',
|
|
80
92
|
});
|
|
81
93
|
}
|
|
82
94
|
return issues;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-structure.js","sourceRoot":"","sources":["../../../src/core/parsers/spec-structure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,
|
|
1
|
+
{"version":3,"file":"spec-structure.js","sourceRoot":"","sources":["../../../src/core/parsers/spec-structure.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,13 +32,20 @@ export interface ProjectConfigResult {
|
|
|
32
32
|
* the ones that have an envelope call the variant below.
|
|
33
33
|
*/
|
|
34
34
|
export declare function readProjectConfig(projectRoot: string): ProjectConfig | null;
|
|
35
|
+
/**
|
|
36
|
+
* The one stderr spelling of a config diagnostic. Each reader used to print
|
|
37
|
+
* its own: `new change` and `instructions` wrote the bare message, `list` and
|
|
38
|
+
* `status` prefixed `Warning:`, so the same config read differently per
|
|
39
|
+
* command. Stderr in both modes: a `--json` stdout stays one document, and a
|
|
40
|
+
* warning is not a failed command.
|
|
41
|
+
*/
|
|
42
|
+
export declare function printProjectConfigDiagnostic(message: string): void;
|
|
35
43
|
/**
|
|
36
44
|
* Stderr copy of the config diagnostics, for commands that never read the
|
|
37
45
|
* config themselves. `list` and `status` resolve each change's schema from its
|
|
38
46
|
* own `.tospec.yaml` and consult the project config only when that field is
|
|
39
47
|
* absent, so a config that no longer parses went unmentioned by exactly the
|
|
40
|
-
* commands a user runs to look around.
|
|
41
|
-
* stays one document, and a warning is not a failed command.
|
|
48
|
+
* commands a user runs to look around.
|
|
42
49
|
*/
|
|
43
50
|
export declare function printProjectConfigDiagnostics(projectRoot: string): void;
|
|
44
51
|
/** The same read, with the dropped fields handed back instead of printed. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-config.d.ts","sourceRoot":"","sources":["../../src/core/project-config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"project-config.d.ts","sourceRoot":"","sources":["../../src/core/project-config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,kFAAkF;AAClF,eAAO,MAAM,mBAAmB;;;;;;;iBA6B9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB,QAAY,CAAC;AAE1C;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,uBAAuB,EAAE,CAAC;CACxC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAM3E;AAQD;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAOlE;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAIvE;AAED,6EAA6E;AAC7E,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,CAuIzF;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC/B,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,GAC5B,MAAM,EAAE,CAeV;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOvE;AAED,8DAA8D;AAC9D,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAExE"}
|
|
@@ -2,6 +2,7 @@ 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
|
+
import { formatLabeled } from '../commands/shared-output.js';
|
|
5
6
|
/** Single source of truth for both `ProjectConfig` and its runtime validation. */
|
|
6
7
|
export const ProjectConfigSchema = z.object({
|
|
7
8
|
schema: z
|
|
@@ -18,7 +19,7 @@ export const ProjectConfigSchema = z.object({
|
|
|
18
19
|
.record(z.string(), z.array(z.string()))
|
|
19
20
|
.optional()
|
|
20
21
|
.describe('Per-artifact rules, keyed by artifact ID'),
|
|
21
|
-
//
|
|
22
|
+
// staleDays: days without a file change before an active change is
|
|
22
23
|
// flagged stale (default 14).
|
|
23
24
|
dashboard: z
|
|
24
25
|
.object({
|
|
@@ -41,21 +42,41 @@ export const MAX_CONTEXT_SIZE = 50 * 1024; // 50KB hard limit on inlined context
|
|
|
41
42
|
export function readProjectConfig(projectRoot) {
|
|
42
43
|
const { config, diagnostics } = readProjectConfigWithDiagnostics(projectRoot);
|
|
43
44
|
for (const diagnostic of diagnostics) {
|
|
44
|
-
|
|
45
|
+
printProjectConfigDiagnostic(diagnostic.message);
|
|
45
46
|
}
|
|
46
47
|
return config;
|
|
47
48
|
}
|
|
49
|
+
// Once per line per process, as global-config's warnOnce: `list`, `status
|
|
50
|
+
// --all` and `validate --all` resolve the schema of every change that names
|
|
51
|
+
// none by re-reading the config, so the same lines printed once per change.
|
|
52
|
+
// Keyed by the formatted line, which carries the config path.
|
|
53
|
+
const printedDiagnostics = new Set();
|
|
54
|
+
/**
|
|
55
|
+
* The one stderr spelling of a config diagnostic. Each reader used to print
|
|
56
|
+
* its own: `new change` and `instructions` wrote the bare message, `list` and
|
|
57
|
+
* `status` prefixed `Warning:`, so the same config read differently per
|
|
58
|
+
* command. Stderr in both modes: a `--json` stdout stays one document, and a
|
|
59
|
+
* warning is not a failed command.
|
|
60
|
+
*/
|
|
61
|
+
export function printProjectConfigDiagnostic(message) {
|
|
62
|
+
// Messages carry no severity prefix: `status[]` has its own `severity`, so a
|
|
63
|
+
// prefix in the text read twice there.
|
|
64
|
+
const line = formatLabeled('Warning', message);
|
|
65
|
+
if (printedDiagnostics.has(line))
|
|
66
|
+
return;
|
|
67
|
+
printedDiagnostics.add(line);
|
|
68
|
+
console.error(line);
|
|
69
|
+
}
|
|
48
70
|
/**
|
|
49
71
|
* Stderr copy of the config diagnostics, for commands that never read the
|
|
50
72
|
* config themselves. `list` and `status` resolve each change's schema from its
|
|
51
73
|
* own `.tospec.yaml` and consult the project config only when that field is
|
|
52
74
|
* absent, so a config that no longer parses went unmentioned by exactly the
|
|
53
|
-
* commands a user runs to look around.
|
|
54
|
-
* stays one document, and a warning is not a failed command.
|
|
75
|
+
* commands a user runs to look around.
|
|
55
76
|
*/
|
|
56
77
|
export function printProjectConfigDiagnostics(projectRoot) {
|
|
57
78
|
for (const diagnostic of readProjectConfigWithDiagnostics(projectRoot).diagnostics) {
|
|
58
|
-
|
|
79
|
+
printProjectConfigDiagnostic(diagnostic.message);
|
|
59
80
|
}
|
|
60
81
|
}
|
|
61
82
|
/** The same read, with the dropped fields handed back instead of printed. */
|
|
@@ -69,7 +90,9 @@ export function readProjectConfigWithDiagnostics(projectRoot) {
|
|
|
69
90
|
try {
|
|
70
91
|
const content = readFileSync(configPath, 'utf-8');
|
|
71
92
|
const raw = parseYaml(content);
|
|
72
|
-
|
|
93
|
+
// Array.isArray because typeof [] === 'object': a list would pass, every
|
|
94
|
+
// field would read undefined, and the config would vanish without a word.
|
|
95
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
73
96
|
return {
|
|
74
97
|
config: null,
|
|
75
98
|
diagnostics: [
|
|
@@ -179,7 +202,7 @@ export function readProjectConfigWithDiagnostics(projectRoot) {
|
|
|
179
202
|
code: 'config_unparseable',
|
|
180
203
|
// First line only, minus the colon that introduces the yaml
|
|
181
204
|
// library's code frame on the lines that follow.
|
|
182
|
-
message: `
|
|
205
|
+
message: `Could not parse ${where} (${error instanceof Error ? error.message.split('\n')[0].replace(/:\s*$/, '') : String(error)}); ignoring it.`,
|
|
183
206
|
},
|
|
184
207
|
],
|
|
185
208
|
};
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"project-config.js","sourceRoot":"","sources":["../../src/core/project-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* command reports the project as uninitialized — nothing is lost, but the
|
|
6
6
|
* diagnostic sends the reader to re-run a command that changes nothing.
|
|
7
7
|
*/
|
|
8
|
+
import type { CommandDiagnostic } from '../commands/shared-output.js';
|
|
8
9
|
/**
|
|
9
10
|
* Relative to `tospec/`, in creation order. Not named for anchoring: whether a
|
|
10
11
|
* directory gets an anchor is computed from whether it ends up empty, and
|
|
@@ -18,4 +19,29 @@ export declare function tospecLayoutDirs(tospecPath: string): string[];
|
|
|
18
19
|
* representable, so adding one beside real content leaves a file nobody wanted.
|
|
19
20
|
*/
|
|
20
21
|
export declare function ensureDirectoryAnchor(directory: string): Promise<void>;
|
|
22
|
+
export declare const LAYOUT_PATH_NOT_DIRECTORY = "layout_path_not_directory";
|
|
23
|
+
/**
|
|
24
|
+
* A layout path held by something that is not a directory. One error for every
|
|
25
|
+
* command that reads or creates under the layout: before it, a file at
|
|
26
|
+
* `tospec/changes` made `list` answer "no changes", exit 0, while `validate
|
|
27
|
+
* --all` and `new change` failed with a bare `ENOTDIR`. `init` keeps its own
|
|
28
|
+
* `init_layout_path_not_directory`, whose fix is to rerun init.
|
|
29
|
+
*/
|
|
30
|
+
export declare class LayoutPathNotDirectoryError extends Error {
|
|
31
|
+
readonly diagnostic: CommandDiagnostic & {
|
|
32
|
+
severity: 'error';
|
|
33
|
+
target: string;
|
|
34
|
+
fix: string;
|
|
35
|
+
};
|
|
36
|
+
constructor(projectRoot: string, occupied: string);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The outermost path from `projectRoot` down to `dir` that exists and is not a
|
|
40
|
+
* directory (links followed), as the error to throw. Outermost: a file at
|
|
41
|
+
* `tospec/changes` is what makes `tospec/changes/archive` unreadable, and naming
|
|
42
|
+
* the inner path sends the reader looking for a file that is not there.
|
|
43
|
+
* Undefined when the chain ends at a missing path or one it cannot stat — the
|
|
44
|
+
* caller's own error then says more.
|
|
45
|
+
*/
|
|
46
|
+
export declare function findLayoutPathNotDirectory(projectRoot: string, dir: string): LayoutPathNotDirectoryError | undefined;
|
|
21
47
|
//# 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;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"project-layout.d.ts","sourceRoot":"","sources":["../../src/core/project-layout.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtE;;;;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;AAED,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AAErE;;;;;;GAMG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,UAAU,EAAE,iBAAiB,GAAG;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAE5F,YAAY,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAYhD;CACF;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,GACV,2BAA2B,GAAG,SAAS,CAczC"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* diagnostic sends the reader to re-run a command that changes nothing.
|
|
7
7
|
*/
|
|
8
8
|
import path from 'path';
|
|
9
|
-
import { promises as fs } from 'fs';
|
|
9
|
+
import { promises as fs, statSync } from 'fs';
|
|
10
10
|
/**
|
|
11
11
|
* Relative to `tospec/`, in creation order. Not named for anchoring: whether a
|
|
12
12
|
* directory gets an anchor is computed from whether it ends up empty, and
|
|
@@ -49,4 +49,54 @@ export async function ensureDirectoryAnchor(directory) {
|
|
|
49
49
|
throw error;
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
export const LAYOUT_PATH_NOT_DIRECTORY = 'layout_path_not_directory';
|
|
53
|
+
/**
|
|
54
|
+
* A layout path held by something that is not a directory. One error for every
|
|
55
|
+
* command that reads or creates under the layout: before it, a file at
|
|
56
|
+
* `tospec/changes` made `list` answer "no changes", exit 0, while `validate
|
|
57
|
+
* --all` and `new change` failed with a bare `ENOTDIR`. `init` keeps its own
|
|
58
|
+
* `init_layout_path_not_directory`, whose fix is to rerun init.
|
|
59
|
+
*/
|
|
60
|
+
export class LayoutPathNotDirectoryError extends Error {
|
|
61
|
+
diagnostic;
|
|
62
|
+
constructor(projectRoot, occupied) {
|
|
63
|
+
const relative = path.relative(projectRoot, occupied).split(path.sep).join('/');
|
|
64
|
+
const message = `"${relative}" exists and is not a directory, so tospec cannot read or create anything under it.`;
|
|
65
|
+
super(message);
|
|
66
|
+
this.name = 'LayoutPathNotDirectoryError';
|
|
67
|
+
this.diagnostic = {
|
|
68
|
+
severity: 'error',
|
|
69
|
+
code: LAYOUT_PATH_NOT_DIRECTORY,
|
|
70
|
+
message,
|
|
71
|
+
target: occupied,
|
|
72
|
+
fix: `Move or rename "${relative}", then rerun the command.`,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The outermost path from `projectRoot` down to `dir` that exists and is not a
|
|
78
|
+
* directory (links followed), as the error to throw. Outermost: a file at
|
|
79
|
+
* `tospec/changes` is what makes `tospec/changes/archive` unreadable, and naming
|
|
80
|
+
* the inner path sends the reader looking for a file that is not there.
|
|
81
|
+
* Undefined when the chain ends at a missing path or one it cannot stat — the
|
|
82
|
+
* caller's own error then says more.
|
|
83
|
+
*/
|
|
84
|
+
export function findLayoutPathNotDirectory(projectRoot, dir) {
|
|
85
|
+
let current = projectRoot;
|
|
86
|
+
for (const segment of path.relative(projectRoot, dir).split(path.sep)) {
|
|
87
|
+
if (!segment)
|
|
88
|
+
continue;
|
|
89
|
+
current = path.join(current, segment);
|
|
90
|
+
let isDirectory;
|
|
91
|
+
try {
|
|
92
|
+
isDirectory = statSync(current).isDirectory();
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
if (!isDirectory)
|
|
98
|
+
return new LayoutPathNotDirectoryError(projectRoot, current);
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
52
102
|
//# sourceMappingURL=project-layout.js.map
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
1
|
+
{"version":3,"file":"project-layout.js","sourceRoot":"","sources":["../../src/core/project-layout.ts"],"names":[],"mappings":"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"}
|