@libar-dev/architect 1.0.0-pre.3
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 +50 -0
- package/LICENSE +25 -0
- package/LICENSE-MCP +62 -0
- package/README.md +147 -0
- package/dist/api/arch-queries.d.ts +95 -0
- package/dist/api/arch-queries.d.ts.map +1 -0
- package/dist/api/arch-queries.js +310 -0
- package/dist/api/arch-queries.js.map +1 -0
- package/dist/api/context-assembler.d.ts +124 -0
- package/dist/api/context-assembler.d.ts.map +1 -0
- package/dist/api/context-assembler.js +472 -0
- package/dist/api/context-assembler.js.map +1 -0
- package/dist/api/context-formatter.d.ts +26 -0
- package/dist/api/context-formatter.d.ts.map +1 -0
- package/dist/api/context-formatter.js +183 -0
- package/dist/api/context-formatter.js.map +1 -0
- package/dist/api/coverage-analyzer.d.ts +38 -0
- package/dist/api/coverage-analyzer.d.ts.map +1 -0
- package/dist/api/coverage-analyzer.js +117 -0
- package/dist/api/coverage-analyzer.js.map +1 -0
- package/dist/api/fuzzy-match.d.ts +75 -0
- package/dist/api/fuzzy-match.d.ts.map +1 -0
- package/dist/api/fuzzy-match.js +150 -0
- package/dist/api/fuzzy-match.js.map +1 -0
- package/dist/api/handoff-generator.d.ts +45 -0
- package/dist/api/handoff-generator.d.ts.map +1 -0
- package/dist/api/handoff-generator.js +139 -0
- package/dist/api/handoff-generator.js.map +1 -0
- package/dist/api/index.d.ts +61 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +54 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/pattern-helpers.d.ts +51 -0
- package/dist/api/pattern-helpers.d.ts.map +1 -0
- package/dist/api/pattern-helpers.js +84 -0
- package/dist/api/pattern-helpers.js.map +1 -0
- package/dist/api/process-state.d.ts +224 -0
- package/dist/api/process-state.d.ts.map +1 -0
- package/dist/api/process-state.js +308 -0
- package/dist/api/process-state.js.map +1 -0
- package/dist/api/rules-query.d.ts +60 -0
- package/dist/api/rules-query.d.ts.map +1 -0
- package/dist/api/rules-query.js +154 -0
- package/dist/api/rules-query.js.map +1 -0
- package/dist/api/scope-validator.d.ts +56 -0
- package/dist/api/scope-validator.d.ts.map +1 -0
- package/dist/api/scope-validator.js +293 -0
- package/dist/api/scope-validator.js.map +1 -0
- package/dist/api/stub-resolver.d.ts +117 -0
- package/dist/api/stub-resolver.d.ts.map +1 -0
- package/dist/api/stub-resolver.js +154 -0
- package/dist/api/stub-resolver.js.map +1 -0
- package/dist/api/summarize.d.ts +75 -0
- package/dist/api/summarize.d.ts.map +1 -0
- package/dist/api/summarize.js +97 -0
- package/dist/api/summarize.js.map +1 -0
- package/dist/api/types.d.ts +221 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +57 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cache/file-cache.d.ts +72 -0
- package/dist/cache/file-cache.d.ts.map +1 -0
- package/dist/cache/file-cache.js +80 -0
- package/dist/cache/file-cache.js.map +1 -0
- package/dist/cache/index.d.ts +5 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +5 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cli/cli-schema.d.ts +83 -0
- package/dist/cli/cli-schema.d.ts.map +1 -0
- package/dist/cli/cli-schema.js +505 -0
- package/dist/cli/cli-schema.js.map +1 -0
- package/dist/cli/dataset-cache.d.ts +66 -0
- package/dist/cli/dataset-cache.d.ts.map +1 -0
- package/dist/cli/dataset-cache.js +179 -0
- package/dist/cli/dataset-cache.js.map +1 -0
- package/dist/cli/error-handler.d.ts +84 -0
- package/dist/cli/error-handler.d.ts.map +1 -0
- package/dist/cli/error-handler.js +197 -0
- package/dist/cli/error-handler.js.map +1 -0
- package/dist/cli/generate-docs.d.ts +30 -0
- package/dist/cli/generate-docs.d.ts.map +1 -0
- package/dist/cli/generate-docs.js +370 -0
- package/dist/cli/generate-docs.js.map +1 -0
- package/dist/cli/lint-patterns.d.ts +57 -0
- package/dist/cli/lint-patterns.d.ts.map +1 -0
- package/dist/cli/lint-patterns.js +257 -0
- package/dist/cli/lint-patterns.js.map +1 -0
- package/dist/cli/lint-process.d.ts +54 -0
- package/dist/cli/lint-process.d.ts.map +1 -0
- package/dist/cli/lint-process.js +319 -0
- package/dist/cli/lint-process.js.map +1 -0
- package/dist/cli/lint-steps.d.ts +32 -0
- package/dist/cli/lint-steps.d.ts.map +1 -0
- package/dist/cli/lint-steps.js +172 -0
- package/dist/cli/lint-steps.js.map +1 -0
- package/dist/cli/mcp-server.d.ts +22 -0
- package/dist/cli/mcp-server.d.ts.map +1 -0
- package/dist/cli/mcp-server.js +57 -0
- package/dist/cli/mcp-server.js.map +1 -0
- package/dist/cli/output-pipeline.d.ts +130 -0
- package/dist/cli/output-pipeline.d.ts.map +1 -0
- package/dist/cli/output-pipeline.js +234 -0
- package/dist/cli/output-pipeline.js.map +1 -0
- package/dist/cli/process-api.d.ts +37 -0
- package/dist/cli/process-api.d.ts.map +1 -0
- package/dist/cli/process-api.js +1550 -0
- package/dist/cli/process-api.js.map +1 -0
- package/dist/cli/repl.d.ts +38 -0
- package/dist/cli/repl.d.ts.map +1 -0
- package/dist/cli/repl.js +239 -0
- package/dist/cli/repl.js.map +1 -0
- package/dist/cli/validate-patterns.d.ts +115 -0
- package/dist/cli/validate-patterns.d.ts.map +1 -0
- package/dist/cli/validate-patterns.js +707 -0
- package/dist/cli/validate-patterns.js.map +1 -0
- package/dist/cli/version.d.ts +35 -0
- package/dist/cli/version.d.ts.map +1 -0
- package/dist/cli/version.js +64 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/config/config-loader.d.ts +167 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +294 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config/defaults.d.ts +92 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +103 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/define-config.d.ts +37 -0
- package/dist/config/define-config.d.ts.map +1 -0
- package/dist/config/define-config.js +38 -0
- package/dist/config/define-config.js.map +1 -0
- package/dist/config/factory.d.ts +79 -0
- package/dist/config/factory.d.ts.map +1 -0
- package/dist/config/factory.js +116 -0
- package/dist/config/factory.js.map +1 -0
- package/dist/config/index.d.ts +45 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +48 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/merge-sources.d.ts +47 -0
- package/dist/config/merge-sources.d.ts.map +1 -0
- package/dist/config/merge-sources.js +61 -0
- package/dist/config/merge-sources.js.map +1 -0
- package/dist/config/presets.d.ts +115 -0
- package/dist/config/presets.d.ts.map +1 -0
- package/dist/config/presets.js +119 -0
- package/dist/config/presets.js.map +1 -0
- package/dist/config/project-config-schema.d.ts +192 -0
- package/dist/config/project-config-schema.d.ts.map +1 -0
- package/dist/config/project-config-schema.js +231 -0
- package/dist/config/project-config-schema.js.map +1 -0
- package/dist/config/project-config.d.ts +229 -0
- package/dist/config/project-config.d.ts.map +1 -0
- package/dist/config/project-config.js +37 -0
- package/dist/config/project-config.js.map +1 -0
- package/dist/config/regex-builders.d.ts +49 -0
- package/dist/config/regex-builders.d.ts.map +1 -0
- package/dist/config/regex-builders.js +85 -0
- package/dist/config/regex-builders.js.map +1 -0
- package/dist/config/resolve-config.d.ts +65 -0
- package/dist/config/resolve-config.d.ts.map +1 -0
- package/dist/config/resolve-config.js +150 -0
- package/dist/config/resolve-config.js.map +1 -0
- package/dist/config/types.d.ts +81 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +22 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/workflow-loader.d.ts +90 -0
- package/dist/config/workflow-loader.d.ts.map +1 -0
- package/dist/config/workflow-loader.js +167 -0
- package/dist/config/workflow-loader.js.map +1 -0
- package/dist/extractor/doc-extractor.d.ts +233 -0
- package/dist/extractor/doc-extractor.d.ts.map +1 -0
- package/dist/extractor/doc-extractor.js +481 -0
- package/dist/extractor/doc-extractor.js.map +1 -0
- package/dist/extractor/dual-source-extractor.d.ts +161 -0
- package/dist/extractor/dual-source-extractor.d.ts.map +1 -0
- package/dist/extractor/dual-source-extractor.js +407 -0
- package/dist/extractor/dual-source-extractor.js.map +1 -0
- package/dist/extractor/gherkin-extractor.d.ts +170 -0
- package/dist/extractor/gherkin-extractor.d.ts.map +1 -0
- package/dist/extractor/gherkin-extractor.js +543 -0
- package/dist/extractor/gherkin-extractor.js.map +1 -0
- package/dist/extractor/index.d.ts +7 -0
- package/dist/extractor/index.d.ts.map +1 -0
- package/dist/extractor/index.js +11 -0
- package/dist/extractor/index.js.map +1 -0
- package/dist/extractor/layer-inference.d.ts +66 -0
- package/dist/extractor/layer-inference.d.ts.map +1 -0
- package/dist/extractor/layer-inference.js +93 -0
- package/dist/extractor/layer-inference.js.map +1 -0
- package/dist/extractor/shape-extractor.d.ts +79 -0
- package/dist/extractor/shape-extractor.d.ts.map +1 -0
- package/dist/extractor/shape-extractor.js +966 -0
- package/dist/extractor/shape-extractor.js.map +1 -0
- package/dist/generators/built-in/cli-recipe-generator.d.ts +30 -0
- package/dist/generators/built-in/cli-recipe-generator.d.ts.map +1 -0
- package/dist/generators/built-in/cli-recipe-generator.js +155 -0
- package/dist/generators/built-in/cli-recipe-generator.js.map +1 -0
- package/dist/generators/built-in/codec-generators.d.ts +29 -0
- package/dist/generators/built-in/codec-generators.d.ts.map +1 -0
- package/dist/generators/built-in/codec-generators.js +195 -0
- package/dist/generators/built-in/codec-generators.js.map +1 -0
- package/dist/generators/built-in/decision-doc-generator.d.ts +204 -0
- package/dist/generators/built-in/decision-doc-generator.d.ts.map +1 -0
- package/dist/generators/built-in/decision-doc-generator.js +654 -0
- package/dist/generators/built-in/decision-doc-generator.js.map +1 -0
- package/dist/generators/built-in/design-review-generator.d.ts +26 -0
- package/dist/generators/built-in/design-review-generator.d.ts.map +1 -0
- package/dist/generators/built-in/design-review-generator.js +94 -0
- package/dist/generators/built-in/design-review-generator.js.map +1 -0
- package/dist/generators/built-in/index.d.ts +22 -0
- package/dist/generators/built-in/index.d.ts.map +1 -0
- package/dist/generators/built-in/index.js +23 -0
- package/dist/generators/built-in/index.js.map +1 -0
- package/dist/generators/built-in/process-api-reference-generator.d.ts +18 -0
- package/dist/generators/built-in/process-api-reference-generator.d.ts.map +1 -0
- package/dist/generators/built-in/process-api-reference-generator.js +85 -0
- package/dist/generators/built-in/process-api-reference-generator.js.map +1 -0
- package/dist/generators/built-in/reference-generators.d.ts +51 -0
- package/dist/generators/built-in/reference-generators.d.ts.map +1 -0
- package/dist/generators/built-in/reference-generators.js +320 -0
- package/dist/generators/built-in/reference-generators.js.map +1 -0
- package/dist/generators/codec-based.d.ts +63 -0
- package/dist/generators/codec-based.d.ts.map +1 -0
- package/dist/generators/codec-based.js +88 -0
- package/dist/generators/codec-based.js.map +1 -0
- package/dist/generators/content-deduplicator.d.ts +114 -0
- package/dist/generators/content-deduplicator.d.ts.map +1 -0
- package/dist/generators/content-deduplicator.js +356 -0
- package/dist/generators/content-deduplicator.js.map +1 -0
- package/dist/generators/index.d.ts +50 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +54 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/orchestrator.d.ts +265 -0
- package/dist/generators/orchestrator.d.ts.map +1 -0
- package/dist/generators/orchestrator.js +570 -0
- package/dist/generators/orchestrator.js.map +1 -0
- package/dist/generators/pipeline/build-pipeline.d.ts +131 -0
- package/dist/generators/pipeline/build-pipeline.d.ts.map +1 -0
- package/dist/generators/pipeline/build-pipeline.js +248 -0
- package/dist/generators/pipeline/build-pipeline.js.map +1 -0
- package/dist/generators/pipeline/context-inference.d.ts +55 -0
- package/dist/generators/pipeline/context-inference.d.ts.map +1 -0
- package/dist/generators/pipeline/context-inference.js +76 -0
- package/dist/generators/pipeline/context-inference.js.map +1 -0
- package/dist/generators/pipeline/index.d.ts +27 -0
- package/dist/generators/pipeline/index.d.ts.map +1 -0
- package/dist/generators/pipeline/index.js +34 -0
- package/dist/generators/pipeline/index.js.map +1 -0
- package/dist/generators/pipeline/merge-patterns.d.ts +33 -0
- package/dist/generators/pipeline/merge-patterns.d.ts.map +1 -0
- package/dist/generators/pipeline/merge-patterns.js +50 -0
- package/dist/generators/pipeline/merge-patterns.js.map +1 -0
- package/dist/generators/pipeline/relationship-resolver.d.ts +47 -0
- package/dist/generators/pipeline/relationship-resolver.d.ts.map +1 -0
- package/dist/generators/pipeline/relationship-resolver.js +132 -0
- package/dist/generators/pipeline/relationship-resolver.js.map +1 -0
- package/dist/generators/pipeline/sequence-utils.d.ts +49 -0
- package/dist/generators/pipeline/sequence-utils.d.ts.map +1 -0
- package/dist/generators/pipeline/sequence-utils.js +235 -0
- package/dist/generators/pipeline/sequence-utils.js.map +1 -0
- package/dist/generators/pipeline/transform-dataset.d.ts +82 -0
- package/dist/generators/pipeline/transform-dataset.d.ts.map +1 -0
- package/dist/generators/pipeline/transform-dataset.js +355 -0
- package/dist/generators/pipeline/transform-dataset.js.map +1 -0
- package/dist/generators/pipeline/transform-types.d.ts +96 -0
- package/dist/generators/pipeline/transform-types.d.ts.map +1 -0
- package/dist/generators/pipeline/transform-types.js +18 -0
- package/dist/generators/pipeline/transform-types.js.map +1 -0
- package/dist/generators/registry.d.ts +64 -0
- package/dist/generators/registry.d.ts.map +1 -0
- package/dist/generators/registry.js +77 -0
- package/dist/generators/registry.js.map +1 -0
- package/dist/generators/source-mapper.d.ts +143 -0
- package/dist/generators/source-mapper.d.ts.map +1 -0
- package/dist/generators/source-mapper.js +602 -0
- package/dist/generators/source-mapper.js.map +1 -0
- package/dist/generators/source-mapping-validator.d.ts +118 -0
- package/dist/generators/source-mapping-validator.d.ts.map +1 -0
- package/dist/generators/source-mapping-validator.js +334 -0
- package/dist/generators/source-mapping-validator.js.map +1 -0
- package/dist/generators/types.d.ts +104 -0
- package/dist/generators/types.d.ts.map +1 -0
- package/dist/generators/types.js +5 -0
- package/dist/generators/types.js.map +1 -0
- package/dist/generators/warning-collector.d.ts +144 -0
- package/dist/generators/warning-collector.d.ts.map +1 -0
- package/dist/generators/warning-collector.js +166 -0
- package/dist/generators/warning-collector.js.map +1 -0
- package/dist/git/branch-diff.d.ts +44 -0
- package/dist/git/branch-diff.d.ts.map +1 -0
- package/dist/git/branch-diff.js +57 -0
- package/dist/git/branch-diff.js.map +1 -0
- package/dist/git/helpers.d.ts +46 -0
- package/dist/git/helpers.d.ts.map +1 -0
- package/dist/git/helpers.js +67 -0
- package/dist/git/helpers.js.map +1 -0
- package/dist/git/index.d.ts +18 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/index.js +18 -0
- package/dist/git/index.js.map +1 -0
- package/dist/git/name-status.d.ts +32 -0
- package/dist/git/name-status.d.ts.map +1 -0
- package/dist/git/name-status.js +66 -0
- package/dist/git/name-status.js.map +1 -0
- package/dist/index.d.ts +107 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +122 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/engine.d.ts +113 -0
- package/dist/lint/engine.d.ts.map +1 -0
- package/dist/lint/engine.js +228 -0
- package/dist/lint/engine.js.map +1 -0
- package/dist/lint/index.d.ts +26 -0
- package/dist/lint/index.d.ts.map +1 -0
- package/dist/lint/index.js +24 -0
- package/dist/lint/index.js.map +1 -0
- package/dist/lint/process-guard/decider.d.ts +166 -0
- package/dist/lint/process-guard/decider.d.ts.map +1 -0
- package/dist/lint/process-guard/decider.js +412 -0
- package/dist/lint/process-guard/decider.js.map +1 -0
- package/dist/lint/process-guard/derive-state.d.ts +96 -0
- package/dist/lint/process-guard/derive-state.d.ts.map +1 -0
- package/dist/lint/process-guard/derive-state.js +368 -0
- package/dist/lint/process-guard/derive-state.js.map +1 -0
- package/dist/lint/process-guard/detect-changes.d.ts +109 -0
- package/dist/lint/process-guard/detect-changes.d.ts.map +1 -0
- package/dist/lint/process-guard/detect-changes.js +487 -0
- package/dist/lint/process-guard/detect-changes.js.map +1 -0
- package/dist/lint/process-guard/index.d.ts +35 -0
- package/dist/lint/process-guard/index.d.ts.map +1 -0
- package/dist/lint/process-guard/index.js +39 -0
- package/dist/lint/process-guard/index.js.map +1 -0
- package/dist/lint/process-guard/types.d.ts +255 -0
- package/dist/lint/process-guard/types.d.ts.map +1 -0
- package/dist/lint/process-guard/types.js +31 -0
- package/dist/lint/process-guard/types.js.map +1 -0
- package/dist/lint/rules.d.ts +147 -0
- package/dist/lint/rules.d.ts.map +1 -0
- package/dist/lint/rules.js +289 -0
- package/dist/lint/rules.js.map +1 -0
- package/dist/lint/steps/cross-checks.d.ts +66 -0
- package/dist/lint/steps/cross-checks.d.ts.map +1 -0
- package/dist/lint/steps/cross-checks.js +290 -0
- package/dist/lint/steps/cross-checks.js.map +1 -0
- package/dist/lint/steps/feature-checks.d.ts +78 -0
- package/dist/lint/steps/feature-checks.d.ts.map +1 -0
- package/dist/lint/steps/feature-checks.js +279 -0
- package/dist/lint/steps/feature-checks.js.map +1 -0
- package/dist/lint/steps/index.d.ts +22 -0
- package/dist/lint/steps/index.d.ts.map +1 -0
- package/dist/lint/steps/index.js +26 -0
- package/dist/lint/steps/index.js.map +1 -0
- package/dist/lint/steps/pair-resolver.d.ts +29 -0
- package/dist/lint/steps/pair-resolver.d.ts.map +1 -0
- package/dist/lint/steps/pair-resolver.js +76 -0
- package/dist/lint/steps/pair-resolver.js.map +1 -0
- package/dist/lint/steps/runner.d.ts +28 -0
- package/dist/lint/steps/runner.d.ts.map +1 -0
- package/dist/lint/steps/runner.js +143 -0
- package/dist/lint/steps/runner.js.map +1 -0
- package/dist/lint/steps/step-checks.d.ts +41 -0
- package/dist/lint/steps/step-checks.d.ts.map +1 -0
- package/dist/lint/steps/step-checks.js +164 -0
- package/dist/lint/steps/step-checks.js.map +1 -0
- package/dist/lint/steps/types.d.ts +95 -0
- package/dist/lint/steps/types.d.ts.map +1 -0
- package/dist/lint/steps/types.js +79 -0
- package/dist/lint/steps/types.js.map +1 -0
- package/dist/lint/steps/utils.d.ts +22 -0
- package/dist/lint/steps/utils.d.ts.map +1 -0
- package/dist/lint/steps/utils.js +57 -0
- package/dist/lint/steps/utils.js.map +1 -0
- package/dist/mcp/file-watcher.d.ts +24 -0
- package/dist/mcp/file-watcher.d.ts.map +1 -0
- package/dist/mcp/file-watcher.js +75 -0
- package/dist/mcp/file-watcher.js.map +1 -0
- package/dist/mcp/index.d.ts +19 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +21 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/pipeline-session.d.ts +33 -0
- package/dist/mcp/pipeline-session.d.ts.map +1 -0
- package/dist/mcp/pipeline-session.js +149 -0
- package/dist/mcp/pipeline-session.js.map +1 -0
- package/dist/mcp/server.d.ts +28 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +197 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tool-registry.d.ts +4 -0
- package/dist/mcp/tool-registry.d.ts.map +1 -0
- package/dist/mcp/tool-registry.js +525 -0
- package/dist/mcp/tool-registry.js.map +1 -0
- package/dist/renderable/codecs/adr.d.ts +4730 -0
- package/dist/renderable/codecs/adr.d.ts.map +1 -0
- package/dist/renderable/codecs/adr.js +590 -0
- package/dist/renderable/codecs/adr.js.map +1 -0
- package/dist/renderable/codecs/architecture.d.ts +4760 -0
- package/dist/renderable/codecs/architecture.d.ts.map +1 -0
- package/dist/renderable/codecs/architecture.js +524 -0
- package/dist/renderable/codecs/architecture.js.map +1 -0
- package/dist/renderable/codecs/business-rules.d.ts +4777 -0
- package/dist/renderable/codecs/business-rules.d.ts.map +1 -0
- package/dist/renderable/codecs/business-rules.js +648 -0
- package/dist/renderable/codecs/business-rules.js.map +1 -0
- package/dist/renderable/codecs/claude-module.d.ts +4710 -0
- package/dist/renderable/codecs/claude-module.d.ts.map +1 -0
- package/dist/renderable/codecs/claude-module.js +214 -0
- package/dist/renderable/codecs/claude-module.js.map +1 -0
- package/dist/renderable/codecs/composite.d.ts +84 -0
- package/dist/renderable/codecs/composite.d.ts.map +1 -0
- package/dist/renderable/codecs/composite.js +124 -0
- package/dist/renderable/codecs/composite.js.map +1 -0
- package/dist/renderable/codecs/convention-extractor.d.ts +105 -0
- package/dist/renderable/codecs/convention-extractor.d.ts.map +1 -0
- package/dist/renderable/codecs/convention-extractor.js +353 -0
- package/dist/renderable/codecs/convention-extractor.js.map +1 -0
- package/dist/renderable/codecs/decision-doc.d.ts +308 -0
- package/dist/renderable/codecs/decision-doc.d.ts.map +1 -0
- package/dist/renderable/codecs/decision-doc.js +485 -0
- package/dist/renderable/codecs/decision-doc.js.map +1 -0
- package/dist/renderable/codecs/design-review.d.ts +55 -0
- package/dist/renderable/codecs/design-review.d.ts.map +1 -0
- package/dist/renderable/codecs/design-review.js +532 -0
- package/dist/renderable/codecs/design-review.js.map +1 -0
- package/dist/renderable/codecs/diagram-utils.d.ts +62 -0
- package/dist/renderable/codecs/diagram-utils.d.ts.map +1 -0
- package/dist/renderable/codecs/diagram-utils.js +70 -0
- package/dist/renderable/codecs/diagram-utils.js.map +1 -0
- package/dist/renderable/codecs/helpers.d.ts +553 -0
- package/dist/renderable/codecs/helpers.d.ts.map +1 -0
- package/dist/renderable/codecs/helpers.js +913 -0
- package/dist/renderable/codecs/helpers.js.map +1 -0
- package/dist/renderable/codecs/index-codec.d.ts +4714 -0
- package/dist/renderable/codecs/index-codec.d.ts.map +1 -0
- package/dist/renderable/codecs/index-codec.js +250 -0
- package/dist/renderable/codecs/index-codec.js.map +1 -0
- package/dist/renderable/codecs/index.d.ts +46 -0
- package/dist/renderable/codecs/index.d.ts.map +1 -0
- package/dist/renderable/codecs/index.js +70 -0
- package/dist/renderable/codecs/index.js.map +1 -0
- package/dist/renderable/codecs/patterns.d.ts +4757 -0
- package/dist/renderable/codecs/patterns.d.ts.map +1 -0
- package/dist/renderable/codecs/patterns.js +462 -0
- package/dist/renderable/codecs/patterns.js.map +1 -0
- package/dist/renderable/codecs/planning.d.ts +14055 -0
- package/dist/renderable/codecs/planning.d.ts.map +1 -0
- package/dist/renderable/codecs/planning.js +449 -0
- package/dist/renderable/codecs/planning.js.map +1 -0
- package/dist/renderable/codecs/pr-changes.d.ts +4742 -0
- package/dist/renderable/codecs/pr-changes.d.ts.map +1 -0
- package/dist/renderable/codecs/pr-changes.js +425 -0
- package/dist/renderable/codecs/pr-changes.js.map +1 -0
- package/dist/renderable/codecs/reference.d.ts +215 -0
- package/dist/renderable/codecs/reference.d.ts.map +1 -0
- package/dist/renderable/codecs/reference.js +1578 -0
- package/dist/renderable/codecs/reference.js.map +1 -0
- package/dist/renderable/codecs/reporting.d.ts +14026 -0
- package/dist/renderable/codecs/reporting.d.ts.map +1 -0
- package/dist/renderable/codecs/reporting.js +365 -0
- package/dist/renderable/codecs/reporting.js.map +1 -0
- package/dist/renderable/codecs/requirements.d.ts +4743 -0
- package/dist/renderable/codecs/requirements.d.ts.map +1 -0
- package/dist/renderable/codecs/requirements.js +428 -0
- package/dist/renderable/codecs/requirements.js.map +1 -0
- package/dist/renderable/codecs/session.d.ts +9410 -0
- package/dist/renderable/codecs/session.d.ts.map +1 -0
- package/dist/renderable/codecs/session.js +848 -0
- package/dist/renderable/codecs/session.js.map +1 -0
- package/dist/renderable/codecs/shape-matcher.d.ts +54 -0
- package/dist/renderable/codecs/shape-matcher.d.ts.map +1 -0
- package/dist/renderable/codecs/shape-matcher.js +106 -0
- package/dist/renderable/codecs/shape-matcher.js.map +1 -0
- package/dist/renderable/codecs/shared-schema.d.ts +44 -0
- package/dist/renderable/codecs/shared-schema.d.ts.map +1 -0
- package/dist/renderable/codecs/shared-schema.js +43 -0
- package/dist/renderable/codecs/shared-schema.js.map +1 -0
- package/dist/renderable/codecs/taxonomy.d.ts +4733 -0
- package/dist/renderable/codecs/taxonomy.d.ts.map +1 -0
- package/dist/renderable/codecs/taxonomy.js +570 -0
- package/dist/renderable/codecs/taxonomy.js.map +1 -0
- package/dist/renderable/codecs/timeline.d.ts +14094 -0
- package/dist/renderable/codecs/timeline.d.ts.map +1 -0
- package/dist/renderable/codecs/timeline.js +906 -0
- package/dist/renderable/codecs/timeline.js.map +1 -0
- package/dist/renderable/codecs/types/base.d.ts +81 -0
- package/dist/renderable/codecs/types/base.d.ts.map +1 -0
- package/dist/renderable/codecs/types/base.js +56 -0
- package/dist/renderable/codecs/types/base.js.map +1 -0
- package/dist/renderable/codecs/types/index.d.ts +5 -0
- package/dist/renderable/codecs/types/index.d.ts.map +1 -0
- package/dist/renderable/codecs/types/index.js +5 -0
- package/dist/renderable/codecs/types/index.js.map +1 -0
- package/dist/renderable/codecs/validation-rules.d.ts +4773 -0
- package/dist/renderable/codecs/validation-rules.d.ts.map +1 -0
- package/dist/renderable/codecs/validation-rules.js +537 -0
- package/dist/renderable/codecs/validation-rules.js.map +1 -0
- package/dist/renderable/generate.d.ts +338 -0
- package/dist/renderable/generate.d.ts.map +1 -0
- package/dist/renderable/generate.js +437 -0
- package/dist/renderable/generate.js.map +1 -0
- package/dist/renderable/index.d.ts +36 -0
- package/dist/renderable/index.d.ts.map +1 -0
- package/dist/renderable/index.js +58 -0
- package/dist/renderable/index.js.map +1 -0
- package/dist/renderable/load-preamble.d.ts +56 -0
- package/dist/renderable/load-preamble.d.ts.map +1 -0
- package/dist/renderable/load-preamble.js +298 -0
- package/dist/renderable/load-preamble.js.map +1 -0
- package/dist/renderable/render.d.ts +61 -0
- package/dist/renderable/render.d.ts.map +1 -0
- package/dist/renderable/render.js +346 -0
- package/dist/renderable/render.js.map +1 -0
- package/dist/renderable/schema.d.ts +194 -0
- package/dist/renderable/schema.d.ts.map +1 -0
- package/dist/renderable/schema.js +197 -0
- package/dist/renderable/schema.js.map +1 -0
- package/dist/renderable/utils.d.ts +146 -0
- package/dist/renderable/utils.d.ts.map +1 -0
- package/dist/renderable/utils.js +362 -0
- package/dist/renderable/utils.js.map +1 -0
- package/dist/scanner/ast-parser.d.ts +75 -0
- package/dist/scanner/ast-parser.d.ts.map +1 -0
- package/dist/scanner/ast-parser.js +835 -0
- package/dist/scanner/ast-parser.js.map +1 -0
- package/dist/scanner/gherkin-ast-parser.d.ts +166 -0
- package/dist/scanner/gherkin-ast-parser.d.ts.map +1 -0
- package/dist/scanner/gherkin-ast-parser.js +507 -0
- package/dist/scanner/gherkin-ast-parser.js.map +1 -0
- package/dist/scanner/gherkin-scanner.d.ts +106 -0
- package/dist/scanner/gherkin-scanner.d.ts.map +1 -0
- package/dist/scanner/gherkin-scanner.js +149 -0
- package/dist/scanner/gherkin-scanner.js.map +1 -0
- package/dist/scanner/index.d.ts +85 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +102 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/pattern-scanner.d.ts +83 -0
- package/dist/scanner/pattern-scanner.d.ts.map +1 -0
- package/dist/scanner/pattern-scanner.js +110 -0
- package/dist/scanner/pattern-scanner.js.map +1 -0
- package/dist/taxonomy/categories.d.ts +47 -0
- package/dist/taxonomy/categories.d.ts.map +1 -0
- package/dist/taxonomy/categories.js +175 -0
- package/dist/taxonomy/categories.js.map +1 -0
- package/dist/taxonomy/claude-section-values.d.ts +12 -0
- package/dist/taxonomy/claude-section-values.d.ts.map +1 -0
- package/dist/taxonomy/claude-section-values.js +17 -0
- package/dist/taxonomy/claude-section-values.js.map +1 -0
- package/dist/taxonomy/conventions.d.ts +13 -0
- package/dist/taxonomy/conventions.d.ts.map +1 -0
- package/dist/taxonomy/conventions.js +27 -0
- package/dist/taxonomy/conventions.js.map +1 -0
- package/dist/taxonomy/deliverable-status.d.ts +99 -0
- package/dist/taxonomy/deliverable-status.d.ts.map +1 -0
- package/dist/taxonomy/deliverable-status.js +131 -0
- package/dist/taxonomy/deliverable-status.js.map +1 -0
- package/dist/taxonomy/format-types.d.ts +17 -0
- package/dist/taxonomy/format-types.d.ts.map +1 -0
- package/dist/taxonomy/format-types.js +23 -0
- package/dist/taxonomy/format-types.js.map +1 -0
- package/dist/taxonomy/generator-options.d.ts +67 -0
- package/dist/taxonomy/generator-options.d.ts.map +1 -0
- package/dist/taxonomy/generator-options.js +75 -0
- package/dist/taxonomy/generator-options.js.map +1 -0
- package/dist/taxonomy/hierarchy-levels.d.ts +23 -0
- package/dist/taxonomy/hierarchy-levels.d.ts.map +1 -0
- package/dist/taxonomy/hierarchy-levels.js +22 -0
- package/dist/taxonomy/hierarchy-levels.js.map +1 -0
- package/dist/taxonomy/index.d.ts +35 -0
- package/dist/taxonomy/index.d.ts.map +1 -0
- package/dist/taxonomy/index.js +56 -0
- package/dist/taxonomy/index.js.map +1 -0
- package/dist/taxonomy/layer-types.d.ts +22 -0
- package/dist/taxonomy/layer-types.d.ts.map +1 -0
- package/dist/taxonomy/layer-types.js +28 -0
- package/dist/taxonomy/layer-types.js.map +1 -0
- package/dist/taxonomy/normalized-status.d.ts +99 -0
- package/dist/taxonomy/normalized-status.d.ts.map +1 -0
- package/dist/taxonomy/normalized-status.js +113 -0
- package/dist/taxonomy/normalized-status.js.map +1 -0
- package/dist/taxonomy/registry-builder.d.ts +104 -0
- package/dist/taxonomy/registry-builder.d.ts.map +1 -0
- package/dist/taxonomy/registry-builder.js +561 -0
- package/dist/taxonomy/registry-builder.js.map +1 -0
- package/dist/taxonomy/risk-levels.d.ts +16 -0
- package/dist/taxonomy/risk-levels.d.ts.map +1 -0
- package/dist/taxonomy/risk-levels.js +15 -0
- package/dist/taxonomy/risk-levels.js.map +1 -0
- package/dist/taxonomy/severity-types.d.ts +6 -0
- package/dist/taxonomy/severity-types.d.ts.map +1 -0
- package/dist/taxonomy/severity-types.js +5 -0
- package/dist/taxonomy/severity-types.js.map +1 -0
- package/dist/taxonomy/status-values.d.ts +39 -0
- package/dist/taxonomy/status-values.d.ts.map +1 -0
- package/dist/taxonomy/status-values.js +42 -0
- package/dist/taxonomy/status-values.js.map +1 -0
- package/dist/types/branded.d.ts +89 -0
- package/dist/types/branded.d.ts.map +1 -0
- package/dist/types/branded.js +57 -0
- package/dist/types/branded.js.map +1 -0
- package/dist/types/errors.d.ts +342 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +251 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +41 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/result.d.ts +78 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +78 -0
- package/dist/types/result.js.map +1 -0
- package/dist/utils/collection-utils.d.ts +49 -0
- package/dist/utils/collection-utils.d.ts.map +1 -0
- package/dist/utils/collection-utils.js +58 -0
- package/dist/utils/collection-utils.js.map +1 -0
- package/dist/utils/id-utils.d.ts +46 -0
- package/dist/utils/id-utils.d.ts.map +1 -0
- package/dist/utils/id-utils.js +51 -0
- package/dist/utils/id-utils.js.map +1 -0
- package/dist/utils/index.d.ts +21 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +21 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/string-utils.d.ts +150 -0
- package/dist/utils/string-utils.d.ts.map +1 -0
- package/dist/utils/string-utils.js +281 -0
- package/dist/utils/string-utils.js.map +1 -0
- package/dist/validation/anti-patterns.d.ts +134 -0
- package/dist/validation/anti-patterns.d.ts.map +1 -0
- package/dist/validation/anti-patterns.js +307 -0
- package/dist/validation/anti-patterns.js.map +1 -0
- package/dist/validation/dod-validator.d.ts +94 -0
- package/dist/validation/dod-validator.d.ts.map +1 -0
- package/dist/validation/dod-validator.js +198 -0
- package/dist/validation/dod-validator.js.map +1 -0
- package/dist/validation/fsm/index.d.ts +59 -0
- package/dist/validation/fsm/index.d.ts.map +1 -0
- package/dist/validation/fsm/index.js +64 -0
- package/dist/validation/fsm/index.js.map +1 -0
- package/dist/validation/fsm/states.d.ts +93 -0
- package/dist/validation/fsm/states.d.ts.map +1 -0
- package/dist/validation/fsm/states.js +98 -0
- package/dist/validation/fsm/states.js.map +1 -0
- package/dist/validation/fsm/transitions.d.ts +100 -0
- package/dist/validation/fsm/transitions.d.ts.map +1 -0
- package/dist/validation/fsm/transitions.js +122 -0
- package/dist/validation/fsm/transitions.js.map +1 -0
- package/dist/validation/fsm/validator.d.ts +163 -0
- package/dist/validation/fsm/validator.d.ts.map +1 -0
- package/dist/validation/fsm/validator.js +205 -0
- package/dist/validation/fsm/validator.js.map +1 -0
- package/dist/validation/index.d.ts +23 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +25 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/types.d.ts +136 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +56 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/validation-schemas/codec-utils.d.ts +188 -0
- package/dist/validation-schemas/codec-utils.d.ts.map +1 -0
- package/dist/validation-schemas/codec-utils.js +258 -0
- package/dist/validation-schemas/codec-utils.js.map +1 -0
- package/dist/validation-schemas/config.d.ts +99 -0
- package/dist/validation-schemas/config.d.ts.map +1 -0
- package/dist/validation-schemas/config.js +178 -0
- package/dist/validation-schemas/config.js.map +1 -0
- package/dist/validation-schemas/doc-directive.d.ts +195 -0
- package/dist/validation-schemas/doc-directive.d.ts.map +1 -0
- package/dist/validation-schemas/doc-directive.js +239 -0
- package/dist/validation-schemas/doc-directive.js.map +1 -0
- package/dist/validation-schemas/dual-source.d.ts +167 -0
- package/dist/validation-schemas/dual-source.d.ts.map +1 -0
- package/dist/validation-schemas/dual-source.js +168 -0
- package/dist/validation-schemas/dual-source.js.map +1 -0
- package/dist/validation-schemas/export-info.d.ts +53 -0
- package/dist/validation-schemas/export-info.d.ts.map +1 -0
- package/dist/validation-schemas/export-info.js +101 -0
- package/dist/validation-schemas/export-info.js.map +1 -0
- package/dist/validation-schemas/extracted-pattern.d.ts +351 -0
- package/dist/validation-schemas/extracted-pattern.d.ts.map +1 -0
- package/dist/validation-schemas/extracted-pattern.js +459 -0
- package/dist/validation-schemas/extracted-pattern.js.map +1 -0
- package/dist/validation-schemas/extracted-shape.d.ts +200 -0
- package/dist/validation-schemas/extracted-shape.d.ts.map +1 -0
- package/dist/validation-schemas/extracted-shape.js +182 -0
- package/dist/validation-schemas/extracted-shape.js.map +1 -0
- package/dist/validation-schemas/feature.d.ts +554 -0
- package/dist/validation-schemas/feature.d.ts.map +1 -0
- package/dist/validation-schemas/feature.js +262 -0
- package/dist/validation-schemas/feature.js.map +1 -0
- package/dist/validation-schemas/index.d.ts +15 -0
- package/dist/validation-schemas/index.d.ts.map +1 -0
- package/dist/validation-schemas/index.js +32 -0
- package/dist/validation-schemas/index.js.map +1 -0
- package/dist/validation-schemas/lint.d.ts +46 -0
- package/dist/validation-schemas/lint.d.ts.map +1 -0
- package/dist/validation-schemas/lint.js +45 -0
- package/dist/validation-schemas/lint.js.map +1 -0
- package/dist/validation-schemas/master-dataset.d.ts +8299 -0
- package/dist/validation-schemas/master-dataset.d.ts.map +1 -0
- package/dist/validation-schemas/master-dataset.js +275 -0
- package/dist/validation-schemas/master-dataset.js.map +1 -0
- package/dist/validation-schemas/output-schemas.d.ts +183 -0
- package/dist/validation-schemas/output-schemas.d.ts.map +1 -0
- package/dist/validation-schemas/output-schemas.js +149 -0
- package/dist/validation-schemas/output-schemas.js.map +1 -0
- package/dist/validation-schemas/scenario-ref.d.ts +80 -0
- package/dist/validation-schemas/scenario-ref.d.ts.map +1 -0
- package/dist/validation-schemas/scenario-ref.js +73 -0
- package/dist/validation-schemas/scenario-ref.js.map +1 -0
- package/dist/validation-schemas/tag-registry.d.ts +210 -0
- package/dist/validation-schemas/tag-registry.d.ts.map +1 -0
- package/dist/validation-schemas/tag-registry.js +248 -0
- package/dist/validation-schemas/tag-registry.js.map +1 -0
- package/dist/validation-schemas/workflow-config.d.ts +125 -0
- package/dist/validation-schemas/workflow-config.d.ts.map +1 -0
- package/dist/validation-schemas/workflow-config.js +138 -0
- package/dist/validation-schemas/workflow-config.js.map +1 -0
- package/docs/ANNOTATION-GUIDE.md +271 -0
- package/docs/ARCHITECTURE.md +1636 -0
- package/docs/CONFIGURATION.md +337 -0
- package/docs/DOCS-GAP-ANALYSIS.md +811 -0
- package/docs/GHERKIN-PATTERNS.md +366 -0
- package/docs/INDEX.md +345 -0
- package/docs/MCP-SETUP.md +140 -0
- package/docs/METHODOLOGY.md +240 -0
- package/docs/PROCESS-API.md +65 -0
- package/docs/PROCESS-GUARD.md +341 -0
- package/docs/SESSION-GUIDES.md +391 -0
- package/docs/TAXONOMY.md +106 -0
- package/docs/VALIDATION.md +418 -0
- package/docs-live/ARCHITECTURE.md +362 -0
- package/docs-live/BUSINESS-RULES.md +24 -0
- package/docs-live/CHANGELOG-GENERATED.md +375 -0
- package/docs-live/DECISIONS.md +78 -0
- package/docs-live/INDEX.md +231 -0
- package/docs-live/PRODUCT-AREAS.md +255 -0
- package/docs-live/TAXONOMY.md +202 -0
- package/docs-live/VALIDATION-RULES.md +119 -0
- package/docs-live/_claude-md/annotation/annotation-overview.md +26 -0
- package/docs-live/_claude-md/annotation/annotation-reference.md +213 -0
- package/docs-live/_claude-md/architecture/architecture-codecs.md +160 -0
- package/docs-live/_claude-md/architecture/architecture-types.md +32 -0
- package/docs-live/_claude-md/architecture/reference-sample.md +162 -0
- package/docs-live/_claude-md/authoring/gherkin-authoring-guide.md +245 -0
- package/docs-live/_claude-md/configuration/configuration-guide.md +216 -0
- package/docs-live/_claude-md/configuration/configuration-overview.md +37 -0
- package/docs-live/_claude-md/core-types/core-types-overview.md +20 -0
- package/docs-live/_claude-md/data-api/data-api-overview.md +39 -0
- package/docs-live/_claude-md/generation/generation-overview.md +30 -0
- package/docs-live/_claude-md/process/process-overview.md +127 -0
- package/docs-live/_claude-md/validation/process-guard.md +185 -0
- package/docs-live/_claude-md/validation/validation-overview.md +37 -0
- package/docs-live/_claude-md/validation/validation-tools-guide.md +242 -0
- package/docs-live/_claude-md/workflow/session-workflow-guide.md +141 -0
- package/docs-live/business-rules/annotation.md +1462 -0
- package/docs-live/business-rules/configuration.md +465 -0
- package/docs-live/business-rules/core-types.md +531 -0
- package/docs-live/business-rules/data-api.md +1403 -0
- package/docs-live/business-rules/generation.md +4726 -0
- package/docs-live/business-rules/process.md +122 -0
- package/docs-live/business-rules/validation.md +998 -0
- package/docs-live/decisions/adr-001-taxonomy-canonical-values.md +197 -0
- package/docs-live/decisions/adr-002-gherkin-only-testing.md +57 -0
- package/docs-live/decisions/adr-003-source-first-pattern-architecture.md +147 -0
- package/docs-live/decisions/adr-004-session-workflow-commands.md +137 -0
- package/docs-live/decisions/adr-005-codec-based-markdown-rendering.md +150 -0
- package/docs-live/decisions/adr-006-single-read-model-architecture.md +136 -0
- package/docs-live/decisions/adr-021-doc-generation-proof-of-concept.md +489 -0
- package/docs-live/product-areas/ANNOTATION.md +591 -0
- package/docs-live/product-areas/CONFIGURATION.md +1048 -0
- package/docs-live/product-areas/CORE-TYPES.md +221 -0
- package/docs-live/product-areas/DATA-API.md +850 -0
- package/docs-live/product-areas/GENERATION.md +1200 -0
- package/docs-live/product-areas/PROCESS.md +351 -0
- package/docs-live/product-areas/VALIDATION.md +1135 -0
- package/docs-live/reference/ANNOTATION-REFERENCE.md +232 -0
- package/docs-live/reference/ARCHITECTURE-CODECS.md +675 -0
- package/docs-live/reference/ARCHITECTURE-TYPES.md +436 -0
- package/docs-live/reference/CONFIGURATION-GUIDE.md +235 -0
- package/docs-live/reference/GHERKIN-AUTHORING-GUIDE.md +270 -0
- package/docs-live/reference/PROCESS-API-RECIPES.md +476 -0
- package/docs-live/reference/PROCESS-API-REFERENCE.md +63 -0
- package/docs-live/reference/PROCESS-GUARD-REFERENCE.md +258 -0
- package/docs-live/reference/REFERENCE-SAMPLE.md +1135 -0
- package/docs-live/reference/SESSION-WORKFLOW-GUIDE.md +384 -0
- package/docs-live/reference/VALIDATION-TOOLS-GUIDE.md +263 -0
- package/docs-live/taxonomy/categories.md +33 -0
- package/docs-live/taxonomy/format-types.md +67 -0
- package/docs-live/taxonomy/metadata-tags.md +693 -0
- package/docs-live/validation/error-catalog.md +78 -0
- package/docs-live/validation/fsm-transitions.md +50 -0
- package/docs-live/validation/protection-levels.md +51 -0
- package/package.json +233 -0
|
@@ -0,0 +1,913 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @architect
|
|
3
|
+
* @architect-core
|
|
4
|
+
* @architect-pattern RichContentHelpers
|
|
5
|
+
* @architect-status completed
|
|
6
|
+
*
|
|
7
|
+
* ## Rich Content Rendering Helpers
|
|
8
|
+
*
|
|
9
|
+
* Shared helper functions for rendering Gherkin rich content in document codecs.
|
|
10
|
+
* Provides granular and composite helpers for DataTables, DocStrings, steps,
|
|
11
|
+
* scenarios, and business rules.
|
|
12
|
+
*
|
|
13
|
+
* ### When to Use
|
|
14
|
+
*
|
|
15
|
+
* - When building custom codecs that need to render Gherkin content
|
|
16
|
+
* - When transforming DataTables, DocStrings, or scenarios into markdown
|
|
17
|
+
* - When implementing acceptance criteria or business rules sections
|
|
18
|
+
*
|
|
19
|
+
* ### Usage Pattern
|
|
20
|
+
*
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import { renderAcceptanceCriteria, renderBusinessRulesSection } from "./helpers.js";
|
|
23
|
+
*
|
|
24
|
+
* // Composite helpers (most common use)
|
|
25
|
+
* sections.push(...renderAcceptanceCriteria(pattern.scenarios));
|
|
26
|
+
* sections.push(...renderBusinessRulesSection(pattern.rules));
|
|
27
|
+
*
|
|
28
|
+
* // Granular helpers (for custom rendering)
|
|
29
|
+
* const tableBlock = renderDataTable(step.dataTable);
|
|
30
|
+
* const codeBlock = renderDocString(step.docString, "markdown");
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
import { table, code, list, paragraph, heading } from '../schema.js';
|
|
34
|
+
import { normalizeLineEndings } from '../../utils/string-utils.js';
|
|
35
|
+
import { extractTablesFromDescription } from './convention-extractor.js';
|
|
36
|
+
/**
|
|
37
|
+
* Partition business rules by ADR-style name prefixes.
|
|
38
|
+
*
|
|
39
|
+
* Rules are categorized based on their name prefix:
|
|
40
|
+
* - "Context..." → context section
|
|
41
|
+
* - "Decision..." → decision section
|
|
42
|
+
* - "Consequence..." → consequences section
|
|
43
|
+
* - Others → other (optionally logged as warning)
|
|
44
|
+
*
|
|
45
|
+
* This is a shared helper used by both ADR and Decision Doc codecs.
|
|
46
|
+
*
|
|
47
|
+
* @param rules - Business rules from the extracted pattern
|
|
48
|
+
* @param options - Partitioning options
|
|
49
|
+
* @returns Partitioned rules by category
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* // ADR codec (warn about unmatched rules)
|
|
54
|
+
* const partitioned = partitionRulesByPrefix(pattern.rules, {
|
|
55
|
+
* warnOnOther: true,
|
|
56
|
+
* patternName: pattern.name
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* // Decision doc codec (no warning)
|
|
60
|
+
* const partitioned = partitionRulesByPrefix(pattern.rules);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export function partitionRulesByPrefix(rules, options = {}) {
|
|
64
|
+
if (!rules || rules.length === 0) {
|
|
65
|
+
return { context: [], decision: [], consequences: [], other: [] };
|
|
66
|
+
}
|
|
67
|
+
const { warnOnOther = false, patternName, onWarning = console.warn } = options;
|
|
68
|
+
const context = [];
|
|
69
|
+
const decision = [];
|
|
70
|
+
const consequences = [];
|
|
71
|
+
const other = [];
|
|
72
|
+
for (const rule of rules) {
|
|
73
|
+
const nameLower = rule.name.toLowerCase();
|
|
74
|
+
if (nameLower.startsWith('context')) {
|
|
75
|
+
context.push(rule);
|
|
76
|
+
}
|
|
77
|
+
else if (nameLower.startsWith('decision')) {
|
|
78
|
+
decision.push(rule);
|
|
79
|
+
}
|
|
80
|
+
else if (nameLower.startsWith('consequence')) {
|
|
81
|
+
consequences.push(rule);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
other.push(rule);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Optionally warn about rules that don't match expected ADR prefixes
|
|
88
|
+
if (warnOnOther && other.length > 0) {
|
|
89
|
+
const otherNames = other.map((r) => `"${r.name}"`).join(', ');
|
|
90
|
+
const patternContext = patternName ? ` in pattern "${patternName}"` : '';
|
|
91
|
+
onWarning(`[codec] ${other.length} rule(s)${patternContext} not matching ADR prefixes (Context/Decision/Consequence): ${otherNames}. These rules will not be rendered in standard ADR sections.`);
|
|
92
|
+
}
|
|
93
|
+
return { context, decision, consequences, other };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Default rich content options
|
|
97
|
+
*
|
|
98
|
+
* Note: onWarning and warningCollector are intentionally undefined by default.
|
|
99
|
+
* When undefined, warnings fall back to console.warn via emitWarning().
|
|
100
|
+
*/
|
|
101
|
+
export const DEFAULT_RICH_CONTENT_OPTIONS = {
|
|
102
|
+
includeSteps: true,
|
|
103
|
+
includeDataTables: true,
|
|
104
|
+
includeDocStrings: true,
|
|
105
|
+
includeRules: true,
|
|
106
|
+
docStringLanguage: 'markdown',
|
|
107
|
+
baseHeadingLevel: 4,
|
|
108
|
+
onWarning: undefined,
|
|
109
|
+
warningCollector: undefined,
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Merge user options with defaults
|
|
113
|
+
*/
|
|
114
|
+
export function mergeRichContentOptions(options) {
|
|
115
|
+
if (!options) {
|
|
116
|
+
return DEFAULT_RICH_CONTENT_OPTIONS;
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
...DEFAULT_RICH_CONTENT_OPTIONS,
|
|
120
|
+
...options,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Format a warning for CI output (GitHub Actions compatible).
|
|
125
|
+
*
|
|
126
|
+
* @param warning - The warning to format
|
|
127
|
+
* @returns Formatted string for CI log parsing
|
|
128
|
+
*/
|
|
129
|
+
export function formatWarningForCI(warning) {
|
|
130
|
+
const parts = [];
|
|
131
|
+
if (warning.file)
|
|
132
|
+
parts.push(`file=${warning.file}`);
|
|
133
|
+
if (warning.line !== undefined)
|
|
134
|
+
parts.push(`line=${warning.line}`);
|
|
135
|
+
parts.push(`code=${warning.code}`);
|
|
136
|
+
const attributes = parts.join(',');
|
|
137
|
+
return `::warning ${attributes}::${warning.message}`;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Emit a warning using the configured handler, collector, or console.warn fallback.
|
|
141
|
+
*
|
|
142
|
+
* Priority order:
|
|
143
|
+
* 1. WarningCollector (if provided) - for structured aggregation
|
|
144
|
+
* 2. onWarning callback (if provided) - for custom handling
|
|
145
|
+
* 3. console.warn - default fallback
|
|
146
|
+
*
|
|
147
|
+
* @param warning - The warning to emit
|
|
148
|
+
* @param options - Options containing warning handlers
|
|
149
|
+
* @param source - Optional source file for collector context
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
function emitWarning(warning, options, source) {
|
|
153
|
+
// Priority 1: Use WarningCollector if available (structured aggregation)
|
|
154
|
+
if (options?.warningCollector) {
|
|
155
|
+
options.warningCollector.capture({
|
|
156
|
+
source: source ?? 'rich-content-rendering',
|
|
157
|
+
category: 'format',
|
|
158
|
+
message: warning.message,
|
|
159
|
+
subcategory: warning.code,
|
|
160
|
+
});
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
// Priority 2: Use onWarning callback if available
|
|
164
|
+
if (options?.onWarning) {
|
|
165
|
+
options.onWarning(warning);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
// Priority 3: Fall back to console.warn with structured format
|
|
169
|
+
const contextSuffix = warning.context ? ` Context: ${warning.context}` : '';
|
|
170
|
+
console.warn(`[${warning.code}] ${warning.message}${contextSuffix}`);
|
|
171
|
+
}
|
|
172
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
173
|
+
// Granular Helpers
|
|
174
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
175
|
+
/**
|
|
176
|
+
* Render a Gherkin DataTable as a markdown table block
|
|
177
|
+
*
|
|
178
|
+
* @param dt - The DataTable to render
|
|
179
|
+
* @returns A table SectionBlock
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```typescript
|
|
183
|
+
* const tableBlock = renderDataTable(step.dataTable);
|
|
184
|
+
* sections.push(tableBlock);
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
export function renderDataTable(dt) {
|
|
188
|
+
const rows = dt.rows.map((row) => {
|
|
189
|
+
return dt.headers.map((header) => row[header] ?? '');
|
|
190
|
+
});
|
|
191
|
+
return table(dt.headers, rows);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Render a DocString as a code block
|
|
195
|
+
*
|
|
196
|
+
* Accepts either a plain string or an object with content and optional mediaType.
|
|
197
|
+
* When mediaType is provided in the object, it takes precedence over the language parameter.
|
|
198
|
+
*
|
|
199
|
+
* @param docString - The DocString content (string or object with content/mediaType)
|
|
200
|
+
* @param language - Optional language hint fallback (default: "markdown")
|
|
201
|
+
* @returns A code SectionBlock
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* // With plain string
|
|
206
|
+
* const codeBlock = renderDocString(step.docString, "json");
|
|
207
|
+
*
|
|
208
|
+
* // With object containing mediaType
|
|
209
|
+
* const codeBlock = renderDocString({ content: "code", mediaType: "typescript" });
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
export function renderDocString(docString, language = 'markdown') {
|
|
213
|
+
if (typeof docString === 'string') {
|
|
214
|
+
// Plain string format
|
|
215
|
+
return code(docString, language);
|
|
216
|
+
}
|
|
217
|
+
// Object format with optional mediaType
|
|
218
|
+
return code(docString.content, docString.mediaType ?? language);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Render scenario steps as a list
|
|
222
|
+
*
|
|
223
|
+
* @param steps - The scenario steps
|
|
224
|
+
* @returns A list SectionBlock
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```typescript
|
|
228
|
+
* const stepsList = renderStepsList(scenario.steps);
|
|
229
|
+
* sections.push(stepsList);
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
export function renderStepsList(steps) {
|
|
233
|
+
const stepItems = steps.map((step) => `${step.keyword} ${step.text}`);
|
|
234
|
+
return list(stepItems);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Default tab width for tab-to-space normalization in dedent.
|
|
238
|
+
*/
|
|
239
|
+
const DEFAULT_TAB_WIDTH = 2;
|
|
240
|
+
/**
|
|
241
|
+
* Normalize tabs to spaces for consistent indentation calculation.
|
|
242
|
+
*
|
|
243
|
+
* @param text - Text that may contain tabs
|
|
244
|
+
* @param tabWidth - Number of spaces per tab (default: 2)
|
|
245
|
+
* @returns Text with tabs replaced by spaces
|
|
246
|
+
*/
|
|
247
|
+
function normalizeTabs(text, tabWidth = DEFAULT_TAB_WIDTH) {
|
|
248
|
+
return text.replace(/\t/g, ' '.repeat(tabWidth));
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Remove common leading indentation from all lines in a code block.
|
|
252
|
+
*
|
|
253
|
+
* When DocStrings are embedded in Gherkin files, they often have consistent
|
|
254
|
+
* indentation to align with the surrounding scenario structure. This function
|
|
255
|
+
* normalizes that indentation by:
|
|
256
|
+
* 1. Normalizing tabs to spaces (default: 2 spaces per tab)
|
|
257
|
+
* 2. Finding the minimum indentation across all non-empty lines
|
|
258
|
+
* 3. Removing that common indentation from every line
|
|
259
|
+
* 4. Trimming trailing whitespace from each line
|
|
260
|
+
*
|
|
261
|
+
* @param text - The code block content to dedent
|
|
262
|
+
* @param tabWidth - Number of spaces per tab (default: 2)
|
|
263
|
+
* @returns The dedented text with normalized indentation
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```typescript
|
|
267
|
+
* // Input (indented to match Gherkin formatting):
|
|
268
|
+
* dedent(" const x = 1;\n const y = 2;")
|
|
269
|
+
* // Returns: "const x = 1;\nconst y = 2;"
|
|
270
|
+
*
|
|
271
|
+
* // Mixed indentation (preserves relative indentation):
|
|
272
|
+
* dedent(" function foo() {\n return 42;\n }")
|
|
273
|
+
* // Returns: "function foo() {\n return 42;\n}"
|
|
274
|
+
*
|
|
275
|
+
* // Tab-indented code (tabs normalized to spaces):
|
|
276
|
+
* dedent("\t\tconst x = 1;")
|
|
277
|
+
* // Returns: "const x = 1;"
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
export function dedent(text, tabWidth = DEFAULT_TAB_WIDTH) {
|
|
281
|
+
// Normalize tabs to spaces before processing
|
|
282
|
+
const normalizedText = normalizeTabs(text, tabWidth);
|
|
283
|
+
const lines = normalizedText.split('\n');
|
|
284
|
+
// Find minimum indentation (ignoring empty lines)
|
|
285
|
+
const nonEmptyLines = lines.filter((line) => line.trim().length > 0);
|
|
286
|
+
if (nonEmptyLines.length === 0)
|
|
287
|
+
return text;
|
|
288
|
+
const minIndent = Math.min(...nonEmptyLines.map((line) => {
|
|
289
|
+
const match = /^(\s*)/.exec(line);
|
|
290
|
+
// The regex always matches (even empty string), but TypeScript needs reassurance
|
|
291
|
+
return match?.[1]?.length ?? 0;
|
|
292
|
+
}));
|
|
293
|
+
// If no common indentation, just trim trailing whitespace
|
|
294
|
+
if (minIndent === 0) {
|
|
295
|
+
return lines.map((line) => line.trimEnd()).join('\n');
|
|
296
|
+
}
|
|
297
|
+
// Remove common indentation and trailing whitespace from each line
|
|
298
|
+
return lines.map((line) => line.slice(minIndent).trimEnd()).join('\n');
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Parse description text for embedded DocStrings and convert to mixed content
|
|
302
|
+
*
|
|
303
|
+
* DocStrings in Gherkin are identified by: """language\n...\n"""
|
|
304
|
+
* Text between DocStrings renders as paragraphs, DocStrings render as code blocks.
|
|
305
|
+
*
|
|
306
|
+
* **Defensive handling:**
|
|
307
|
+
* - Normalizes Windows line endings (CRLF → LF) before parsing
|
|
308
|
+
* - Detects unclosed DocStrings (odd count of """) and returns plain paragraph fallback
|
|
309
|
+
* - Handles empty input gracefully
|
|
310
|
+
* - Dedents code block content to normalize indentation from Gherkin formatting
|
|
311
|
+
*
|
|
312
|
+
* @param description - The description text that may contain DocStrings
|
|
313
|
+
* @param options - Optional rendering options (used for warning callback)
|
|
314
|
+
* @returns Array of SectionBlocks (paragraphs and code blocks)
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```typescript
|
|
318
|
+
* // Input with DocString:
|
|
319
|
+
* // "Some text\n\"\"\"typescript\nconst x = 1;\n\"\"\"\nMore text"
|
|
320
|
+
* // Output: [paragraph("Some text"), code("const x = 1;", "typescript"), paragraph("More text")]
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
export function parseDescriptionWithDocStrings(description, options) {
|
|
324
|
+
// Handle empty input
|
|
325
|
+
if (!description || description.trim().length === 0) {
|
|
326
|
+
return [];
|
|
327
|
+
}
|
|
328
|
+
// Normalize line endings (Windows CRLF → LF)
|
|
329
|
+
const normalized = normalizeLineEndings(description);
|
|
330
|
+
// Detect unclosed DocStrings (odd number of """)
|
|
331
|
+
// Important: Exclude """ that appears inside backticks (inline code examples)
|
|
332
|
+
// e.g., `"""typescript` should not be counted as a delimiter
|
|
333
|
+
const withoutInlineCode = normalized.replace(/`[^`]+`/g, '');
|
|
334
|
+
const docStringDelimiters = withoutInlineCode.match(/"""/g);
|
|
335
|
+
if (docStringDelimiters && docStringDelimiters.length % 2 !== 0) {
|
|
336
|
+
// Unclosed DocString detected - return as plain paragraph to avoid corruption
|
|
337
|
+
// This is a defensive fallback; the content may not render as intended
|
|
338
|
+
emitWarning({
|
|
339
|
+
code: 'unclosed-docstring',
|
|
340
|
+
message: 'Unclosed DocString detected (odd number of """ delimiters)',
|
|
341
|
+
context: `Found ${docStringDelimiters.length} delimiters in description`,
|
|
342
|
+
}, options);
|
|
343
|
+
return [paragraph(normalized.trim())];
|
|
344
|
+
}
|
|
345
|
+
const sections = [];
|
|
346
|
+
// Match """language\ncontent\n""" pattern (language is optional)
|
|
347
|
+
const docStringPattern = /"""(\w*)\n([\s\S]*?)"""/g;
|
|
348
|
+
let lastIndex = 0;
|
|
349
|
+
let match;
|
|
350
|
+
while ((match = docStringPattern.exec(normalized)) !== null) {
|
|
351
|
+
// Text before this DocString
|
|
352
|
+
const textBefore = normalized.slice(lastIndex, match.index).trim();
|
|
353
|
+
if (textBefore) {
|
|
354
|
+
sections.push(paragraph(textBefore));
|
|
355
|
+
}
|
|
356
|
+
// The DocString as a code block (empty string means no language hint)
|
|
357
|
+
// Apply dedent to normalize indentation from Gherkin formatting
|
|
358
|
+
const language = (match[1] ?? '').length > 0 ? match[1] : 'text';
|
|
359
|
+
const rawContent = (match[2] ?? '').trim();
|
|
360
|
+
const content = dedent(rawContent);
|
|
361
|
+
sections.push(code(content, language));
|
|
362
|
+
lastIndex = match.index + match[0].length;
|
|
363
|
+
}
|
|
364
|
+
// Text after last DocString (or entire text if no DocStrings)
|
|
365
|
+
const textAfter = normalized.slice(lastIndex).trim();
|
|
366
|
+
if (textAfter) {
|
|
367
|
+
sections.push(paragraph(textAfter));
|
|
368
|
+
}
|
|
369
|
+
return sections;
|
|
370
|
+
}
|
|
371
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
372
|
+
// Backtick Content Protection
|
|
373
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
374
|
+
/**
|
|
375
|
+
* Protect backtick-quoted content from regex matching by replacing with placeholders.
|
|
376
|
+
*
|
|
377
|
+
* This is essential when parsing markdown-style content where `**bold**` patterns
|
|
378
|
+
* might appear inside inline code (e.g., `` `**Verified by:**` ``). Without protection,
|
|
379
|
+
* regexes that look for `**` boundaries will incorrectly match inside backticks.
|
|
380
|
+
*
|
|
381
|
+
* @param text - The text to process
|
|
382
|
+
* @returns Object with processed text and restore function
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* ```typescript
|
|
386
|
+
* const { processed, restore } = protectBacktickContent("Text `**inside**` more");
|
|
387
|
+
* // processed = "Text __BT0__ more"
|
|
388
|
+
* const result = "Extracted: __BT0__";
|
|
389
|
+
* restore(result); // "Extracted: `**inside**`"
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
export function protectBacktickContent(text) {
|
|
393
|
+
const placeholders = [];
|
|
394
|
+
// Use unique prefix to reduce collision risk with real content
|
|
395
|
+
const processed = text.replace(/`[^`]+`/g, (match) => {
|
|
396
|
+
placeholders.push(match);
|
|
397
|
+
return `__LIBAR_BT_${placeholders.length - 1}__`;
|
|
398
|
+
});
|
|
399
|
+
const restore = (s) => s.replace(/__LIBAR_BT_(\d+)__/g, (_, i) => placeholders[Number(i)] ?? '');
|
|
400
|
+
return { processed, restore };
|
|
401
|
+
}
|
|
402
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
403
|
+
// Text Utilities
|
|
404
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
405
|
+
/**
|
|
406
|
+
* Truncate text to a maximum length, adding ellipsis if truncated.
|
|
407
|
+
*
|
|
408
|
+
* Attempts to truncate at word boundaries for cleaner output.
|
|
409
|
+
* If the text is already shorter than maxLength, returns it unchanged.
|
|
410
|
+
*
|
|
411
|
+
* @param text - The text to truncate
|
|
412
|
+
* @param maxLength - Maximum length (0 or negative = no limit)
|
|
413
|
+
* @returns Truncated text with "..." suffix if truncated
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```typescript
|
|
417
|
+
* truncateText("This is a long description", 15);
|
|
418
|
+
* // Returns: "This is a..."
|
|
419
|
+
*
|
|
420
|
+
* truncateText("Short", 100);
|
|
421
|
+
* // Returns: "Short"
|
|
422
|
+
* ```
|
|
423
|
+
*/
|
|
424
|
+
export function truncateText(text, maxLength) {
|
|
425
|
+
if (!text || maxLength <= 0 || text.length <= maxLength) {
|
|
426
|
+
return text || '';
|
|
427
|
+
}
|
|
428
|
+
// Find the last space before maxLength to truncate at word boundary
|
|
429
|
+
const truncateAt = maxLength - 3; // Reserve space for "..."
|
|
430
|
+
const lastSpace = text.lastIndexOf(' ', truncateAt);
|
|
431
|
+
// If no space found, truncate at exact position
|
|
432
|
+
const cutPoint = lastSpace > 0 ? lastSpace : truncateAt;
|
|
433
|
+
return text.slice(0, cutPoint).trim() + '...';
|
|
434
|
+
}
|
|
435
|
+
export { extractFirstSentenceRaw as extractFirstSentence } from '../../utils/string-utils.js';
|
|
436
|
+
/**
|
|
437
|
+
* Parse structured annotations from a business rule description.
|
|
438
|
+
*
|
|
439
|
+
* Extracts:
|
|
440
|
+
* - `**Invariant:** <text>` - until next `**` annotation or end
|
|
441
|
+
* - `**Rationale:** <text>` - until next `**` annotation or end
|
|
442
|
+
* - `**Verified by:** <comma,separated,list>`
|
|
443
|
+
* - DocStrings ("""language\n...\n""") as code blocks
|
|
444
|
+
*
|
|
445
|
+
* The remaining content after extraction is returned in `remainingContent`.
|
|
446
|
+
*
|
|
447
|
+
* @param description - The rule description text to parse
|
|
448
|
+
* @returns Parsed annotations with structured fields
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* ```typescript
|
|
452
|
+
* const annotations = parseBusinessRuleAnnotations(`
|
|
453
|
+
* **Invariant:** Only one reservation can exist for a given key.
|
|
454
|
+
*
|
|
455
|
+
* **Rationale:** Prevents TOCTOU race conditions.
|
|
456
|
+
*
|
|
457
|
+
* **Verified by:** Concurrent reservations, Expired cleanup
|
|
458
|
+
* `);
|
|
459
|
+
* // annotations.invariant === "Only one reservation can exist for a given key."
|
|
460
|
+
* // annotations.rationale === "Prevents TOCTOU race conditions."
|
|
461
|
+
* // annotations.verifiedBy === ["Concurrent reservations", "Expired cleanup"]
|
|
462
|
+
* ```
|
|
463
|
+
*/
|
|
464
|
+
export function parseBusinessRuleAnnotations(description) {
|
|
465
|
+
if (!description || description.trim().length === 0) {
|
|
466
|
+
return {};
|
|
467
|
+
}
|
|
468
|
+
// Normalize line endings
|
|
469
|
+
const normalized = normalizeLineEndings(description);
|
|
470
|
+
const result = {};
|
|
471
|
+
const codeExamples = [];
|
|
472
|
+
// Step 1: Extract code fences FIRST (before annotation parsing)
|
|
473
|
+
// This prevents code fences from being captured inside annotations
|
|
474
|
+
// Extract Gherkin DocStrings (""" format)
|
|
475
|
+
const docStringPattern = /"""(\w*)\n([\s\S]*?)"""/g;
|
|
476
|
+
let docMatch;
|
|
477
|
+
while ((docMatch = docStringPattern.exec(normalized)) !== null) {
|
|
478
|
+
const language = (docMatch[1] ?? '').length > 0 ? docMatch[1] : 'text';
|
|
479
|
+
const content = (docMatch[2] ?? '').trim();
|
|
480
|
+
if (content) {
|
|
481
|
+
codeExamples.push(code(content, language));
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
// Extract markdown code fences (``` format)
|
|
485
|
+
const markdownCodePattern = /```(\w*)\n([\s\S]*?)```/g;
|
|
486
|
+
let mdMatch;
|
|
487
|
+
while ((mdMatch = markdownCodePattern.exec(normalized)) !== null) {
|
|
488
|
+
const language = (mdMatch[1] ?? '').length > 0 ? mdMatch[1] : 'text';
|
|
489
|
+
const content = (mdMatch[2] ?? '').trim();
|
|
490
|
+
if (content) {
|
|
491
|
+
codeExamples.push(code(content, language));
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (codeExamples.length > 0) {
|
|
495
|
+
result.codeExamples = codeExamples;
|
|
496
|
+
}
|
|
497
|
+
// Step 2: Remove code fences from text before parsing annotations
|
|
498
|
+
// This ensures annotations don't accidentally capture code fence content
|
|
499
|
+
let textWithoutCode = normalized;
|
|
500
|
+
textWithoutCode = textWithoutCode.replace(/"""(\w*)\n[\s\S]*?"""/g, '');
|
|
501
|
+
textWithoutCode = textWithoutCode.replace(/```(\w*)\n[\s\S]*?```/g, '');
|
|
502
|
+
// Step 2a: Remove table lines (| ... |) from text before parsing annotations.
|
|
503
|
+
// Tables are extracted separately by extractTablesFromDescription() upstream.
|
|
504
|
+
// Without this, annotation regexes over-capture table content and whitespace
|
|
505
|
+
// normalization collapses tables into single-line text inside invariant/rationale.
|
|
506
|
+
// Note: stripMarkdownTables() also strips these downstream in remainingContent;
|
|
507
|
+
// the early strip here prevents annotation regex over-capture before that point.
|
|
508
|
+
textWithoutCode = textWithoutCode
|
|
509
|
+
.split('\n')
|
|
510
|
+
.filter((line) => {
|
|
511
|
+
const trimmed = line.trim();
|
|
512
|
+
return !(trimmed.startsWith('|') && trimmed.endsWith('|'));
|
|
513
|
+
})
|
|
514
|
+
.join('\n');
|
|
515
|
+
// Step 2b: Protect backtick-quoted content from regex matching
|
|
516
|
+
// This prevents `**Verified by:**` inside backticks from being treated as annotation boundary
|
|
517
|
+
// e.g., "Scenario names in `**Verified by:**` are matched" should not truncate at `**V`
|
|
518
|
+
const { processed: protectedText, restore } = protectBacktickContent(textWithoutCode);
|
|
519
|
+
// Step 3: Extract annotations from protected text
|
|
520
|
+
// Extract **Invariant:** - matches until next ** or end of string
|
|
521
|
+
const invariantPattern = /\*\*Invariant:\*\*\s*([\s\S]*?)(?=\*\*[A-Z]|\*\*$|$)/i;
|
|
522
|
+
const invariantMatch = invariantPattern.exec(protectedText);
|
|
523
|
+
if (invariantMatch?.[1]) {
|
|
524
|
+
const invariantText = invariantMatch[1].trim();
|
|
525
|
+
// Clean up: remove trailing empty lines and normalize whitespace, then restore backticks
|
|
526
|
+
result.invariant = restore(invariantText
|
|
527
|
+
.replace(/\n\s*\n/g, ' ')
|
|
528
|
+
.replace(/\s+/g, ' ')
|
|
529
|
+
.trim());
|
|
530
|
+
}
|
|
531
|
+
// Extract **Rationale:** - matches until next ** or end of string
|
|
532
|
+
const rationalePattern = /\*\*Rationale:\*\*\s*([\s\S]*?)(?=\*\*[A-Z]|\*\*$|$)/i;
|
|
533
|
+
const rationaleMatch = rationalePattern.exec(protectedText);
|
|
534
|
+
if (rationaleMatch?.[1]) {
|
|
535
|
+
const rationaleText = rationaleMatch[1].trim();
|
|
536
|
+
result.rationale = restore(rationaleText
|
|
537
|
+
.replace(/\n\s*\n/g, ' ')
|
|
538
|
+
.replace(/\s+/g, ' ')
|
|
539
|
+
.trim());
|
|
540
|
+
}
|
|
541
|
+
// Extract **Verified by:** - parse as comma-separated list
|
|
542
|
+
const verifiedByPattern = /\*\*Verified by:\*\*\s*([\s\S]*?)(?=\*\*[A-Z]|\*\*$|$)/i;
|
|
543
|
+
const verifiedByMatch = verifiedByPattern.exec(protectedText);
|
|
544
|
+
if (verifiedByMatch?.[1]) {
|
|
545
|
+
const verifiedByText = verifiedByMatch[1].trim();
|
|
546
|
+
// Split by comma and clean up each entry (restore backticks in each item)
|
|
547
|
+
result.verifiedBy = verifiedByText
|
|
548
|
+
.split(',')
|
|
549
|
+
.map((s) => restore(s.trim()))
|
|
550
|
+
.filter((s) => s.length > 0);
|
|
551
|
+
}
|
|
552
|
+
// Extract **API:** See `path` references (can appear multiple times)
|
|
553
|
+
// Note: This pattern looks for content INSIDE backticks, so we use the original
|
|
554
|
+
// textWithoutCode which still has backticks intact (only code fences removed)
|
|
555
|
+
// Pattern is case-insensitive and allows optional bold markers:
|
|
556
|
+
// - "**API:** See `path`" (standard bold)
|
|
557
|
+
// - "API: See `path`" (plain text)
|
|
558
|
+
// - "api: see `path`" (lowercase)
|
|
559
|
+
const apiRefPattern = /(?:\*\*)?API:(?:\*\*)?\s*See\s*`([^`]+)`/gi;
|
|
560
|
+
const apiRefs = [];
|
|
561
|
+
let apiMatch;
|
|
562
|
+
while ((apiMatch = apiRefPattern.exec(textWithoutCode)) !== null) {
|
|
563
|
+
const path = apiMatch[1]?.trim();
|
|
564
|
+
if (path && path.length > 0) {
|
|
565
|
+
apiRefs.push(path);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
if (apiRefs.length > 0) {
|
|
569
|
+
result.apiRefs = apiRefs;
|
|
570
|
+
}
|
|
571
|
+
// Extract **Input:** - sequence step input type annotation
|
|
572
|
+
const inputPattern = /\*\*Input:\*\*\s*([\s\S]*?)(?=\*\*[A-Z]|\*\*$|$)/i;
|
|
573
|
+
const inputMatch = inputPattern.exec(protectedText);
|
|
574
|
+
if (inputMatch?.[1]) {
|
|
575
|
+
const inputText = inputMatch[1].trim();
|
|
576
|
+
result.input = restore(inputText
|
|
577
|
+
.replace(/\n\s*\n/g, ' ')
|
|
578
|
+
.replace(/\s+/g, ' ')
|
|
579
|
+
.trim());
|
|
580
|
+
}
|
|
581
|
+
// Extract **Output:** - sequence step output type annotation
|
|
582
|
+
const outputPattern = /\*\*Output:\*\*\s*([\s\S]*?)(?=\*\*[A-Z]|\*\*$|$)/i;
|
|
583
|
+
const outputMatch = outputPattern.exec(protectedText);
|
|
584
|
+
if (outputMatch?.[1]) {
|
|
585
|
+
const outputText = outputMatch[1].trim();
|
|
586
|
+
result.output = restore(outputText
|
|
587
|
+
.replace(/\n\s*\n/g, ' ')
|
|
588
|
+
.replace(/\s+/g, ' ')
|
|
589
|
+
.trim());
|
|
590
|
+
}
|
|
591
|
+
// Step 4: Calculate remaining content (after removing annotations from protected text)
|
|
592
|
+
// Use protectedText to ensure regexes don't stop at `**X` inside backticks
|
|
593
|
+
let remaining = protectedText;
|
|
594
|
+
// Remove **Invariant:** block
|
|
595
|
+
remaining = remaining.replace(/\*\*Invariant:\*\*\s*[\s\S]*?(?=\*\*[A-Z]|\*\*$|$)/i, '');
|
|
596
|
+
// Remove **Rationale:** block
|
|
597
|
+
remaining = remaining.replace(/\*\*Rationale:\*\*\s*[\s\S]*?(?=\*\*[A-Z]|\*\*$|$)/i, '');
|
|
598
|
+
// Remove **Verified by:** block
|
|
599
|
+
remaining = remaining.replace(/\*\*Verified by:\*\*\s*[\s\S]*?(?=\*\*[A-Z]|\*\*$|$)/i, '');
|
|
600
|
+
// Remove **Input:** block
|
|
601
|
+
remaining = remaining.replace(/\*\*Input:\*\*\s*[\s\S]*?(?=\*\*[A-Z]|\*\*$|$)/i, '');
|
|
602
|
+
// Remove **Output:** block
|
|
603
|
+
remaining = remaining.replace(/\*\*Output:\*\*\s*[\s\S]*?(?=\*\*[A-Z]|\*\*$|$)/i, '');
|
|
604
|
+
// Remove **API:** See `path` references (use original pattern for protected text)
|
|
605
|
+
// Pattern matches both bold and non-bold, case-insensitive
|
|
606
|
+
remaining = remaining.replace(/(?:\*\*)?API:(?:\*\*)?\s*See\s*__LIBAR_BT_\d+__/gi, '');
|
|
607
|
+
// Clean up remaining content and restore backticks
|
|
608
|
+
remaining = restore(remaining.trim());
|
|
609
|
+
// Strip markdown tables from remaining content (tables are extracted separately
|
|
610
|
+
// by extractTables() in business-rules.ts to avoid duplicate rendering)
|
|
611
|
+
remaining = stripMarkdownTables(remaining);
|
|
612
|
+
if (remaining.length > 0) {
|
|
613
|
+
result.remainingContent = remaining;
|
|
614
|
+
}
|
|
615
|
+
return result;
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Strip markdown tables from text content.
|
|
619
|
+
*
|
|
620
|
+
* Tables are identified by lines starting and ending with | character.
|
|
621
|
+
* This removes header rows, separator rows, and data rows to prevent
|
|
622
|
+
* duplicate rendering when tables are extracted separately.
|
|
623
|
+
*
|
|
624
|
+
* @param text - Text that may contain markdown tables
|
|
625
|
+
* @returns Text with tables removed and excess newlines cleaned up
|
|
626
|
+
*
|
|
627
|
+
* @example
|
|
628
|
+
* ```typescript
|
|
629
|
+
* const text = "Intro\n| Col | Col |\n| --- | --- |\n| A | B |\nOutro";
|
|
630
|
+
* stripMarkdownTables(text); // "Intro\n\nOutro"
|
|
631
|
+
* ```
|
|
632
|
+
*/
|
|
633
|
+
export function stripMarkdownTables(text) {
|
|
634
|
+
if (!text)
|
|
635
|
+
return text;
|
|
636
|
+
return text
|
|
637
|
+
.split('\n')
|
|
638
|
+
.filter((line) => {
|
|
639
|
+
const trimmed = line.trim();
|
|
640
|
+
// Skip lines that are markdown table rows (start and end with |)
|
|
641
|
+
return !(trimmed.startsWith('|') && trimmed.endsWith('|'));
|
|
642
|
+
})
|
|
643
|
+
.join('\n')
|
|
644
|
+
.replace(/\n{3,}/g, '\n\n') // Clean up excess newlines
|
|
645
|
+
.trim();
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Render a single business rule with its description and verification info
|
|
649
|
+
*
|
|
650
|
+
* Parses the description for embedded DocStrings and renders them as code blocks.
|
|
651
|
+
*
|
|
652
|
+
* @param rule - The business rule to render
|
|
653
|
+
* @returns Array of SectionBlocks for the rule
|
|
654
|
+
*
|
|
655
|
+
* @example
|
|
656
|
+
* ```typescript
|
|
657
|
+
* sections.push(...renderBusinessRule(rule));
|
|
658
|
+
* ```
|
|
659
|
+
*/
|
|
660
|
+
export function renderBusinessRule(rule) {
|
|
661
|
+
const sections = [];
|
|
662
|
+
sections.push(paragraph(`**${rule.name}**`));
|
|
663
|
+
if (rule.description) {
|
|
664
|
+
// Parse DocStrings in description instead of plain paragraph
|
|
665
|
+
sections.push(...parseDescriptionWithDocStrings(rule.description));
|
|
666
|
+
}
|
|
667
|
+
if (rule.scenarioNames.length > 0) {
|
|
668
|
+
sections.push(paragraph(`_Verified by: ${rule.scenarioNames.join(', ')}_`));
|
|
669
|
+
}
|
|
670
|
+
return sections;
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Render a rule description using structured annotation parsing.
|
|
674
|
+
*
|
|
675
|
+
* Extracts `**Invariant:**`, `**Rationale:**`, `**Verified by:**`, tables, and
|
|
676
|
+
* code examples for polished output with proper table formatting and separator rows.
|
|
677
|
+
*
|
|
678
|
+
* IMPORTANT: Table lines are stripped BEFORE annotation regexes so that bold markers
|
|
679
|
+
* inside table cells (e.g. `| **Context:** ... |`) don't act as false annotation
|
|
680
|
+
* boundaries that truncate the lazy `[\s\S]*?` capture.
|
|
681
|
+
*
|
|
682
|
+
* @param description - Raw rule description text from Gherkin Rule: block
|
|
683
|
+
* @returns Array of SectionBlocks with structured content
|
|
684
|
+
*/
|
|
685
|
+
export function renderRuleDescription(description) {
|
|
686
|
+
const blocks = [];
|
|
687
|
+
const annotations = parseBusinessRuleAnnotations(description);
|
|
688
|
+
// 1. Render structured annotations first (extracted cleanly)
|
|
689
|
+
if (annotations.invariant) {
|
|
690
|
+
blocks.push(paragraph(`**Invariant:** ${annotations.invariant}`));
|
|
691
|
+
}
|
|
692
|
+
if (annotations.rationale) {
|
|
693
|
+
blocks.push(paragraph(`**Rationale:** ${annotations.rationale}`));
|
|
694
|
+
}
|
|
695
|
+
// 2. Extract tables and render with proper markdown formatting (separator rows)
|
|
696
|
+
const tables = extractTablesFromDescription(description);
|
|
697
|
+
for (const tbl of tables) {
|
|
698
|
+
const rows = tbl.rows.map((row) => tbl.headers.map((h) => row[h] ?? ''));
|
|
699
|
+
blocks.push(table([...tbl.headers], rows));
|
|
700
|
+
}
|
|
701
|
+
// 3. Render remaining content with interleaved DocStrings preserved.
|
|
702
|
+
// Strip table lines FIRST (before annotation regexes) so that bold markers
|
|
703
|
+
// inside table cells (e.g. `| **Context:** ... |`) don't act as false
|
|
704
|
+
// annotation boundaries that truncate the lazy `[\s\S]*?` capture.
|
|
705
|
+
// Then strip known annotations and pass through parseDescriptionWithDocStrings
|
|
706
|
+
// which preserves text → code → text → code ordering.
|
|
707
|
+
let stripped = description
|
|
708
|
+
.split('\n')
|
|
709
|
+
.filter((line) => {
|
|
710
|
+
const trimmed = line.trim();
|
|
711
|
+
return !(trimmed.startsWith('|') && trimmed.endsWith('|'));
|
|
712
|
+
})
|
|
713
|
+
.join('\n');
|
|
714
|
+
stripped = stripped.replace(/\*\*Invariant:\*\*\s*[\s\S]*?(?=\*\*[A-Z]|\*\*$|$)/i, '');
|
|
715
|
+
stripped = stripped.replace(/\*\*Rationale:\*\*\s*[\s\S]*?(?=\*\*[A-Z]|\*\*$|$)/i, '');
|
|
716
|
+
stripped = stripped.replace(/\*\*Verified by:\*\*\s*[\s\S]*?(?=\*\*[A-Z]|\*\*$|$)/i, '');
|
|
717
|
+
const strippedTrimmed = stripped.trim();
|
|
718
|
+
if (strippedTrimmed.length > 0) {
|
|
719
|
+
blocks.push(...parseDescriptionWithDocStrings(strippedTrimmed));
|
|
720
|
+
}
|
|
721
|
+
// 4. Render verified-by list last
|
|
722
|
+
if (annotations.verifiedBy && annotations.verifiedBy.length > 0) {
|
|
723
|
+
blocks.push(paragraph('**Verified by:**'));
|
|
724
|
+
blocks.push(list([...annotations.verifiedBy]));
|
|
725
|
+
}
|
|
726
|
+
return blocks;
|
|
727
|
+
}
|
|
728
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
729
|
+
// Composite Helpers
|
|
730
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
731
|
+
/**
|
|
732
|
+
* Render a scenario's content including steps, DataTables, and DocStrings
|
|
733
|
+
*
|
|
734
|
+
* @param scenario - The scenario to render
|
|
735
|
+
* @param options - Rendering options
|
|
736
|
+
* @returns Array of SectionBlocks for the scenario
|
|
737
|
+
*
|
|
738
|
+
* @example
|
|
739
|
+
* ```typescript
|
|
740
|
+
* for (const scenario of pattern.scenarios) {
|
|
741
|
+
* sections.push(...renderScenarioContent(scenario));
|
|
742
|
+
* }
|
|
743
|
+
* ```
|
|
744
|
+
*/
|
|
745
|
+
export function renderScenarioContent(scenario, options) {
|
|
746
|
+
const opts = mergeRichContentOptions(options);
|
|
747
|
+
const sections = [];
|
|
748
|
+
// Scenario name as bold paragraph
|
|
749
|
+
sections.push(paragraph(`**${scenario.scenarioName}**`));
|
|
750
|
+
// Render steps if available and enabled
|
|
751
|
+
if (opts.includeSteps && scenario.steps && scenario.steps.length > 0) {
|
|
752
|
+
sections.push(renderStepsList(scenario.steps));
|
|
753
|
+
// Render DataTables and DocStrings after the step list
|
|
754
|
+
for (const step of scenario.steps) {
|
|
755
|
+
if (opts.includeDataTables && step.dataTable && step.dataTable.headers.length > 0) {
|
|
756
|
+
sections.push(renderDataTable(step.dataTable));
|
|
757
|
+
}
|
|
758
|
+
if (opts.includeDocStrings && step.docString) {
|
|
759
|
+
sections.push(renderDocString(step.docString, opts.docStringLanguage));
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
return sections;
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* Render acceptance criteria from a list of scenarios
|
|
767
|
+
*
|
|
768
|
+
* Includes a "Acceptance Criteria" heading followed by all scenarios
|
|
769
|
+
* with their steps, DataTables, and DocStrings.
|
|
770
|
+
*
|
|
771
|
+
* @param scenarios - The scenarios to render as acceptance criteria
|
|
772
|
+
* @param options - Rendering options (including baseHeadingLevel for proper hierarchy)
|
|
773
|
+
* @returns Array of SectionBlocks, empty if no scenarios
|
|
774
|
+
*
|
|
775
|
+
* @example
|
|
776
|
+
* ```typescript
|
|
777
|
+
* if (pattern.scenarios && pattern.scenarios.length > 0) {
|
|
778
|
+
* // Default H4 heading
|
|
779
|
+
* sections.push(...renderAcceptanceCriteria(pattern.scenarios));
|
|
780
|
+
*
|
|
781
|
+
* // H2 heading for top-level section in detail documents
|
|
782
|
+
* sections.push(...renderAcceptanceCriteria(pattern.scenarios, { baseHeadingLevel: 2 }));
|
|
783
|
+
* }
|
|
784
|
+
* ```
|
|
785
|
+
*/
|
|
786
|
+
export function renderAcceptanceCriteria(scenarios, options) {
|
|
787
|
+
if (!scenarios || scenarios.length === 0) {
|
|
788
|
+
return [];
|
|
789
|
+
}
|
|
790
|
+
const opts = mergeRichContentOptions(options);
|
|
791
|
+
const sections = [];
|
|
792
|
+
sections.push(heading(opts.baseHeadingLevel, 'Acceptance Criteria'));
|
|
793
|
+
for (const scenario of scenarios) {
|
|
794
|
+
sections.push(...renderScenarioContent(scenario, options));
|
|
795
|
+
}
|
|
796
|
+
return sections;
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Render a business rules section from a list of rules
|
|
800
|
+
*
|
|
801
|
+
* Includes a "Business Rules" heading followed by all rules
|
|
802
|
+
* with their descriptions and verification info.
|
|
803
|
+
*
|
|
804
|
+
* @param rules - The business rules to render
|
|
805
|
+
* @param options - Rendering options (including baseHeadingLevel for proper hierarchy)
|
|
806
|
+
* @returns Array of SectionBlocks, empty if no rules
|
|
807
|
+
*
|
|
808
|
+
* @example
|
|
809
|
+
* ```typescript
|
|
810
|
+
* if (pattern.rules && pattern.rules.length > 0) {
|
|
811
|
+
* // Default H4 heading
|
|
812
|
+
* sections.push(...renderBusinessRulesSection(pattern.rules));
|
|
813
|
+
*
|
|
814
|
+
* // H2 heading for top-level section in detail documents
|
|
815
|
+
* sections.push(...renderBusinessRulesSection(pattern.rules, { baseHeadingLevel: 2 }));
|
|
816
|
+
* }
|
|
817
|
+
* ```
|
|
818
|
+
*/
|
|
819
|
+
export function renderBusinessRulesSection(rules, options) {
|
|
820
|
+
if (!rules || rules.length === 0) {
|
|
821
|
+
return [];
|
|
822
|
+
}
|
|
823
|
+
const opts = mergeRichContentOptions(options);
|
|
824
|
+
const sections = [];
|
|
825
|
+
sections.push(heading(opts.baseHeadingLevel, 'Business Rules'));
|
|
826
|
+
for (const rule of rules) {
|
|
827
|
+
sections.push(...renderBusinessRule(rule));
|
|
828
|
+
}
|
|
829
|
+
return sections;
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Render all rich content for a pattern (scenarios + rules)
|
|
833
|
+
*
|
|
834
|
+
* Convenience function that combines acceptance criteria and business rules.
|
|
835
|
+
*
|
|
836
|
+
* @param pattern - Object with optional scenarios and rules arrays
|
|
837
|
+
* @param options - Rendering options
|
|
838
|
+
* @returns Array of SectionBlocks
|
|
839
|
+
*
|
|
840
|
+
* @example
|
|
841
|
+
* ```typescript
|
|
842
|
+
* sections.push(...renderPatternRichContent(pattern));
|
|
843
|
+
* ```
|
|
844
|
+
*/
|
|
845
|
+
export function renderPatternRichContent(pattern, options) {
|
|
846
|
+
const opts = mergeRichContentOptions(options);
|
|
847
|
+
const sections = [];
|
|
848
|
+
// Add acceptance criteria from scenarios
|
|
849
|
+
if (pattern.scenarios && pattern.scenarios.length > 0) {
|
|
850
|
+
sections.push(...renderAcceptanceCriteria(pattern.scenarios, opts));
|
|
851
|
+
}
|
|
852
|
+
// Add business rules
|
|
853
|
+
if (opts.includeRules && pattern.rules && pattern.rules.length > 0) {
|
|
854
|
+
sections.push(...renderBusinessRulesSection(pattern.rules, opts));
|
|
855
|
+
}
|
|
856
|
+
return sections;
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Render extracted TypeScript shapes as markdown code blocks.
|
|
860
|
+
*
|
|
861
|
+
* @param shapes - Shapes to render
|
|
862
|
+
* @param options - Rendering options
|
|
863
|
+
* @returns Markdown string with fenced code blocks
|
|
864
|
+
*/
|
|
865
|
+
export function renderShapesAsMarkdown(shapes, options = {}) {
|
|
866
|
+
const { groupInSingleBlock = true, includeJsDoc = true } = options;
|
|
867
|
+
if (shapes.length === 0) {
|
|
868
|
+
return '';
|
|
869
|
+
}
|
|
870
|
+
const renderShape = (shape) => {
|
|
871
|
+
const parts = [];
|
|
872
|
+
if (includeJsDoc && shape.jsDoc) {
|
|
873
|
+
parts.push(shape.jsDoc);
|
|
874
|
+
}
|
|
875
|
+
parts.push(shape.sourceText);
|
|
876
|
+
return parts.join('\n');
|
|
877
|
+
};
|
|
878
|
+
if (groupInSingleBlock) {
|
|
879
|
+
const content = shapes.map(renderShape).join('\n\n');
|
|
880
|
+
return '```typescript\n' + content + '\n```';
|
|
881
|
+
}
|
|
882
|
+
return shapes.map((shape) => '```typescript\n' + renderShape(shape) + '\n```').join('\n\n');
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Render property documentation as a markdown table.
|
|
886
|
+
*
|
|
887
|
+
* Generates a two-column table with property names and their JSDoc descriptions.
|
|
888
|
+
* Returns empty string if no property docs exist.
|
|
889
|
+
*
|
|
890
|
+
* @param propertyDocs - Property documentation array from ExtractedShape
|
|
891
|
+
* @returns Markdown table string, or empty string if no docs
|
|
892
|
+
*
|
|
893
|
+
* @example
|
|
894
|
+
* ```typescript
|
|
895
|
+
* const table = renderPropertyDocsTable(shape.propertyDocs);
|
|
896
|
+
* if (table) {
|
|
897
|
+
* sections.push(md(table));
|
|
898
|
+
* }
|
|
899
|
+
* ```
|
|
900
|
+
*/
|
|
901
|
+
export function renderPropertyDocsTable(propertyDocs) {
|
|
902
|
+
if (!propertyDocs || propertyDocs.length === 0) {
|
|
903
|
+
return '';
|
|
904
|
+
}
|
|
905
|
+
const lines = ['| Property | Description |', '| --- | --- |'];
|
|
906
|
+
for (const prop of propertyDocs) {
|
|
907
|
+
// Escape pipe characters in description to prevent table breakage
|
|
908
|
+
const escapedDesc = prop.jsDoc.replace(/\|/g, '\\|');
|
|
909
|
+
lines.push(`| \`${prop.name}\` | ${escapedDesc} |`);
|
|
910
|
+
}
|
|
911
|
+
return lines.join('\n');
|
|
912
|
+
}
|
|
913
|
+
//# sourceMappingURL=helpers.js.map
|