@sdd-method/sdd-cli 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +17 -0
- package/README.md +151 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/bundle.d.ts +20 -0
- package/dist/lib/bundle.d.ts.map +1 -0
- package/dist/lib/bundle.js +75 -0
- package/dist/lib/bundle.js.map +1 -0
- package/dist/lib/generate-claude-md/index.d.ts +16 -0
- package/dist/lib/generate-claude-md/index.d.ts.map +1 -0
- package/dist/lib/generate-claude-md/index.js +89 -0
- package/dist/lib/generate-claude-md/index.js.map +1 -0
- package/dist/lib/hooks-seed/entries.d.ts +16 -0
- package/dist/lib/hooks-seed/entries.d.ts.map +1 -0
- package/dist/lib/hooks-seed/entries.js +47 -0
- package/dist/lib/hooks-seed/entries.js.map +1 -0
- package/dist/lib/hooks-seed/index.d.ts +17 -0
- package/dist/lib/hooks-seed/index.d.ts.map +1 -0
- package/dist/lib/hooks-seed/index.js +15 -0
- package/dist/lib/hooks-seed/index.js.map +1 -0
- package/dist/lib/hooks-seed/merge.d.ts +24 -0
- package/dist/lib/hooks-seed/merge.d.ts.map +1 -0
- package/dist/lib/hooks-seed/merge.js +73 -0
- package/dist/lib/hooks-seed/merge.js.map +1 -0
- package/dist/lib/hooks-seed/types.d.ts +27 -0
- package/dist/lib/hooks-seed/types.d.ts.map +1 -0
- package/dist/lib/hooks-seed/types.js +20 -0
- package/dist/lib/hooks-seed/types.js.map +1 -0
- package/dist/lib/init/app.d.ts +21 -0
- package/dist/lib/init/app.d.ts.map +1 -0
- package/dist/lib/init/app.js +132 -0
- package/dist/lib/init/app.js.map +1 -0
- package/dist/lib/init/ci-workflow.d.ts +29 -0
- package/dist/lib/init/ci-workflow.d.ts.map +1 -0
- package/dist/lib/init/ci-workflow.js +78 -0
- package/dist/lib/init/ci-workflow.js.map +1 -0
- package/dist/lib/init/claude-md.d.ts +19 -0
- package/dist/lib/init/claude-md.d.ts.map +1 -0
- package/dist/lib/init/claude-md.js +140 -0
- package/dist/lib/init/claude-md.js.map +1 -0
- package/dist/lib/init/index.d.ts +33 -0
- package/dist/lib/init/index.d.ts.map +1 -0
- package/dist/lib/init/index.js +232 -0
- package/dist/lib/init/index.js.map +1 -0
- package/dist/lib/init/integration.d.ts +53 -0
- package/dist/lib/init/integration.d.ts.map +1 -0
- package/dist/lib/init/integration.js +237 -0
- package/dist/lib/init/integration.js.map +1 -0
- package/dist/lib/init/platform.d.ts +26 -0
- package/dist/lib/init/platform.d.ts.map +1 -0
- package/dist/lib/init/platform.js +188 -0
- package/dist/lib/init/platform.js.map +1 -0
- package/dist/lib/list/discover.d.ts +8 -0
- package/dist/lib/list/discover.d.ts.map +1 -0
- package/dist/lib/list/discover.js +77 -0
- package/dist/lib/list/discover.js.map +1 -0
- package/dist/lib/list/format.d.ts +9 -0
- package/dist/lib/list/format.d.ts.map +1 -0
- package/dist/lib/list/format.js +44 -0
- package/dist/lib/list/format.js.map +1 -0
- package/dist/lib/list/index.d.ts +12 -0
- package/dist/lib/list/index.d.ts.map +1 -0
- package/dist/lib/list/index.js +15 -0
- package/dist/lib/list/index.js.map +1 -0
- package/dist/lib/lock-file.d.ts +14 -0
- package/dist/lib/lock-file.d.ts.map +1 -0
- package/dist/lib/lock-file.js +80 -0
- package/dist/lib/lock-file.js.map +1 -0
- package/dist/lib/mcp/build-info.d.ts +9 -0
- package/dist/lib/mcp/build-info.d.ts.map +1 -0
- package/dist/lib/mcp/build-info.js +10 -0
- package/dist/lib/mcp/build-info.js.map +1 -0
- package/dist/lib/mcp/errors.d.ts +23 -0
- package/dist/lib/mcp/errors.d.ts.map +1 -0
- package/dist/lib/mcp/errors.js +25 -0
- package/dist/lib/mcp/errors.js.map +1 -0
- package/dist/lib/mcp/parse/frontmatter.d.ts +22 -0
- package/dist/lib/mcp/parse/frontmatter.d.ts.map +1 -0
- package/dist/lib/mcp/parse/frontmatter.js +49 -0
- package/dist/lib/mcp/parse/frontmatter.js.map +1 -0
- package/dist/lib/mcp/parse/gate-registry.d.ts +19 -0
- package/dist/lib/mcp/parse/gate-registry.d.ts.map +1 -0
- package/dist/lib/mcp/parse/gate-registry.js +68 -0
- package/dist/lib/mcp/parse/gate-registry.js.map +1 -0
- package/dist/lib/mcp/parse/paths.d.ts +21 -0
- package/dist/lib/mcp/parse/paths.d.ts.map +1 -0
- package/dist/lib/mcp/parse/paths.js +83 -0
- package/dist/lib/mcp/parse/paths.js.map +1 -0
- package/dist/lib/mcp/pin/errors.d.ts +11 -0
- package/dist/lib/mcp/pin/errors.d.ts.map +1 -0
- package/dist/lib/mcp/pin/errors.js +32 -0
- package/dist/lib/mcp/pin/errors.js.map +1 -0
- package/dist/lib/mcp/pin/index.d.ts +18 -0
- package/dist/lib/mcp/pin/index.d.ts.map +1 -0
- package/dist/lib/mcp/pin/index.js +29 -0
- package/dist/lib/mcp/pin/index.js.map +1 -0
- package/dist/lib/mcp/pin/read.d.ts +24 -0
- package/dist/lib/mcp/pin/read.d.ts.map +1 -0
- package/dist/lib/mcp/pin/read.js +64 -0
- package/dist/lib/mcp/pin/read.js.map +1 -0
- package/dist/lib/mcp/pin/resolve.d.ts +12 -0
- package/dist/lib/mcp/pin/resolve.d.ts.map +1 -0
- package/dist/lib/mcp/pin/resolve.js +33 -0
- package/dist/lib/mcp/pin/resolve.js.map +1 -0
- package/dist/lib/mcp/prompts/evaluate-cascade.d.ts +14 -0
- package/dist/lib/mcp/prompts/evaluate-cascade.d.ts.map +1 -0
- package/dist/lib/mcp/prompts/evaluate-cascade.js +147 -0
- package/dist/lib/mcp/prompts/evaluate-cascade.js.map +1 -0
- package/dist/lib/mcp/prompts/index.d.ts +9 -0
- package/dist/lib/mcp/prompts/index.d.ts.map +1 -0
- package/dist/lib/mcp/prompts/index.js +23 -0
- package/dist/lib/mcp/prompts/index.js.map +1 -0
- package/dist/lib/mcp/prompts/propose-adr.d.ts +12 -0
- package/dist/lib/mcp/prompts/propose-adr.d.ts.map +1 -0
- package/dist/lib/mcp/prompts/propose-adr.js +94 -0
- package/dist/lib/mcp/prompts/propose-adr.js.map +1 -0
- package/dist/lib/mcp/prompts/review-data-model-change.d.ts +10 -0
- package/dist/lib/mcp/prompts/review-data-model-change.d.ts.map +1 -0
- package/dist/lib/mcp/prompts/review-data-model-change.js +134 -0
- package/dist/lib/mcp/prompts/review-data-model-change.js.map +1 -0
- package/dist/lib/mcp/prompts/template-loader.d.ts +29 -0
- package/dist/lib/mcp/prompts/template-loader.d.ts.map +1 -0
- package/dist/lib/mcp/prompts/template-loader.js +44 -0
- package/dist/lib/mcp/prompts/template-loader.js.map +1 -0
- package/dist/lib/mcp/prompts/types.d.ts +17 -0
- package/dist/lib/mcp/prompts/types.d.ts.map +1 -0
- package/dist/lib/mcp/prompts/types.js +10 -0
- package/dist/lib/mcp/prompts/types.js.map +1 -0
- package/dist/lib/mcp/prompts/write-capability-spec.d.ts +8 -0
- package/dist/lib/mcp/prompts/write-capability-spec.d.ts.map +1 -0
- package/dist/lib/mcp/prompts/write-capability-spec.js +85 -0
- package/dist/lib/mcp/prompts/write-capability-spec.js.map +1 -0
- package/dist/lib/mcp/prompts/write-feature-spec.d.ts +10 -0
- package/dist/lib/mcp/prompts/write-feature-spec.d.ts.map +1 -0
- package/dist/lib/mcp/prompts/write-feature-spec.js +94 -0
- package/dist/lib/mcp/prompts/write-feature-spec.js.map +1 -0
- package/dist/lib/mcp/prompts/write-work-order.d.ts +7 -0
- package/dist/lib/mcp/prompts/write-work-order.d.ts.map +1 -0
- package/dist/lib/mcp/prompts/write-work-order.js +69 -0
- package/dist/lib/mcp/prompts/write-work-order.js.map +1 -0
- package/dist/lib/mcp/reader.d.ts +37 -0
- package/dist/lib/mcp/reader.d.ts.map +1 -0
- package/dist/lib/mcp/reader.js +93 -0
- package/dist/lib/mcp/reader.js.map +1 -0
- package/dist/lib/mcp/resources/adrs.d.ts +3 -0
- package/dist/lib/mcp/resources/adrs.d.ts.map +1 -0
- package/dist/lib/mcp/resources/adrs.js +97 -0
- package/dist/lib/mcp/resources/adrs.js.map +1 -0
- package/dist/lib/mcp/resources/data-models.d.ts +14 -0
- package/dist/lib/mcp/resources/data-models.d.ts.map +1 -0
- package/dist/lib/mcp/resources/data-models.js +81 -0
- package/dist/lib/mcp/resources/data-models.js.map +1 -0
- package/dist/lib/mcp/resources/gates.d.ts +9 -0
- package/dist/lib/mcp/resources/gates.d.ts.map +1 -0
- package/dist/lib/mcp/resources/gates.js +90 -0
- package/dist/lib/mcp/resources/gates.js.map +1 -0
- package/dist/lib/mcp/resources/glossary.d.ts +16 -0
- package/dist/lib/mcp/resources/glossary.d.ts.map +1 -0
- package/dist/lib/mcp/resources/glossary.js +87 -0
- package/dist/lib/mcp/resources/glossary.js.map +1 -0
- package/dist/lib/mcp/resources/specs.d.ts +23 -0
- package/dist/lib/mcp/resources/specs.d.ts.map +1 -0
- package/dist/lib/mcp/resources/specs.js +151 -0
- package/dist/lib/mcp/resources/specs.js.map +1 -0
- package/dist/lib/mcp/resources/version.d.ts +3 -0
- package/dist/lib/mcp/resources/version.d.ts.map +1 -0
- package/dist/lib/mcp/resources/version.js +45 -0
- package/dist/lib/mcp/resources/version.js.map +1 -0
- package/dist/lib/mcp/server.d.ts +29 -0
- package/dist/lib/mcp/server.d.ts.map +1 -0
- package/dist/lib/mcp/server.js +104 -0
- package/dist/lib/mcp/server.js.map +1 -0
- package/dist/lib/mcp/tools/cascade-impact.d.ts +22 -0
- package/dist/lib/mcp/tools/cascade-impact.d.ts.map +1 -0
- package/dist/lib/mcp/tools/cascade-impact.js +53 -0
- package/dist/lib/mcp/tools/cascade-impact.js.map +1 -0
- package/dist/lib/mcp/tools/find-consumers-of-contract.d.ts +7 -0
- package/dist/lib/mcp/tools/find-consumers-of-contract.d.ts.map +1 -0
- package/dist/lib/mcp/tools/find-consumers-of-contract.js +70 -0
- package/dist/lib/mcp/tools/find-consumers-of-contract.js.map +1 -0
- package/dist/lib/mcp/tools/find-consumers.d.ts +7 -0
- package/dist/lib/mcp/tools/find-consumers.d.ts.map +1 -0
- package/dist/lib/mcp/tools/find-consumers.js +52 -0
- package/dist/lib/mcp/tools/find-consumers.js.map +1 -0
- package/dist/lib/mcp/tools/find-dependencies.d.ts +8 -0
- package/dist/lib/mcp/tools/find-dependencies.d.ts.map +1 -0
- package/dist/lib/mcp/tools/find-dependencies.js +89 -0
- package/dist/lib/mcp/tools/find-dependencies.js.map +1 -0
- package/dist/lib/mcp/tools/find-dependents.d.ts +8 -0
- package/dist/lib/mcp/tools/find-dependents.d.ts.map +1 -0
- package/dist/lib/mcp/tools/find-dependents.js +89 -0
- package/dist/lib/mcp/tools/find-dependents.js.map +1 -0
- package/dist/lib/mcp/tools/find-producers.d.ts +8 -0
- package/dist/lib/mcp/tools/find-producers.d.ts.map +1 -0
- package/dist/lib/mcp/tools/find-producers.js +57 -0
- package/dist/lib/mcp/tools/find-producers.js.map +1 -0
- package/dist/lib/mcp/tools/find-related-specs.d.ts +9 -0
- package/dist/lib/mcp/tools/find-related-specs.d.ts.map +1 -0
- package/dist/lib/mcp/tools/find-related-specs.js +92 -0
- package/dist/lib/mcp/tools/find-related-specs.js.map +1 -0
- package/dist/lib/mcp/tools/list-adrs.d.ts +3 -0
- package/dist/lib/mcp/tools/list-adrs.d.ts.map +1 -0
- package/dist/lib/mcp/tools/list-adrs.js +73 -0
- package/dist/lib/mcp/tools/list-adrs.js.map +1 -0
- package/dist/lib/mcp/tools/query-gate-status.d.ts +3 -0
- package/dist/lib/mcp/tools/query-gate-status.d.ts.map +1 -0
- package/dist/lib/mcp/tools/query-gate-status.js +82 -0
- package/dist/lib/mcp/tools/query-gate-status.js.map +1 -0
- package/dist/lib/mcp/tools/search-specs.d.ts +12 -0
- package/dist/lib/mcp/tools/search-specs.d.ts.map +1 -0
- package/dist/lib/mcp/tools/search-specs.js +151 -0
- package/dist/lib/mcp/tools/search-specs.js.map +1 -0
- package/dist/lib/mcp/workspace.d.ts +25 -0
- package/dist/lib/mcp/workspace.d.ts.map +1 -0
- package/dist/lib/mcp/workspace.js +129 -0
- package/dist/lib/mcp/workspace.js.map +1 -0
- package/dist/lib/mcp-seed/entries.d.ts +19 -0
- package/dist/lib/mcp-seed/entries.d.ts.map +1 -0
- package/dist/lib/mcp-seed/entries.js +14 -0
- package/dist/lib/mcp-seed/entries.js.map +1 -0
- package/dist/lib/mcp-seed/index.d.ts +36 -0
- package/dist/lib/mcp-seed/index.d.ts.map +1 -0
- package/dist/lib/mcp-seed/index.js +28 -0
- package/dist/lib/mcp-seed/index.js.map +1 -0
- package/dist/lib/mcp-seed/merge.d.ts +34 -0
- package/dist/lib/mcp-seed/merge.d.ts.map +1 -0
- package/dist/lib/mcp-seed/merge.js +99 -0
- package/dist/lib/mcp-seed/merge.js.map +1 -0
- package/dist/lib/mcp-seed/types.d.ts +24 -0
- package/dist/lib/mcp-seed/types.d.ts.map +1 -0
- package/dist/lib/mcp-seed/types.js +13 -0
- package/dist/lib/mcp-seed/types.js.map +1 -0
- package/dist/lib/plan/index.d.ts +19 -0
- package/dist/lib/plan/index.d.ts.map +1 -0
- package/dist/lib/plan/index.js +69 -0
- package/dist/lib/plan/index.js.map +1 -0
- package/dist/lib/plan/read-sdd.d.ts +46 -0
- package/dist/lib/plan/read-sdd.d.ts.map +1 -0
- package/dist/lib/plan/read-sdd.js +102 -0
- package/dist/lib/plan/read-sdd.js.map +1 -0
- package/dist/lib/plan/render-template.d.ts +8 -0
- package/dist/lib/plan/render-template.d.ts.map +1 -0
- package/dist/lib/plan/render-template.js +60 -0
- package/dist/lib/plan/render-template.js.map +1 -0
- package/dist/lib/repo-kind.d.ts +20 -0
- package/dist/lib/repo-kind.d.ts.map +1 -0
- package/dist/lib/repo-kind.js +73 -0
- package/dist/lib/repo-kind.js.map +1 -0
- package/dist/lib/scripts.d.ts +2 -0
- package/dist/lib/scripts.d.ts.map +1 -0
- package/dist/lib/scripts.js +7 -0
- package/dist/lib/scripts.js.map +1 -0
- package/dist/lib/sdd-index/cascade.d.ts +46 -0
- package/dist/lib/sdd-index/cascade.d.ts.map +1 -0
- package/dist/lib/sdd-index/cascade.js +91 -0
- package/dist/lib/sdd-index/cascade.js.map +1 -0
- package/dist/lib/sdd-index/contracts.d.ts +29 -0
- package/dist/lib/sdd-index/contracts.d.ts.map +1 -0
- package/dist/lib/sdd-index/contracts.js +216 -0
- package/dist/lib/sdd-index/contracts.js.map +1 -0
- package/dist/lib/sdd-index/data-model.d.ts +13 -0
- package/dist/lib/sdd-index/data-model.d.ts.map +1 -0
- package/dist/lib/sdd-index/data-model.js +23 -0
- package/dist/lib/sdd-index/data-model.js.map +1 -0
- package/dist/lib/sdd-index/execution-map.d.ts +34 -0
- package/dist/lib/sdd-index/execution-map.d.ts.map +1 -0
- package/dist/lib/sdd-index/execution-map.js +105 -0
- package/dist/lib/sdd-index/execution-map.js.map +1 -0
- package/dist/lib/sdd-index/graph.d.ts +28 -0
- package/dist/lib/sdd-index/graph.d.ts.map +1 -0
- package/dist/lib/sdd-index/graph.js +122 -0
- package/dist/lib/sdd-index/graph.js.map +1 -0
- package/dist/lib/sdd-index/index.d.ts +29 -0
- package/dist/lib/sdd-index/index.d.ts.map +1 -0
- package/dist/lib/sdd-index/index.js +79 -0
- package/dist/lib/sdd-index/index.js.map +1 -0
- package/dist/lib/sdd-index/repo-config.d.ts +23 -0
- package/dist/lib/sdd-index/repo-config.d.ts.map +1 -0
- package/dist/lib/sdd-index/repo-config.js +150 -0
- package/dist/lib/sdd-index/repo-config.js.map +1 -0
- package/dist/lib/sdd-index/types.d.ts +106 -0
- package/dist/lib/sdd-index/types.d.ts.map +1 -0
- package/dist/lib/sdd-index/types.js +13 -0
- package/dist/lib/sdd-index/types.js.map +1 -0
- package/dist/lib/sdd-index/watch.d.ts +24 -0
- package/dist/lib/sdd-index/watch.d.ts.map +1 -0
- package/dist/lib/sdd-index/watch.js +112 -0
- package/dist/lib/sdd-index/watch.js.map +1 -0
- package/dist/lib/spawn.d.ts +8 -0
- package/dist/lib/spawn.d.ts.map +1 -0
- package/dist/lib/spawn.js +16 -0
- package/dist/lib/spawn.js.map +1 -0
- package/dist/lib/sync/apply.d.ts +3 -0
- package/dist/lib/sync/apply.d.ts.map +1 -0
- package/dist/lib/sync/apply.js +16 -0
- package/dist/lib/sync/apply.js.map +1 -0
- package/dist/lib/sync/diff.d.ts +8 -0
- package/dist/lib/sync/diff.d.ts.map +1 -0
- package/dist/lib/sync/diff.js +48 -0
- package/dist/lib/sync/diff.js.map +1 -0
- package/dist/lib/sync/index.d.ts +17 -0
- package/dist/lib/sync/index.d.ts.map +1 -0
- package/dist/lib/sync/index.js +184 -0
- package/dist/lib/sync/index.js.map +1 -0
- package/dist/lib/sync/settings-merge.d.ts +45 -0
- package/dist/lib/sync/settings-merge.d.ts.map +1 -0
- package/dist/lib/sync/settings-merge.js +109 -0
- package/dist/lib/sync/settings-merge.js.map +1 -0
- package/dist/lib/sync/source-tag.d.ts +5 -0
- package/dist/lib/sync/source-tag.d.ts.map +1 -0
- package/dist/lib/sync/source-tag.js +34 -0
- package/dist/lib/sync/source-tag.js.map +1 -0
- package/dist/lib/sync/yaml-block-merge.d.ts +50 -0
- package/dist/lib/sync/yaml-block-merge.d.ts.map +1 -0
- package/dist/lib/sync/yaml-block-merge.js +113 -0
- package/dist/lib/sync/yaml-block-merge.js.map +1 -0
- package/dist/lib/validate/aggregate.d.ts +13 -0
- package/dist/lib/validate/aggregate.d.ts.map +1 -0
- package/dist/lib/validate/aggregate.js +35 -0
- package/dist/lib/validate/aggregate.js.map +1 -0
- package/dist/lib/validate/dispatch.d.ts +34 -0
- package/dist/lib/validate/dispatch.d.ts.map +1 -0
- package/dist/lib/validate/dispatch.js +167 -0
- package/dist/lib/validate/dispatch.js.map +1 -0
- package/dist/lib/validate/index.d.ts +13 -0
- package/dist/lib/validate/index.d.ts.map +1 -0
- package/dist/lib/validate/index.js +69 -0
- package/dist/lib/validate/index.js.map +1 -0
- package/dist/lib/validate/runner.d.ts +16 -0
- package/dist/lib/validate/runner.d.ts.map +1 -0
- package/dist/lib/validate/runner.js +66 -0
- package/dist/lib/validate/runner.js.map +1 -0
- package/dist/verbs/generate-claude-md.d.ts +3 -0
- package/dist/verbs/generate-claude-md.d.ts.map +1 -0
- package/dist/verbs/generate-claude-md.js +36 -0
- package/dist/verbs/generate-claude-md.js.map +1 -0
- package/dist/verbs/init.d.ts +3 -0
- package/dist/verbs/init.d.ts.map +1 -0
- package/dist/verbs/init.js +90 -0
- package/dist/verbs/init.js.map +1 -0
- package/dist/verbs/list.d.ts +3 -0
- package/dist/verbs/list.d.ts.map +1 -0
- package/dist/verbs/list.js +43 -0
- package/dist/verbs/list.js.map +1 -0
- package/dist/verbs/mcp.d.ts +3 -0
- package/dist/verbs/mcp.d.ts.map +1 -0
- package/dist/verbs/mcp.js +22 -0
- package/dist/verbs/mcp.js.map +1 -0
- package/dist/verbs/plan.d.ts +3 -0
- package/dist/verbs/plan.d.ts.map +1 -0
- package/dist/verbs/plan.js +41 -0
- package/dist/verbs/plan.js.map +1 -0
- package/dist/verbs/sync.d.ts +3 -0
- package/dist/verbs/sync.d.ts.map +1 -0
- package/dist/verbs/sync.js +27 -0
- package/dist/verbs/sync.js.map +1 -0
- package/dist/verbs/validate.d.ts +3 -0
- package/dist/verbs/validate.d.ts.map +1 -0
- package/dist/verbs/validate.js +21 -0
- package/dist/verbs/validate.js.map +1 -0
- package/package.json +61 -0
- package/scripts/README.md +48 -0
- package/scripts/sync-method-baseline.sh +258 -0
- package/scripts/validate-app-dependencies.sh +289 -0
- package/scripts/validate-app-docs.sh +185 -0
- package/scripts/validate-integration-docs.sh +222 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract producer metadata from contract artefacts.
|
|
3
|
+
*
|
|
4
|
+
* Each adopter uses different conventions inside the raw artefact
|
|
5
|
+
* format (OpenAPI `x-*` extensions, proto options, Avro doc fields,
|
|
6
|
+
* SpiceDB comments). We try a few best-effort patterns and fall back
|
|
7
|
+
* to marking the node as metadata-incomplete — it's better to return
|
|
8
|
+
* a partial graph than to fail hard.
|
|
9
|
+
*
|
|
10
|
+
* The shape we care about:
|
|
11
|
+
* - `producedAggregates` — aggregate names this contract describes
|
|
12
|
+
* - `producedEvents` — event names this contract publishes
|
|
13
|
+
*
|
|
14
|
+
* Producer / consumer *service* linkage is derived later in graph.ts
|
|
15
|
+
* from repo-config declarations, not from the artefact itself.
|
|
16
|
+
*/
|
|
17
|
+
import { parse as parseYaml } from "yaml";
|
|
18
|
+
/**
|
|
19
|
+
* Parse a single contract artefact and return its producer metadata.
|
|
20
|
+
* `relPath` is relative to the SDD root.
|
|
21
|
+
*/
|
|
22
|
+
export function readContract(reader, relPath, kind) {
|
|
23
|
+
const raw = reader.readFile(relPath);
|
|
24
|
+
if (raw === null) {
|
|
25
|
+
return {
|
|
26
|
+
path: relPath,
|
|
27
|
+
kind,
|
|
28
|
+
producedAggregates: [],
|
|
29
|
+
producedEvents: [],
|
|
30
|
+
producers: [],
|
|
31
|
+
consumers: [],
|
|
32
|
+
metadataIncomplete: true,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const result = parseByKind(raw, kind);
|
|
36
|
+
return {
|
|
37
|
+
path: relPath,
|
|
38
|
+
kind,
|
|
39
|
+
producedAggregates: result.aggregates,
|
|
40
|
+
producedEvents: result.events,
|
|
41
|
+
producers: [],
|
|
42
|
+
consumers: [],
|
|
43
|
+
metadataIncomplete: result.metadataIncomplete,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function parseByKind(raw, kind) {
|
|
47
|
+
switch (kind) {
|
|
48
|
+
case "openapi":
|
|
49
|
+
return parseOpenApi(raw);
|
|
50
|
+
case "avro":
|
|
51
|
+
return parseAvro(raw);
|
|
52
|
+
case "proto":
|
|
53
|
+
return parseProto(raw);
|
|
54
|
+
case "spicedb":
|
|
55
|
+
return parseSpiceDb(raw);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* OpenAPI producer metadata via `x-sdd-aggregate` / `x-sdd-events`
|
|
60
|
+
* extensions at the document root. Falls back to deriving aggregates
|
|
61
|
+
* from the `tags` field.
|
|
62
|
+
*/
|
|
63
|
+
function parseOpenApi(raw) {
|
|
64
|
+
let doc;
|
|
65
|
+
try {
|
|
66
|
+
doc = parseYaml(raw);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return { aggregates: [], events: [], metadataIncomplete: true };
|
|
70
|
+
}
|
|
71
|
+
if (!doc || typeof doc !== "object" || Array.isArray(doc)) {
|
|
72
|
+
return { aggregates: [], events: [], metadataIncomplete: true };
|
|
73
|
+
}
|
|
74
|
+
const record = doc;
|
|
75
|
+
const aggregates = stringArray(record["x-sdd-aggregate"])
|
|
76
|
+
.concat(stringArray(record["x-sdd-aggregates"]));
|
|
77
|
+
const events = stringArray(record["x-sdd-events"]);
|
|
78
|
+
if (aggregates.length === 0 && events.length === 0) {
|
|
79
|
+
// Fallback: extract from `tags[].name`
|
|
80
|
+
const tags = record["tags"];
|
|
81
|
+
if (Array.isArray(tags)) {
|
|
82
|
+
for (const t of tags) {
|
|
83
|
+
if (t && typeof t === "object" && !Array.isArray(t)) {
|
|
84
|
+
const name = t["name"];
|
|
85
|
+
if (typeof name === "string")
|
|
86
|
+
aggregates.push(name);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
aggregates: dedupe(aggregates),
|
|
93
|
+
events: dedupe(events),
|
|
94
|
+
metadataIncomplete: aggregates.length === 0 && events.length === 0,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Avro: treat top-level record names as events (by convention, event
|
|
99
|
+
* schemas are single-record files named after the event). Namespace is
|
|
100
|
+
* captured as the aggregate grouping.
|
|
101
|
+
*/
|
|
102
|
+
function parseAvro(raw) {
|
|
103
|
+
let doc;
|
|
104
|
+
try {
|
|
105
|
+
doc = JSON.parse(raw);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return { aggregates: [], events: [], metadataIncomplete: true };
|
|
109
|
+
}
|
|
110
|
+
const records = [];
|
|
111
|
+
if (doc && typeof doc === "object") {
|
|
112
|
+
if (Array.isArray(doc)) {
|
|
113
|
+
for (const d of doc) {
|
|
114
|
+
if (d && typeof d === "object" && !Array.isArray(d)) {
|
|
115
|
+
records.push(d);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
records.push(doc);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const aggregates = [];
|
|
124
|
+
const events = [];
|
|
125
|
+
for (const r of records) {
|
|
126
|
+
if (r["type"] === "record") {
|
|
127
|
+
const name = r["name"];
|
|
128
|
+
if (typeof name === "string")
|
|
129
|
+
events.push(name);
|
|
130
|
+
const ns = r["namespace"];
|
|
131
|
+
if (typeof ns === "string")
|
|
132
|
+
aggregates.push(ns);
|
|
133
|
+
// x-extensions at record level
|
|
134
|
+
aggregates.push(...stringArray(r["x-sdd-aggregate"]));
|
|
135
|
+
events.push(...stringArray(r["x-sdd-events"]));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
aggregates: dedupe(aggregates),
|
|
140
|
+
events: dedupe(events),
|
|
141
|
+
metadataIncomplete: records.length === 0,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Proto: extract `service` / `message` names via regex. Proper
|
|
146
|
+
* proto parsing is overkill for metadata extraction; this matches the
|
|
147
|
+
* typical convention where the aggregate name is embedded in the
|
|
148
|
+
* service name (e.g. `PartyService`).
|
|
149
|
+
*/
|
|
150
|
+
function parseProto(raw) {
|
|
151
|
+
const aggregates = [];
|
|
152
|
+
const events = [];
|
|
153
|
+
const lines = raw.split("\n");
|
|
154
|
+
const serviceRe = /^\s*service\s+(\w+)/;
|
|
155
|
+
const messageRe = /^\s*message\s+(\w+)/;
|
|
156
|
+
const aggregateCommentRe = /\/\/\s*sdd:aggregate\s+(\w+)/i;
|
|
157
|
+
const eventCommentRe = /\/\/\s*sdd:event\s+(\w+)/i;
|
|
158
|
+
let matchedAny = false;
|
|
159
|
+
for (const line of lines) {
|
|
160
|
+
const svc = line.match(serviceRe);
|
|
161
|
+
if (svc && svc[1]) {
|
|
162
|
+
aggregates.push(svc[1]);
|
|
163
|
+
matchedAny = true;
|
|
164
|
+
}
|
|
165
|
+
const msg = line.match(messageRe);
|
|
166
|
+
if (msg && msg[1]) {
|
|
167
|
+
events.push(msg[1]);
|
|
168
|
+
matchedAny = true;
|
|
169
|
+
}
|
|
170
|
+
const aggC = line.match(aggregateCommentRe);
|
|
171
|
+
if (aggC && aggC[1]) {
|
|
172
|
+
aggregates.push(aggC[1]);
|
|
173
|
+
matchedAny = true;
|
|
174
|
+
}
|
|
175
|
+
const evC = line.match(eventCommentRe);
|
|
176
|
+
if (evC && evC[1]) {
|
|
177
|
+
events.push(evC[1]);
|
|
178
|
+
matchedAny = true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
aggregates: dedupe(aggregates),
|
|
183
|
+
events: dedupe(events),
|
|
184
|
+
metadataIncomplete: !matchedAny,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* SpiceDB schemas declare `definition` blocks; each definition is an
|
|
189
|
+
* aggregate. This is a coarse match — enough for dependency-graph
|
|
190
|
+
* reasoning.
|
|
191
|
+
*/
|
|
192
|
+
function parseSpiceDb(raw) {
|
|
193
|
+
const aggregates = [];
|
|
194
|
+
const defRe = /^\s*definition\s+([\w/]+)/gm;
|
|
195
|
+
let m;
|
|
196
|
+
while ((m = defRe.exec(raw)) !== null) {
|
|
197
|
+
if (m[1])
|
|
198
|
+
aggregates.push(m[1]);
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
aggregates: dedupe(aggregates),
|
|
202
|
+
events: [],
|
|
203
|
+
metadataIncomplete: aggregates.length === 0,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function stringArray(v) {
|
|
207
|
+
if (typeof v === "string")
|
|
208
|
+
return [v];
|
|
209
|
+
if (!Array.isArray(v))
|
|
210
|
+
return [];
|
|
211
|
+
return v.filter((x) => typeof x === "string");
|
|
212
|
+
}
|
|
213
|
+
function dedupe(xs) {
|
|
214
|
+
return Array.from(new Set(xs));
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/lib/sdd-index/contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract entity names from a mermaid data-model file. Mirrors the
|
|
3
|
+
* awk pattern in `orchestration/scripts/validate-cascade-completeness.sh`
|
|
4
|
+
* line 313: treat any top-level `<Identifier> {` block as an entity
|
|
5
|
+
* declaration.
|
|
6
|
+
*
|
|
7
|
+
* Output is deduplicated and sorted for deterministic downstream use.
|
|
8
|
+
* Malformed or non-mermaid input returns an empty list — callers
|
|
9
|
+
* surface a warning via `metadata_incomplete` on the returned
|
|
10
|
+
* message.
|
|
11
|
+
*/
|
|
12
|
+
export declare function extractEntities(body: string): readonly string[];
|
|
13
|
+
//# sourceMappingURL=data-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-model.d.ts","sourceRoot":"","sources":["../../../src/lib/sdd-index/data-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAQ/D"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract entity names from a mermaid data-model file. Mirrors the
|
|
3
|
+
* awk pattern in `orchestration/scripts/validate-cascade-completeness.sh`
|
|
4
|
+
* line 313: treat any top-level `<Identifier> {` block as an entity
|
|
5
|
+
* declaration.
|
|
6
|
+
*
|
|
7
|
+
* Output is deduplicated and sorted for deterministic downstream use.
|
|
8
|
+
* Malformed or non-mermaid input returns an empty list — callers
|
|
9
|
+
* surface a warning via `metadata_incomplete` on the returned
|
|
10
|
+
* message.
|
|
11
|
+
*/
|
|
12
|
+
const ENTITY_RE = /^\s*([A-Za-z][A-Za-z0-9_]+)\s*\{\s*$/gm;
|
|
13
|
+
export function extractEntities(body) {
|
|
14
|
+
const seen = new Set();
|
|
15
|
+
let m;
|
|
16
|
+
ENTITY_RE.lastIndex = 0;
|
|
17
|
+
while ((m = ENTITY_RE.exec(body)) !== null) {
|
|
18
|
+
if (m[1])
|
|
19
|
+
seen.add(m[1]);
|
|
20
|
+
}
|
|
21
|
+
return Array.from(seen).sort();
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=data-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-model.js","sourceRoot":"","sources":["../../../src/lib/sdd-index/data-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,SAAS,GAAG,wCAAwC,CAAC;AAE3D,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,CAAyB,CAAC;IAC9B,SAAS,CAAC,SAAS,GAAG,CAAC,CAAC;IACxB,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse docs/platform/execution-dependency-map.md if present.
|
|
3
|
+
*
|
|
4
|
+
* The map is an adopter-owned narrative artefact (ADR 0074 §4.3). The
|
|
5
|
+
* scope doc explicitly marks it as a narrative overlay — repo-config
|
|
6
|
+
* wins if they disagree. We extract any unambiguous edges we can find
|
|
7
|
+
* and ignore the rest; on parse failure we return an empty list plus
|
|
8
|
+
* a warning.
|
|
9
|
+
*
|
|
10
|
+
* Expected pattern (by convention; adopters vary):
|
|
11
|
+
*
|
|
12
|
+
* - consumer-service --build-start--> producer-service
|
|
13
|
+
* - consumer-service --go-live--> producer-service
|
|
14
|
+
* - consumer-service --migration-dependency--> producer-service
|
|
15
|
+
*
|
|
16
|
+
* Plus YAML-fenced blocks of the form:
|
|
17
|
+
*
|
|
18
|
+
* ```yaml
|
|
19
|
+
* edges:
|
|
20
|
+
* - from: consumer-service
|
|
21
|
+
* to: producer-service
|
|
22
|
+
* kind: go-live
|
|
23
|
+
* note: "..."
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import type { SddReader } from "../mcp/reader.js";
|
|
27
|
+
import type { ExecutionEdge } from "./types.js";
|
|
28
|
+
export declare const EXECUTION_MAP_PATH = "docs/platform/execution-dependency-map.md";
|
|
29
|
+
export interface ExecutionMapResult {
|
|
30
|
+
readonly edges: readonly ExecutionEdge[];
|
|
31
|
+
readonly warnings: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
export declare function readExecutionMap(reader: SddReader): ExecutionMapResult;
|
|
34
|
+
//# sourceMappingURL=execution-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-map.d.ts","sourceRoot":"","sources":["../../../src/lib/sdd-index/execution-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAkB,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhE,eAAO,MAAM,kBAAkB,8CACc,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAWD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,kBAAkB,CAwEtE"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse docs/platform/execution-dependency-map.md if present.
|
|
3
|
+
*
|
|
4
|
+
* The map is an adopter-owned narrative artefact (ADR 0074 §4.3). The
|
|
5
|
+
* scope doc explicitly marks it as a narrative overlay — repo-config
|
|
6
|
+
* wins if they disagree. We extract any unambiguous edges we can find
|
|
7
|
+
* and ignore the rest; on parse failure we return an empty list plus
|
|
8
|
+
* a warning.
|
|
9
|
+
*
|
|
10
|
+
* Expected pattern (by convention; adopters vary):
|
|
11
|
+
*
|
|
12
|
+
* - consumer-service --build-start--> producer-service
|
|
13
|
+
* - consumer-service --go-live--> producer-service
|
|
14
|
+
* - consumer-service --migration-dependency--> producer-service
|
|
15
|
+
*
|
|
16
|
+
* Plus YAML-fenced blocks of the form:
|
|
17
|
+
*
|
|
18
|
+
* ```yaml
|
|
19
|
+
* edges:
|
|
20
|
+
* - from: consumer-service
|
|
21
|
+
* to: producer-service
|
|
22
|
+
* kind: go-live
|
|
23
|
+
* note: "..."
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import { parse as parseYaml } from "yaml";
|
|
27
|
+
export const EXECUTION_MAP_PATH = "docs/platform/execution-dependency-map.md";
|
|
28
|
+
const VALID_KINDS = new Set([
|
|
29
|
+
"build-start",
|
|
30
|
+
"go-live",
|
|
31
|
+
"migration-dependency",
|
|
32
|
+
]);
|
|
33
|
+
const LINE_EDGE_RE = /^\s*-\s+([\w.-]+)\s+--(build-start|go-live|migration-dependency)-->\s+([\w.-]+)\s*(?:#\s*(.*))?$/i;
|
|
34
|
+
export function readExecutionMap(reader) {
|
|
35
|
+
const raw = reader.readFile(EXECUTION_MAP_PATH);
|
|
36
|
+
if (raw === null)
|
|
37
|
+
return { edges: [], warnings: [] };
|
|
38
|
+
const edges = [];
|
|
39
|
+
const warnings = [];
|
|
40
|
+
// 1) Line-form edges.
|
|
41
|
+
for (const line of raw.split("\n")) {
|
|
42
|
+
const m = line.match(LINE_EDGE_RE);
|
|
43
|
+
if (!m)
|
|
44
|
+
continue;
|
|
45
|
+
const [, from, kindRaw, to, note] = m;
|
|
46
|
+
if (!from || !kindRaw || !to)
|
|
47
|
+
continue;
|
|
48
|
+
const kind = kindRaw.toLowerCase();
|
|
49
|
+
if (!VALID_KINDS.has(kind))
|
|
50
|
+
continue;
|
|
51
|
+
edges.push({
|
|
52
|
+
from,
|
|
53
|
+
to,
|
|
54
|
+
kind,
|
|
55
|
+
...(note ? { note: note.trim() } : {}),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// 2) YAML-fenced `edges:` blocks.
|
|
59
|
+
const yamlBlockRe = /```ya?ml\s*\n([\s\S]*?)\n```/g;
|
|
60
|
+
let block;
|
|
61
|
+
while ((block = yamlBlockRe.exec(raw)) !== null) {
|
|
62
|
+
const body = block[1] ?? "";
|
|
63
|
+
if (!body.includes("edges"))
|
|
64
|
+
continue;
|
|
65
|
+
let doc;
|
|
66
|
+
try {
|
|
67
|
+
doc = parseYaml(body);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
warnings.push(`execution-map: fenced YAML block failed to parse (${err.message})`);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (!doc || typeof doc !== "object" || Array.isArray(doc))
|
|
74
|
+
continue;
|
|
75
|
+
const edgesField = doc["edges"];
|
|
76
|
+
if (!Array.isArray(edgesField))
|
|
77
|
+
continue;
|
|
78
|
+
for (const entry of edgesField) {
|
|
79
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry))
|
|
80
|
+
continue;
|
|
81
|
+
const obj = entry;
|
|
82
|
+
const from = typeof obj["from"] === "string" ? obj["from"] : undefined;
|
|
83
|
+
const to = typeof obj["to"] === "string" ? obj["to"] : undefined;
|
|
84
|
+
const kindRaw = typeof obj["kind"] === "string" ? obj["kind"] : undefined;
|
|
85
|
+
if (!from || !to || !kindRaw) {
|
|
86
|
+
warnings.push(`execution-map: edge is missing from/to/kind (entry: ${JSON.stringify(entry)})`);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const kind = kindRaw;
|
|
90
|
+
if (!VALID_KINDS.has(kind)) {
|
|
91
|
+
warnings.push(`execution-map: edge has unknown kind '${kindRaw}' (valid: build-start, go-live, migration-dependency)`);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const note = typeof obj["note"] === "string" ? obj["note"] : undefined;
|
|
95
|
+
edges.push({
|
|
96
|
+
from,
|
|
97
|
+
to,
|
|
98
|
+
kind,
|
|
99
|
+
...(note ? { note } : {}),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return { edges, warnings };
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=execution-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-map.js","sourceRoot":"","sources":["../../../src/lib/sdd-index/execution-map.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph-builder pass. Consumes already-parsed ServiceNodes + ContractNodes
|
|
3
|
+
* and derives the cross-reference maps that dependency-graph tools query:
|
|
4
|
+
*
|
|
5
|
+
* - producers: aggregate/event → service ids that own it
|
|
6
|
+
* - consumers: aggregate/event → service ids that depend on it
|
|
7
|
+
* - pins: contract path → (service id → version string)
|
|
8
|
+
*
|
|
9
|
+
* Producer linkage from repo-config: a service that declares a contract
|
|
10
|
+
* and owns at least one of its produced aggregates is marked as a
|
|
11
|
+
* producer of that contract. Everyone else who declares the contract
|
|
12
|
+
* is a consumer. This is deliberately asymmetric — adopters tend not
|
|
13
|
+
* to flag producer-vs-consumer explicitly, so ownership of the
|
|
14
|
+
* aggregate is our tiebreaker. When no service owns the aggregates,
|
|
15
|
+
* all declaring services are consumers and no producer is recorded
|
|
16
|
+
* (surfaced via metadataIncomplete on the ContractNode).
|
|
17
|
+
*/
|
|
18
|
+
import type { ContractNode, ExecutionEdge, ServiceNode } from "./types.js";
|
|
19
|
+
export interface GraphBuildResult {
|
|
20
|
+
readonly services: ReadonlyMap<string, ServiceNode>;
|
|
21
|
+
readonly contracts: ReadonlyMap<string, ContractNode>;
|
|
22
|
+
readonly producers: ReadonlyMap<string, readonly string[]>;
|
|
23
|
+
readonly consumers: ReadonlyMap<string, readonly string[]>;
|
|
24
|
+
readonly pins: ReadonlyMap<string, ReadonlyMap<string, string>>;
|
|
25
|
+
readonly warnings: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
export declare function buildGraph(serviceList: readonly ServiceNode[], contractList: readonly ContractNode[], _edges: readonly ExecutionEdge[]): GraphBuildResult;
|
|
28
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/lib/sdd-index/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACtD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IAC3D,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IAC3D,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,wBAAgB,UAAU,CACxB,WAAW,EAAE,SAAS,WAAW,EAAE,EACnC,YAAY,EAAE,SAAS,YAAY,EAAE,EACrC,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,gBAAgB,CAwFlB"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph-builder pass. Consumes already-parsed ServiceNodes + ContractNodes
|
|
3
|
+
* and derives the cross-reference maps that dependency-graph tools query:
|
|
4
|
+
*
|
|
5
|
+
* - producers: aggregate/event → service ids that own it
|
|
6
|
+
* - consumers: aggregate/event → service ids that depend on it
|
|
7
|
+
* - pins: contract path → (service id → version string)
|
|
8
|
+
*
|
|
9
|
+
* Producer linkage from repo-config: a service that declares a contract
|
|
10
|
+
* and owns at least one of its produced aggregates is marked as a
|
|
11
|
+
* producer of that contract. Everyone else who declares the contract
|
|
12
|
+
* is a consumer. This is deliberately asymmetric — adopters tend not
|
|
13
|
+
* to flag producer-vs-consumer explicitly, so ownership of the
|
|
14
|
+
* aggregate is our tiebreaker. When no service owns the aggregates,
|
|
15
|
+
* all declaring services are consumers and no producer is recorded
|
|
16
|
+
* (surfaced via metadataIncomplete on the ContractNode).
|
|
17
|
+
*/
|
|
18
|
+
export function buildGraph(serviceList, contractList, _edges) {
|
|
19
|
+
const services = new Map();
|
|
20
|
+
for (const s of serviceList)
|
|
21
|
+
services.set(s.id, s);
|
|
22
|
+
const contractsByPath = new Map();
|
|
23
|
+
for (const c of contractList)
|
|
24
|
+
contractsByPath.set(c.path, c);
|
|
25
|
+
const producersAcc = new Map();
|
|
26
|
+
const consumersAcc = new Map();
|
|
27
|
+
const pinsAcc = new Map();
|
|
28
|
+
const contractProducers = new Map();
|
|
29
|
+
const contractConsumers = new Map();
|
|
30
|
+
const warnings = [];
|
|
31
|
+
for (const service of serviceList) {
|
|
32
|
+
const ownedAggregates = new Set(service.aggregates);
|
|
33
|
+
for (const ref of service.contracts) {
|
|
34
|
+
const contract = contractsByPath.get(ref.path);
|
|
35
|
+
// Version pin map.
|
|
36
|
+
if (ref.version) {
|
|
37
|
+
let inner = pinsAcc.get(ref.path);
|
|
38
|
+
if (!inner) {
|
|
39
|
+
inner = new Map();
|
|
40
|
+
pinsAcc.set(ref.path, inner);
|
|
41
|
+
}
|
|
42
|
+
inner.set(service.id, ref.version);
|
|
43
|
+
}
|
|
44
|
+
// Producer / consumer classification.
|
|
45
|
+
const producesAny = contract
|
|
46
|
+
? contract.producedAggregates.some((a) => ownedAggregates.has(a))
|
|
47
|
+
: ownedAggregates.size > 0 &&
|
|
48
|
+
service.aggregates.some((a) => ref.path.includes(a));
|
|
49
|
+
if (producesAny) {
|
|
50
|
+
addToSetMap(contractProducers, ref.path, service.id);
|
|
51
|
+
// Also index every produced event/aggregate → this service.
|
|
52
|
+
if (contract) {
|
|
53
|
+
for (const agg of contract.producedAggregates) {
|
|
54
|
+
addToSetMap(producersAcc, agg, service.id);
|
|
55
|
+
}
|
|
56
|
+
for (const ev of contract.producedEvents) {
|
|
57
|
+
addToSetMap(producersAcc, ev, service.id);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (const agg of service.aggregates) {
|
|
61
|
+
addToSetMap(producersAcc, agg, service.id);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
addToSetMap(contractConsumers, ref.path, service.id);
|
|
66
|
+
if (contract) {
|
|
67
|
+
for (const agg of contract.producedAggregates) {
|
|
68
|
+
addToSetMap(consumersAcc, agg, service.id);
|
|
69
|
+
}
|
|
70
|
+
for (const ev of contract.producedEvents) {
|
|
71
|
+
addToSetMap(consumersAcc, ev, service.id);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Rewrite ContractNodes with their resolved producer/consumer lists.
|
|
78
|
+
const contracts = new Map();
|
|
79
|
+
for (const [path, node] of contractsByPath) {
|
|
80
|
+
const producers = Array.from(contractProducers.get(path) ?? []).sort();
|
|
81
|
+
const consumers = Array.from(contractConsumers.get(path) ?? []).sort();
|
|
82
|
+
if (producers.length === 0 && !node.metadataIncomplete) {
|
|
83
|
+
warnings.push(`graph: contract ${path} has consumers but no producer could be identified (aggregates ${JSON.stringify(node.producedAggregates)})`);
|
|
84
|
+
}
|
|
85
|
+
contracts.set(path, {
|
|
86
|
+
...node,
|
|
87
|
+
producers,
|
|
88
|
+
consumers,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
services,
|
|
93
|
+
contracts,
|
|
94
|
+
producers: freezeSetMap(producersAcc),
|
|
95
|
+
consumers: freezeSetMap(consumersAcc),
|
|
96
|
+
pins: freezeInnerMap(pinsAcc),
|
|
97
|
+
warnings,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function addToSetMap(map, key, value) {
|
|
101
|
+
let inner = map.get(key);
|
|
102
|
+
if (!inner) {
|
|
103
|
+
inner = new Set();
|
|
104
|
+
map.set(key, inner);
|
|
105
|
+
}
|
|
106
|
+
inner.add(value);
|
|
107
|
+
}
|
|
108
|
+
function freezeSetMap(map) {
|
|
109
|
+
const out = new Map();
|
|
110
|
+
for (const [k, set] of map) {
|
|
111
|
+
out.set(k, Array.from(set).sort());
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
function freezeInnerMap(map) {
|
|
116
|
+
const out = new Map();
|
|
117
|
+
for (const [k, inner] of map) {
|
|
118
|
+
out.set(k, new Map(inner));
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../src/lib/sdd-index/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public facade for the in-memory SDD index. Consumers call
|
|
3
|
+
* `getSddIndex(reader)` and get a fully-populated `SddIndex` with
|
|
4
|
+
* lazy-built, per-reader caching.
|
|
5
|
+
*
|
|
6
|
+
* Cache keying is by `sddRoot + pin` so a pinned read and a live read
|
|
7
|
+
* maintain separate indexes (scope doc §Pin semantics: pinned reads
|
|
8
|
+
* bypass live index; no drift detection).
|
|
9
|
+
*/
|
|
10
|
+
import type { SddIndex } from "./types.js";
|
|
11
|
+
import type { SddReader } from "../mcp/reader.js";
|
|
12
|
+
export type { SddIndex } from "./types.js";
|
|
13
|
+
export type { ContractKind, ContractNode, ContractRef, DependencyKind, ExecutionEdge, ServiceNode, StabilityClass, } from "./types.js";
|
|
14
|
+
export { REPO_CONFIG_DIR, parseRepoConfigFile, readAllRepoConfigs, } from "./repo-config.js";
|
|
15
|
+
export { EXECUTION_MAP_PATH, readExecutionMap } from "./execution-map.js";
|
|
16
|
+
export { readContract } from "./contracts.js";
|
|
17
|
+
export { buildGraph } from "./graph.js";
|
|
18
|
+
export declare function getSddIndex(reader: SddReader): SddIndex;
|
|
19
|
+
/**
|
|
20
|
+
* Drop any cached index for the given reader. Called by the file-watch
|
|
21
|
+
* invalidation hook (WS6) when the SDD changes under a live reader.
|
|
22
|
+
* Pinned-reader caches are never invalidated — the tree at that SHA is
|
|
23
|
+
* immutable by definition.
|
|
24
|
+
*/
|
|
25
|
+
export declare function invalidateSddIndex(reader: SddReader): void;
|
|
26
|
+
/** Exposed for tests; production callers should use getSddIndex(). */
|
|
27
|
+
export declare function clearSddIndexCache(): void;
|
|
28
|
+
export declare function buildSddIndex(reader: SddReader): SddIndex;
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/sdd-index/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAGV,QAAQ,EAET,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,WAAW,EACX,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKxC,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAOvD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAI1D;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAuCzD"}
|