@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,966 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @architect
|
|
3
|
+
* @architect-pattern ShapeExtractor
|
|
4
|
+
* @architect-status completed
|
|
5
|
+
* @architect-phase 26
|
|
6
|
+
* @architect-implements ShapeExtraction
|
|
7
|
+
* @architect-uses typescript-estree
|
|
8
|
+
*
|
|
9
|
+
* ## Shape Extractor - TypeScript Type Extraction
|
|
10
|
+
*
|
|
11
|
+
* Extracts TypeScript type definitions (interfaces, type aliases, enums,
|
|
12
|
+
* function signatures) from source files for documentation generation.
|
|
13
|
+
*
|
|
14
|
+
* ### When to Use
|
|
15
|
+
*
|
|
16
|
+
* - When processing @architect-extract-shapes tags during extraction
|
|
17
|
+
* - When generating documentation that needs actual type definitions
|
|
18
|
+
* - When eliminating duplication between JSDoc examples and code
|
|
19
|
+
*
|
|
20
|
+
* ### Key Concepts
|
|
21
|
+
*
|
|
22
|
+
* - **AST-based extraction**: Uses typescript-estree for accurate parsing
|
|
23
|
+
* - **Preserves formatting**: Extracts exact source text, not regenerated
|
|
24
|
+
* - **Includes JSDoc**: Type-level JSDoc comments are preserved
|
|
25
|
+
* - **Order from tag**: Shapes appear in tag-specified order, not source order
|
|
26
|
+
*/
|
|
27
|
+
import { parse } from '@typescript-eslint/typescript-estree';
|
|
28
|
+
import { Result } from '../types/result.js';
|
|
29
|
+
// =============================================================================
|
|
30
|
+
// Constants
|
|
31
|
+
// =============================================================================
|
|
32
|
+
/**
|
|
33
|
+
* Maximum line gap between JSDoc comment end and declaration start.
|
|
34
|
+
* Allows 1 blank line between JSDoc and declaration (comment end line + 1 blank + decl line = 3 gap)
|
|
35
|
+
*/
|
|
36
|
+
const MAX_JSDOC_LINE_DISTANCE = 3;
|
|
37
|
+
/**
|
|
38
|
+
* Strict adjacency required for property-level JSDoc.
|
|
39
|
+
* Property JSDoc must end on the line immediately before the property (no gap allowed).
|
|
40
|
+
* This prevents interface-level JSDoc from being misattributed to the first property.
|
|
41
|
+
*/
|
|
42
|
+
const PROPERTY_JSDOC_MAX_GAP = 1;
|
|
43
|
+
/**
|
|
44
|
+
* Maximum source code size in bytes (5MB).
|
|
45
|
+
* Prevents memory exhaustion from oversized input during AST parsing.
|
|
46
|
+
*/
|
|
47
|
+
const MAX_SOURCE_SIZE_BYTES = 5 * 1024 * 1024;
|
|
48
|
+
// =============================================================================
|
|
49
|
+
// Parse Helper
|
|
50
|
+
// =============================================================================
|
|
51
|
+
/**
|
|
52
|
+
* Parse TypeScript source with the correct JSX mode.
|
|
53
|
+
* JSX must only be enabled for .tsx files — enabling it for .ts files causes
|
|
54
|
+
* generic arrow functions like `<T>(v: T)` to be mis-parsed as JSX elements.
|
|
55
|
+
*/
|
|
56
|
+
function parseSource(sourceCode, jsx) {
|
|
57
|
+
return parse(sourceCode, { loc: true, range: true, comment: true, jsx });
|
|
58
|
+
}
|
|
59
|
+
// =============================================================================
|
|
60
|
+
// Main Extraction Function
|
|
61
|
+
// =============================================================================
|
|
62
|
+
/**
|
|
63
|
+
* Extract named shapes from TypeScript source code.
|
|
64
|
+
*
|
|
65
|
+
* @param sourceCode - The TypeScript source code to parse
|
|
66
|
+
* @param shapeNames - Names of shapes to extract (in desired output order)
|
|
67
|
+
* @param options - Extraction options
|
|
68
|
+
* @returns Result containing extraction result with shapes, warnings, and not-found list
|
|
69
|
+
*/
|
|
70
|
+
export function extractShapes(sourceCode, shapeNames, options = {}) {
|
|
71
|
+
// Validate input size to prevent memory exhaustion
|
|
72
|
+
if (sourceCode.length > MAX_SOURCE_SIZE_BYTES) {
|
|
73
|
+
return Result.err(new Error(`Source code size (${sourceCode.length} bytes) exceeds maximum allowed (${MAX_SOURCE_SIZE_BYTES} bytes)`));
|
|
74
|
+
}
|
|
75
|
+
const { includeJsDoc = true, preserveFormatting = true } = options;
|
|
76
|
+
const shapes = [];
|
|
77
|
+
const notFound = [];
|
|
78
|
+
const imported = [];
|
|
79
|
+
const reExported = [];
|
|
80
|
+
const warnings = [];
|
|
81
|
+
// Parse the source code
|
|
82
|
+
let ast;
|
|
83
|
+
try {
|
|
84
|
+
ast = parseSource(sourceCode, options.jsx ?? false);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return Result.err(error instanceof Error ? error : new Error(`Failed to parse source code: ${String(error)}`));
|
|
88
|
+
}
|
|
89
|
+
// Build maps of declarations and imports/re-exports
|
|
90
|
+
const declarations = findDeclarations(ast);
|
|
91
|
+
const importsAndReExports = findImportsAndReExports(ast);
|
|
92
|
+
// Process each requested shape name
|
|
93
|
+
for (const shapeName of shapeNames) {
|
|
94
|
+
// Check if it's a local declaration
|
|
95
|
+
const declarationList = declarations.get(shapeName);
|
|
96
|
+
if (declarationList !== undefined) {
|
|
97
|
+
const declaration = pickBestDeclaration(declarationList);
|
|
98
|
+
const shape = extractShape(sourceCode, declaration, ast.comments ?? [], {
|
|
99
|
+
includeJsDoc,
|
|
100
|
+
preserveFormatting,
|
|
101
|
+
});
|
|
102
|
+
shapes.push(shape);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
// Check if it's an import or re-export
|
|
106
|
+
const importInfo = importsAndReExports.get(shapeName);
|
|
107
|
+
if (importInfo) {
|
|
108
|
+
if (importInfo.isReExport) {
|
|
109
|
+
reExported.push({
|
|
110
|
+
name: shapeName,
|
|
111
|
+
sourceModule: importInfo.sourceModule,
|
|
112
|
+
typeOnly: importInfo.typeOnly,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
imported.push(shapeName);
|
|
117
|
+
}
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// Not found at all
|
|
121
|
+
notFound.push(shapeName);
|
|
122
|
+
}
|
|
123
|
+
return Result.ok({ shapes, notFound, imported, reExported, warnings });
|
|
124
|
+
}
|
|
125
|
+
// =============================================================================
|
|
126
|
+
// AST Traversal Functions
|
|
127
|
+
// =============================================================================
|
|
128
|
+
/**
|
|
129
|
+
* Find all declarations that could be extracted as shapes.
|
|
130
|
+
*/
|
|
131
|
+
function findDeclarations(ast) {
|
|
132
|
+
const declarations = new Map();
|
|
133
|
+
function pushDeclaration(decl) {
|
|
134
|
+
const existing = declarations.get(decl.name);
|
|
135
|
+
if (existing !== undefined) {
|
|
136
|
+
existing.push(decl);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
declarations.set(decl.name, [decl]);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
for (const node of ast.body) {
|
|
143
|
+
// Handle export declarations
|
|
144
|
+
if (node.type === 'ExportNamedDeclaration') {
|
|
145
|
+
if (node.declaration) {
|
|
146
|
+
const found = processDeclaration(node.declaration, true);
|
|
147
|
+
for (const decl of found) {
|
|
148
|
+
pushDeclaration(decl);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Handle export { Foo } without a source (local re-export)
|
|
152
|
+
if (!node.source) {
|
|
153
|
+
for (const spec of node.specifiers) {
|
|
154
|
+
const localName = spec.local.name;
|
|
155
|
+
// This might reference a local declaration - mark all as exported
|
|
156
|
+
const existing = declarations.get(localName);
|
|
157
|
+
if (existing !== undefined) {
|
|
158
|
+
for (const decl of existing) {
|
|
159
|
+
decl.exported = true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Handle non-exported declarations
|
|
166
|
+
else {
|
|
167
|
+
const found = processDeclaration(node, false);
|
|
168
|
+
for (const decl of found) {
|
|
169
|
+
const existing = declarations.get(decl.name);
|
|
170
|
+
// Only add if no exported version of same kind already exists
|
|
171
|
+
if (existing !== undefined) {
|
|
172
|
+
const hasExportedSameKind = existing.some((e) => e.exported && e.kind === decl.kind);
|
|
173
|
+
if (!hasExportedSameKind) {
|
|
174
|
+
existing.push(decl);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
declarations.set(decl.name, [decl]);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return declarations;
|
|
184
|
+
}
|
|
185
|
+
/** Priority ranking for declaration kinds — type-level preferred for documentation */
|
|
186
|
+
const KIND_PRIORITY = {
|
|
187
|
+
interface: 0,
|
|
188
|
+
type: 1,
|
|
189
|
+
enum: 2,
|
|
190
|
+
function: 3,
|
|
191
|
+
const: 4,
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Pick the best declaration from an array of same-name declarations.
|
|
195
|
+
* Prefers type-level constructs (interface, type, enum) over value-level (function, const).
|
|
196
|
+
*/
|
|
197
|
+
function pickBestDeclaration(declarations) {
|
|
198
|
+
if (declarations.length === 1) {
|
|
199
|
+
const only = declarations[0];
|
|
200
|
+
if (only === undefined)
|
|
201
|
+
throw new Error('Empty declarations array');
|
|
202
|
+
return only;
|
|
203
|
+
}
|
|
204
|
+
const sorted = [...declarations].sort((a, b) => KIND_PRIORITY[a.kind] - KIND_PRIORITY[b.kind]);
|
|
205
|
+
const best = sorted[0];
|
|
206
|
+
if (best === undefined)
|
|
207
|
+
throw new Error('Empty declarations array after sort');
|
|
208
|
+
return best;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Process a declaration node and extract shape info.
|
|
212
|
+
*/
|
|
213
|
+
function processDeclaration(node, exported) {
|
|
214
|
+
const results = [];
|
|
215
|
+
switch (node.type) {
|
|
216
|
+
case 'TSInterfaceDeclaration':
|
|
217
|
+
results.push({
|
|
218
|
+
node,
|
|
219
|
+
kind: 'interface',
|
|
220
|
+
name: node.id.name,
|
|
221
|
+
exported,
|
|
222
|
+
});
|
|
223
|
+
break;
|
|
224
|
+
case 'TSTypeAliasDeclaration':
|
|
225
|
+
results.push({
|
|
226
|
+
node,
|
|
227
|
+
kind: 'type',
|
|
228
|
+
name: node.id.name,
|
|
229
|
+
exported,
|
|
230
|
+
});
|
|
231
|
+
break;
|
|
232
|
+
case 'TSEnumDeclaration':
|
|
233
|
+
results.push({
|
|
234
|
+
node,
|
|
235
|
+
kind: 'enum',
|
|
236
|
+
name: node.id.name,
|
|
237
|
+
exported,
|
|
238
|
+
});
|
|
239
|
+
break;
|
|
240
|
+
case 'FunctionDeclaration':
|
|
241
|
+
if (node.id) {
|
|
242
|
+
results.push({
|
|
243
|
+
node,
|
|
244
|
+
kind: 'function',
|
|
245
|
+
name: node.id.name,
|
|
246
|
+
exported,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
break;
|
|
250
|
+
case 'VariableDeclaration':
|
|
251
|
+
// Handle const declarations
|
|
252
|
+
if (node.kind === 'const') {
|
|
253
|
+
for (const declarator of node.declarations) {
|
|
254
|
+
if (declarator.id.type === 'Identifier') {
|
|
255
|
+
results.push({
|
|
256
|
+
node: declarator,
|
|
257
|
+
kind: 'const',
|
|
258
|
+
name: declarator.id.name,
|
|
259
|
+
exported,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
return results;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Find all imports and re-exports.
|
|
270
|
+
*/
|
|
271
|
+
function findImportsAndReExports(ast) {
|
|
272
|
+
const result = new Map();
|
|
273
|
+
for (const node of ast.body) {
|
|
274
|
+
// Import declarations
|
|
275
|
+
if (node.type === 'ImportDeclaration') {
|
|
276
|
+
const sourceModule = node.source.value;
|
|
277
|
+
const typeOnly = node.importKind === 'type';
|
|
278
|
+
for (const spec of node.specifiers) {
|
|
279
|
+
if (spec.type === 'ImportSpecifier') {
|
|
280
|
+
result.set(spec.local.name, {
|
|
281
|
+
name: spec.local.name,
|
|
282
|
+
sourceModule,
|
|
283
|
+
isReExport: false,
|
|
284
|
+
typeOnly: typeOnly || spec.importKind === 'type',
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
else if (spec.type === 'ImportDefaultSpecifier') {
|
|
288
|
+
result.set(spec.local.name, {
|
|
289
|
+
name: spec.local.name,
|
|
290
|
+
sourceModule,
|
|
291
|
+
isReExport: false,
|
|
292
|
+
typeOnly,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Export declarations with source (re-exports)
|
|
298
|
+
if (node.type === 'ExportNamedDeclaration' && node.source) {
|
|
299
|
+
const sourceModule = node.source.value;
|
|
300
|
+
const typeOnly = node.exportKind === 'type';
|
|
301
|
+
for (const spec of node.specifiers) {
|
|
302
|
+
const exportedName = spec.exported.type === 'Identifier' ? spec.exported.name : spec.exported.value;
|
|
303
|
+
result.set(exportedName, {
|
|
304
|
+
name: exportedName,
|
|
305
|
+
sourceModule,
|
|
306
|
+
isReExport: true,
|
|
307
|
+
typeOnly,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// Export all (export * from './module')
|
|
312
|
+
if (node.type === 'ExportAllDeclaration') {
|
|
313
|
+
// We can't know specific names from export *, just note it
|
|
314
|
+
// This is handled by the "not found" case
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
319
|
+
// =============================================================================
|
|
320
|
+
// Shape Extraction
|
|
321
|
+
// =============================================================================
|
|
322
|
+
/**
|
|
323
|
+
* Extract a single shape from its declaration.
|
|
324
|
+
*/
|
|
325
|
+
function extractShape(sourceCode, declaration, comments, options) {
|
|
326
|
+
const { node, kind, name, exported } = declaration;
|
|
327
|
+
// Get the node's range for source extraction (guaranteed by parse options: range: true)
|
|
328
|
+
let sourceText = sourceCode.slice(node.range[0], node.range[1]);
|
|
329
|
+
// For functions, convert to signature only (remove body)
|
|
330
|
+
// Uses AST body range for precise location — avoids brace-matching that
|
|
331
|
+
// fails on object parameter types like { timeout: number }
|
|
332
|
+
if (kind === 'function' && node.type === 'FunctionDeclaration') {
|
|
333
|
+
const funcNode = node;
|
|
334
|
+
const bodyStart = funcNode.body.range[0];
|
|
335
|
+
const declStart = node.range[0];
|
|
336
|
+
sourceText = sourceCode.slice(declStart, bodyStart).trim();
|
|
337
|
+
if (sourceText.startsWith('export ')) {
|
|
338
|
+
sourceText = sourceText.slice('export '.length);
|
|
339
|
+
}
|
|
340
|
+
sourceText = sourceText.trim() + ';';
|
|
341
|
+
}
|
|
342
|
+
// For const, extract just the type annotation if present
|
|
343
|
+
if (kind === 'const' && node.type === 'VariableDeclarator') {
|
|
344
|
+
const declNode = node;
|
|
345
|
+
if (declNode.id.typeAnnotation) {
|
|
346
|
+
// Extract const with type annotation (ranges guaranteed by parse options)
|
|
347
|
+
const idRange = declNode.id.range;
|
|
348
|
+
const typeRange = declNode.id.typeAnnotation.range;
|
|
349
|
+
sourceText = `const ${sourceCode.slice(idRange[0], typeRange[1])};`;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// Get JSDoc if requested, stripping @architect-* annotation lines
|
|
353
|
+
let jsDoc;
|
|
354
|
+
if (options.includeJsDoc) {
|
|
355
|
+
const rawJsDoc = extractPrecedingJsDoc(sourceCode, node, comments);
|
|
356
|
+
jsDoc = rawJsDoc !== undefined ? stripArchitectTags(rawJsDoc) : undefined;
|
|
357
|
+
}
|
|
358
|
+
// DD-3: Parse @param/@returns/@throws from JSDoc for function shapes
|
|
359
|
+
let parsedTags;
|
|
360
|
+
if (options.includeJsDoc && kind === 'function' && jsDoc) {
|
|
361
|
+
parsedTags = parseJsDocTags(jsDoc);
|
|
362
|
+
}
|
|
363
|
+
// Get line number (guaranteed by parse options: loc: true)
|
|
364
|
+
const lineNumber = node.loc.start.line;
|
|
365
|
+
// Extract type parameters for interfaces and types
|
|
366
|
+
let typeParameters;
|
|
367
|
+
if (node.type === 'TSInterfaceDeclaration' || node.type === 'TSTypeAliasDeclaration') {
|
|
368
|
+
const params = node.typeParameters;
|
|
369
|
+
if (params?.params) {
|
|
370
|
+
typeParameters = params.params.map((p) => sourceCode.slice(p.range[0], p.range[1]));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// Extract extends for interfaces
|
|
374
|
+
let extendsArr;
|
|
375
|
+
if (node.type === 'TSInterfaceDeclaration' && node.extends.length > 0) {
|
|
376
|
+
extendsArr = node.extends.map((ext) => sourceCode.slice(ext.range[0], ext.range[1]));
|
|
377
|
+
}
|
|
378
|
+
// Extract property-level JSDoc for interfaces
|
|
379
|
+
// Uses strict adjacency to prevent interface-level JSDoc from being misattributed to first property
|
|
380
|
+
// Performance optimization: pre-sort comments once O(c log c), then O(log c) per property lookup
|
|
381
|
+
let propertyDocs;
|
|
382
|
+
if (options.includeJsDoc && node.type === 'TSInterfaceDeclaration') {
|
|
383
|
+
const docs = [];
|
|
384
|
+
// Get the line where the interface body starts (the `{` line)
|
|
385
|
+
// loc is guaranteed by parse options: { range: true, loc: true }
|
|
386
|
+
const interfaceBodyStartLine = node.body.loc.start.line;
|
|
387
|
+
// Pre-process comments once for O(log c) binary search per property
|
|
388
|
+
// This converts O(m × c) to O(c log c + m log c) where m=properties, c=comments
|
|
389
|
+
const sortedComments = prepareJsDocComments(comments);
|
|
390
|
+
for (const member of node.body.body) {
|
|
391
|
+
if (member.type === 'TSPropertySignature' && member.key.type === 'Identifier') {
|
|
392
|
+
const propName = member.key.name;
|
|
393
|
+
// Use strict adjacency - comment must be inside interface body and immediately before property
|
|
394
|
+
const propJsDoc = findStrictlyAdjacentPropertyJsDoc(sourceCode, member, sortedComments, interfaceBodyStartLine);
|
|
395
|
+
if (propJsDoc) {
|
|
396
|
+
// Extract just the text content from JSDoc, removing delimiters
|
|
397
|
+
const cleanedJsDoc = extractJsDocText(propJsDoc);
|
|
398
|
+
if (cleanedJsDoc) {
|
|
399
|
+
docs.push({ name: propName, jsDoc: cleanedJsDoc });
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (docs.length > 0) {
|
|
405
|
+
propertyDocs = docs;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
name,
|
|
410
|
+
kind,
|
|
411
|
+
sourceText,
|
|
412
|
+
jsDoc,
|
|
413
|
+
lineNumber,
|
|
414
|
+
typeParameters,
|
|
415
|
+
extends: extendsArr,
|
|
416
|
+
exported,
|
|
417
|
+
propertyDocs,
|
|
418
|
+
// DD-3: Include parsed JSDoc tags for function shapes
|
|
419
|
+
params: parsedTags !== undefined && parsedTags.params.length > 0 ? parsedTags.params : undefined,
|
|
420
|
+
returns: parsedTags?.returns,
|
|
421
|
+
throws: parsedTags !== undefined && parsedTags.throws.length > 0 ? parsedTags.throws : undefined,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Strip @architect-* annotation lines from a JSDoc comment.
|
|
426
|
+
*
|
|
427
|
+
* Preserves standard JSDoc tags (@param, @returns, @example, etc.) and
|
|
428
|
+
* all non-annotation content. Returns undefined if all content lines were
|
|
429
|
+
* annotation tags (empty JSDoc after stripping).
|
|
430
|
+
*/
|
|
431
|
+
function extractJsDocLineContent(line) {
|
|
432
|
+
return line
|
|
433
|
+
.trim()
|
|
434
|
+
.replace(/^\/\*\*\s*/, '') // strip leading /**
|
|
435
|
+
.replace(/\*\/\s*$/, '') // strip trailing */
|
|
436
|
+
.replace(/^\*\s?/, '') // strip leading * (JSDoc continuation)
|
|
437
|
+
.trim();
|
|
438
|
+
}
|
|
439
|
+
function stripArchitectTags(jsDoc) {
|
|
440
|
+
const lines = jsDoc.split('\n');
|
|
441
|
+
const filtered = lines.filter((line) => !extractJsDocLineContent(line).startsWith('@architect'));
|
|
442
|
+
// Check if anything meaningful remains (not just /** and */)
|
|
443
|
+
const hasContent = filtered.some((line) => extractJsDocLineContent(line).length > 0);
|
|
444
|
+
if (!hasContent)
|
|
445
|
+
return undefined;
|
|
446
|
+
// Clean up consecutive empty JSDoc lines left by tag removal
|
|
447
|
+
const result = [];
|
|
448
|
+
let prevWasEmptyJsDocLine = false;
|
|
449
|
+
for (const line of filtered) {
|
|
450
|
+
const trimmed = line.trim();
|
|
451
|
+
const isEmptyJsDocLine = trimmed === '*' || trimmed === '';
|
|
452
|
+
if (isEmptyJsDocLine && prevWasEmptyJsDocLine)
|
|
453
|
+
continue;
|
|
454
|
+
result.push(line);
|
|
455
|
+
prevWasEmptyJsDocLine = isEmptyJsDocLine;
|
|
456
|
+
}
|
|
457
|
+
return result.join('\n');
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Extract JSDoc comment preceding a node.
|
|
461
|
+
*/
|
|
462
|
+
function extractPrecedingJsDoc(sourceCode, node, comments) {
|
|
463
|
+
// Range and loc are guaranteed by parse options: { range: true, loc: true }
|
|
464
|
+
const nodeStart = node.range[0];
|
|
465
|
+
const nodeLine = node.loc.start.line;
|
|
466
|
+
// Find the closest block comment that ends before this node
|
|
467
|
+
// and is a JSDoc comment (starts with /**)
|
|
468
|
+
let closestJsDoc;
|
|
469
|
+
for (const comment of comments) {
|
|
470
|
+
if (comment.type !== 'Block')
|
|
471
|
+
continue;
|
|
472
|
+
if (!comment.value.startsWith('*'))
|
|
473
|
+
continue; // JSDoc starts with /**
|
|
474
|
+
const commentEnd = comment.range[1];
|
|
475
|
+
const commentEndLine = comment.loc.end.line;
|
|
476
|
+
// Comment must end before node starts
|
|
477
|
+
if (commentEnd > nodeStart)
|
|
478
|
+
continue;
|
|
479
|
+
// Comment must be close to the node
|
|
480
|
+
if (nodeLine - commentEndLine > MAX_JSDOC_LINE_DISTANCE)
|
|
481
|
+
continue;
|
|
482
|
+
// This is a candidate - pick the one closest to the node
|
|
483
|
+
if (!closestJsDoc || comment.range[1] > closestJsDoc.range[1]) {
|
|
484
|
+
closestJsDoc = comment;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if (!closestJsDoc)
|
|
488
|
+
return undefined;
|
|
489
|
+
// Return the full JSDoc including delimiters
|
|
490
|
+
return sourceCode.slice(closestJsDoc.range[0], closestJsDoc.range[1]);
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Pre-process comments for efficient property JSDoc lookup.
|
|
494
|
+
*
|
|
495
|
+
* Filters to only JSDoc block comments and sorts by end line for binary search.
|
|
496
|
+
* This is O(c log c) but done once per file, enabling O(log c) lookups per property.
|
|
497
|
+
*
|
|
498
|
+
* @param comments - All comments from the AST
|
|
499
|
+
* @returns Sorted array of JSDoc comments with pre-extracted line info
|
|
500
|
+
*/
|
|
501
|
+
function prepareJsDocComments(comments) {
|
|
502
|
+
const jsDocComments = [];
|
|
503
|
+
for (const comment of comments) {
|
|
504
|
+
// Filter: Must be a block comment with JSDoc format (starts with *)
|
|
505
|
+
if (comment.type !== 'Block' || !comment.value.startsWith('*')) {
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
// Pre-extract line info (loc guaranteed by parse options: { loc: true })
|
|
509
|
+
jsDocComments.push({
|
|
510
|
+
comment,
|
|
511
|
+
endLine: comment.loc.end.line,
|
|
512
|
+
startLine: comment.loc.start.line,
|
|
513
|
+
endPosition: comment.range[1],
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
// Sort by end line for binary search
|
|
517
|
+
jsDocComments.sort((a, b) => a.endLine - b.endLine);
|
|
518
|
+
return jsDocComments;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Binary search to find a JSDoc comment that ends at or near a target line.
|
|
522
|
+
*
|
|
523
|
+
* Returns the index of the comment with the largest endLine <= targetLine,
|
|
524
|
+
* or -1 if no such comment exists.
|
|
525
|
+
*
|
|
526
|
+
* @param sortedComments - Comments sorted by endLine
|
|
527
|
+
* @param targetLine - The line to search for
|
|
528
|
+
* @returns Index of matching comment, or -1 if not found
|
|
529
|
+
*/
|
|
530
|
+
function findCommentEndingAtLine(sortedComments, targetLine) {
|
|
531
|
+
if (sortedComments.length === 0)
|
|
532
|
+
return -1;
|
|
533
|
+
let left = 0;
|
|
534
|
+
let right = sortedComments.length - 1;
|
|
535
|
+
let result = -1;
|
|
536
|
+
while (left <= right) {
|
|
537
|
+
const mid = Math.floor((left + right) / 2);
|
|
538
|
+
const comment = sortedComments[mid];
|
|
539
|
+
if (!comment)
|
|
540
|
+
break;
|
|
541
|
+
const endLine = comment.endLine;
|
|
542
|
+
if (endLine === targetLine) {
|
|
543
|
+
// Exact match - could be multiple, find the rightmost one
|
|
544
|
+
result = mid;
|
|
545
|
+
left = mid + 1;
|
|
546
|
+
}
|
|
547
|
+
else if (endLine < targetLine) {
|
|
548
|
+
left = mid + 1;
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
right = mid - 1;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
return result;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Find JSDoc comment strictly adjacent to an interface property member.
|
|
558
|
+
*
|
|
559
|
+
* Unlike extractPrecedingJsDoc which allows a 3-line gap, this function requires:
|
|
560
|
+
* 1. Comment must be INSIDE the interface body (start line > minLine)
|
|
561
|
+
* 2. Comment must end exactly at member.startLine - 1 (strictly adjacent)
|
|
562
|
+
*
|
|
563
|
+
* This prevents interface-level JSDoc from being misattributed to the first property
|
|
564
|
+
* when the interface is tightly formatted.
|
|
565
|
+
*
|
|
566
|
+
* Performance: O(log c) per property when using pre-sorted comments, vs O(c) previously.
|
|
567
|
+
*
|
|
568
|
+
* @param sourceCode - Full source code text
|
|
569
|
+
* @param member - The property member node
|
|
570
|
+
* @param sortedComments - Pre-sorted JSDoc comments (call prepareJsDocComments once per file)
|
|
571
|
+
* @param interfaceBodyStartLine - Line where interface body starts (the `{` line)
|
|
572
|
+
* @returns JSDoc string if found, undefined otherwise
|
|
573
|
+
*/
|
|
574
|
+
function findStrictlyAdjacentPropertyJsDoc(sourceCode, member, sortedComments, interfaceBodyStartLine) {
|
|
575
|
+
// Range and loc are guaranteed by parse options: { range: true, loc: true }
|
|
576
|
+
const memberStartLine = member.loc.start.line;
|
|
577
|
+
const memberStart = member.range[0];
|
|
578
|
+
// Property JSDoc must end exactly on the line before the property
|
|
579
|
+
const expectedCommentEndLine = memberStartLine - PROPERTY_JSDOC_MAX_GAP;
|
|
580
|
+
// Binary search for comment ending at expected line
|
|
581
|
+
const index = findCommentEndingAtLine(sortedComments, expectedCommentEndLine);
|
|
582
|
+
if (index === -1)
|
|
583
|
+
return undefined;
|
|
584
|
+
// Check all comments ending at that line (there could be multiple)
|
|
585
|
+
// Start from the found index and check backwards/forwards for exact matches
|
|
586
|
+
for (let i = index; i >= 0; i--) {
|
|
587
|
+
const entry = sortedComments[i];
|
|
588
|
+
if (entry?.endLine !== expectedCommentEndLine)
|
|
589
|
+
break;
|
|
590
|
+
// Comment must end before the member starts (character position)
|
|
591
|
+
if (entry.endPosition > memberStart)
|
|
592
|
+
continue;
|
|
593
|
+
// Comment must be INSIDE the interface body (after the opening brace line)
|
|
594
|
+
if (entry.startLine <= interfaceBodyStartLine)
|
|
595
|
+
continue;
|
|
596
|
+
// Found a valid property-level JSDoc
|
|
597
|
+
return sourceCode.slice(entry.comment.range[0], entry.comment.range[1]);
|
|
598
|
+
}
|
|
599
|
+
return undefined;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Parse @param, @returns, and @throws tags from raw JSDoc text.
|
|
603
|
+
*
|
|
604
|
+
* DD-3: Handles both TypeScript-style (`@param name - desc`) and
|
|
605
|
+
* JSDoc-style (`@param {Type} name desc`) formats. Multi-line tag
|
|
606
|
+
* descriptions are supported — lines not starting with `@` are
|
|
607
|
+
* continuations of the previous tag.
|
|
608
|
+
*
|
|
609
|
+
* @param rawJsDoc - Raw JSDoc text with delimiters (/** ... *\/)
|
|
610
|
+
* @returns Structured param/returns/throws data
|
|
611
|
+
*/
|
|
612
|
+
function parseJsDocTags(rawJsDoc) {
|
|
613
|
+
// Strip JSDoc delimiters and leading asterisks
|
|
614
|
+
let text = rawJsDoc.trim();
|
|
615
|
+
if (text.startsWith('/**')) {
|
|
616
|
+
text = text.slice(3);
|
|
617
|
+
}
|
|
618
|
+
if (text.endsWith('*/')) {
|
|
619
|
+
text = text.slice(0, -2);
|
|
620
|
+
}
|
|
621
|
+
const lines = text.split('\n').map((line) => {
|
|
622
|
+
let cleaned = line.trim();
|
|
623
|
+
if (cleaned.startsWith('*')) {
|
|
624
|
+
cleaned = cleaned.slice(1).trim();
|
|
625
|
+
}
|
|
626
|
+
return cleaned;
|
|
627
|
+
});
|
|
628
|
+
const params = [];
|
|
629
|
+
let returns;
|
|
630
|
+
const throws = [];
|
|
631
|
+
// Regex for @param with optional {Type}: @param {Type} name - description
|
|
632
|
+
const paramRegex = /^@param\s+(?:\{([^}]+)\}\s+)?([\w.]+)\s*(?:-\s*)?(.*)$/;
|
|
633
|
+
// Regex for @returns/@return with optional {Type}
|
|
634
|
+
const returnsRegex = /^@returns?\s+(?:\{([^}]+)\}\s+)?(.*)$/;
|
|
635
|
+
// Regex for @throws/@throw with optional {Type}
|
|
636
|
+
const throwsRegex = /^@throws?\s+(?:\{([^}]+)\}\s+)?(.*)$/;
|
|
637
|
+
let currentTag;
|
|
638
|
+
for (const line of lines) {
|
|
639
|
+
if (line.length === 0) {
|
|
640
|
+
currentTag = undefined;
|
|
641
|
+
continue;
|
|
642
|
+
}
|
|
643
|
+
// Try @param
|
|
644
|
+
const paramMatch = paramRegex.exec(line);
|
|
645
|
+
if (paramMatch) {
|
|
646
|
+
const paramName = paramMatch[2] ?? '';
|
|
647
|
+
const paramType = paramMatch[1];
|
|
648
|
+
const paramDesc = paramMatch[3] ?? '';
|
|
649
|
+
params.push({
|
|
650
|
+
name: paramName,
|
|
651
|
+
type: paramType ?? undefined,
|
|
652
|
+
description: paramDesc.trim(),
|
|
653
|
+
});
|
|
654
|
+
currentTag = { target: 'param', index: params.length - 1 };
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
// Try @returns
|
|
658
|
+
const returnsMatch = returnsRegex.exec(line);
|
|
659
|
+
if (returnsMatch) {
|
|
660
|
+
const retType = returnsMatch[1];
|
|
661
|
+
const retDesc = returnsMatch[2] ?? '';
|
|
662
|
+
returns = {
|
|
663
|
+
type: retType ?? undefined,
|
|
664
|
+
description: retDesc.trim(),
|
|
665
|
+
};
|
|
666
|
+
currentTag = { target: 'returns', index: 0 };
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
// Try @throws
|
|
670
|
+
const throwsMatch = throwsRegex.exec(line);
|
|
671
|
+
if (throwsMatch) {
|
|
672
|
+
const throwType = throwsMatch[1];
|
|
673
|
+
const throwDesc = throwsMatch[2] ?? '';
|
|
674
|
+
throws.push({
|
|
675
|
+
type: throwType ?? undefined,
|
|
676
|
+
description: throwDesc.trim(),
|
|
677
|
+
});
|
|
678
|
+
currentTag = { target: 'throws', index: throws.length - 1 };
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
// Any other @tag breaks the current continuation
|
|
682
|
+
if (line.startsWith('@')) {
|
|
683
|
+
currentTag = undefined;
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
// Continuation line for current tag
|
|
687
|
+
if (currentTag) {
|
|
688
|
+
const continuation = line.trim();
|
|
689
|
+
if (continuation.length === 0)
|
|
690
|
+
continue;
|
|
691
|
+
const paramEntry = currentTag.target === 'param' ? params[currentTag.index] : undefined;
|
|
692
|
+
const throwEntry = currentTag.target === 'throws' ? throws[currentTag.index] : undefined;
|
|
693
|
+
if (currentTag.target === 'param' && paramEntry !== undefined) {
|
|
694
|
+
params[currentTag.index] = {
|
|
695
|
+
...paramEntry,
|
|
696
|
+
description: paramEntry.description.length > 0
|
|
697
|
+
? `${paramEntry.description} ${continuation}`
|
|
698
|
+
: continuation,
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
else if (currentTag.target === 'returns' && returns !== undefined) {
|
|
702
|
+
returns = {
|
|
703
|
+
...returns,
|
|
704
|
+
description: returns.description.length > 0
|
|
705
|
+
? `${returns.description} ${continuation}`
|
|
706
|
+
: continuation,
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
else if (currentTag.target === 'throws' && throwEntry !== undefined) {
|
|
710
|
+
throws[currentTag.index] = {
|
|
711
|
+
...throwEntry,
|
|
712
|
+
description: throwEntry.description.length > 0
|
|
713
|
+
? `${throwEntry.description} ${continuation}`
|
|
714
|
+
: continuation,
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return { params, returns, throws };
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Extract clean text content from a JSDoc comment.
|
|
723
|
+
*
|
|
724
|
+
* Removes the JSDoc delimiters (/** and *\/) and leading asterisks from each line.
|
|
725
|
+
* Returns the first meaningful line as the description.
|
|
726
|
+
*/
|
|
727
|
+
function extractJsDocText(jsDoc) {
|
|
728
|
+
// Remove /** prefix and */ suffix
|
|
729
|
+
let text = jsDoc.trim();
|
|
730
|
+
if (text.startsWith('/**')) {
|
|
731
|
+
text = text.slice(3);
|
|
732
|
+
}
|
|
733
|
+
if (text.endsWith('*/')) {
|
|
734
|
+
text = text.slice(0, -2);
|
|
735
|
+
}
|
|
736
|
+
// Split into lines and clean each line
|
|
737
|
+
const lines = text
|
|
738
|
+
.split('\n')
|
|
739
|
+
.map((line) => {
|
|
740
|
+
// Remove leading whitespace and asterisk
|
|
741
|
+
let cleaned = line.trim();
|
|
742
|
+
if (cleaned.startsWith('*')) {
|
|
743
|
+
cleaned = cleaned.slice(1).trim();
|
|
744
|
+
}
|
|
745
|
+
return cleaned;
|
|
746
|
+
})
|
|
747
|
+
.filter((line) => line.length > 0 && !line.startsWith('@')); // Skip empty and tag lines
|
|
748
|
+
// DD-2: Return all non-empty, non-tag lines joined with space (not just first line)
|
|
749
|
+
// Space-join because property JSDoc renders in table cells where newlines break formatting
|
|
750
|
+
return lines.length > 0 ? lines.join(' ') : undefined;
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* DD-4: Extract all exported declarations from a file as shapes.
|
|
754
|
+
*
|
|
755
|
+
* Auto-discovery mode: when `@architect-extract-shapes *` is used,
|
|
756
|
+
* all exported types/interfaces/enums/functions/consts are extracted
|
|
757
|
+
* without requiring explicit names.
|
|
758
|
+
*
|
|
759
|
+
* @param sourceCode - File content
|
|
760
|
+
* @returns Result with all exported shapes
|
|
761
|
+
*/
|
|
762
|
+
function extractAllExportedShapes(sourceCode, jsx = false) {
|
|
763
|
+
// Validate input size
|
|
764
|
+
if (sourceCode.length > MAX_SOURCE_SIZE_BYTES) {
|
|
765
|
+
return Result.err(new Error(`Source code size (${sourceCode.length} bytes) exceeds maximum allowed (${MAX_SOURCE_SIZE_BYTES} bytes)`));
|
|
766
|
+
}
|
|
767
|
+
let ast;
|
|
768
|
+
try {
|
|
769
|
+
ast = parseSource(sourceCode, jsx);
|
|
770
|
+
}
|
|
771
|
+
catch (error) {
|
|
772
|
+
return Result.err(error instanceof Error ? error : new Error(`Failed to parse source code: ${String(error)}`));
|
|
773
|
+
}
|
|
774
|
+
const declarations = findDeclarations(ast);
|
|
775
|
+
const shapes = [];
|
|
776
|
+
const warnings = [];
|
|
777
|
+
// Extract best exported declaration per name (one shape per name)
|
|
778
|
+
for (const [, declarationList] of declarations) {
|
|
779
|
+
const exportedDecls = declarationList.filter((d) => d.exported);
|
|
780
|
+
if (exportedDecls.length === 0)
|
|
781
|
+
continue;
|
|
782
|
+
const best = pickBestDeclaration(exportedDecls);
|
|
783
|
+
const shape = extractShape(sourceCode, best, ast.comments ?? [], {
|
|
784
|
+
includeJsDoc: true,
|
|
785
|
+
preserveFormatting: true,
|
|
786
|
+
});
|
|
787
|
+
shapes.push(shape);
|
|
788
|
+
}
|
|
789
|
+
if (shapes.length > 50) {
|
|
790
|
+
warnings.push(`[extract-shapes] Auto-discovery extracted ${shapes.length} shapes. ` +
|
|
791
|
+
`This may indicate the file has too many exports for effective documentation.`);
|
|
792
|
+
}
|
|
793
|
+
return Result.ok({ shapes, notFound: [], imported: [], reExported: [], warnings });
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Process extract-shapes tag and return shapes for ExtractedPattern.
|
|
797
|
+
*
|
|
798
|
+
* Called by the document extractor when processing TypeScript files
|
|
799
|
+
* with @architect-extract-shapes tags.
|
|
800
|
+
*
|
|
801
|
+
* DD-4: Supports wildcard `*` for auto-discovery mode.
|
|
802
|
+
*
|
|
803
|
+
* @param sourceCode - File content
|
|
804
|
+
* @param extractShapesTag - Comma-separated shape names from tag, or `*` for auto-discovery
|
|
805
|
+
* @returns Result with extracted shapes and any warnings
|
|
806
|
+
*/
|
|
807
|
+
export function processExtractShapesTag(sourceCode, extractShapesTag, options) {
|
|
808
|
+
const jsx = options?.jsx ?? false;
|
|
809
|
+
// DD-4: Auto-shape discovery via wildcard
|
|
810
|
+
const shapeNames = extractShapesTag
|
|
811
|
+
.split(',')
|
|
812
|
+
.map((s) => s.trim())
|
|
813
|
+
.filter(Boolean);
|
|
814
|
+
const hasWildcard = shapeNames.includes('*');
|
|
815
|
+
if (hasWildcard) {
|
|
816
|
+
// Wildcard must be sole value — reject mixed case
|
|
817
|
+
if (shapeNames.length > 1) {
|
|
818
|
+
const namedShapes = shapeNames.filter((n) => n !== '*');
|
|
819
|
+
return {
|
|
820
|
+
shapes: [],
|
|
821
|
+
warnings: [
|
|
822
|
+
`[extract-shapes] Wildcard '*' must be the sole extract-shapes value. ` +
|
|
823
|
+
`Ignoring named shapes: ${namedShapes.join(', ')}. Use '*' alone or list specific names.`,
|
|
824
|
+
],
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
const result = extractAllExportedShapes(sourceCode, jsx);
|
|
828
|
+
if (!result.ok) {
|
|
829
|
+
return {
|
|
830
|
+
shapes: [],
|
|
831
|
+
warnings: [`[extract-shapes] ${result.error.message}`],
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
return { shapes: [...result.value.shapes], warnings: [...result.value.warnings] };
|
|
835
|
+
}
|
|
836
|
+
const extractionResult = extractShapes(sourceCode, shapeNames, { jsx });
|
|
837
|
+
// If extraction failed (parse error), return empty shapes with error as warning
|
|
838
|
+
if (!extractionResult.ok) {
|
|
839
|
+
return {
|
|
840
|
+
shapes: [],
|
|
841
|
+
warnings: [`[extract-shapes] ${extractionResult.error.message}`],
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
const result = extractionResult.value;
|
|
845
|
+
const warnings = [...result.warnings];
|
|
846
|
+
// Collect warnings for not-found shapes
|
|
847
|
+
for (const name of result.notFound) {
|
|
848
|
+
warnings.push(`[extract-shapes] Shape '${name}' not found in file`);
|
|
849
|
+
}
|
|
850
|
+
// Collect warnings for imported shapes
|
|
851
|
+
for (const name of result.imported) {
|
|
852
|
+
warnings.push(`[extract-shapes] Shape '${name}' is imported, not defined in this file. ` +
|
|
853
|
+
`Add @architect-extract-shapes to the source file instead.`);
|
|
854
|
+
}
|
|
855
|
+
// Collect warnings for re-exported shapes with source module info
|
|
856
|
+
for (const reExport of result.reExported) {
|
|
857
|
+
const typeOnlyNote = reExport.typeOnly ? ' (type-only)' : '';
|
|
858
|
+
warnings.push(`[extract-shapes] Shape '${reExport.name}' is re-exported${typeOnlyNote} from '${reExport.sourceModule}'. ` +
|
|
859
|
+
`Add @architect-extract-shapes to ${reExport.sourceModule} instead.`);
|
|
860
|
+
}
|
|
861
|
+
return { shapes: [...result.shapes], warnings };
|
|
862
|
+
}
|
|
863
|
+
// =============================================================================
|
|
864
|
+
// Declaration-Level Shape Discovery (DD-1, DD-2, DD-4, DD-7)
|
|
865
|
+
// =============================================================================
|
|
866
|
+
/**
|
|
867
|
+
* Extract the @architect-shape tag from JSDoc text.
|
|
868
|
+
*
|
|
869
|
+
* Returns `{ tagged: true, group }` if the tag is present,
|
|
870
|
+
* where `group` is `undefined` for bare tags and a string for valued tags.
|
|
871
|
+
*
|
|
872
|
+
* @param jsDocText - Raw JSDoc text including delimiters
|
|
873
|
+
*/
|
|
874
|
+
function extractShapeTag(jsDocText) {
|
|
875
|
+
// Match tag with optional group name, excluding JSDoc delimiters (* and /).
|
|
876
|
+
// Negative lookahead (?!-) prevents matching hypothetical architect-shape-* tags.
|
|
877
|
+
const match = /architect-shape(?!-)(?:\s+([^\s*/]+))?/.exec(jsDocText);
|
|
878
|
+
if (!match)
|
|
879
|
+
return { tagged: false };
|
|
880
|
+
const group = match[1];
|
|
881
|
+
if (group !== undefined) {
|
|
882
|
+
return { tagged: true, group };
|
|
883
|
+
}
|
|
884
|
+
return { tagged: true };
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Extract the @architect-include tag from JSDoc text.
|
|
888
|
+
*
|
|
889
|
+
* Returns an array of include values if the tag is present (CSV format),
|
|
890
|
+
* or `undefined` if the tag is absent. Values are trimmed and filtered for empties.
|
|
891
|
+
*
|
|
892
|
+
* @param jsDocText - Raw JSDoc text including delimiters
|
|
893
|
+
*/
|
|
894
|
+
function extractIncludeTag(jsDocText) {
|
|
895
|
+
const match = /architect-include(?!-)(?:\s+([^\n@*]+))?/.exec(jsDocText);
|
|
896
|
+
if (!match)
|
|
897
|
+
return undefined;
|
|
898
|
+
const raw = match[1];
|
|
899
|
+
if (raw === undefined)
|
|
900
|
+
return undefined;
|
|
901
|
+
const values = raw
|
|
902
|
+
.split(',')
|
|
903
|
+
.map((v) => v.trim())
|
|
904
|
+
.filter((v) => v.length > 0);
|
|
905
|
+
return values.length > 0 ? values : undefined;
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Discover declarations tagged with @architect-shape in source code.
|
|
909
|
+
*
|
|
910
|
+
* Scans all top-level declarations (exported and non-exported per DD-7)
|
|
911
|
+
* for @architect-shape tags in their preceding JSDoc. Tagged declarations
|
|
912
|
+
* are extracted as shapes with an optional group from the tag value (DD-5).
|
|
913
|
+
*
|
|
914
|
+
* Reuses existing infrastructure: findDeclarations(), extractPrecedingJsDoc(),
|
|
915
|
+
* and extractShape() — no parser changes needed (DD-2).
|
|
916
|
+
*
|
|
917
|
+
* @param sourceCode - TypeScript source code to scan
|
|
918
|
+
* @param options - Parse options (jsx should match file extension)
|
|
919
|
+
* @returns Result containing discovered shapes and warnings
|
|
920
|
+
*/
|
|
921
|
+
export function discoverTaggedShapes(sourceCode, options) {
|
|
922
|
+
// Validate input size
|
|
923
|
+
if (sourceCode.length > MAX_SOURCE_SIZE_BYTES) {
|
|
924
|
+
return Result.err(new Error(`Source code size (${sourceCode.length} bytes) exceeds maximum allowed (${MAX_SOURCE_SIZE_BYTES} bytes)`));
|
|
925
|
+
}
|
|
926
|
+
// Parse with correct JSX mode (DD-2: stay on estree parser)
|
|
927
|
+
let ast;
|
|
928
|
+
try {
|
|
929
|
+
ast = parseSource(sourceCode, options?.jsx ?? false);
|
|
930
|
+
}
|
|
931
|
+
catch (error) {
|
|
932
|
+
return Result.err(error instanceof Error ? error : new Error(`Failed to parse source code: ${String(error)}`));
|
|
933
|
+
}
|
|
934
|
+
// DD-7: Get ALL declarations (exported + non-exported)
|
|
935
|
+
const declarations = findDeclarations(ast);
|
|
936
|
+
const comments = ast.comments ?? [];
|
|
937
|
+
const shapes = [];
|
|
938
|
+
const warnings = [];
|
|
939
|
+
for (const [, declarationList] of declarations) {
|
|
940
|
+
for (const declaration of declarationList) {
|
|
941
|
+
// Get JSDoc for this declaration (respects MAX_JSDOC_LINE_DISTANCE)
|
|
942
|
+
const jsDoc = extractPrecedingJsDoc(sourceCode, declaration.node, comments);
|
|
943
|
+
if (jsDoc === undefined)
|
|
944
|
+
continue;
|
|
945
|
+
// Check for @architect-shape tag
|
|
946
|
+
const tagResult = extractShapeTag(jsDoc);
|
|
947
|
+
if (!tagResult.tagged)
|
|
948
|
+
continue;
|
|
949
|
+
// Extract the shape using existing infrastructure
|
|
950
|
+
const shape = extractShape(sourceCode, declaration, comments, {
|
|
951
|
+
includeJsDoc: true,
|
|
952
|
+
preserveFormatting: true,
|
|
953
|
+
});
|
|
954
|
+
// DD-5: Add group field from tag value
|
|
955
|
+
// DD-3 (CrossCuttingDocumentInclusion): Add includes from @architect-include
|
|
956
|
+
const includeValues = extractIncludeTag(jsDoc);
|
|
957
|
+
shapes.push({
|
|
958
|
+
...shape,
|
|
959
|
+
group: tagResult.group,
|
|
960
|
+
...(includeValues !== undefined && { includes: includeValues }),
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
return Result.ok({ shapes, warnings });
|
|
965
|
+
}
|
|
966
|
+
//# sourceMappingURL=shape-extractor.js.map
|