@libar-dev/architect 1.0.0-pre.3 → 1.0.0-pre.5
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 +1 -1
- package/README.md +5 -5
- package/dist/api/arch-queries.d.ts.map +1 -1
- package/dist/api/context-assembler.d.ts.map +1 -1
- package/dist/api/handoff-generator.d.ts.map +1 -1
- package/dist/api/index.d.ts +8 -8
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +7 -7
- package/dist/api/index.js.map +1 -1
- package/dist/api/{process-state.d.ts → pattern-graph-api.d.ts} +15 -15
- package/dist/api/pattern-graph-api.d.ts.map +1 -0
- package/dist/api/{process-state.js → pattern-graph-api.js} +13 -13
- package/dist/api/pattern-graph-api.js.map +1 -0
- package/dist/api/rules-query.d.ts +6 -6
- package/dist/api/rules-query.d.ts.map +1 -1
- package/dist/api/rules-query.js +4 -4
- package/dist/api/rules-query.js.map +1 -1
- package/dist/api/scope-validator.d.ts.map +1 -1
- package/dist/api/types.d.ts +8 -8
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/types.js +5 -5
- package/dist/cli/cli-schema.d.ts +3 -4
- package/dist/cli/cli-schema.d.ts.map +1 -1
- package/dist/cli/cli-schema.js +13 -14
- package/dist/cli/cli-schema.js.map +1 -1
- package/dist/cli/output-pipeline.d.ts.map +1 -1
- package/dist/cli/pattern-graph-cli.d.ts.map +1 -0
- package/dist/cli/validate-patterns.d.ts.map +1 -1
- package/dist/generators/built-in/cli-recipe-generator.d.ts +3 -4
- package/dist/generators/built-in/cli-recipe-generator.d.ts.map +1 -1
- package/dist/generators/built-in/cli-recipe-generator.js +6 -7
- package/dist/generators/built-in/cli-recipe-generator.js.map +1 -1
- package/dist/generators/built-in/cli-reference-generator.d.ts +18 -0
- package/dist/generators/built-in/cli-reference-generator.d.ts.map +1 -0
- package/dist/generators/built-in/{process-api-reference-generator.js → cli-reference-generator.js} +13 -13
- package/dist/generators/built-in/cli-reference-generator.js.map +1 -0
- package/dist/generators/built-in/codec-generators.js +12 -12
- package/dist/generators/built-in/codec-generators.js.map +1 -1
- package/dist/generators/built-in/design-review-generator.d.ts.map +1 -1
- package/dist/generators/built-in/reference-generators.d.ts.map +1 -1
- package/dist/generators/codec-based.d.ts.map +1 -1
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/orchestrator.d.ts.map +1 -1
- package/dist/generators/pipeline/build-pipeline.d.ts +17 -14
- package/dist/generators/pipeline/build-pipeline.d.ts.map +1 -1
- package/dist/generators/pipeline/build-pipeline.js +27 -21
- package/dist/generators/pipeline/build-pipeline.js.map +1 -1
- package/dist/generators/pipeline/index.d.ts.map +1 -1
- package/dist/generators/types.d.ts.map +1 -1
- package/dist/mcp/pipeline-session.d.ts.map +1 -1
- package/dist/renderable/codecs/index-codec.d.ts.map +1 -1
- package/dist/renderable/codecs/index-codec.js +54 -28
- package/dist/renderable/codecs/index-codec.js.map +1 -1
- package/docs/ANNOTATION-GUIDE.md +5 -5
- package/docs/ARCHITECTURE.md +79 -79
- package/docs/{PROCESS-API.md → CLI.md} +6 -6
- package/docs/CONFIGURATION.md +2 -2
- package/docs/DOCS-GAP-ANALYSIS.md +65 -65
- package/docs/INDEX.md +34 -34
- package/docs/MCP-SETUP.md +3 -3
- package/docs/METHODOLOGY.md +1 -1
- package/docs/SESSION-GUIDES.md +3 -3
- package/docs/VALIDATION.md +4 -4
- package/docs-live/ARCHITECTURE.md +48 -42
- package/docs-live/BUSINESS-RULES.md +3 -3
- package/docs-live/CHANGELOG-GENERATED.md +109 -103
- package/docs-live/INDEX.md +21 -21
- package/docs-live/PRODUCT-AREAS.md +7 -7
- package/docs-live/TAXONOMY.md +3 -5
- package/docs-live/_claude-md/annotation/annotation-overview.md +1 -1
- package/docs-live/_claude-md/annotation/annotation-reference.md +5 -5
- package/docs-live/_claude-md/architecture/architecture-types.md +4 -4
- package/docs-live/_claude-md/architecture/reference-sample.md +2 -2
- package/docs-live/_claude-md/data-api/data-api-overview.md +2 -2
- package/docs-live/_claude-md/generation/generation-overview.md +15 -15
- package/docs-live/_claude-md/process/process-overview.md +1 -1
- package/docs-live/_claude-md/validation/validation-overview.md +1 -1
- package/docs-live/business-rules/annotation.md +1 -2
- package/docs-live/business-rules/configuration.md +1 -1
- package/docs-live/business-rules/data-api.md +149 -136
- package/docs-live/business-rules/generation.md +172 -20
- package/docs-live/decisions/adr-003-source-first-pattern-architecture.md +1 -1
- package/docs-live/decisions/adr-005-codec-based-markdown-rendering.md +5 -5
- package/docs-live/decisions/adr-006-single-read-model-architecture.md +24 -24
- package/docs-live/product-areas/ANNOTATION.md +19 -9
- package/docs-live/product-areas/CONFIGURATION.md +39 -19
- package/docs-live/product-areas/DATA-API.md +155 -151
- package/docs-live/product-areas/GENERATION.md +159 -144
- package/docs-live/product-areas/PROCESS.md +4 -4
- package/docs-live/product-areas/VALIDATION.md +35 -20
- package/docs-live/reference/ANNOTATION-REFERENCE.md +5 -5
- package/docs-live/reference/ARCHITECTURE-CODECS.md +11 -11
- package/docs-live/reference/ARCHITECTURE-TYPES.md +28 -25
- package/docs-live/reference/{PROCESS-API-RECIPES.md → CLI-RECIPES.md} +11 -11
- package/docs-live/reference/{PROCESS-API-REFERENCE.md → CLI-REFERENCE.md} +2 -2
- package/docs-live/reference/REFERENCE-SAMPLE.md +56 -56
- package/docs-live/reference/SESSION-WORKFLOW-GUIDE.md +3 -3
- package/docs-live/taxonomy/format-types.md +2 -2
- package/docs-live/taxonomy/metadata-tags.md +1 -23
- package/package.json +7 -7
- package/dist/api/arch-queries.d.ts +0 -95
- package/dist/api/arch-queries.js +0 -310
- package/dist/api/arch-queries.js.map +0 -1
- package/dist/api/context-assembler.d.ts +0 -124
- package/dist/api/context-assembler.js +0 -472
- package/dist/api/context-assembler.js.map +0 -1
- package/dist/api/context-formatter.d.ts +0 -26
- package/dist/api/context-formatter.js +0 -183
- package/dist/api/context-formatter.js.map +0 -1
- package/dist/api/coverage-analyzer.d.ts +0 -38
- package/dist/api/coverage-analyzer.d.ts.map +0 -1
- package/dist/api/coverage-analyzer.js +0 -117
- package/dist/api/coverage-analyzer.js.map +0 -1
- package/dist/api/fuzzy-match.d.ts +0 -75
- package/dist/api/fuzzy-match.d.ts.map +0 -1
- package/dist/api/fuzzy-match.js +0 -150
- package/dist/api/fuzzy-match.js.map +0 -1
- package/dist/api/handoff-generator.d.ts +0 -45
- package/dist/api/handoff-generator.js +0 -139
- package/dist/api/handoff-generator.js.map +0 -1
- package/dist/api/pattern-helpers.d.ts +0 -51
- package/dist/api/pattern-helpers.d.ts.map +0 -1
- package/dist/api/pattern-helpers.js +0 -84
- package/dist/api/pattern-helpers.js.map +0 -1
- package/dist/api/process-state.d.ts.map +0 -1
- package/dist/api/process-state.js.map +0 -1
- package/dist/api/scope-validator.d.ts +0 -56
- package/dist/api/scope-validator.js +0 -293
- package/dist/api/scope-validator.js.map +0 -1
- package/dist/api/stub-resolver.d.ts +0 -117
- package/dist/api/stub-resolver.d.ts.map +0 -1
- package/dist/api/stub-resolver.js +0 -154
- package/dist/api/stub-resolver.js.map +0 -1
- package/dist/api/summarize.d.ts +0 -75
- package/dist/api/summarize.d.ts.map +0 -1
- package/dist/api/summarize.js +0 -97
- package/dist/api/summarize.js.map +0 -1
- package/dist/cache/file-cache.d.ts +0 -72
- package/dist/cache/file-cache.d.ts.map +0 -1
- package/dist/cache/file-cache.js +0 -80
- package/dist/cache/file-cache.js.map +0 -1
- package/dist/cache/index.d.ts +0 -5
- package/dist/cache/index.d.ts.map +0 -1
- package/dist/cache/index.js +0 -5
- package/dist/cache/index.js.map +0 -1
- package/dist/cli/dataset-cache.d.ts +0 -66
- package/dist/cli/dataset-cache.js +0 -179
- package/dist/cli/dataset-cache.js.map +0 -1
- package/dist/cli/error-handler.d.ts +0 -84
- package/dist/cli/error-handler.d.ts.map +0 -1
- package/dist/cli/error-handler.js +0 -197
- package/dist/cli/error-handler.js.map +0 -1
- package/dist/cli/generate-docs.d.ts +0 -30
- package/dist/cli/generate-docs.js +0 -370
- package/dist/cli/generate-docs.js.map +0 -1
- package/dist/cli/lint-patterns.d.ts +0 -57
- package/dist/cli/lint-patterns.d.ts.map +0 -1
- package/dist/cli/lint-patterns.js +0 -257
- package/dist/cli/lint-patterns.js.map +0 -1
- package/dist/cli/lint-process.d.ts +0 -54
- package/dist/cli/lint-process.d.ts.map +0 -1
- package/dist/cli/lint-process.js +0 -319
- package/dist/cli/lint-process.js.map +0 -1
- package/dist/cli/lint-steps.d.ts +0 -32
- package/dist/cli/lint-steps.d.ts.map +0 -1
- package/dist/cli/lint-steps.js +0 -172
- package/dist/cli/lint-steps.js.map +0 -1
- package/dist/cli/mcp-server.d.ts +0 -22
- package/dist/cli/mcp-server.js +0 -57
- package/dist/cli/mcp-server.js.map +0 -1
- package/dist/cli/output-pipeline.d.ts +0 -130
- package/dist/cli/output-pipeline.js +0 -234
- package/dist/cli/output-pipeline.js.map +0 -1
- package/dist/cli/process-api.d.ts +0 -37
- package/dist/cli/process-api.d.ts.map +0 -1
- package/dist/cli/process-api.js +0 -1550
- package/dist/cli/process-api.js.map +0 -1
- package/dist/cli/repl.d.ts +0 -38
- package/dist/cli/repl.js +0 -239
- package/dist/cli/repl.js.map +0 -1
- package/dist/cli/validate-patterns.d.ts +0 -115
- package/dist/cli/validate-patterns.js +0 -707
- package/dist/cli/validate-patterns.js.map +0 -1
- package/dist/cli/version.d.ts +0 -35
- package/dist/cli/version.d.ts.map +0 -1
- package/dist/cli/version.js +0 -64
- package/dist/cli/version.js.map +0 -1
- package/dist/config/config-loader.d.ts +0 -167
- package/dist/config/config-loader.d.ts.map +0 -1
- package/dist/config/config-loader.js +0 -294
- package/dist/config/config-loader.js.map +0 -1
- package/dist/config/defaults.d.ts +0 -92
- package/dist/config/defaults.d.ts.map +0 -1
- package/dist/config/defaults.js +0 -103
- package/dist/config/defaults.js.map +0 -1
- package/dist/config/define-config.d.ts +0 -37
- package/dist/config/define-config.d.ts.map +0 -1
- package/dist/config/define-config.js +0 -38
- package/dist/config/define-config.js.map +0 -1
- package/dist/config/factory.d.ts +0 -79
- package/dist/config/factory.d.ts.map +0 -1
- package/dist/config/factory.js +0 -116
- package/dist/config/factory.js.map +0 -1
- package/dist/config/index.d.ts +0 -45
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js +0 -48
- package/dist/config/index.js.map +0 -1
- package/dist/config/merge-sources.d.ts +0 -47
- package/dist/config/merge-sources.d.ts.map +0 -1
- package/dist/config/merge-sources.js +0 -61
- package/dist/config/merge-sources.js.map +0 -1
- package/dist/config/presets.d.ts +0 -115
- package/dist/config/presets.d.ts.map +0 -1
- package/dist/config/presets.js +0 -119
- package/dist/config/presets.js.map +0 -1
- package/dist/config/project-config-schema.d.ts +0 -192
- package/dist/config/project-config-schema.d.ts.map +0 -1
- package/dist/config/project-config-schema.js +0 -231
- package/dist/config/project-config-schema.js.map +0 -1
- package/dist/config/project-config.d.ts +0 -229
- package/dist/config/project-config.d.ts.map +0 -1
- package/dist/config/project-config.js +0 -37
- package/dist/config/project-config.js.map +0 -1
- package/dist/config/regex-builders.d.ts +0 -49
- package/dist/config/regex-builders.d.ts.map +0 -1
- package/dist/config/regex-builders.js +0 -85
- package/dist/config/regex-builders.js.map +0 -1
- package/dist/config/resolve-config.d.ts +0 -65
- package/dist/config/resolve-config.d.ts.map +0 -1
- package/dist/config/resolve-config.js +0 -150
- package/dist/config/resolve-config.js.map +0 -1
- package/dist/config/types.d.ts +0 -81
- package/dist/config/types.d.ts.map +0 -1
- package/dist/config/types.js +0 -22
- package/dist/config/types.js.map +0 -1
- package/dist/config/workflow-loader.d.ts +0 -90
- package/dist/config/workflow-loader.d.ts.map +0 -1
- package/dist/config/workflow-loader.js +0 -167
- package/dist/config/workflow-loader.js.map +0 -1
- package/dist/extractor/doc-extractor.d.ts +0 -233
- package/dist/extractor/doc-extractor.d.ts.map +0 -1
- package/dist/extractor/doc-extractor.js +0 -481
- package/dist/extractor/doc-extractor.js.map +0 -1
- package/dist/extractor/dual-source-extractor.d.ts +0 -161
- package/dist/extractor/dual-source-extractor.d.ts.map +0 -1
- package/dist/extractor/dual-source-extractor.js +0 -407
- package/dist/extractor/dual-source-extractor.js.map +0 -1
- package/dist/extractor/gherkin-extractor.d.ts +0 -170
- package/dist/extractor/gherkin-extractor.d.ts.map +0 -1
- package/dist/extractor/gherkin-extractor.js +0 -543
- package/dist/extractor/gherkin-extractor.js.map +0 -1
- package/dist/extractor/index.d.ts +0 -7
- package/dist/extractor/index.d.ts.map +0 -1
- package/dist/extractor/index.js +0 -11
- package/dist/extractor/index.js.map +0 -1
- package/dist/extractor/layer-inference.d.ts +0 -66
- package/dist/extractor/layer-inference.d.ts.map +0 -1
- package/dist/extractor/layer-inference.js +0 -93
- package/dist/extractor/layer-inference.js.map +0 -1
- package/dist/extractor/shape-extractor.d.ts +0 -79
- package/dist/extractor/shape-extractor.d.ts.map +0 -1
- package/dist/extractor/shape-extractor.js +0 -966
- package/dist/extractor/shape-extractor.js.map +0 -1
- package/dist/generators/built-in/codec-generators.d.ts +0 -29
- package/dist/generators/built-in/decision-doc-generator.d.ts +0 -204
- package/dist/generators/built-in/decision-doc-generator.js +0 -654
- package/dist/generators/built-in/decision-doc-generator.js.map +0 -1
- package/dist/generators/built-in/design-review-generator.d.ts +0 -26
- package/dist/generators/built-in/design-review-generator.js +0 -94
- package/dist/generators/built-in/design-review-generator.js.map +0 -1
- package/dist/generators/built-in/index.d.ts +0 -22
- package/dist/generators/built-in/index.js +0 -23
- package/dist/generators/built-in/index.js.map +0 -1
- package/dist/generators/built-in/process-api-reference-generator.d.ts +0 -18
- package/dist/generators/built-in/process-api-reference-generator.d.ts.map +0 -1
- package/dist/generators/built-in/process-api-reference-generator.js.map +0 -1
- package/dist/generators/built-in/reference-generators.d.ts +0 -51
- package/dist/generators/built-in/reference-generators.js +0 -320
- package/dist/generators/built-in/reference-generators.js.map +0 -1
- package/dist/generators/codec-based.d.ts +0 -63
- package/dist/generators/codec-based.js +0 -88
- package/dist/generators/codec-based.js.map +0 -1
- package/dist/generators/content-deduplicator.d.ts +0 -114
- package/dist/generators/content-deduplicator.d.ts.map +0 -1
- package/dist/generators/content-deduplicator.js +0 -356
- package/dist/generators/content-deduplicator.js.map +0 -1
- package/dist/generators/index.d.ts +0 -50
- package/dist/generators/index.js +0 -54
- package/dist/generators/index.js.map +0 -1
- package/dist/generators/orchestrator.d.ts +0 -265
- package/dist/generators/orchestrator.js +0 -570
- package/dist/generators/orchestrator.js.map +0 -1
- package/dist/generators/pipeline/context-inference.d.ts +0 -55
- package/dist/generators/pipeline/context-inference.d.ts.map +0 -1
- package/dist/generators/pipeline/context-inference.js +0 -76
- package/dist/generators/pipeline/context-inference.js.map +0 -1
- package/dist/generators/pipeline/index.d.ts +0 -27
- package/dist/generators/pipeline/index.js +0 -34
- package/dist/generators/pipeline/index.js.map +0 -1
- package/dist/generators/pipeline/merge-patterns.d.ts +0 -33
- package/dist/generators/pipeline/merge-patterns.d.ts.map +0 -1
- package/dist/generators/pipeline/merge-patterns.js +0 -50
- package/dist/generators/pipeline/merge-patterns.js.map +0 -1
- package/dist/generators/pipeline/relationship-resolver.d.ts +0 -47
- package/dist/generators/pipeline/relationship-resolver.d.ts.map +0 -1
- package/dist/generators/pipeline/relationship-resolver.js +0 -132
- package/dist/generators/pipeline/relationship-resolver.js.map +0 -1
- package/dist/generators/pipeline/sequence-utils.d.ts +0 -49
- package/dist/generators/pipeline/sequence-utils.d.ts.map +0 -1
- package/dist/generators/pipeline/sequence-utils.js +0 -235
- package/dist/generators/pipeline/sequence-utils.js.map +0 -1
- package/dist/generators/pipeline/transform-dataset.d.ts +0 -82
- package/dist/generators/pipeline/transform-dataset.d.ts.map +0 -1
- package/dist/generators/pipeline/transform-dataset.js +0 -355
- package/dist/generators/pipeline/transform-dataset.js.map +0 -1
- package/dist/generators/pipeline/transform-types.d.ts +0 -96
- package/dist/generators/pipeline/transform-types.d.ts.map +0 -1
- package/dist/generators/pipeline/transform-types.js +0 -18
- package/dist/generators/pipeline/transform-types.js.map +0 -1
- package/dist/generators/registry.d.ts +0 -64
- package/dist/generators/registry.js +0 -77
- package/dist/generators/registry.js.map +0 -1
- package/dist/generators/source-mapper.d.ts +0 -143
- package/dist/generators/source-mapper.d.ts.map +0 -1
- package/dist/generators/source-mapper.js +0 -602
- package/dist/generators/source-mapper.js.map +0 -1
- package/dist/generators/source-mapping-validator.d.ts +0 -118
- package/dist/generators/source-mapping-validator.d.ts.map +0 -1
- package/dist/generators/source-mapping-validator.js +0 -334
- package/dist/generators/source-mapping-validator.js.map +0 -1
- package/dist/generators/types.d.ts +0 -104
- package/dist/generators/types.js +0 -5
- package/dist/generators/types.js.map +0 -1
- package/dist/generators/warning-collector.d.ts +0 -144
- package/dist/generators/warning-collector.d.ts.map +0 -1
- package/dist/generators/warning-collector.js +0 -166
- package/dist/generators/warning-collector.js.map +0 -1
- package/dist/git/branch-diff.d.ts +0 -44
- package/dist/git/branch-diff.d.ts.map +0 -1
- package/dist/git/branch-diff.js +0 -57
- package/dist/git/branch-diff.js.map +0 -1
- package/dist/git/helpers.d.ts +0 -46
- package/dist/git/helpers.d.ts.map +0 -1
- package/dist/git/helpers.js +0 -67
- package/dist/git/helpers.js.map +0 -1
- package/dist/git/index.d.ts +0 -18
- package/dist/git/index.d.ts.map +0 -1
- package/dist/git/index.js +0 -18
- package/dist/git/index.js.map +0 -1
- package/dist/git/name-status.d.ts +0 -32
- package/dist/git/name-status.d.ts.map +0 -1
- package/dist/git/name-status.js +0 -66
- package/dist/git/name-status.js.map +0 -1
- package/dist/index.d.ts +0 -107
- package/dist/index.js +0 -122
- package/dist/index.js.map +0 -1
- package/dist/lint/engine.d.ts +0 -113
- package/dist/lint/engine.d.ts.map +0 -1
- package/dist/lint/engine.js +0 -228
- package/dist/lint/engine.js.map +0 -1
- package/dist/lint/index.d.ts +0 -26
- package/dist/lint/index.d.ts.map +0 -1
- package/dist/lint/index.js +0 -24
- package/dist/lint/index.js.map +0 -1
- package/dist/lint/process-guard/decider.d.ts +0 -166
- package/dist/lint/process-guard/decider.d.ts.map +0 -1
- package/dist/lint/process-guard/decider.js +0 -412
- package/dist/lint/process-guard/decider.js.map +0 -1
- package/dist/lint/process-guard/derive-state.d.ts +0 -96
- package/dist/lint/process-guard/derive-state.d.ts.map +0 -1
- package/dist/lint/process-guard/derive-state.js +0 -368
- package/dist/lint/process-guard/derive-state.js.map +0 -1
- package/dist/lint/process-guard/detect-changes.d.ts +0 -109
- package/dist/lint/process-guard/detect-changes.d.ts.map +0 -1
- package/dist/lint/process-guard/detect-changes.js +0 -487
- package/dist/lint/process-guard/detect-changes.js.map +0 -1
- package/dist/lint/process-guard/index.d.ts +0 -35
- package/dist/lint/process-guard/index.d.ts.map +0 -1
- package/dist/lint/process-guard/index.js +0 -39
- package/dist/lint/process-guard/index.js.map +0 -1
- package/dist/lint/process-guard/types.d.ts +0 -255
- package/dist/lint/process-guard/types.d.ts.map +0 -1
- package/dist/lint/process-guard/types.js +0 -31
- package/dist/lint/process-guard/types.js.map +0 -1
- package/dist/lint/rules.d.ts +0 -147
- package/dist/lint/rules.d.ts.map +0 -1
- package/dist/lint/rules.js +0 -289
- package/dist/lint/rules.js.map +0 -1
- package/dist/lint/steps/cross-checks.d.ts +0 -66
- package/dist/lint/steps/cross-checks.d.ts.map +0 -1
- package/dist/lint/steps/cross-checks.js +0 -290
- package/dist/lint/steps/cross-checks.js.map +0 -1
- package/dist/lint/steps/feature-checks.d.ts +0 -78
- package/dist/lint/steps/feature-checks.d.ts.map +0 -1
- package/dist/lint/steps/feature-checks.js +0 -279
- package/dist/lint/steps/feature-checks.js.map +0 -1
- package/dist/lint/steps/index.d.ts +0 -22
- package/dist/lint/steps/index.d.ts.map +0 -1
- package/dist/lint/steps/index.js +0 -26
- package/dist/lint/steps/index.js.map +0 -1
- package/dist/lint/steps/pair-resolver.d.ts +0 -29
- package/dist/lint/steps/pair-resolver.d.ts.map +0 -1
- package/dist/lint/steps/pair-resolver.js +0 -76
- package/dist/lint/steps/pair-resolver.js.map +0 -1
- package/dist/lint/steps/runner.d.ts +0 -28
- package/dist/lint/steps/runner.d.ts.map +0 -1
- package/dist/lint/steps/runner.js +0 -143
- package/dist/lint/steps/runner.js.map +0 -1
- package/dist/lint/steps/step-checks.d.ts +0 -41
- package/dist/lint/steps/step-checks.d.ts.map +0 -1
- package/dist/lint/steps/step-checks.js +0 -164
- package/dist/lint/steps/step-checks.js.map +0 -1
- package/dist/lint/steps/types.d.ts +0 -95
- package/dist/lint/steps/types.d.ts.map +0 -1
- package/dist/lint/steps/types.js +0 -79
- package/dist/lint/steps/types.js.map +0 -1
- package/dist/lint/steps/utils.d.ts +0 -22
- package/dist/lint/steps/utils.d.ts.map +0 -1
- package/dist/lint/steps/utils.js +0 -57
- package/dist/lint/steps/utils.js.map +0 -1
- package/dist/mcp/file-watcher.d.ts +0 -24
- package/dist/mcp/file-watcher.js +0 -75
- package/dist/mcp/file-watcher.js.map +0 -1
- package/dist/mcp/index.d.ts +0 -19
- package/dist/mcp/index.js +0 -21
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/pipeline-session.d.ts +0 -33
- package/dist/mcp/pipeline-session.js +0 -149
- package/dist/mcp/pipeline-session.js.map +0 -1
- package/dist/mcp/server.d.ts +0 -28
- package/dist/mcp/server.js +0 -197
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/tool-registry.d.ts +0 -4
- package/dist/mcp/tool-registry.js +0 -525
- package/dist/mcp/tool-registry.js.map +0 -1
- package/dist/renderable/codecs/adr.d.ts +0 -4730
- package/dist/renderable/codecs/adr.d.ts.map +0 -1
- package/dist/renderable/codecs/adr.js +0 -590
- package/dist/renderable/codecs/adr.js.map +0 -1
- package/dist/renderable/codecs/architecture.d.ts +0 -4760
- package/dist/renderable/codecs/architecture.d.ts.map +0 -1
- package/dist/renderable/codecs/architecture.js +0 -524
- package/dist/renderable/codecs/architecture.js.map +0 -1
- package/dist/renderable/codecs/business-rules.d.ts +0 -4777
- package/dist/renderable/codecs/business-rules.d.ts.map +0 -1
- package/dist/renderable/codecs/business-rules.js +0 -648
- package/dist/renderable/codecs/business-rules.js.map +0 -1
- package/dist/renderable/codecs/claude-module.d.ts +0 -4710
- package/dist/renderable/codecs/claude-module.d.ts.map +0 -1
- package/dist/renderable/codecs/claude-module.js +0 -214
- package/dist/renderable/codecs/claude-module.js.map +0 -1
- package/dist/renderable/codecs/composite.d.ts +0 -84
- package/dist/renderable/codecs/composite.d.ts.map +0 -1
- package/dist/renderable/codecs/composite.js +0 -124
- package/dist/renderable/codecs/composite.js.map +0 -1
- package/dist/renderable/codecs/convention-extractor.d.ts +0 -105
- package/dist/renderable/codecs/convention-extractor.d.ts.map +0 -1
- package/dist/renderable/codecs/convention-extractor.js +0 -353
- package/dist/renderable/codecs/convention-extractor.js.map +0 -1
- package/dist/renderable/codecs/decision-doc.d.ts +0 -308
- package/dist/renderable/codecs/decision-doc.d.ts.map +0 -1
- package/dist/renderable/codecs/decision-doc.js +0 -485
- package/dist/renderable/codecs/decision-doc.js.map +0 -1
- package/dist/renderable/codecs/design-review.d.ts +0 -55
- package/dist/renderable/codecs/design-review.d.ts.map +0 -1
- package/dist/renderable/codecs/design-review.js +0 -532
- package/dist/renderable/codecs/design-review.js.map +0 -1
- package/dist/renderable/codecs/diagram-utils.d.ts +0 -62
- package/dist/renderable/codecs/diagram-utils.d.ts.map +0 -1
- package/dist/renderable/codecs/diagram-utils.js +0 -70
- package/dist/renderable/codecs/diagram-utils.js.map +0 -1
- package/dist/renderable/codecs/helpers.d.ts +0 -553
- package/dist/renderable/codecs/helpers.d.ts.map +0 -1
- package/dist/renderable/codecs/helpers.js +0 -913
- package/dist/renderable/codecs/helpers.js.map +0 -1
- package/dist/renderable/codecs/index-codec.d.ts +0 -4714
- package/dist/renderable/codecs/index.d.ts +0 -46
- package/dist/renderable/codecs/index.d.ts.map +0 -1
- package/dist/renderable/codecs/index.js +0 -70
- package/dist/renderable/codecs/index.js.map +0 -1
- package/dist/renderable/codecs/patterns.d.ts +0 -4757
- package/dist/renderable/codecs/patterns.d.ts.map +0 -1
- package/dist/renderable/codecs/patterns.js +0 -462
- package/dist/renderable/codecs/patterns.js.map +0 -1
- package/dist/renderable/codecs/planning.d.ts +0 -14055
- package/dist/renderable/codecs/planning.d.ts.map +0 -1
- package/dist/renderable/codecs/planning.js +0 -449
- package/dist/renderable/codecs/planning.js.map +0 -1
- package/dist/renderable/codecs/pr-changes.d.ts +0 -4742
- package/dist/renderable/codecs/pr-changes.d.ts.map +0 -1
- package/dist/renderable/codecs/pr-changes.js +0 -425
- package/dist/renderable/codecs/pr-changes.js.map +0 -1
- package/dist/renderable/codecs/reference.d.ts +0 -215
- package/dist/renderable/codecs/reference.d.ts.map +0 -1
- package/dist/renderable/codecs/reference.js +0 -1578
- package/dist/renderable/codecs/reference.js.map +0 -1
- package/dist/renderable/codecs/reporting.d.ts +0 -14026
- package/dist/renderable/codecs/reporting.d.ts.map +0 -1
- package/dist/renderable/codecs/reporting.js +0 -365
- package/dist/renderable/codecs/reporting.js.map +0 -1
- package/dist/renderable/codecs/requirements.d.ts +0 -4743
- package/dist/renderable/codecs/requirements.d.ts.map +0 -1
- package/dist/renderable/codecs/requirements.js +0 -428
- package/dist/renderable/codecs/requirements.js.map +0 -1
- package/dist/renderable/codecs/session.d.ts +0 -9410
- package/dist/renderable/codecs/session.d.ts.map +0 -1
- package/dist/renderable/codecs/session.js +0 -848
- package/dist/renderable/codecs/session.js.map +0 -1
- package/dist/renderable/codecs/shape-matcher.d.ts +0 -54
- package/dist/renderable/codecs/shape-matcher.d.ts.map +0 -1
- package/dist/renderable/codecs/shape-matcher.js +0 -106
- package/dist/renderable/codecs/shape-matcher.js.map +0 -1
- package/dist/renderable/codecs/shared-schema.d.ts +0 -44
- package/dist/renderable/codecs/shared-schema.d.ts.map +0 -1
- package/dist/renderable/codecs/shared-schema.js +0 -43
- package/dist/renderable/codecs/shared-schema.js.map +0 -1
- package/dist/renderable/codecs/taxonomy.d.ts +0 -4733
- package/dist/renderable/codecs/taxonomy.d.ts.map +0 -1
- package/dist/renderable/codecs/taxonomy.js +0 -570
- package/dist/renderable/codecs/taxonomy.js.map +0 -1
- package/dist/renderable/codecs/timeline.d.ts +0 -14094
- package/dist/renderable/codecs/timeline.d.ts.map +0 -1
- package/dist/renderable/codecs/timeline.js +0 -906
- package/dist/renderable/codecs/timeline.js.map +0 -1
- package/dist/renderable/codecs/types/base.d.ts +0 -81
- package/dist/renderable/codecs/types/base.d.ts.map +0 -1
- package/dist/renderable/codecs/types/base.js +0 -56
- package/dist/renderable/codecs/types/base.js.map +0 -1
- package/dist/renderable/codecs/types/index.d.ts +0 -5
- package/dist/renderable/codecs/types/index.d.ts.map +0 -1
- package/dist/renderable/codecs/types/index.js +0 -5
- package/dist/renderable/codecs/types/index.js.map +0 -1
- package/dist/renderable/codecs/validation-rules.d.ts +0 -4773
- package/dist/renderable/codecs/validation-rules.d.ts.map +0 -1
- package/dist/renderable/codecs/validation-rules.js +0 -537
- package/dist/renderable/codecs/validation-rules.js.map +0 -1
- package/dist/renderable/generate.d.ts +0 -338
- package/dist/renderable/generate.d.ts.map +0 -1
- package/dist/renderable/generate.js +0 -437
- package/dist/renderable/generate.js.map +0 -1
- package/dist/renderable/index.d.ts +0 -36
- package/dist/renderable/index.d.ts.map +0 -1
- package/dist/renderable/index.js +0 -58
- package/dist/renderable/index.js.map +0 -1
- package/dist/renderable/load-preamble.d.ts +0 -56
- package/dist/renderable/load-preamble.d.ts.map +0 -1
- package/dist/renderable/load-preamble.js +0 -298
- package/dist/renderable/load-preamble.js.map +0 -1
- package/dist/renderable/render.d.ts +0 -61
- package/dist/renderable/render.d.ts.map +0 -1
- package/dist/renderable/render.js +0 -346
- package/dist/renderable/render.js.map +0 -1
- package/dist/renderable/schema.d.ts +0 -194
- package/dist/renderable/schema.d.ts.map +0 -1
- package/dist/renderable/schema.js +0 -197
- package/dist/renderable/schema.js.map +0 -1
- package/dist/renderable/utils.d.ts +0 -146
- package/dist/renderable/utils.d.ts.map +0 -1
- package/dist/renderable/utils.js +0 -362
- package/dist/renderable/utils.js.map +0 -1
- package/dist/scanner/ast-parser.d.ts +0 -75
- package/dist/scanner/ast-parser.d.ts.map +0 -1
- package/dist/scanner/ast-parser.js +0 -835
- package/dist/scanner/ast-parser.js.map +0 -1
- package/dist/scanner/gherkin-ast-parser.d.ts +0 -166
- package/dist/scanner/gherkin-ast-parser.d.ts.map +0 -1
- package/dist/scanner/gherkin-ast-parser.js +0 -507
- package/dist/scanner/gherkin-ast-parser.js.map +0 -1
- package/dist/scanner/gherkin-scanner.d.ts +0 -106
- package/dist/scanner/gherkin-scanner.d.ts.map +0 -1
- package/dist/scanner/gherkin-scanner.js +0 -149
- package/dist/scanner/gherkin-scanner.js.map +0 -1
- package/dist/scanner/index.d.ts +0 -85
- package/dist/scanner/index.d.ts.map +0 -1
- package/dist/scanner/index.js +0 -102
- package/dist/scanner/index.js.map +0 -1
- package/dist/scanner/pattern-scanner.d.ts +0 -83
- package/dist/scanner/pattern-scanner.d.ts.map +0 -1
- package/dist/scanner/pattern-scanner.js +0 -110
- package/dist/scanner/pattern-scanner.js.map +0 -1
- package/dist/taxonomy/categories.d.ts +0 -47
- package/dist/taxonomy/categories.d.ts.map +0 -1
- package/dist/taxonomy/categories.js +0 -175
- package/dist/taxonomy/categories.js.map +0 -1
- package/dist/taxonomy/claude-section-values.d.ts +0 -12
- package/dist/taxonomy/claude-section-values.d.ts.map +0 -1
- package/dist/taxonomy/claude-section-values.js +0 -17
- package/dist/taxonomy/claude-section-values.js.map +0 -1
- package/dist/taxonomy/conventions.d.ts +0 -13
- package/dist/taxonomy/conventions.d.ts.map +0 -1
- package/dist/taxonomy/conventions.js +0 -27
- package/dist/taxonomy/conventions.js.map +0 -1
- package/dist/taxonomy/deliverable-status.d.ts +0 -99
- package/dist/taxonomy/deliverable-status.d.ts.map +0 -1
- package/dist/taxonomy/deliverable-status.js +0 -131
- package/dist/taxonomy/deliverable-status.js.map +0 -1
- package/dist/taxonomy/format-types.d.ts +0 -17
- package/dist/taxonomy/format-types.d.ts.map +0 -1
- package/dist/taxonomy/format-types.js +0 -23
- package/dist/taxonomy/format-types.js.map +0 -1
- package/dist/taxonomy/generator-options.d.ts +0 -67
- package/dist/taxonomy/generator-options.d.ts.map +0 -1
- package/dist/taxonomy/generator-options.js +0 -75
- package/dist/taxonomy/generator-options.js.map +0 -1
- package/dist/taxonomy/hierarchy-levels.d.ts +0 -23
- package/dist/taxonomy/hierarchy-levels.d.ts.map +0 -1
- package/dist/taxonomy/hierarchy-levels.js +0 -22
- package/dist/taxonomy/hierarchy-levels.js.map +0 -1
- package/dist/taxonomy/index.d.ts +0 -35
- package/dist/taxonomy/index.d.ts.map +0 -1
- package/dist/taxonomy/index.js +0 -56
- package/dist/taxonomy/index.js.map +0 -1
- package/dist/taxonomy/layer-types.d.ts +0 -22
- package/dist/taxonomy/layer-types.d.ts.map +0 -1
- package/dist/taxonomy/layer-types.js +0 -28
- package/dist/taxonomy/layer-types.js.map +0 -1
- package/dist/taxonomy/normalized-status.d.ts +0 -99
- package/dist/taxonomy/normalized-status.d.ts.map +0 -1
- package/dist/taxonomy/normalized-status.js +0 -113
- package/dist/taxonomy/normalized-status.js.map +0 -1
- package/dist/taxonomy/registry-builder.d.ts +0 -104
- package/dist/taxonomy/registry-builder.d.ts.map +0 -1
- package/dist/taxonomy/registry-builder.js +0 -561
- package/dist/taxonomy/registry-builder.js.map +0 -1
- package/dist/taxonomy/risk-levels.d.ts +0 -16
- package/dist/taxonomy/risk-levels.d.ts.map +0 -1
- package/dist/taxonomy/risk-levels.js +0 -15
- package/dist/taxonomy/risk-levels.js.map +0 -1
- package/dist/taxonomy/severity-types.d.ts +0 -6
- package/dist/taxonomy/severity-types.d.ts.map +0 -1
- package/dist/taxonomy/severity-types.js +0 -5
- package/dist/taxonomy/severity-types.js.map +0 -1
- package/dist/taxonomy/status-values.d.ts +0 -39
- package/dist/taxonomy/status-values.d.ts.map +0 -1
- package/dist/taxonomy/status-values.js +0 -42
- package/dist/taxonomy/status-values.js.map +0 -1
- package/dist/types/branded.d.ts +0 -89
- package/dist/types/branded.d.ts.map +0 -1
- package/dist/types/branded.js +0 -57
- package/dist/types/branded.js.map +0 -1
- package/dist/types/errors.d.ts +0 -342
- package/dist/types/errors.d.ts.map +0 -1
- package/dist/types/errors.js +0 -251
- package/dist/types/errors.js.map +0 -1
- package/dist/types/index.d.ts +0 -41
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -5
- package/dist/types/index.js.map +0 -1
- package/dist/types/result.d.ts +0 -78
- package/dist/types/result.d.ts.map +0 -1
- package/dist/types/result.js +0 -78
- package/dist/types/result.js.map +0 -1
- package/dist/utils/collection-utils.d.ts +0 -49
- package/dist/utils/collection-utils.d.ts.map +0 -1
- package/dist/utils/collection-utils.js +0 -58
- package/dist/utils/collection-utils.js.map +0 -1
- package/dist/utils/id-utils.d.ts +0 -46
- package/dist/utils/id-utils.d.ts.map +0 -1
- package/dist/utils/id-utils.js +0 -51
- package/dist/utils/id-utils.js.map +0 -1
- package/dist/utils/index.d.ts +0 -21
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -21
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/string-utils.d.ts +0 -150
- package/dist/utils/string-utils.d.ts.map +0 -1
- package/dist/utils/string-utils.js +0 -281
- package/dist/utils/string-utils.js.map +0 -1
- package/dist/validation/anti-patterns.d.ts +0 -134
- package/dist/validation/anti-patterns.d.ts.map +0 -1
- package/dist/validation/anti-patterns.js +0 -307
- package/dist/validation/anti-patterns.js.map +0 -1
- package/dist/validation/dod-validator.d.ts +0 -94
- package/dist/validation/dod-validator.d.ts.map +0 -1
- package/dist/validation/dod-validator.js +0 -198
- package/dist/validation/dod-validator.js.map +0 -1
- package/dist/validation/fsm/index.d.ts +0 -59
- package/dist/validation/fsm/index.d.ts.map +0 -1
- package/dist/validation/fsm/index.js +0 -64
- package/dist/validation/fsm/index.js.map +0 -1
- package/dist/validation/fsm/states.d.ts +0 -93
- package/dist/validation/fsm/states.d.ts.map +0 -1
- package/dist/validation/fsm/states.js +0 -98
- package/dist/validation/fsm/states.js.map +0 -1
- package/dist/validation/fsm/transitions.d.ts +0 -100
- package/dist/validation/fsm/transitions.d.ts.map +0 -1
- package/dist/validation/fsm/transitions.js +0 -122
- package/dist/validation/fsm/transitions.js.map +0 -1
- package/dist/validation/fsm/validator.d.ts +0 -163
- package/dist/validation/fsm/validator.d.ts.map +0 -1
- package/dist/validation/fsm/validator.js +0 -205
- package/dist/validation/fsm/validator.js.map +0 -1
- package/dist/validation/index.d.ts +0 -23
- package/dist/validation/index.d.ts.map +0 -1
- package/dist/validation/index.js +0 -25
- package/dist/validation/index.js.map +0 -1
- package/dist/validation/types.d.ts +0 -136
- package/dist/validation/types.d.ts.map +0 -1
- package/dist/validation/types.js +0 -56
- package/dist/validation/types.js.map +0 -1
- package/dist/validation-schemas/codec-utils.d.ts +0 -188
- package/dist/validation-schemas/codec-utils.d.ts.map +0 -1
- package/dist/validation-schemas/codec-utils.js +0 -258
- package/dist/validation-schemas/codec-utils.js.map +0 -1
- package/dist/validation-schemas/config.d.ts +0 -99
- package/dist/validation-schemas/config.d.ts.map +0 -1
- package/dist/validation-schemas/config.js +0 -178
- package/dist/validation-schemas/config.js.map +0 -1
- package/dist/validation-schemas/doc-directive.d.ts +0 -195
- package/dist/validation-schemas/doc-directive.d.ts.map +0 -1
- package/dist/validation-schemas/doc-directive.js +0 -239
- package/dist/validation-schemas/doc-directive.js.map +0 -1
- package/dist/validation-schemas/dual-source.d.ts +0 -167
- package/dist/validation-schemas/dual-source.d.ts.map +0 -1
- package/dist/validation-schemas/dual-source.js +0 -168
- package/dist/validation-schemas/dual-source.js.map +0 -1
- package/dist/validation-schemas/export-info.d.ts +0 -53
- package/dist/validation-schemas/export-info.d.ts.map +0 -1
- package/dist/validation-schemas/export-info.js +0 -101
- package/dist/validation-schemas/export-info.js.map +0 -1
- package/dist/validation-schemas/extracted-pattern.d.ts +0 -351
- package/dist/validation-schemas/extracted-pattern.d.ts.map +0 -1
- package/dist/validation-schemas/extracted-pattern.js +0 -459
- package/dist/validation-schemas/extracted-pattern.js.map +0 -1
- package/dist/validation-schemas/extracted-shape.d.ts +0 -200
- package/dist/validation-schemas/extracted-shape.d.ts.map +0 -1
- package/dist/validation-schemas/extracted-shape.js +0 -182
- package/dist/validation-schemas/extracted-shape.js.map +0 -1
- package/dist/validation-schemas/feature.d.ts +0 -554
- package/dist/validation-schemas/feature.d.ts.map +0 -1
- package/dist/validation-schemas/feature.js +0 -262
- package/dist/validation-schemas/feature.js.map +0 -1
- package/dist/validation-schemas/index.d.ts +0 -15
- package/dist/validation-schemas/index.d.ts.map +0 -1
- package/dist/validation-schemas/index.js +0 -32
- package/dist/validation-schemas/index.js.map +0 -1
- package/dist/validation-schemas/lint.d.ts +0 -46
- package/dist/validation-schemas/lint.d.ts.map +0 -1
- package/dist/validation-schemas/lint.js +0 -45
- package/dist/validation-schemas/lint.js.map +0 -1
- package/dist/validation-schemas/master-dataset.d.ts +0 -8299
- package/dist/validation-schemas/master-dataset.d.ts.map +0 -1
- package/dist/validation-schemas/master-dataset.js +0 -275
- package/dist/validation-schemas/master-dataset.js.map +0 -1
- package/dist/validation-schemas/output-schemas.d.ts +0 -183
- package/dist/validation-schemas/output-schemas.d.ts.map +0 -1
- package/dist/validation-schemas/output-schemas.js +0 -149
- package/dist/validation-schemas/output-schemas.js.map +0 -1
- package/dist/validation-schemas/scenario-ref.d.ts +0 -80
- package/dist/validation-schemas/scenario-ref.d.ts.map +0 -1
- package/dist/validation-schemas/scenario-ref.js +0 -73
- package/dist/validation-schemas/scenario-ref.js.map +0 -1
- package/dist/validation-schemas/tag-registry.d.ts +0 -210
- package/dist/validation-schemas/tag-registry.d.ts.map +0 -1
- package/dist/validation-schemas/tag-registry.js +0 -248
- package/dist/validation-schemas/tag-registry.js.map +0 -1
- package/dist/validation-schemas/workflow-config.d.ts +0 -125
- package/dist/validation-schemas/workflow-config.d.ts.map +0 -1
- package/dist/validation-schemas/workflow-config.js +0 -138
- package/dist/validation-schemas/workflow-config.js.map +0 -1
package/dist/cli/process-api.js
DELETED
|
@@ -1,1550 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* @architect
|
|
4
|
-
* @architect-core @architect-cli
|
|
5
|
-
* @architect-pattern ProcessAPICLIImpl
|
|
6
|
-
* @architect-status active
|
|
7
|
-
* @architect-implements ProcessStateAPICLI
|
|
8
|
-
* @architect-arch-role service
|
|
9
|
-
* @architect-arch-context cli
|
|
10
|
-
* @architect-arch-layer application
|
|
11
|
-
* @architect-uses ProcessStateAPI, MasterDataset, PipelineFactory, RulesQueryModule, PatternSummarizerImpl, FuzzyMatcherImpl, OutputPipelineImpl
|
|
12
|
-
* @architect-used-by npm scripts, Claude Code sessions
|
|
13
|
-
* @architect-usecase "When querying project state from CLI"
|
|
14
|
-
* @architect-usecase "When Claude Code needs real-time delivery state queries"
|
|
15
|
-
*
|
|
16
|
-
* ## architect - CLI Query Interface to ProcessStateAPI
|
|
17
|
-
*
|
|
18
|
-
* Exposes ProcessStateAPI methods as CLI subcommands with JSON output.
|
|
19
|
-
* Runs pipeline steps 1-8 (config -> scan -> extract -> transform),
|
|
20
|
-
* then routes subcommands to API methods.
|
|
21
|
-
*
|
|
22
|
-
* ### When to Use
|
|
23
|
-
*
|
|
24
|
-
* - When Claude Code needs real-time delivery state queries
|
|
25
|
-
* - When AI agents need structured JSON instead of regenerating markdown
|
|
26
|
-
* - When scripting architect queries in CI/CD
|
|
27
|
-
*
|
|
28
|
-
* ### Key Concepts
|
|
29
|
-
*
|
|
30
|
-
* - **Subcommand Routing**: CLI subcommands map to ProcessStateAPI methods
|
|
31
|
-
* - **JSON Output**: All output is JSON to stdout, errors to stderr
|
|
32
|
-
* - **Pipeline Reuse**: Steps 1-8 match architect-generate exactly
|
|
33
|
-
* - **QueryResult Envelope**: All output wrapped in success/error discriminated union
|
|
34
|
-
* - **Output Shaping**: 594KB -> 4KB via summarization and modifiers
|
|
35
|
-
*/
|
|
36
|
-
// ─── Error Convention ───────────────────────────────────────────────────
|
|
37
|
-
// CLI modules use throw/catch + process.exit(). Pipeline modules use Result<T,E>.
|
|
38
|
-
// See src/cli/error-handler.ts for the unified handler.
|
|
39
|
-
// ────────────────────────────────────────────────────────────────────────
|
|
40
|
-
import * as path from 'path';
|
|
41
|
-
import * as fs from 'fs';
|
|
42
|
-
import { applyProjectSourceDefaults, findConfigFile } from '../config/config-loader.js';
|
|
43
|
-
import { buildMasterDataset, } from '../generators/pipeline/index.js';
|
|
44
|
-
import { createProcessStateAPI } from '../api/process-state.js';
|
|
45
|
-
import { createSuccess, createError, QueryApiError, } from '../api/types.js';
|
|
46
|
-
import { computeCacheKey, tryLoadCache, writeCache, getCacheDir, cacheFileExists, } from './dataset-cache.js';
|
|
47
|
-
import { handleCliError } from './error-handler.js';
|
|
48
|
-
import { printVersionAndExit } from './version.js';
|
|
49
|
-
import { CLI_SCHEMA } from './cli-schema.js';
|
|
50
|
-
import { VALID_TRANSITIONS, isValidTransition as fsmIsValidTransition, getValidTransitionsFrom as fsmGetValidTransitionsFrom, } from '../validation/fsm/transitions.js';
|
|
51
|
-
import { validateTransition as fsmValidateTransition, getProtectionSummary as fsmGetProtectionSummary, } from '../validation/fsm/validator.js';
|
|
52
|
-
import { fuzzyMatchPatterns } from '../api/fuzzy-match.js';
|
|
53
|
-
import { allPatternNames, getSequenceEntry, suggestPattern, firstImplements, getPatternName, } from '../api/pattern-helpers.js';
|
|
54
|
-
import { findStubPatterns, resolveStubs, groupStubsByPattern, extractDecisionItems, findPdrReferences, } from '../api/stub-resolver.js';
|
|
55
|
-
import { applyOutputPipeline, applyListFilters, validateModifiers, formatOutput, PATTERN_ARRAY_METHODS, DEFAULT_OUTPUT_MODIFIERS, } from './output-pipeline.js';
|
|
56
|
-
import { assembleContext, buildDepTree, buildFileReadingList, buildOverview, isValidSessionType, } from '../api/context-assembler.js';
|
|
57
|
-
import { formatContextBundle, formatDepTree, formatFileReadingList, formatOverview, } from '../api/context-formatter.js';
|
|
58
|
-
import { computeNeighborhood, compareContexts, aggregateTagUsage, buildSourceInventory, findOrphanPatterns, } from '../api/arch-queries.js';
|
|
59
|
-
import { analyzeCoverage, findUnannotatedFiles } from '../api/coverage-analyzer.js';
|
|
60
|
-
import { validateScope, formatScopeValidation } from '../api/scope-validator.js';
|
|
61
|
-
import { generateHandoff, formatHandoff, } from '../api/handoff-generator.js';
|
|
62
|
-
import { execSync } from 'child_process';
|
|
63
|
-
import { glob } from 'glob';
|
|
64
|
-
import { startRepl } from './repl.js';
|
|
65
|
-
import { queryBusinessRules } from '../api/rules-query.js';
|
|
66
|
-
/**
|
|
67
|
-
* Handle position-independent flags (help, version, cache, dry-run, modifiers, format).
|
|
68
|
-
* These work regardless of position — before or after the subcommand.
|
|
69
|
-
*
|
|
70
|
-
* @returns Number of additional args consumed (0 for booleans, 1 for --value flags).
|
|
71
|
-
* Returns -1 if the arg is not a position-independent flag.
|
|
72
|
-
*/
|
|
73
|
-
function handlePositionIndependentFlag(state, arg, nextArg) {
|
|
74
|
-
switch (arg) {
|
|
75
|
-
case '-h':
|
|
76
|
-
case '--help':
|
|
77
|
-
if (state.config.subcommand !== null) {
|
|
78
|
-
state.config.subcommandHelp = state.config.subcommand;
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
state.config.help = true;
|
|
82
|
-
}
|
|
83
|
-
return 0;
|
|
84
|
-
case '-v':
|
|
85
|
-
case '--version':
|
|
86
|
-
state.config.version = true;
|
|
87
|
-
return 0;
|
|
88
|
-
case '--no-cache':
|
|
89
|
-
state.config.noCache = true;
|
|
90
|
-
return 0;
|
|
91
|
-
case '--dry-run':
|
|
92
|
-
state.config.dryRun = true;
|
|
93
|
-
return 0;
|
|
94
|
-
case '--names-only':
|
|
95
|
-
state.namesOnly = true;
|
|
96
|
-
return 0;
|
|
97
|
-
case '--count':
|
|
98
|
-
state.count = true;
|
|
99
|
-
return 0;
|
|
100
|
-
case '--fields':
|
|
101
|
-
if (!nextArg || nextArg.startsWith('-')) {
|
|
102
|
-
throw new Error(`${arg} requires a value (comma-separated field names)`);
|
|
103
|
-
}
|
|
104
|
-
state.fields = nextArg.split(',').map((f) => f.trim());
|
|
105
|
-
return 1;
|
|
106
|
-
case '--full':
|
|
107
|
-
state.full = true;
|
|
108
|
-
return 0;
|
|
109
|
-
case '--format':
|
|
110
|
-
if (nextArg !== 'json' && nextArg !== 'compact') {
|
|
111
|
-
throw new Error(`${arg} must be "json" or "compact"`);
|
|
112
|
-
}
|
|
113
|
-
state.config.format = nextArg;
|
|
114
|
-
return 1;
|
|
115
|
-
default:
|
|
116
|
-
return -1;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Handle position-dependent global flags (input, features, base-dir, workflow, session).
|
|
121
|
-
* These only apply before the subcommand is detected.
|
|
122
|
-
*
|
|
123
|
-
* @returns Number of additional args consumed (always 1 for these flags).
|
|
124
|
-
* @throws On unknown flag.
|
|
125
|
-
*/
|
|
126
|
-
function handleGlobalFlag(state, arg, nextArg) {
|
|
127
|
-
switch (arg) {
|
|
128
|
-
case '-i':
|
|
129
|
-
case '--input':
|
|
130
|
-
if (!nextArg || nextArg.startsWith('-')) {
|
|
131
|
-
throw new Error(`${arg} requires a value`);
|
|
132
|
-
}
|
|
133
|
-
state.config.input.push(nextArg);
|
|
134
|
-
return 1;
|
|
135
|
-
case '-f':
|
|
136
|
-
case '--features':
|
|
137
|
-
if (!nextArg || nextArg.startsWith('-')) {
|
|
138
|
-
throw new Error(`${arg} requires a value`);
|
|
139
|
-
}
|
|
140
|
-
state.config.features.push(nextArg);
|
|
141
|
-
return 1;
|
|
142
|
-
case '-b':
|
|
143
|
-
case '--base-dir':
|
|
144
|
-
if (!nextArg || nextArg.startsWith('-')) {
|
|
145
|
-
throw new Error(`${arg} requires a value`);
|
|
146
|
-
}
|
|
147
|
-
state.config.baseDir = nextArg;
|
|
148
|
-
return 1;
|
|
149
|
-
case '-w':
|
|
150
|
-
case '--workflow':
|
|
151
|
-
if (!nextArg || nextArg.startsWith('-')) {
|
|
152
|
-
throw new Error(`${arg} requires a value`);
|
|
153
|
-
}
|
|
154
|
-
state.config.workflowPath = nextArg;
|
|
155
|
-
return 1;
|
|
156
|
-
case '--session':
|
|
157
|
-
if (!nextArg || !isValidSessionType(nextArg)) {
|
|
158
|
-
throw new Error(`${arg} must be "planning", "design", or "implement"`);
|
|
159
|
-
}
|
|
160
|
-
state.config.sessionType = nextArg;
|
|
161
|
-
return 1;
|
|
162
|
-
default:
|
|
163
|
-
throw new Error(`Unknown option: ${arg}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Handle positional args: first becomes subcommand, rest become subArgs.
|
|
168
|
-
*/
|
|
169
|
-
function handlePositionalArg(state, arg) {
|
|
170
|
-
if (state.config.subcommand === null) {
|
|
171
|
-
state.config.subcommand = arg;
|
|
172
|
-
state.parsingFlags = false;
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
state.config.subArgs.push(arg);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
function parseArgs(argv = process.argv.slice(2)) {
|
|
179
|
-
const state = {
|
|
180
|
-
config: {
|
|
181
|
-
input: [],
|
|
182
|
-
features: [],
|
|
183
|
-
baseDir: process.cwd(),
|
|
184
|
-
workflowPath: null,
|
|
185
|
-
subcommand: null,
|
|
186
|
-
subArgs: [],
|
|
187
|
-
help: false,
|
|
188
|
-
version: false,
|
|
189
|
-
modifiers: { ...DEFAULT_OUTPUT_MODIFIERS },
|
|
190
|
-
format: 'json',
|
|
191
|
-
sessionType: null,
|
|
192
|
-
noCache: false,
|
|
193
|
-
dryRun: false,
|
|
194
|
-
subcommandHelp: null,
|
|
195
|
-
},
|
|
196
|
-
namesOnly: false,
|
|
197
|
-
count: false,
|
|
198
|
-
fields: null,
|
|
199
|
-
full: false,
|
|
200
|
-
parsingFlags: true,
|
|
201
|
-
};
|
|
202
|
-
for (let i = 0; i < argv.length; i++) {
|
|
203
|
-
const arg = argv[i];
|
|
204
|
-
if (arg === undefined)
|
|
205
|
-
continue;
|
|
206
|
-
const nextArg = argv[i + 1];
|
|
207
|
-
// pnpm passes '--' as a literal arg separator — skip it
|
|
208
|
-
if (arg === '--') {
|
|
209
|
-
state.parsingFlags = false;
|
|
210
|
-
continue;
|
|
211
|
-
}
|
|
212
|
-
// Position-independent flags (work before and after subcommand)
|
|
213
|
-
const piConsumed = handlePositionIndependentFlag(state, arg, nextArg);
|
|
214
|
-
if (piConsumed >= 0) {
|
|
215
|
-
i += piConsumed;
|
|
216
|
-
continue;
|
|
217
|
-
}
|
|
218
|
-
// Position-dependent global flags (only before subcommand)
|
|
219
|
-
if (state.parsingFlags && arg.startsWith('-')) {
|
|
220
|
-
i += handleGlobalFlag(state, arg, nextArg);
|
|
221
|
-
continue;
|
|
222
|
-
}
|
|
223
|
-
// Positional: subcommand or subArg
|
|
224
|
-
handlePositionalArg(state, arg);
|
|
225
|
-
}
|
|
226
|
-
state.config.modifiers = {
|
|
227
|
-
namesOnly: state.namesOnly,
|
|
228
|
-
count: state.count,
|
|
229
|
-
fields: state.fields,
|
|
230
|
-
full: state.full,
|
|
231
|
-
};
|
|
232
|
-
return state.config;
|
|
233
|
-
}
|
|
234
|
-
// =============================================================================
|
|
235
|
-
// Help
|
|
236
|
-
// =============================================================================
|
|
237
|
-
function formatHelpOptions(group) {
|
|
238
|
-
return group.options
|
|
239
|
-
.map((opt) => {
|
|
240
|
-
const short = opt.short !== undefined ? `${opt.short}, ` : ' ';
|
|
241
|
-
// Extract bare flag name (without value placeholder) for alignment
|
|
242
|
-
const flag = opt.flag.padEnd(24);
|
|
243
|
-
return ` ${short}${flag}${opt.description}`;
|
|
244
|
-
})
|
|
245
|
-
.join('\n');
|
|
246
|
-
}
|
|
247
|
-
function showHelp() {
|
|
248
|
-
const options = formatHelpOptions(CLI_SCHEMA.globalOptions);
|
|
249
|
-
const modifiers = formatHelpOptions(CLI_SCHEMA.outputModifiers);
|
|
250
|
-
const filters = formatHelpOptions(CLI_SCHEMA.listFilters);
|
|
251
|
-
const sessions = formatHelpOptions(CLI_SCHEMA.sessionOptions);
|
|
252
|
-
console.log(`
|
|
253
|
-
architect - Query project state from annotated sources
|
|
254
|
-
|
|
255
|
-
Use this instead of reading generated markdown or launching explore agents.
|
|
256
|
-
Targeted queries use 5-10x less context than file reads.
|
|
257
|
-
|
|
258
|
-
Usage: architect [options] <subcommand> [args...]
|
|
259
|
-
|
|
260
|
-
Quick Start — Session Recipe:
|
|
261
|
-
|
|
262
|
-
1. overview Project health (progress, blockers)
|
|
263
|
-
2. scope-validate <pattern> implement Pre-flight check (FSM, deps, prereqs)
|
|
264
|
-
3. context <pattern> --session design Curated context bundle for the session
|
|
265
|
-
|
|
266
|
-
Session Workflow Commands (text output — use these first):
|
|
267
|
-
|
|
268
|
-
overview Executive summary: progress, active phases, blockers
|
|
269
|
-
scope-validate <pat> <type> Pre-flight readiness check (PASS/BLOCKED/WARN verdict)
|
|
270
|
-
Catches FSM violations and missing deps BEFORE you start.
|
|
271
|
-
Types: implement, design
|
|
272
|
-
context <pat> --session <type> Curated context bundle tailored to session type
|
|
273
|
-
planning — minimal: pattern metadata and spec file
|
|
274
|
-
design — full: metadata, stubs, deps, deliverables
|
|
275
|
-
implement — focused: deliverables, FSM state, test files
|
|
276
|
-
dep-tree <pat> [--depth N] Dependency chain with status
|
|
277
|
-
files <pat> [--related] File reading list with implementation paths
|
|
278
|
-
handoff --pattern <pat> Session-end state: deliverables, blockers, date
|
|
279
|
-
Options: --git (include recent commits), --session <id>
|
|
280
|
-
|
|
281
|
-
Pattern Discovery (JSON output):
|
|
282
|
-
|
|
283
|
-
status Status counts and completion percentage
|
|
284
|
-
list [filters] Filtered pattern listing (composable with modifiers below)
|
|
285
|
-
search <query> Fuzzy name search with match scores
|
|
286
|
-
pattern <name> Full detail for one pattern
|
|
287
|
-
Warning: ~66KB for completed patterns — prefer 'context --session'
|
|
288
|
-
stubs [pattern] Design stubs with target paths and resolution status
|
|
289
|
-
stubs --unresolved Only stubs with missing target files
|
|
290
|
-
decisions <pattern> AD-N design decisions from stub descriptions
|
|
291
|
-
pdr <number> Cross-reference patterns mentioning a PDR number
|
|
292
|
-
rules [filters] Business rules and invariants from feature specs
|
|
293
|
-
--product-area <name> Filter by product area
|
|
294
|
-
--pattern <name> Filter by pattern name
|
|
295
|
-
--only-invariants Only rules with explicit invariants
|
|
296
|
-
|
|
297
|
-
Architecture Queries (JSON output):
|
|
298
|
-
|
|
299
|
-
arch neighborhood <pat> What does this pattern touch? (uses/usedBy/sameContext)
|
|
300
|
-
arch blocking What's stuck? Patterns blocked by incomplete deps
|
|
301
|
-
arch dangling Broken references (pattern names that don't exist)
|
|
302
|
-
arch orphans Isolated patterns with no relationships
|
|
303
|
-
arch coverage Annotation completeness across input files
|
|
304
|
-
arch roles All arch-roles with pattern counts
|
|
305
|
-
arch context [name] Patterns in bounded context (list all if no name)
|
|
306
|
-
arch layer [name] Patterns in architecture layer (list all if no name)
|
|
307
|
-
arch compare <c1> <c2> Cross-context shared deps and integration points
|
|
308
|
-
|
|
309
|
-
Design Review:
|
|
310
|
-
|
|
311
|
-
sequence [name] Sequence diagram data for design reviews
|
|
312
|
-
No args: list patterns with sequence annotations
|
|
313
|
-
With name: steps, participants, data flow types
|
|
314
|
-
|
|
315
|
-
Metadata & Inventory:
|
|
316
|
-
|
|
317
|
-
tags Tag usage report (counts per tag and value)
|
|
318
|
-
sources File inventory by type (TS, Gherkin, Stubs)
|
|
319
|
-
unannotated [--path dir] TypeScript files missing @architect annotations
|
|
320
|
-
query <method> [args...] Execute any query API method directly
|
|
321
|
-
|
|
322
|
-
Options:
|
|
323
|
-
|
|
324
|
-
${options}
|
|
325
|
-
|
|
326
|
-
Output Modifiers (composable with any list/query):
|
|
327
|
-
|
|
328
|
-
${modifiers}
|
|
329
|
-
|
|
330
|
-
List Filters (for 'list' subcommand):
|
|
331
|
-
|
|
332
|
-
${filters}
|
|
333
|
-
|
|
334
|
-
Session Types (for 'context' and 'scope-validate'):
|
|
335
|
-
|
|
336
|
-
${sessions}
|
|
337
|
-
|
|
338
|
-
Common Recipes:
|
|
339
|
-
|
|
340
|
-
Starting a session:
|
|
341
|
-
architect overview
|
|
342
|
-
architect scope-validate MyPattern implement
|
|
343
|
-
architect context MyPattern --session implement
|
|
344
|
-
|
|
345
|
-
Finding what to work on:
|
|
346
|
-
architect list --status roadmap --names-only
|
|
347
|
-
architect arch blocking
|
|
348
|
-
architect query getRoadmapItems --names-only
|
|
349
|
-
|
|
350
|
-
Investigating a pattern:
|
|
351
|
-
architect search EventStore
|
|
352
|
-
architect dep-tree EventStoreDurability --depth 2
|
|
353
|
-
architect arch neighborhood EventStoreDurability
|
|
354
|
-
architect stubs EventStoreDurability
|
|
355
|
-
|
|
356
|
-
Design session prep:
|
|
357
|
-
architect context MyPattern --session design
|
|
358
|
-
architect decisions MyPattern
|
|
359
|
-
architect stubs --unresolved
|
|
360
|
-
|
|
361
|
-
Ending a session:
|
|
362
|
-
architect handoff --pattern MyPattern
|
|
363
|
-
|
|
364
|
-
Session Types (for --session flag):
|
|
365
|
-
|
|
366
|
-
planning Minimal: pattern metadata and spec file only
|
|
367
|
-
design Full: metadata, description, stubs, deps, deliverables
|
|
368
|
-
implement Focused: deliverables, FSM state, test files
|
|
369
|
-
|
|
370
|
-
Which session? Start coding -> implement. Complex decisions -> design.
|
|
371
|
-
New pattern -> planning. Not sure -> run 'overview' first.
|
|
372
|
-
|
|
373
|
-
Available API Methods (for 'query'):
|
|
374
|
-
|
|
375
|
-
Status: getPatternsByNormalizedStatus, getPatternsByStatus, getStatusCounts,
|
|
376
|
-
getStatusDistribution, getCompletionPercentage
|
|
377
|
-
Phase: getPatternsByPhase, getPhaseProgress, getActivePhases, getAllPhases
|
|
378
|
-
FSM: isValidTransition, checkTransition, getValidTransitionsFrom,
|
|
379
|
-
getProtectionInfo
|
|
380
|
-
Pattern: getPattern, getPatternDependencies, getPatternRelationships,
|
|
381
|
-
getRelatedPatterns, getApiReferences, getPatternDeliverables,
|
|
382
|
-
getPatternsByCategory, getCategories
|
|
383
|
-
Timeline: getPatternsByQuarter, getQuarters, getCurrentWork, getRoadmapItems,
|
|
384
|
-
getRecentlyCompleted
|
|
385
|
-
Raw: getMasterDataset
|
|
386
|
-
`);
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Per-subcommand help: shows usage, flags, and examples for a specific subcommand.
|
|
390
|
-
* Looks up command narrative from CLI_SCHEMA.commandNarratives.
|
|
391
|
-
*/
|
|
392
|
-
function showSubcommandHelp(subcommand) {
|
|
393
|
-
// Search for the command in commandNarratives groups
|
|
394
|
-
const narratives = CLI_SCHEMA.commandNarratives;
|
|
395
|
-
if (narratives !== undefined) {
|
|
396
|
-
for (const group of narratives) {
|
|
397
|
-
for (const cmd of group.commands) {
|
|
398
|
-
if (cmd.command === subcommand) {
|
|
399
|
-
console.log(`\narchitect ${subcommand} — ${cmd.description}\n`);
|
|
400
|
-
console.log(`Usage: ${cmd.usageExample}\n`);
|
|
401
|
-
if (cmd.details !== undefined) {
|
|
402
|
-
console.log(cmd.details);
|
|
403
|
-
console.log('');
|
|
404
|
-
}
|
|
405
|
-
if (cmd.expectedOutput !== undefined) {
|
|
406
|
-
console.log(`Expected output: ${cmd.expectedOutput}\n`);
|
|
407
|
-
}
|
|
408
|
-
// Show applicable option groups
|
|
409
|
-
const applicableGroups = getSubcommandOptionGroups(subcommand);
|
|
410
|
-
for (const groupKey of applicableGroups) {
|
|
411
|
-
const optGroup = CLI_SCHEMA[groupKey];
|
|
412
|
-
if (optGroup !== undefined && 'options' in optGroup) {
|
|
413
|
-
console.log(`${optGroup.title}:\n`);
|
|
414
|
-
console.log(formatHelpOptions(optGroup));
|
|
415
|
-
console.log('');
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
// Fallback: subcommand not found in narratives
|
|
424
|
-
console.log(`\nNo detailed help available for '${subcommand}'.`);
|
|
425
|
-
console.log('Run architect --help for the full command reference.\n');
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Map subcommands to their applicable CLI option groups.
|
|
429
|
-
*/
|
|
430
|
-
function getSubcommandOptionGroups(subcommand) {
|
|
431
|
-
const mapping = {
|
|
432
|
-
context: ['sessionOptions'],
|
|
433
|
-
'scope-validate': ['sessionOptions'],
|
|
434
|
-
list: ['listFilters', 'outputModifiers'],
|
|
435
|
-
search: ['outputModifiers'],
|
|
436
|
-
query: ['outputModifiers'],
|
|
437
|
-
status: ['outputModifiers'],
|
|
438
|
-
pattern: ['outputModifiers'],
|
|
439
|
-
stubs: ['outputModifiers'],
|
|
440
|
-
decisions: ['outputModifiers'],
|
|
441
|
-
pdr: ['outputModifiers'],
|
|
442
|
-
rules: ['outputModifiers'],
|
|
443
|
-
tags: ['outputModifiers'],
|
|
444
|
-
sources: ['outputModifiers'],
|
|
445
|
-
arch: ['outputModifiers'],
|
|
446
|
-
sequence: ['outputModifiers'],
|
|
447
|
-
};
|
|
448
|
-
return mapping[subcommand] ?? [];
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* Execute dry-run: show pipeline scope (files, config, cache) without processing.
|
|
452
|
-
*/
|
|
453
|
-
async function executeDryRun(opts) {
|
|
454
|
-
const baseDir = path.resolve(opts.baseDir);
|
|
455
|
-
// Resolve globs to file lists
|
|
456
|
-
const tsFiles = await glob(opts.input, { cwd: baseDir });
|
|
457
|
-
const featureFiles = await glob(opts.features, { cwd: baseDir });
|
|
458
|
-
// Check config file
|
|
459
|
-
const configPath = await findConfigFile(baseDir);
|
|
460
|
-
// Check cache status
|
|
461
|
-
const cacheDir = getCacheDir(opts.baseDir);
|
|
462
|
-
const cacheInfo = cacheFileExists(cacheDir);
|
|
463
|
-
console.log('=== DRY RUN ===');
|
|
464
|
-
console.log(`Config: ${formatConfigStatus(configPath)}`);
|
|
465
|
-
console.log(`Base dir: ${baseDir}`);
|
|
466
|
-
console.log(`Input patterns: ${opts.input.join(', ')}`);
|
|
467
|
-
console.log(`Feature patterns: ${opts.features.join(', ')}`);
|
|
468
|
-
console.log(`TypeScript files: ${tsFiles.length}`);
|
|
469
|
-
console.log(`Feature files: ${featureFiles.length}`);
|
|
470
|
-
console.log(`Workflow: ${opts.workflowPath ?? 'default (6-phase-standard)'}`);
|
|
471
|
-
if (cacheInfo.exists) {
|
|
472
|
-
const sizeKb = cacheInfo.sizeBytes !== undefined
|
|
473
|
-
? `${(cacheInfo.sizeBytes / 1024).toFixed(1)}KB`
|
|
474
|
-
: 'unknown';
|
|
475
|
-
console.log(`Cache: ${path.join(cacheDir, 'dataset.json')} (${sizeKb})`);
|
|
476
|
-
}
|
|
477
|
-
else {
|
|
478
|
-
console.log('Cache: none');
|
|
479
|
-
}
|
|
480
|
-
console.log(`Subcommand: ${opts.subcommand ?? '(none)'}`);
|
|
481
|
-
console.log('\nNo pipeline processing performed.');
|
|
482
|
-
}
|
|
483
|
-
// =============================================================================
|
|
484
|
-
// Config File Default Resolution
|
|
485
|
-
// =============================================================================
|
|
486
|
-
/**
|
|
487
|
-
* If --input and --features are not provided, try to load defaults from config.
|
|
488
|
-
* Prefers loadProjectConfig() for repos with a project config file,
|
|
489
|
-
* falls back to filesystem auto-detection for repos without one.
|
|
490
|
-
*/
|
|
491
|
-
async function applyConfigDefaults(config) {
|
|
492
|
-
const applied = await applyProjectSourceDefaults(config);
|
|
493
|
-
if (applied) {
|
|
494
|
-
return;
|
|
495
|
-
}
|
|
496
|
-
// Fall back to existing filesystem auto-detection for repos without config
|
|
497
|
-
await applyConfigDefaultsFallback(config);
|
|
498
|
-
}
|
|
499
|
-
/**
|
|
500
|
-
* Filesystem-based auto-detection fallback for repos without a config file.
|
|
501
|
-
* Checks for conventional directory structures and applies defaults.
|
|
502
|
-
*/
|
|
503
|
-
async function applyConfigDefaultsFallback(config) {
|
|
504
|
-
const baseDir = path.resolve(config.baseDir);
|
|
505
|
-
if (config.input.length === 0) {
|
|
506
|
-
// Check for config file existence as signal to use defaults
|
|
507
|
-
const configPath = await findConfigFile(baseDir);
|
|
508
|
-
if (configPath !== null) {
|
|
509
|
-
config.input.push('src/**/*.ts');
|
|
510
|
-
// Also check for stubs directory
|
|
511
|
-
const stubsDir = path.join(baseDir, 'architect', 'stubs');
|
|
512
|
-
if (fs.existsSync(stubsDir)) {
|
|
513
|
-
config.input.push('architect/stubs/**/*.ts');
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
if (config.features.length === 0) {
|
|
518
|
-
const specsDir = path.join(baseDir, 'architect', 'specs');
|
|
519
|
-
if (fs.existsSync(specsDir)) {
|
|
520
|
-
config.features.push('architect/specs/*.feature');
|
|
521
|
-
}
|
|
522
|
-
const releasesDir = path.join(baseDir, 'architect', 'releases');
|
|
523
|
-
if (fs.existsSync(releasesDir)) {
|
|
524
|
-
config.features.push('architect/releases/*.feature');
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
function formatConfigStatus(configPath) {
|
|
529
|
-
return configPath !== null
|
|
530
|
-
? `${path.basename(configPath)} (auto-detected)`
|
|
531
|
-
: 'none (filesystem fallback)';
|
|
532
|
-
}
|
|
533
|
-
// =============================================================================
|
|
534
|
-
// Pipeline
|
|
535
|
-
// =============================================================================
|
|
536
|
-
async function buildPipeline(config) {
|
|
537
|
-
const result = await buildMasterDataset({
|
|
538
|
-
input: config.input,
|
|
539
|
-
features: config.features,
|
|
540
|
-
baseDir: config.baseDir,
|
|
541
|
-
mergeConflictStrategy: 'fatal',
|
|
542
|
-
...(config.workflowPath !== null ? { workflowPath: config.workflowPath } : {}),
|
|
543
|
-
});
|
|
544
|
-
if (!result.ok) {
|
|
545
|
-
console.error(`Pipeline error [${result.error.step}]: ${result.error.message}`);
|
|
546
|
-
process.exit(1);
|
|
547
|
-
}
|
|
548
|
-
for (const w of result.value.warnings) {
|
|
549
|
-
console.warn(`⚠️ ${w.message}`);
|
|
550
|
-
}
|
|
551
|
-
return result.value;
|
|
552
|
-
}
|
|
553
|
-
// =============================================================================
|
|
554
|
-
// FSM Short-Circuit (bypass pipeline for static FSM queries)
|
|
555
|
-
// =============================================================================
|
|
556
|
-
/**
|
|
557
|
-
* FSM methods that operate on static const data and do not need the pipeline.
|
|
558
|
-
* When `query <method>` matches one of these, we dispatch directly to the FSM
|
|
559
|
-
* module, saving the 2-5 second pipeline build.
|
|
560
|
-
*/
|
|
561
|
-
const FSM_SHORT_CIRCUIT_METHODS = new Set([
|
|
562
|
-
'isValidTransition',
|
|
563
|
-
'checkTransition',
|
|
564
|
-
'getValidTransitionsFrom',
|
|
565
|
-
'getProtectionInfo',
|
|
566
|
-
]);
|
|
567
|
-
/**
|
|
568
|
-
* Validate and parse a CLI string as a ProcessStatusValue.
|
|
569
|
-
* Rejects unknown status values with a helpful error message.
|
|
570
|
-
*/
|
|
571
|
-
function parseProcessStatus(value, usage, label) {
|
|
572
|
-
if (value === undefined) {
|
|
573
|
-
throw new QueryApiError('INVALID_ARGUMENT', usage);
|
|
574
|
-
}
|
|
575
|
-
if (!(value in VALID_TRANSITIONS)) {
|
|
576
|
-
const valid = Object.keys(VALID_TRANSITIONS).join(', ');
|
|
577
|
-
throw new QueryApiError('INVALID_ARGUMENT', `Unknown ${label}: "${value}". Expected one of: ${valid}`);
|
|
578
|
-
}
|
|
579
|
-
return value;
|
|
580
|
-
}
|
|
581
|
-
/**
|
|
582
|
-
* Attempt to handle an FSM query without building the pipeline.
|
|
583
|
-
*
|
|
584
|
-
* @returns The FSM result data if this is a short-circuit candidate, or
|
|
585
|
-
* `undefined` if the query should go through the normal pipeline path.
|
|
586
|
-
*/
|
|
587
|
-
function tryFsmShortCircuit(subcommand, subArgs) {
|
|
588
|
-
if (subcommand !== 'query')
|
|
589
|
-
return undefined;
|
|
590
|
-
const methodName = subArgs[0];
|
|
591
|
-
if (methodName === undefined || !FSM_SHORT_CIRCUIT_METHODS.has(methodName)) {
|
|
592
|
-
return undefined;
|
|
593
|
-
}
|
|
594
|
-
const fsmArgs = subArgs.slice(1);
|
|
595
|
-
switch (methodName) {
|
|
596
|
-
case 'isValidTransition': {
|
|
597
|
-
const usage = 'Usage: architect query isValidTransition <fromStatus> <toStatus>';
|
|
598
|
-
const from = parseProcessStatus(fsmArgs[0], usage, 'fromStatus');
|
|
599
|
-
const to = parseProcessStatus(fsmArgs[1], usage, 'toStatus');
|
|
600
|
-
return fsmIsValidTransition(from, to);
|
|
601
|
-
}
|
|
602
|
-
case 'checkTransition': {
|
|
603
|
-
const from = fsmArgs[0];
|
|
604
|
-
const to = fsmArgs[1];
|
|
605
|
-
if (from === undefined || to === undefined) {
|
|
606
|
-
throw new QueryApiError('INVALID_ARGUMENT', 'Usage: architect query checkTransition <fromStatus> <toStatus>');
|
|
607
|
-
}
|
|
608
|
-
const result = fsmValidateTransition(from, to);
|
|
609
|
-
return {
|
|
610
|
-
from: result.from,
|
|
611
|
-
to: result.to,
|
|
612
|
-
valid: result.valid,
|
|
613
|
-
error: result.error,
|
|
614
|
-
validAlternatives: result.validAlternatives,
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
case 'getValidTransitionsFrom': {
|
|
618
|
-
const status = parseProcessStatus(fsmArgs[0], 'Usage: architect query getValidTransitionsFrom <status>', 'status');
|
|
619
|
-
return fsmGetValidTransitionsFrom(status);
|
|
620
|
-
}
|
|
621
|
-
case 'getProtectionInfo': {
|
|
622
|
-
const status = parseProcessStatus(fsmArgs[0], 'Usage: architect query getProtectionInfo <status>', 'status');
|
|
623
|
-
const summary = fsmGetProtectionSummary(status);
|
|
624
|
-
return {
|
|
625
|
-
status,
|
|
626
|
-
level: summary.level,
|
|
627
|
-
description: summary.description,
|
|
628
|
-
canAddDeliverables: summary.canAddDeliverables,
|
|
629
|
-
requiresUnlock: summary.requiresUnlock,
|
|
630
|
-
};
|
|
631
|
-
}
|
|
632
|
-
default:
|
|
633
|
-
return undefined;
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
// =============================================================================
|
|
637
|
-
// Subcommand Handlers
|
|
638
|
-
// =============================================================================
|
|
639
|
-
function handleStatus(api) {
|
|
640
|
-
return {
|
|
641
|
-
counts: api.getStatusCounts(),
|
|
642
|
-
completionPercentage: api.getCompletionPercentage(),
|
|
643
|
-
distribution: api.getStatusDistribution(),
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
function coerceArg(arg) {
|
|
647
|
-
const asInt = parseInt(arg, 10);
|
|
648
|
-
if (!isNaN(asInt) && String(asInt) === arg) {
|
|
649
|
-
return asInt;
|
|
650
|
-
}
|
|
651
|
-
return arg;
|
|
652
|
-
}
|
|
653
|
-
/**
|
|
654
|
-
* Require a string argument at the given index, throwing INVALID_ARGUMENT if missing.
|
|
655
|
-
*/
|
|
656
|
-
function requireStringArg(args, index, methodName) {
|
|
657
|
-
if (args[index] === undefined) {
|
|
658
|
-
throw new QueryApiError('INVALID_ARGUMENT', `${methodName} requires an argument at position ${index + 1}`);
|
|
659
|
-
}
|
|
660
|
-
return String(args[index]);
|
|
661
|
-
}
|
|
662
|
-
/**
|
|
663
|
-
* Require a numeric argument at the given index, throwing INVALID_ARGUMENT if missing or NaN.
|
|
664
|
-
*/
|
|
665
|
-
function requireNumberArg(args, index, methodName) {
|
|
666
|
-
if (args[index] === undefined) {
|
|
667
|
-
throw new QueryApiError('INVALID_ARGUMENT', `${methodName} requires a numeric argument at position ${index + 1}`);
|
|
668
|
-
}
|
|
669
|
-
const value = Number(args[index]);
|
|
670
|
-
if (isNaN(value)) {
|
|
671
|
-
throw new QueryApiError('INVALID_ARGUMENT', `${methodName} requires a numeric argument, got: "${String(args[index])}"`);
|
|
672
|
-
}
|
|
673
|
-
return value;
|
|
674
|
-
}
|
|
675
|
-
const API_METHODS = [
|
|
676
|
-
'getPatternsByNormalizedStatus',
|
|
677
|
-
'getPatternsByStatus',
|
|
678
|
-
'getStatusCounts',
|
|
679
|
-
'getStatusDistribution',
|
|
680
|
-
'getCompletionPercentage',
|
|
681
|
-
'getPatternsByPhase',
|
|
682
|
-
'getPhaseProgress',
|
|
683
|
-
'getActivePhases',
|
|
684
|
-
'getAllPhases',
|
|
685
|
-
'isValidTransition',
|
|
686
|
-
'checkTransition',
|
|
687
|
-
'getValidTransitionsFrom',
|
|
688
|
-
'getProtectionInfo',
|
|
689
|
-
'getPattern',
|
|
690
|
-
'getPatternDependencies',
|
|
691
|
-
'getPatternRelationships',
|
|
692
|
-
'getRelatedPatterns',
|
|
693
|
-
'getApiReferences',
|
|
694
|
-
'getPatternDeliverables',
|
|
695
|
-
'getPatternsByCategory',
|
|
696
|
-
'getCategories',
|
|
697
|
-
'getPatternsByQuarter',
|
|
698
|
-
'getQuarters',
|
|
699
|
-
'getCurrentWork',
|
|
700
|
-
'getRoadmapItems',
|
|
701
|
-
'getRecentlyCompleted',
|
|
702
|
-
'getMasterDataset',
|
|
703
|
-
];
|
|
704
|
-
/**
|
|
705
|
-
* Typed dispatch map: each entry invokes the API method with correct parameter types.
|
|
706
|
-
* The Record<ApiMethodName, ...> type ensures compile-time completeness — adding a
|
|
707
|
-
* method to API_METHODS without a dispatch entry causes a type error.
|
|
708
|
-
*/
|
|
709
|
-
const API_DISPATCH = {
|
|
710
|
-
// Status queries
|
|
711
|
-
getPatternsByNormalizedStatus: (api, args) => api.getPatternsByNormalizedStatus(requireStringArg(args, 0, 'getPatternsByNormalizedStatus')),
|
|
712
|
-
getPatternsByStatus: (api, args) => api.getPatternsByStatus(requireStringArg(args, 0, 'getPatternsByStatus')),
|
|
713
|
-
getStatusCounts: (api) => api.getStatusCounts(),
|
|
714
|
-
getStatusDistribution: (api) => api.getStatusDistribution(),
|
|
715
|
-
getCompletionPercentage: (api) => api.getCompletionPercentage(),
|
|
716
|
-
// Phase queries
|
|
717
|
-
getPatternsByPhase: (api, args) => api.getPatternsByPhase(requireNumberArg(args, 0, 'getPatternsByPhase')),
|
|
718
|
-
getPhaseProgress: (api, args) => api.getPhaseProgress(requireNumberArg(args, 0, 'getPhaseProgress')),
|
|
719
|
-
getActivePhases: (api) => api.getActivePhases(),
|
|
720
|
-
getAllPhases: (api) => api.getAllPhases(),
|
|
721
|
-
// FSM queries
|
|
722
|
-
isValidTransition: (api, args) => api.isValidTransition(requireStringArg(args, 0, 'isValidTransition'), requireStringArg(args, 1, 'isValidTransition')),
|
|
723
|
-
checkTransition: (api, args) => api.checkTransition(requireStringArg(args, 0, 'checkTransition'), requireStringArg(args, 1, 'checkTransition')),
|
|
724
|
-
getValidTransitionsFrom: (api, args) => api.getValidTransitionsFrom(requireStringArg(args, 0, 'getValidTransitionsFrom')),
|
|
725
|
-
getProtectionInfo: (api, args) => api.getProtectionInfo(requireStringArg(args, 0, 'getProtectionInfo')),
|
|
726
|
-
// Pattern queries
|
|
727
|
-
getPattern: (api, args) => api.getPattern(requireStringArg(args, 0, 'getPattern')),
|
|
728
|
-
getPatternDependencies: (api, args) => api.getPatternDependencies(requireStringArg(args, 0, 'getPatternDependencies')),
|
|
729
|
-
getPatternRelationships: (api, args) => api.getPatternRelationships(requireStringArg(args, 0, 'getPatternRelationships')),
|
|
730
|
-
getRelatedPatterns: (api, args) => api.getRelatedPatterns(requireStringArg(args, 0, 'getRelatedPatterns')),
|
|
731
|
-
getApiReferences: (api, args) => api.getApiReferences(requireStringArg(args, 0, 'getApiReferences')),
|
|
732
|
-
getPatternDeliverables: (api, args) => api.getPatternDeliverables(requireStringArg(args, 0, 'getPatternDeliverables')),
|
|
733
|
-
getPatternsByCategory: (api, args) => api.getPatternsByCategory(requireStringArg(args, 0, 'getPatternsByCategory')),
|
|
734
|
-
getCategories: (api) => api.getCategories(),
|
|
735
|
-
// Timeline queries
|
|
736
|
-
getPatternsByQuarter: (api, args) => api.getPatternsByQuarter(requireStringArg(args, 0, 'getPatternsByQuarter')),
|
|
737
|
-
getQuarters: (api) => api.getQuarters(),
|
|
738
|
-
getCurrentWork: (api) => api.getCurrentWork(),
|
|
739
|
-
getRoadmapItems: (api) => api.getRoadmapItems(),
|
|
740
|
-
getRecentlyCompleted: (api, args) => {
|
|
741
|
-
const limit = args[0] !== undefined ? Number(args[0]) : undefined;
|
|
742
|
-
return api.getRecentlyCompleted(limit);
|
|
743
|
-
},
|
|
744
|
-
// Raw access
|
|
745
|
-
getMasterDataset: (api) => api.getMasterDataset(),
|
|
746
|
-
};
|
|
747
|
-
function handleQuery(api, args) {
|
|
748
|
-
const methodName = args[0];
|
|
749
|
-
if (!methodName) {
|
|
750
|
-
throw new QueryApiError('INVALID_ARGUMENT', 'Usage: architect query <method> [args...]\nMethods: ' + API_METHODS.join(', '));
|
|
751
|
-
}
|
|
752
|
-
if (!API_METHODS.includes(methodName)) {
|
|
753
|
-
throw new QueryApiError('UNKNOWN_METHOD', `Unknown API method: ${methodName}\nAvailable: ${API_METHODS.join(', ')}`);
|
|
754
|
-
}
|
|
755
|
-
const dispatch = API_DISPATCH[methodName];
|
|
756
|
-
const coercedArgs = args.slice(1).map(coerceArg);
|
|
757
|
-
return { methodName, result: dispatch(api, coercedArgs) };
|
|
758
|
-
}
|
|
759
|
-
function handlePattern(api, args) {
|
|
760
|
-
const name = args[0];
|
|
761
|
-
if (!name) {
|
|
762
|
-
throw new QueryApiError('INVALID_ARGUMENT', 'Usage: architect pattern <name>');
|
|
763
|
-
}
|
|
764
|
-
const pattern = api.getPattern(name);
|
|
765
|
-
if (!pattern) {
|
|
766
|
-
const hint = suggestPattern(name, allPatternNames(api.getMasterDataset()));
|
|
767
|
-
throw new QueryApiError('PATTERN_NOT_FOUND', `Pattern not found: "${name}".${hint}`);
|
|
768
|
-
}
|
|
769
|
-
return {
|
|
770
|
-
...pattern,
|
|
771
|
-
deliverables: api.getPatternDeliverables(name),
|
|
772
|
-
dependencies: api.getPatternDependencies(name),
|
|
773
|
-
relationships: api.getPatternRelationships(name),
|
|
774
|
-
};
|
|
775
|
-
}
|
|
776
|
-
/**
|
|
777
|
-
* Parse list-specific filter flags from subArgs.
|
|
778
|
-
*/
|
|
779
|
-
function parseListFilters(subArgs) {
|
|
780
|
-
let status = null;
|
|
781
|
-
let phase = null;
|
|
782
|
-
let category = null;
|
|
783
|
-
let source = null;
|
|
784
|
-
let archContext = null;
|
|
785
|
-
let productArea = null;
|
|
786
|
-
let limit = null;
|
|
787
|
-
let offset = null;
|
|
788
|
-
for (let i = 0; i < subArgs.length; i++) {
|
|
789
|
-
const arg = subArgs[i];
|
|
790
|
-
const next = subArgs[i + 1];
|
|
791
|
-
switch (arg) {
|
|
792
|
-
case '--status':
|
|
793
|
-
status = next ?? null;
|
|
794
|
-
i++;
|
|
795
|
-
break;
|
|
796
|
-
case '--phase': {
|
|
797
|
-
const parsed = next !== undefined ? parseInt(next, 10) : NaN;
|
|
798
|
-
if (isNaN(parsed)) {
|
|
799
|
-
throw new QueryApiError('INVALID_ARGUMENT', `Invalid --phase value: "${next ?? ''}". Expected an integer.`);
|
|
800
|
-
}
|
|
801
|
-
phase = parsed;
|
|
802
|
-
i++;
|
|
803
|
-
break;
|
|
804
|
-
}
|
|
805
|
-
case '--category':
|
|
806
|
-
category = next ?? null;
|
|
807
|
-
i++;
|
|
808
|
-
break;
|
|
809
|
-
case '--source':
|
|
810
|
-
if (next === 'typescript' || next === 'ts') {
|
|
811
|
-
source = 'typescript';
|
|
812
|
-
}
|
|
813
|
-
else if (next === 'gherkin' || next === 'feature') {
|
|
814
|
-
source = 'gherkin';
|
|
815
|
-
}
|
|
816
|
-
i++;
|
|
817
|
-
break;
|
|
818
|
-
case '--limit': {
|
|
819
|
-
const parsed = next !== undefined ? parseInt(next, 10) : NaN;
|
|
820
|
-
if (isNaN(parsed) || parsed < 1) {
|
|
821
|
-
throw new QueryApiError('INVALID_ARGUMENT', `Invalid --limit value: "${next ?? ''}". Expected a positive integer.`);
|
|
822
|
-
}
|
|
823
|
-
limit = parsed;
|
|
824
|
-
i++;
|
|
825
|
-
break;
|
|
826
|
-
}
|
|
827
|
-
case '--offset': {
|
|
828
|
-
const parsed = next !== undefined ? parseInt(next, 10) : NaN;
|
|
829
|
-
if (isNaN(parsed) || parsed < 0) {
|
|
830
|
-
throw new QueryApiError('INVALID_ARGUMENT', `Invalid --offset value: "${next ?? ''}". Expected a non-negative integer.`);
|
|
831
|
-
}
|
|
832
|
-
offset = parsed;
|
|
833
|
-
i++;
|
|
834
|
-
break;
|
|
835
|
-
}
|
|
836
|
-
case '--arch-context':
|
|
837
|
-
archContext = next ?? null;
|
|
838
|
-
i++;
|
|
839
|
-
break;
|
|
840
|
-
case '--product-area':
|
|
841
|
-
productArea = next ?? null;
|
|
842
|
-
i++;
|
|
843
|
-
break;
|
|
844
|
-
default:
|
|
845
|
-
if (arg?.startsWith('-') === true) {
|
|
846
|
-
console.warn(`Warning: Unknown flag '${arg}' ignored`);
|
|
847
|
-
}
|
|
848
|
-
break;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
return { status, phase, category, source, archContext, productArea, limit, offset };
|
|
852
|
-
}
|
|
853
|
-
/**
|
|
854
|
-
* Generate contextual hint for empty list results.
|
|
855
|
-
*/
|
|
856
|
-
function generateEmptyHint(dataset, filters) {
|
|
857
|
-
if (filters.status !== null) {
|
|
858
|
-
const counts = dataset.counts;
|
|
859
|
-
const alternatives = [];
|
|
860
|
-
if (counts.active > 0 && filters.status !== 'active') {
|
|
861
|
-
alternatives.push(`${counts.active} active`);
|
|
862
|
-
}
|
|
863
|
-
if (counts.planned > 0 && filters.status !== 'roadmap') {
|
|
864
|
-
alternatives.push(`${counts.planned} roadmap`);
|
|
865
|
-
}
|
|
866
|
-
if (counts.completed > 0 && filters.status !== 'completed') {
|
|
867
|
-
alternatives.push(`${counts.completed} completed`);
|
|
868
|
-
}
|
|
869
|
-
if (alternatives.length > 0) {
|
|
870
|
-
// Pick the first available alternative for the suggestion command
|
|
871
|
-
const statusPriority = [
|
|
872
|
-
{ status: 'active', count: counts.active },
|
|
873
|
-
{ status: 'roadmap', count: counts.planned },
|
|
874
|
-
{ status: 'completed', count: counts.completed },
|
|
875
|
-
];
|
|
876
|
-
const altStatus = statusPriority.find((s) => s.count > 0 && s.status !== filters.status)?.status ?? 'active';
|
|
877
|
-
return `No ${filters.status} patterns. ${alternatives.join(', ')} exist. Try: list --status ${altStatus}`;
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
return undefined;
|
|
881
|
-
}
|
|
882
|
-
function handleList(dataset, subArgs, modifiers) {
|
|
883
|
-
const filters = parseListFilters(subArgs);
|
|
884
|
-
const filtered = applyListFilters(dataset, filters);
|
|
885
|
-
if (filtered.length === 0) {
|
|
886
|
-
const hint = generateEmptyHint(dataset, filters);
|
|
887
|
-
return { patterns: [], hint };
|
|
888
|
-
}
|
|
889
|
-
const input = { kind: 'patterns', data: filtered };
|
|
890
|
-
return applyOutputPipeline(input, modifiers);
|
|
891
|
-
}
|
|
892
|
-
function handleSearch(api, subArgs) {
|
|
893
|
-
const query = subArgs[0];
|
|
894
|
-
if (!query) {
|
|
895
|
-
throw new QueryApiError('INVALID_ARGUMENT', 'Usage: architect search <query>');
|
|
896
|
-
}
|
|
897
|
-
const names = allPatternNames(api.getMasterDataset());
|
|
898
|
-
const matches = fuzzyMatchPatterns(query, names);
|
|
899
|
-
if (matches.length === 0) {
|
|
900
|
-
const hint = `No patterns matched "${query}".${suggestPattern(query, names)}`;
|
|
901
|
-
return { matches: [], hint };
|
|
902
|
-
}
|
|
903
|
-
return { matches };
|
|
904
|
-
}
|
|
905
|
-
async function handleArch(ctx) {
|
|
906
|
-
const args = ctx.subArgs;
|
|
907
|
-
const subCmd = args[0];
|
|
908
|
-
// Graph health commands work on relationshipIndex/validation, not archIndex
|
|
909
|
-
if (subCmd === 'dangling')
|
|
910
|
-
return ctx.validation.danglingReferences;
|
|
911
|
-
if (subCmd === 'orphans')
|
|
912
|
-
return findOrphanPatterns(ctx.dataset);
|
|
913
|
-
if (subCmd === 'blocking')
|
|
914
|
-
return buildOverview(ctx.dataset).blocking;
|
|
915
|
-
const archIndex = ctx.dataset.archIndex;
|
|
916
|
-
if (!archIndex || archIndex.all.length === 0) {
|
|
917
|
-
throw new QueryApiError('PATTERN_NOT_FOUND', 'No architecture data available. Ensure patterns have @architect-arch-role annotations.');
|
|
918
|
-
}
|
|
919
|
-
switch (subCmd) {
|
|
920
|
-
case 'roles':
|
|
921
|
-
return Object.entries(archIndex.byRole).map(([role, patterns]) => ({
|
|
922
|
-
role,
|
|
923
|
-
count: patterns.length,
|
|
924
|
-
patterns: patterns.map((p) => p.name),
|
|
925
|
-
}));
|
|
926
|
-
case 'context': {
|
|
927
|
-
const contextName = args[1];
|
|
928
|
-
if (!contextName) {
|
|
929
|
-
return Object.entries(archIndex.byContext).map(([ctxName, patterns]) => ({
|
|
930
|
-
context: ctxName,
|
|
931
|
-
count: patterns.length,
|
|
932
|
-
patterns: patterns.map((p) => p.name),
|
|
933
|
-
}));
|
|
934
|
-
}
|
|
935
|
-
const contextPatterns = archIndex.byContext[contextName];
|
|
936
|
-
if (!contextPatterns) {
|
|
937
|
-
throw new QueryApiError('CATEGORY_NOT_FOUND', `Context not found: "${contextName}"\nAvailable: ${Object.keys(archIndex.byContext).join(', ')}`);
|
|
938
|
-
}
|
|
939
|
-
const ctxInput = { kind: 'patterns', data: contextPatterns };
|
|
940
|
-
return applyOutputPipeline(ctxInput, ctx.modifiers);
|
|
941
|
-
}
|
|
942
|
-
case 'layer': {
|
|
943
|
-
const layerName = args[1];
|
|
944
|
-
if (!layerName) {
|
|
945
|
-
return Object.entries(archIndex.byLayer).map(([layer, patterns]) => ({
|
|
946
|
-
layer,
|
|
947
|
-
count: patterns.length,
|
|
948
|
-
patterns: patterns.map((p) => p.name),
|
|
949
|
-
}));
|
|
950
|
-
}
|
|
951
|
-
const layerPatterns = archIndex.byLayer[layerName];
|
|
952
|
-
if (!layerPatterns) {
|
|
953
|
-
throw new QueryApiError('CATEGORY_NOT_FOUND', `Layer not found: "${layerName}"\nAvailable: ${Object.keys(archIndex.byLayer).join(', ')}`);
|
|
954
|
-
}
|
|
955
|
-
const layerInput = { kind: 'patterns', data: layerPatterns };
|
|
956
|
-
return applyOutputPipeline(layerInput, ctx.modifiers);
|
|
957
|
-
}
|
|
958
|
-
case 'neighborhood': {
|
|
959
|
-
const patternName = args[1];
|
|
960
|
-
if (!patternName) {
|
|
961
|
-
throw new QueryApiError('INVALID_ARGUMENT', 'Usage: architect arch neighborhood <pattern>');
|
|
962
|
-
}
|
|
963
|
-
const neighborhood = computeNeighborhood(patternName, ctx.dataset);
|
|
964
|
-
if (neighborhood === undefined) {
|
|
965
|
-
const hint = suggestPattern(patternName, allPatternNames(ctx.dataset));
|
|
966
|
-
throw new QueryApiError('PATTERN_NOT_FOUND', `Pattern not found: "${patternName}".${hint}`);
|
|
967
|
-
}
|
|
968
|
-
return neighborhood;
|
|
969
|
-
}
|
|
970
|
-
case 'compare': {
|
|
971
|
-
const ctx1Name = args[1];
|
|
972
|
-
const ctx2Name = args[2];
|
|
973
|
-
if (!ctx1Name || !ctx2Name) {
|
|
974
|
-
throw new QueryApiError('INVALID_ARGUMENT', 'Usage: architect arch compare <ctx1> <ctx2>');
|
|
975
|
-
}
|
|
976
|
-
const comparison = compareContexts(ctx1Name, ctx2Name, ctx.dataset);
|
|
977
|
-
if (comparison === undefined) {
|
|
978
|
-
const available = Object.keys(archIndex.byContext).join(', ');
|
|
979
|
-
throw new QueryApiError('CONTEXT_NOT_FOUND', `Context not found. Available: ${available}`);
|
|
980
|
-
}
|
|
981
|
-
return comparison;
|
|
982
|
-
}
|
|
983
|
-
case 'coverage':
|
|
984
|
-
try {
|
|
985
|
-
return await analyzeCoverage(ctx.dataset, ctx.cliConfig.input, ctx.cliConfig.baseDir, ctx.registry);
|
|
986
|
-
}
|
|
987
|
-
catch (err) {
|
|
988
|
-
throw new QueryApiError('INVALID_ARGUMENT', `Coverage analysis failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
989
|
-
}
|
|
990
|
-
default:
|
|
991
|
-
throw new QueryApiError('UNKNOWN_METHOD', `Unknown arch subcommand: ${subCmd ?? '(none)'}\nAvailable: roles, context [name], layer [name], neighborhood <pattern>, compare <ctx1> <ctx2>, coverage, dangling, orphans, blocking`);
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
// =============================================================================
|
|
995
|
-
// Stub Integration Handlers
|
|
996
|
-
// =============================================================================
|
|
997
|
-
function handleSequence(dataset, subArgs, modifiers) {
|
|
998
|
-
const index = dataset.sequenceIndex;
|
|
999
|
-
if (!index || Object.keys(index).length === 0) {
|
|
1000
|
-
return { message: 'No patterns with sequence annotations found', patterns: [], count: 0 };
|
|
1001
|
-
}
|
|
1002
|
-
if (subArgs.length === 0) {
|
|
1003
|
-
const patterns = Object.keys(index);
|
|
1004
|
-
if (modifiers.count)
|
|
1005
|
-
return { count: patterns.length };
|
|
1006
|
-
if (modifiers.namesOnly)
|
|
1007
|
-
return patterns;
|
|
1008
|
-
return { patterns, count: patterns.length };
|
|
1009
|
-
}
|
|
1010
|
-
const patternName = subArgs[0] ?? '';
|
|
1011
|
-
const entry = getSequenceEntry(dataset, patternName);
|
|
1012
|
-
if (!entry) {
|
|
1013
|
-
const available = Object.keys(index);
|
|
1014
|
-
const hint = suggestPattern(patternName, available);
|
|
1015
|
-
throw new QueryApiError('PATTERN_NOT_FOUND', `No sequence data for "${patternName}".${hint} Available: ${available.join(', ')}`);
|
|
1016
|
-
}
|
|
1017
|
-
return entry;
|
|
1018
|
-
}
|
|
1019
|
-
// =============================================================================
|
|
1020
|
-
function handleStubs(dataset, subArgs, baseDir) {
|
|
1021
|
-
const stubs = findStubPatterns(dataset);
|
|
1022
|
-
const resolutions = resolveStubs(stubs, baseDir);
|
|
1023
|
-
// Parse optional pattern name and --unresolved flag
|
|
1024
|
-
let patternFilter;
|
|
1025
|
-
let unresolvedOnly = false;
|
|
1026
|
-
for (const arg of subArgs) {
|
|
1027
|
-
if (arg === '--unresolved') {
|
|
1028
|
-
unresolvedOnly = true;
|
|
1029
|
-
}
|
|
1030
|
-
else {
|
|
1031
|
-
patternFilter = arg;
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
let filtered = resolutions;
|
|
1035
|
-
// Filter by pattern name if provided
|
|
1036
|
-
if (patternFilter !== undefined) {
|
|
1037
|
-
const lowerFilter = patternFilter.toLowerCase();
|
|
1038
|
-
filtered = filtered.filter((r) => r.implementsPattern?.toLowerCase() === lowerFilter ||
|
|
1039
|
-
r.stubName.toLowerCase() === lowerFilter);
|
|
1040
|
-
if (filtered.length === 0) {
|
|
1041
|
-
const stubNames = [...new Set(resolutions.map((r) => r.implementsPattern ?? r.stubName))];
|
|
1042
|
-
const hint = suggestPattern(patternFilter, stubNames);
|
|
1043
|
-
throw new QueryApiError('STUB_NOT_FOUND', `No stubs found for pattern: "${patternFilter}".${hint}`);
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
// Filter unresolved only
|
|
1047
|
-
if (unresolvedOnly) {
|
|
1048
|
-
filtered = filtered.filter((r) => !r.targetExists);
|
|
1049
|
-
}
|
|
1050
|
-
return groupStubsByPattern(filtered);
|
|
1051
|
-
}
|
|
1052
|
-
function handleDecisions(dataset, subArgs) {
|
|
1053
|
-
const patternName = subArgs[0];
|
|
1054
|
-
if (patternName === undefined) {
|
|
1055
|
-
throw new QueryApiError('INVALID_ARGUMENT', 'Usage: decisions <pattern>');
|
|
1056
|
-
}
|
|
1057
|
-
// Find stubs implementing this pattern
|
|
1058
|
-
const stubs = findStubPatterns(dataset);
|
|
1059
|
-
const patternStubs = stubs.filter((s) => {
|
|
1060
|
-
const implName = firstImplements(s);
|
|
1061
|
-
return (implName?.toLowerCase() === patternName.toLowerCase() ||
|
|
1062
|
-
getPatternName(s).toLowerCase() === patternName.toLowerCase());
|
|
1063
|
-
});
|
|
1064
|
-
if (patternStubs.length === 0) {
|
|
1065
|
-
const stubNames = [...new Set(stubs.map((s) => firstImplements(s) ?? getPatternName(s)))];
|
|
1066
|
-
const hint = suggestPattern(patternName, stubNames);
|
|
1067
|
-
throw new QueryApiError('STUB_NOT_FOUND', `No decisions found for pattern: "${patternName}".${hint}`);
|
|
1068
|
-
}
|
|
1069
|
-
// Extract decisions from each stub's description
|
|
1070
|
-
const decisions = patternStubs.map((stub) => ({
|
|
1071
|
-
stub: getPatternName(stub),
|
|
1072
|
-
file: stub.source.file,
|
|
1073
|
-
since: stub.since,
|
|
1074
|
-
decisions: extractDecisionItems(stub.directive.description),
|
|
1075
|
-
}));
|
|
1076
|
-
return {
|
|
1077
|
-
pattern: patternName,
|
|
1078
|
-
stubs: decisions,
|
|
1079
|
-
totalDecisions: decisions.reduce((sum, d) => sum + d.decisions.length, 0),
|
|
1080
|
-
};
|
|
1081
|
-
}
|
|
1082
|
-
function handlePdr(dataset, subArgs) {
|
|
1083
|
-
const pdrNumber = subArgs[0];
|
|
1084
|
-
if (pdrNumber === undefined) {
|
|
1085
|
-
throw new QueryApiError('INVALID_ARGUMENT', 'Usage: pdr <number> (e.g., pdr 012)');
|
|
1086
|
-
}
|
|
1087
|
-
// Normalize: strip leading "PDR-" if user passed it
|
|
1088
|
-
const normalizedNumber = pdrNumber.replace(/^PDR-/i, '').padStart(3, '0');
|
|
1089
|
-
const references = findPdrReferences(dataset.patterns, normalizedNumber);
|
|
1090
|
-
if (references.length === 0) {
|
|
1091
|
-
throw new QueryApiError('PDR_NOT_FOUND', `No patterns reference PDR-${normalizedNumber}`);
|
|
1092
|
-
}
|
|
1093
|
-
return {
|
|
1094
|
-
pdr: `PDR-${normalizedNumber}`,
|
|
1095
|
-
referenceCount: references.length,
|
|
1096
|
-
references,
|
|
1097
|
-
};
|
|
1098
|
-
}
|
|
1099
|
-
// =============================================================================
|
|
1100
|
-
// Business Rules Handler
|
|
1101
|
-
// =============================================================================
|
|
1102
|
-
function parseRulesFilters(subArgs) {
|
|
1103
|
-
let productArea = null;
|
|
1104
|
-
let patternName = null;
|
|
1105
|
-
let onlyInvariants = false;
|
|
1106
|
-
for (let i = 0; i < subArgs.length; i++) {
|
|
1107
|
-
const arg = subArgs[i];
|
|
1108
|
-
if (arg === '--product-area') {
|
|
1109
|
-
if (i + 1 >= subArgs.length || subArgs[i + 1]?.startsWith('-') === true) {
|
|
1110
|
-
throw new QueryApiError('INVALID_ARGUMENT', '--product-area requires a value');
|
|
1111
|
-
}
|
|
1112
|
-
productArea = subArgs[++i] ?? null;
|
|
1113
|
-
}
|
|
1114
|
-
else if (arg === '--pattern') {
|
|
1115
|
-
if (i + 1 >= subArgs.length || subArgs[i + 1]?.startsWith('-') === true) {
|
|
1116
|
-
throw new QueryApiError('INVALID_ARGUMENT', '--pattern requires a value');
|
|
1117
|
-
}
|
|
1118
|
-
patternName = subArgs[++i] ?? null;
|
|
1119
|
-
}
|
|
1120
|
-
else if (arg === '--only-invariants') {
|
|
1121
|
-
onlyInvariants = true;
|
|
1122
|
-
}
|
|
1123
|
-
else if (typeof arg === 'string' && arg.startsWith('-')) {
|
|
1124
|
-
console.warn(`Warning: Unknown flag '${arg}' ignored`);
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
return { productArea, patternName, onlyInvariants };
|
|
1128
|
-
}
|
|
1129
|
-
function handleRules(ctx) {
|
|
1130
|
-
const filters = parseRulesFilters(ctx.subArgs);
|
|
1131
|
-
const result = queryBusinessRules(ctx.dataset, filters);
|
|
1132
|
-
// Empty-result hint (delegated from query, applied per output modifier)
|
|
1133
|
-
if (result.totalRules === 0 && (filters.productArea !== null || filters.patternName !== null)) {
|
|
1134
|
-
if (ctx.modifiers.count) {
|
|
1135
|
-
return { totalRules: 0, totalInvariants: 0, hint: result.hint };
|
|
1136
|
-
}
|
|
1137
|
-
if (ctx.modifiers.namesOnly) {
|
|
1138
|
-
return { names: [], hint: result.hint };
|
|
1139
|
-
}
|
|
1140
|
-
return { productAreas: [], totalRules: 0, totalInvariants: 0, hint: result.hint };
|
|
1141
|
-
}
|
|
1142
|
-
// Handle output modifiers
|
|
1143
|
-
if (ctx.modifiers.count) {
|
|
1144
|
-
return { totalRules: result.totalRules, totalInvariants: result.totalInvariants };
|
|
1145
|
-
}
|
|
1146
|
-
if (ctx.modifiers.namesOnly) {
|
|
1147
|
-
return result.allRuleNames;
|
|
1148
|
-
}
|
|
1149
|
-
return {
|
|
1150
|
-
productAreas: result.productAreas,
|
|
1151
|
-
totalRules: result.totalRules,
|
|
1152
|
-
totalInvariants: result.totalInvariants,
|
|
1153
|
-
};
|
|
1154
|
-
}
|
|
1155
|
-
// =============================================================================
|
|
1156
|
-
// Context Assembly Handlers (text output — ADR-008)
|
|
1157
|
-
// =============================================================================
|
|
1158
|
-
function parseSessionFromSubArgs(subArgs) {
|
|
1159
|
-
const idx = subArgs.indexOf('--session');
|
|
1160
|
-
if (idx === -1)
|
|
1161
|
-
return null;
|
|
1162
|
-
const val = subArgs[idx + 1];
|
|
1163
|
-
if (val !== undefined && isValidSessionType(val))
|
|
1164
|
-
return val;
|
|
1165
|
-
return null;
|
|
1166
|
-
}
|
|
1167
|
-
function handleContext(ctx) {
|
|
1168
|
-
const patternNames = [];
|
|
1169
|
-
for (let i = 0; i < ctx.subArgs.length; i++) {
|
|
1170
|
-
const arg = ctx.subArgs[i];
|
|
1171
|
-
if (arg === '--session') {
|
|
1172
|
-
i++; // skip the value
|
|
1173
|
-
continue;
|
|
1174
|
-
}
|
|
1175
|
-
if (arg !== undefined && !arg.startsWith('-')) {
|
|
1176
|
-
patternNames.push(arg);
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
if (patternNames.length === 0) {
|
|
1180
|
-
throw new QueryApiError('CONTEXT_ASSEMBLY_ERROR', 'Usage: architect context <pattern> [pattern2...] [--session planning|design|implement]');
|
|
1181
|
-
}
|
|
1182
|
-
const sessionType = ctx.sessionType ?? parseSessionFromSubArgs(ctx.subArgs) ?? 'design';
|
|
1183
|
-
const bundle = assembleContext(ctx.dataset, ctx.api, {
|
|
1184
|
-
patterns: patternNames,
|
|
1185
|
-
sessionType,
|
|
1186
|
-
baseDir: ctx.baseDir,
|
|
1187
|
-
});
|
|
1188
|
-
return formatContextBundle(bundle);
|
|
1189
|
-
}
|
|
1190
|
-
function handleFiles(ctx) {
|
|
1191
|
-
const patternName = ctx.subArgs.find((a) => !a.startsWith('-'));
|
|
1192
|
-
if (patternName === undefined) {
|
|
1193
|
-
throw new QueryApiError('CONTEXT_ASSEMBLY_ERROR', 'Usage: architect files <pattern> [--related]');
|
|
1194
|
-
}
|
|
1195
|
-
const includeRelated = ctx.subArgs.includes('--related');
|
|
1196
|
-
const list = buildFileReadingList(ctx.dataset, patternName, includeRelated);
|
|
1197
|
-
return formatFileReadingList(list);
|
|
1198
|
-
}
|
|
1199
|
-
function handleDepTreeCmd(ctx) {
|
|
1200
|
-
const patternName = ctx.subArgs.find((a) => !a.startsWith('-'));
|
|
1201
|
-
if (patternName === undefined) {
|
|
1202
|
-
throw new QueryApiError('CONTEXT_ASSEMBLY_ERROR', 'Usage: architect dep-tree <pattern> [--depth N]');
|
|
1203
|
-
}
|
|
1204
|
-
// Parse --depth N
|
|
1205
|
-
let maxDepth = 3;
|
|
1206
|
-
const depthIdx = ctx.subArgs.indexOf('--depth');
|
|
1207
|
-
if (depthIdx !== -1) {
|
|
1208
|
-
const depthVal = ctx.subArgs[depthIdx + 1];
|
|
1209
|
-
if (depthVal !== undefined) {
|
|
1210
|
-
const parsed = parseInt(depthVal, 10);
|
|
1211
|
-
if (!isNaN(parsed) && parsed > 0) {
|
|
1212
|
-
maxDepth = Math.min(parsed, 10);
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
const tree = buildDepTree(ctx.dataset, {
|
|
1217
|
-
pattern: patternName,
|
|
1218
|
-
maxDepth,
|
|
1219
|
-
includeImplementationDeps: true,
|
|
1220
|
-
});
|
|
1221
|
-
return formatDepTree(tree);
|
|
1222
|
-
}
|
|
1223
|
-
function handleOverviewCmd(ctx) {
|
|
1224
|
-
const overview = buildOverview(ctx.dataset);
|
|
1225
|
-
return formatOverview(overview);
|
|
1226
|
-
}
|
|
1227
|
-
// =============================================================================
|
|
1228
|
-
// Session Workflow Handlers (text output — ADR-008)
|
|
1229
|
-
// =============================================================================
|
|
1230
|
-
const VALID_SCOPE_TYPES = new Set(['implement', 'design']);
|
|
1231
|
-
function handleScopeValidate(ctx) {
|
|
1232
|
-
// Parse pattern name (positional, first non-flag arg)
|
|
1233
|
-
let patternName;
|
|
1234
|
-
let scopeType = 'implement';
|
|
1235
|
-
let strict = false;
|
|
1236
|
-
for (let i = 0; i < ctx.subArgs.length; i++) {
|
|
1237
|
-
const arg = ctx.subArgs[i];
|
|
1238
|
-
if (arg === '--type') {
|
|
1239
|
-
const val = ctx.subArgs[i + 1];
|
|
1240
|
-
if (val !== undefined && VALID_SCOPE_TYPES.has(val)) {
|
|
1241
|
-
scopeType = val;
|
|
1242
|
-
}
|
|
1243
|
-
else {
|
|
1244
|
-
throw new QueryApiError('INVALID_ARGUMENT', `--type must be "implement" or "design", got: "${val ?? ''}"`);
|
|
1245
|
-
}
|
|
1246
|
-
i++;
|
|
1247
|
-
}
|
|
1248
|
-
else if (arg === '--strict') {
|
|
1249
|
-
// DD-4: promotes WARN → BLOCKED (consistent with architect-guard --strict)
|
|
1250
|
-
strict = true;
|
|
1251
|
-
}
|
|
1252
|
-
else if (arg !== undefined && !arg.startsWith('-')) {
|
|
1253
|
-
if (patternName === undefined) {
|
|
1254
|
-
patternName = arg;
|
|
1255
|
-
}
|
|
1256
|
-
else if (VALID_SCOPE_TYPES.has(arg)) {
|
|
1257
|
-
// DD-6: positional scope type also accepted
|
|
1258
|
-
scopeType = arg;
|
|
1259
|
-
}
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
if (patternName === undefined) {
|
|
1263
|
-
throw new QueryApiError('INVALID_ARGUMENT', 'Usage: architect scope-validate <pattern> [implement|design] [--type implement|design] [--strict]');
|
|
1264
|
-
}
|
|
1265
|
-
const result = validateScope(ctx.api, ctx.dataset, {
|
|
1266
|
-
patternName,
|
|
1267
|
-
scopeType,
|
|
1268
|
-
baseDir: ctx.baseDir,
|
|
1269
|
-
strict,
|
|
1270
|
-
});
|
|
1271
|
-
return formatScopeValidation(result);
|
|
1272
|
-
}
|
|
1273
|
-
// 'review' is handoff-specific — not a global session type (parsed locally, not by top-level --session)
|
|
1274
|
-
const VALID_HANDOFF_SESSION_TYPES = new Set([
|
|
1275
|
-
'planning',
|
|
1276
|
-
'design',
|
|
1277
|
-
'implement',
|
|
1278
|
-
'review',
|
|
1279
|
-
]);
|
|
1280
|
-
function handleHandoff(ctx) {
|
|
1281
|
-
let patternName;
|
|
1282
|
-
let sessionType;
|
|
1283
|
-
let useGit = false;
|
|
1284
|
-
for (let i = 0; i < ctx.subArgs.length; i++) {
|
|
1285
|
-
const arg = ctx.subArgs[i];
|
|
1286
|
-
if (arg === '--pattern') {
|
|
1287
|
-
patternName = ctx.subArgs[i + 1];
|
|
1288
|
-
if (patternName === undefined) {
|
|
1289
|
-
throw new QueryApiError('INVALID_ARGUMENT', '--pattern requires a value');
|
|
1290
|
-
}
|
|
1291
|
-
i++;
|
|
1292
|
-
}
|
|
1293
|
-
else if (arg === '--session') {
|
|
1294
|
-
const val = ctx.subArgs[i + 1];
|
|
1295
|
-
if (val !== undefined && VALID_HANDOFF_SESSION_TYPES.has(val)) {
|
|
1296
|
-
sessionType = val;
|
|
1297
|
-
}
|
|
1298
|
-
else {
|
|
1299
|
-
throw new QueryApiError('INVALID_ARGUMENT', `--session must be "planning", "design", "implement", or "review", got: "${val ?? ''}"`);
|
|
1300
|
-
}
|
|
1301
|
-
i++;
|
|
1302
|
-
}
|
|
1303
|
-
else if (arg === '--git') {
|
|
1304
|
-
useGit = true;
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
// Also accept from top-level parsed --session
|
|
1308
|
-
if (sessionType === undefined && ctx.sessionType !== null) {
|
|
1309
|
-
sessionType = ctx.sessionType;
|
|
1310
|
-
}
|
|
1311
|
-
// Pattern name uses --pattern flag (not positional) to avoid ambiguity with --git and --session
|
|
1312
|
-
if (patternName === undefined) {
|
|
1313
|
-
throw new QueryApiError('INVALID_ARGUMENT', 'Usage: architect handoff --pattern <name> [--git] [--session planning|design|implement|review]');
|
|
1314
|
-
}
|
|
1315
|
-
// DD-2: git integration is opt-in — CLI handler owns the shell call
|
|
1316
|
-
let modifiedFiles;
|
|
1317
|
-
if (useGit) {
|
|
1318
|
-
try {
|
|
1319
|
-
const output = execSync('git diff --name-only HEAD', { encoding: 'utf-8' });
|
|
1320
|
-
modifiedFiles = output
|
|
1321
|
-
.trim()
|
|
1322
|
-
.split('\n')
|
|
1323
|
-
.filter((line) => line.length > 0);
|
|
1324
|
-
}
|
|
1325
|
-
catch (err) {
|
|
1326
|
-
console.error(`Warning: git diff failed: ${err instanceof Error ? err.message : String(err)}. Handoff will not include modified files.`);
|
|
1327
|
-
modifiedFiles = undefined;
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
const options = { patternName };
|
|
1331
|
-
if (sessionType !== undefined) {
|
|
1332
|
-
options.sessionType = sessionType;
|
|
1333
|
-
}
|
|
1334
|
-
if (modifiedFiles !== undefined) {
|
|
1335
|
-
options.modifiedFiles = modifiedFiles;
|
|
1336
|
-
}
|
|
1337
|
-
const doc = generateHandoff(ctx.api, ctx.dataset, options);
|
|
1338
|
-
return formatHandoff(doc);
|
|
1339
|
-
}
|
|
1340
|
-
// =============================================================================
|
|
1341
|
-
// Subcommand Router
|
|
1342
|
-
// =============================================================================
|
|
1343
|
-
async function routeSubcommand(ctx) {
|
|
1344
|
-
switch (ctx.subcommand) {
|
|
1345
|
-
case 'context':
|
|
1346
|
-
return handleContext(ctx);
|
|
1347
|
-
case 'files':
|
|
1348
|
-
return handleFiles(ctx);
|
|
1349
|
-
case 'dep-tree':
|
|
1350
|
-
return handleDepTreeCmd(ctx);
|
|
1351
|
-
case 'overview':
|
|
1352
|
-
return handleOverviewCmd(ctx);
|
|
1353
|
-
case 'scope-validate':
|
|
1354
|
-
return handleScopeValidate(ctx);
|
|
1355
|
-
case 'handoff':
|
|
1356
|
-
return handleHandoff(ctx);
|
|
1357
|
-
case 'status':
|
|
1358
|
-
return handleStatus(ctx.api);
|
|
1359
|
-
case 'query': {
|
|
1360
|
-
const { methodName, result } = handleQuery(ctx.api, ctx.subArgs);
|
|
1361
|
-
// Apply output pipeline for pattern-array methods
|
|
1362
|
-
if (PATTERN_ARRAY_METHODS.has(methodName)) {
|
|
1363
|
-
const input = {
|
|
1364
|
-
kind: 'patterns',
|
|
1365
|
-
data: result,
|
|
1366
|
-
};
|
|
1367
|
-
return applyOutputPipeline(input, ctx.modifiers);
|
|
1368
|
-
}
|
|
1369
|
-
return result;
|
|
1370
|
-
}
|
|
1371
|
-
case 'pattern':
|
|
1372
|
-
return handlePattern(ctx.api, ctx.subArgs);
|
|
1373
|
-
case 'list':
|
|
1374
|
-
return handleList(ctx.dataset, ctx.subArgs, ctx.modifiers);
|
|
1375
|
-
case 'search':
|
|
1376
|
-
return handleSearch(ctx.api, ctx.subArgs);
|
|
1377
|
-
case 'arch':
|
|
1378
|
-
return handleArch(ctx);
|
|
1379
|
-
case 'stubs':
|
|
1380
|
-
return handleStubs(ctx.dataset, ctx.subArgs, ctx.cliConfig.baseDir);
|
|
1381
|
-
case 'decisions':
|
|
1382
|
-
return handleDecisions(ctx.dataset, ctx.subArgs);
|
|
1383
|
-
case 'pdr':
|
|
1384
|
-
return handlePdr(ctx.dataset, ctx.subArgs);
|
|
1385
|
-
case 'rules':
|
|
1386
|
-
return handleRules(ctx);
|
|
1387
|
-
case 'tags':
|
|
1388
|
-
return aggregateTagUsage(ctx.dataset);
|
|
1389
|
-
case 'sources':
|
|
1390
|
-
return buildSourceInventory(ctx.dataset);
|
|
1391
|
-
case 'sequence':
|
|
1392
|
-
return handleSequence(ctx.dataset, ctx.subArgs, ctx.modifiers);
|
|
1393
|
-
case 'unannotated': {
|
|
1394
|
-
let pathFilter;
|
|
1395
|
-
for (let i = 0; i < ctx.subArgs.length; i++) {
|
|
1396
|
-
if (ctx.subArgs[i] === '--path') {
|
|
1397
|
-
pathFilter = ctx.subArgs[i + 1];
|
|
1398
|
-
break;
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
try {
|
|
1402
|
-
return await findUnannotatedFiles(ctx.cliConfig.input, ctx.cliConfig.baseDir, ctx.registry, pathFilter);
|
|
1403
|
-
}
|
|
1404
|
-
catch (err) {
|
|
1405
|
-
throw new QueryApiError('INVALID_ARGUMENT', `Unannotated file scan failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
|
-
default:
|
|
1409
|
-
throw new QueryApiError('UNKNOWN_METHOD', `Unknown subcommand: ${ctx.subcommand}\nAvailable: context, files, dep-tree, overview, scope-validate, handoff, status, query, pattern, list, search, arch, stubs, decisions, pdr, rules, tags, sources, sequence, unannotated`);
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
// =============================================================================
|
|
1413
|
-
// Main
|
|
1414
|
-
// =============================================================================
|
|
1415
|
-
/**
|
|
1416
|
-
* Build extended query metadata from pipeline results.
|
|
1417
|
-
*/
|
|
1418
|
-
function buildQueryMetadataExtra(validation, cacheHit, cacheAgeMs, pipelineMs) {
|
|
1419
|
-
return {
|
|
1420
|
-
validation: {
|
|
1421
|
-
danglingReferenceCount: validation.danglingReferences.length,
|
|
1422
|
-
malformedPatternCount: validation.malformedPatterns.length,
|
|
1423
|
-
unknownStatusCount: validation.unknownStatuses.length,
|
|
1424
|
-
warningCount: validation.warningCount,
|
|
1425
|
-
},
|
|
1426
|
-
cache: cacheAgeMs !== undefined ? { hit: cacheHit, ageMs: cacheAgeMs } : { hit: cacheHit },
|
|
1427
|
-
pipelineMs,
|
|
1428
|
-
};
|
|
1429
|
-
}
|
|
1430
|
-
async function main() {
|
|
1431
|
-
const opts = parseArgs();
|
|
1432
|
-
if (opts.version) {
|
|
1433
|
-
printVersionAndExit('architect');
|
|
1434
|
-
}
|
|
1435
|
-
if (opts.help || !opts.subcommand) {
|
|
1436
|
-
showHelp();
|
|
1437
|
-
process.exit(opts.help ? 0 : 1);
|
|
1438
|
-
}
|
|
1439
|
-
// Per-subcommand help (e.g., `architect context --help`)
|
|
1440
|
-
if (opts.subcommandHelp !== null) {
|
|
1441
|
-
showSubcommandHelp(opts.subcommandHelp);
|
|
1442
|
-
process.exit(0);
|
|
1443
|
-
}
|
|
1444
|
-
// REPL mode: interactive multi-query session (manages its own pipeline lifecycle)
|
|
1445
|
-
if (opts.subcommand === 'repl') {
|
|
1446
|
-
await applyConfigDefaults(opts);
|
|
1447
|
-
await startRepl({
|
|
1448
|
-
input: opts.input,
|
|
1449
|
-
features: opts.features,
|
|
1450
|
-
baseDir: opts.baseDir,
|
|
1451
|
-
workflowPath: opts.workflowPath,
|
|
1452
|
-
});
|
|
1453
|
-
return;
|
|
1454
|
-
}
|
|
1455
|
-
// Validate output modifiers before any expensive work
|
|
1456
|
-
validateModifiers(opts.modifiers);
|
|
1457
|
-
// FSM short-circuit: bypass pipeline for static FSM queries (2-5s saving)
|
|
1458
|
-
if (opts.subcommand === 'query') {
|
|
1459
|
-
const fsmResult = tryFsmShortCircuit(opts.subcommand, opts.subArgs);
|
|
1460
|
-
if (fsmResult !== undefined) {
|
|
1461
|
-
const envelope = createSuccess(fsmResult, 0);
|
|
1462
|
-
const output = formatOutput(envelope, opts.format);
|
|
1463
|
-
console.log(output);
|
|
1464
|
-
return;
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
// Resolve config file defaults if --input and --features not provided
|
|
1468
|
-
await applyConfigDefaults(opts);
|
|
1469
|
-
if (opts.input.length === 0) {
|
|
1470
|
-
console.error('Error: --input is required (or place architect.config.ts or architect.config.js in your project for auto-detection)');
|
|
1471
|
-
console.error('');
|
|
1472
|
-
console.error('Example:');
|
|
1473
|
-
console.error(' architect -i "src/**/*.ts" status');
|
|
1474
|
-
process.exit(1);
|
|
1475
|
-
}
|
|
1476
|
-
// Dry-run: show pipeline scope without executing
|
|
1477
|
-
if (opts.dryRun) {
|
|
1478
|
-
await executeDryRun(opts);
|
|
1479
|
-
return;
|
|
1480
|
-
}
|
|
1481
|
-
// Pipeline execution with caching
|
|
1482
|
-
const startMs = performance.now();
|
|
1483
|
-
let pipelineResult;
|
|
1484
|
-
let cacheHit = false;
|
|
1485
|
-
let cacheAgeMs;
|
|
1486
|
-
if (!opts.noCache) {
|
|
1487
|
-
const cacheDir = getCacheDir(opts.baseDir);
|
|
1488
|
-
const cacheKey = await computeCacheKey({
|
|
1489
|
-
input: opts.input,
|
|
1490
|
-
features: opts.features,
|
|
1491
|
-
baseDir: opts.baseDir,
|
|
1492
|
-
mergeConflictStrategy: 'fatal',
|
|
1493
|
-
...(opts.workflowPath !== null ? { workflowPath: opts.workflowPath } : {}),
|
|
1494
|
-
});
|
|
1495
|
-
const cached = await tryLoadCache(cacheKey, cacheDir);
|
|
1496
|
-
if (cached !== undefined) {
|
|
1497
|
-
pipelineResult = cached.result;
|
|
1498
|
-
cacheHit = true;
|
|
1499
|
-
cacheAgeMs = cached.ageMs;
|
|
1500
|
-
}
|
|
1501
|
-
else {
|
|
1502
|
-
pipelineResult = await buildPipeline(opts);
|
|
1503
|
-
void writeCache(pipelineResult, cacheKey, cacheDir);
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1506
|
-
else {
|
|
1507
|
-
pipelineResult = await buildPipeline(opts);
|
|
1508
|
-
}
|
|
1509
|
-
const pipelineMs = Math.round(performance.now() - startMs);
|
|
1510
|
-
const { dataset: masterDataset, validation } = pipelineResult;
|
|
1511
|
-
// Build extended metadata for JSON responses
|
|
1512
|
-
const extra = buildQueryMetadataExtra(validation, cacheHit, cacheAgeMs, pipelineMs);
|
|
1513
|
-
// Create ProcessStateAPI
|
|
1514
|
-
const api = createProcessStateAPI(masterDataset);
|
|
1515
|
-
// Route and execute subcommand
|
|
1516
|
-
const result = await routeSubcommand({
|
|
1517
|
-
api,
|
|
1518
|
-
dataset: masterDataset,
|
|
1519
|
-
validation,
|
|
1520
|
-
subcommand: opts.subcommand,
|
|
1521
|
-
subArgs: opts.subArgs,
|
|
1522
|
-
modifiers: opts.modifiers,
|
|
1523
|
-
sessionType: opts.sessionType,
|
|
1524
|
-
baseDir: path.resolve(opts.baseDir),
|
|
1525
|
-
cliConfig: { input: opts.input, features: opts.features, baseDir: opts.baseDir },
|
|
1526
|
-
registry: masterDataset.tagRegistry,
|
|
1527
|
-
});
|
|
1528
|
-
// Dual output path (ADR-008):
|
|
1529
|
-
// Text commands (context, files, dep-tree, overview) return string → output directly.
|
|
1530
|
-
// JSON commands return objects → wrap in QueryResult envelope.
|
|
1531
|
-
if (typeof result === 'string') {
|
|
1532
|
-
console.log(result);
|
|
1533
|
-
}
|
|
1534
|
-
else {
|
|
1535
|
-
const envelope = createSuccess(result, masterDataset.counts.total, extra);
|
|
1536
|
-
const output = formatOutput(envelope, opts.format);
|
|
1537
|
-
console.log(output);
|
|
1538
|
-
}
|
|
1539
|
-
}
|
|
1540
|
-
void main().catch((error) => {
|
|
1541
|
-
// QueryApiError -> structured error envelope
|
|
1542
|
-
if (error instanceof QueryApiError) {
|
|
1543
|
-
const envelope = createError(error.code, error.message);
|
|
1544
|
-
console.log(JSON.stringify(envelope, null, 2));
|
|
1545
|
-
process.exit(1);
|
|
1546
|
-
return;
|
|
1547
|
-
}
|
|
1548
|
-
handleCliError(error, 1);
|
|
1549
|
-
});
|
|
1550
|
-
//# sourceMappingURL=process-api.js.map
|