@documentation-robotics/cli 0.1.0 → 0.1.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/LICENSE +21 -0
- package/README.md +466 -693
- package/dist/analysis/data-model-analyzer.js +189 -0
- package/dist/analysis/data-model-analyzer.js.map +7 -0
- package/dist/analysis/index.js +3 -0
- package/dist/analysis/index.js.map +7 -0
- package/dist/analysis/relationship-classifier.js +181 -0
- package/dist/analysis/relationship-classifier.js.map +7 -0
- package/dist/analyzers/base-analyzer.js +1 -0
- package/dist/analyzers/base-analyzer.js.map +7 -0
- package/dist/analyzers/call-graph-utils.js +39 -0
- package/dist/analyzers/call-graph-utils.js.map +7 -0
- package/dist/analyzers/cbm-analyzer.js +1205 -0
- package/dist/analyzers/cbm-analyzer.js.map +7 -0
- package/dist/analyzers/heuristic-utils.js +55 -0
- package/dist/analyzers/heuristic-utils.js.map +7 -0
- package/dist/analyzers/mapping-loader.js +146 -0
- package/dist/analyzers/mapping-loader.js.map +7 -0
- package/dist/analyzers/registry.js +124 -0
- package/dist/analyzers/registry.js.map +7 -0
- package/dist/analyzers/session-state.js +176 -0
- package/dist/analyzers/session-state.js.map +7 -0
- package/dist/analyzers/stdio-client.js +206 -0
- package/dist/analyzers/stdio-client.js.map +7 -0
- package/dist/analyzers/types.js +15 -0
- package/dist/analyzers/types.js.map +7 -0
- package/dist/analyzers/verify-engine.js +209 -0
- package/dist/analyzers/verify-engine.js.map +7 -0
- package/dist/analyzers/verify-ignore.js +130 -0
- package/dist/analyzers/verify-ignore.js.map +7 -0
- package/dist/analyzers/version.js +8 -0
- package/dist/analyzers/version.js.map +7 -0
- package/dist/audit/ai/runner.js +41 -0
- package/dist/audit/ai/runner.js.map +7 -0
- package/dist/audit/differential-analyzer.js +183 -0
- package/dist/audit/differential-analyzer.js.map +7 -0
- package/dist/audit/index.js +32 -0
- package/dist/audit/index.js.map +7 -0
- package/dist/audit/nodes/ai/evaluator.js +49 -0
- package/dist/audit/nodes/ai/evaluator.js.map +7 -0
- package/dist/audit/nodes/ai/parser.js +55 -0
- package/dist/audit/nodes/ai/parser.js.map +7 -0
- package/dist/audit/nodes/ai/prompts.js +103 -0
- package/dist/audit/nodes/ai/prompts.js.map +7 -0
- package/dist/audit/nodes/analysis/node-completeness-checker.js +32 -0
- package/dist/audit/nodes/analysis/node-completeness-checker.js.map +7 -0
- package/dist/audit/nodes/analysis/node-definition-analyzer.js +47 -0
- package/dist/audit/nodes/analysis/node-definition-analyzer.js.map +7 -0
- package/dist/audit/nodes/analysis/node-overlap-detector.js +79 -0
- package/dist/audit/nodes/analysis/node-overlap-detector.js.map +7 -0
- package/dist/audit/nodes/model/orchestrator.js +82 -0
- package/dist/audit/nodes/model/orchestrator.js.map +7 -0
- package/dist/audit/nodes/spec/loader.js +116 -0
- package/dist/audit/nodes/spec/loader.js.map +7 -0
- package/dist/audit/nodes/spec/orchestrator.js +68 -0
- package/dist/audit/nodes/spec/orchestrator.js.map +7 -0
- package/dist/audit/nodes/types.js +1 -0
- package/dist/audit/nodes/types.js.map +7 -0
- package/dist/audit/pipeline/index.js +5 -0
- package/dist/audit/pipeline/index.js.map +7 -0
- package/dist/audit/pipeline/pipeline-orchestrator.js +218 -0
- package/dist/audit/pipeline/pipeline-orchestrator.js.map +7 -0
- package/dist/audit/relationships/ai/evaluator.js +235 -0
- package/dist/audit/relationships/ai/evaluator.js.map +7 -0
- package/dist/audit/relationships/ai/parser.js +197 -0
- package/dist/audit/relationships/ai/parser.js.map +7 -0
- package/dist/audit/relationships/ai/prompts.js +274 -0
- package/dist/audit/relationships/ai/prompts.js.map +7 -0
- package/dist/audit/relationships/analysis/balance-assessor.js +115 -0
- package/dist/audit/relationships/analysis/balance-assessor.js.map +7 -0
- package/dist/audit/relationships/analysis/coverage-analyzer.js +99 -0
- package/dist/audit/relationships/analysis/coverage-analyzer.js.map +7 -0
- package/dist/audit/relationships/analysis/duplicate-detector.js +95 -0
- package/dist/audit/relationships/analysis/duplicate-detector.js.map +7 -0
- package/dist/audit/relationships/analysis/gap-analyzer.js +99 -0
- package/dist/audit/relationships/analysis/gap-analyzer.js.map +7 -0
- package/dist/audit/relationships/analysis/layer-templates.js +294 -0
- package/dist/audit/relationships/analysis/layer-templates.js.map +7 -0
- package/dist/audit/relationships/graph/connectivity.js +129 -0
- package/dist/audit/relationships/graph/connectivity.js.map +7 -0
- package/dist/audit/relationships/graph/relationship-graph.js +179 -0
- package/dist/audit/relationships/graph/relationship-graph.js.map +7 -0
- package/dist/audit/relationships/model/balance-assessor.js +49 -0
- package/dist/audit/relationships/model/balance-assessor.js.map +7 -0
- package/dist/audit/relationships/model/coverage-analyzer.js +34 -0
- package/dist/audit/relationships/model/coverage-analyzer.js.map +7 -0
- package/dist/audit/relationships/model/duplicate-detector.js +68 -0
- package/dist/audit/relationships/model/duplicate-detector.js.map +7 -0
- package/dist/audit/relationships/model/gap-analyzer.js +41 -0
- package/dist/audit/relationships/model/gap-analyzer.js.map +7 -0
- package/dist/audit/relationships/model/orchestrator.js +126 -0
- package/dist/audit/relationships/model/orchestrator.js.map +7 -0
- package/dist/audit/relationships/spec/orchestrator.js +157 -0
- package/dist/audit/relationships/spec/orchestrator.js.map +7 -0
- package/dist/audit/reports/index.js +5 -0
- package/dist/audit/reports/index.js.map +7 -0
- package/dist/audit/reports/report-generator.js +118 -0
- package/dist/audit/reports/report-generator.js.map +7 -0
- package/dist/audit/snapshot-storage.js +163 -0
- package/dist/audit/snapshot-storage.js.map +7 -0
- package/dist/audit/types.js +21 -0
- package/dist/audit/types.js.map +7 -0
- package/dist/cli.js +223 -92
- package/dist/cli.js.map +3 -3
- package/dist/coding-agents/agents/claude-code.js +147 -0
- package/dist/coding-agents/agents/claude-code.js.map +7 -0
- package/dist/coding-agents/agents/index.js +5 -0
- package/dist/coding-agents/agents/index.js.map +7 -0
- package/dist/coding-agents/agents/types.js +1 -0
- package/dist/coding-agents/agents/types.js.map +7 -0
- package/dist/coding-agents/base-chat-client.js +45 -0
- package/dist/coding-agents/base-chat-client.js.map +7 -0
- package/dist/coding-agents/chat-utils.js +23 -0
- package/dist/coding-agents/chat-utils.js.map +7 -0
- package/dist/coding-agents/claude-code-client.js +246 -0
- package/dist/coding-agents/claude-code-client.js.map +7 -0
- package/dist/coding-agents/copilot-client.js +209 -0
- package/dist/coding-agents/copilot-client.js.map +7 -0
- package/dist/commands/add.js +95 -33
- package/dist/commands/add.js.map +2 -2
- package/dist/commands/analyzer.js +511 -0
- package/dist/commands/analyzer.js.map +7 -0
- package/dist/commands/audit-diff.js +49 -0
- package/dist/commands/audit-diff.js.map +7 -0
- package/dist/commands/audit-snapshots.js +62 -0
- package/dist/commands/audit-snapshots.js.map +7 -0
- package/dist/commands/audit.js +81 -0
- package/dist/commands/audit.js.map +7 -0
- package/dist/commands/catalog.js +248 -0
- package/dist/commands/catalog.js.map +7 -0
- package/dist/commands/changeset.js +577 -66
- package/dist/commands/changeset.js.map +2 -2
- package/dist/commands/chat.js +106 -83
- package/dist/commands/chat.js.map +2 -2
- package/dist/commands/claude.js +74 -0
- package/dist/commands/claude.js.map +7 -0
- package/dist/commands/conformance.js +71 -68
- package/dist/commands/conformance.js.map +2 -2
- package/dist/commands/copilot.js +75 -0
- package/dist/commands/copilot.js.map +7 -0
- package/dist/commands/delete.js +125 -11
- package/dist/commands/delete.js.map +3 -3
- package/dist/commands/discover-logic.js +44 -0
- package/dist/commands/discover-logic.js.map +7 -0
- package/dist/commands/docs.js +87 -0
- package/dist/commands/docs.js.map +7 -0
- package/dist/commands/element.js +14 -20
- package/dist/commands/element.js.map +2 -2
- package/dist/commands/export.js +13 -3
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/import.js +51 -0
- package/dist/commands/import.js.map +7 -0
- package/dist/commands/info.js +30 -24
- package/dist/commands/info.js.map +2 -2
- package/dist/commands/init.js +27 -11
- package/dist/commands/init.js.map +2 -2
- package/dist/commands/list.js +63 -13
- package/dist/commands/list.js.map +3 -3
- package/dist/commands/relationship.js +225 -37
- package/dist/commands/relationship.js.map +2 -2
- package/dist/commands/report.js +54 -0
- package/dist/commands/report.js.map +7 -0
- package/dist/commands/reports.js +45 -0
- package/dist/commands/reports.js.map +7 -0
- package/dist/commands/schema.js +135 -0
- package/dist/commands/schema.js.map +7 -0
- package/dist/commands/search.js +40 -12
- package/dist/commands/search.js.map +2 -2
- package/dist/commands/show.js +58 -27
- package/dist/commands/show.js.map +2 -2
- package/dist/commands/stats.js +35 -0
- package/dist/commands/stats.js.map +7 -0
- package/dist/commands/trace.js +39 -16
- package/dist/commands/trace.js.map +2 -2
- package/dist/commands/update.js +141 -14
- package/dist/commands/update.js.map +2 -2
- package/dist/commands/upgrade.js +210 -46
- package/dist/commands/upgrade.js.map +3 -3
- package/dist/commands/validate.js +142 -23
- package/dist/commands/validate.js.map +3 -3
- package/dist/commands/version.js +8 -12
- package/dist/commands/version.js.map +2 -2
- package/dist/commands/visualize.js +155 -25
- package/dist/commands/visualize.js.map +2 -2
- package/dist/core/base-snapshot-manager.js +84 -0
- package/dist/core/base-snapshot-manager.js.map +7 -0
- package/dist/core/changeset-exporter.js +305 -0
- package/dist/core/changeset-exporter.js.map +7 -0
- package/dist/core/changeset-validator.js +41 -0
- package/dist/core/changeset-validator.js.map +7 -0
- package/dist/core/changeset.js +88 -173
- package/dist/core/changeset.js.map +2 -2
- package/dist/core/dependency-tracker.js +4 -2
- package/dist/core/dependency-tracker.js.map +2 -2
- package/dist/core/element.js +98 -27
- package/dist/core/element.js.map +2 -2
- package/dist/core/golden-copy-cache.js +290 -0
- package/dist/core/golden-copy-cache.js.map +7 -0
- package/dist/core/graph-model.js +266 -0
- package/dist/core/graph-model.js.map +7 -0
- package/dist/core/layer.js +159 -16
- package/dist/core/layer.js.map +2 -2
- package/dist/core/layers.js +32 -0
- package/dist/core/layers.js.map +7 -0
- package/dist/core/manifest.js +32 -11
- package/dist/core/manifest.js.map +2 -2
- package/dist/core/migration-registry.js +56 -1
- package/dist/core/migration-registry.js.map +2 -2
- package/dist/core/model.js +424 -217
- package/dist/core/model.js.map +3 -3
- package/dist/core/mutation-handler.js +179 -0
- package/dist/core/mutation-handler.js.map +7 -0
- package/dist/core/reference-registry.js +29 -21
- package/dist/core/reference-registry.js.map +2 -2
- package/dist/core/relationship-catalog.js +189 -0
- package/dist/core/relationship-catalog.js.map +7 -0
- package/dist/core/relationship-registry.js.map +2 -2
- package/dist/core/relationships.js.map +1 -1
- package/dist/core/report-data-model.js +285 -0
- package/dist/core/report-data-model.js.map +7 -0
- package/dist/core/spec-data-service.js +185 -0
- package/dist/core/spec-data-service.js.map +7 -0
- package/dist/core/spec-loader-types.js +1 -0
- package/dist/core/spec-loader-types.js.map +7 -0
- package/dist/core/spec-loader.js +234 -0
- package/dist/core/spec-loader.js.map +7 -0
- package/dist/core/staged-changeset-storage.js +282 -0
- package/dist/core/staged-changeset-storage.js.map +7 -0
- package/dist/core/staging-area.js +1002 -0
- package/dist/core/staging-area.js.map +7 -0
- package/dist/core/stats-collector.js +169 -0
- package/dist/core/stats-collector.js.map +7 -0
- package/dist/core/virtual-projection.js +443 -0
- package/dist/core/virtual-projection.js.map +7 -0
- package/dist/export/archimate-exporter.js +99 -60
- package/dist/export/archimate-exporter.js.map +2 -2
- package/dist/export/audit-formatters.js +479 -0
- package/dist/export/audit-formatters.js.map +7 -0
- package/dist/export/diff-formatters.js +99 -0
- package/dist/export/diff-formatters.js.map +7 -0
- package/dist/export/export-manager.js.map +2 -2
- package/dist/export/graphml-exporter.js +44 -27
- package/dist/export/graphml-exporter.js.map +2 -2
- package/dist/export/index.js +4 -0
- package/dist/export/index.js.map +2 -2
- package/dist/export/json-schema-exporter.js +55 -42
- package/dist/export/json-schema-exporter.js.map +2 -2
- package/dist/export/markdown-exporter.js +92 -70
- package/dist/export/markdown-exporter.js.map +2 -2
- package/dist/export/markdown-generator.js +248 -0
- package/dist/export/markdown-generator.js.map +7 -0
- package/dist/export/markdown-utils.js +30 -0
- package/dist/export/markdown-utils.js.map +7 -0
- package/dist/export/mermaid-markdown-exporter.js +37 -0
- package/dist/export/mermaid-markdown-exporter.js.map +7 -0
- package/dist/export/openapi-exporter.js +119 -71
- package/dist/export/openapi-exporter.js.map +2 -2
- package/dist/export/plantuml-exporter.js +104 -39
- package/dist/export/plantuml-exporter.js.map +2 -2
- package/dist/export/report-formatters.js +111 -0
- package/dist/export/report-formatters.js.map +7 -0
- package/dist/export/stats-formatters.js +98 -0
- package/dist/export/stats-formatters.js.map +7 -0
- package/dist/export/types.js +2 -14
- package/dist/export/types.js.map +2 -2
- package/dist/export/verify-formatters.js +153 -0
- package/dist/export/verify-formatters.js.map +7 -0
- package/dist/generated/compiled-validators.js +17 -0
- package/dist/generated/compiled-validators.js.map +7 -0
- package/dist/generated/index.js +31 -0
- package/dist/generated/index.js.map +7 -0
- package/dist/generated/layer-registry.js +190 -0
- package/dist/generated/layer-registry.js.map +7 -0
- package/dist/generated/layer-types.js +7 -0
- package/dist/generated/layer-types.js.map +7 -0
- package/dist/generated/node-types.js +1719 -0
- package/dist/generated/node-types.js.map +7 -0
- package/dist/generated/relationship-index.js +14552 -0
- package/dist/generated/relationship-index.js.map +7 -0
- package/dist/import/archimate-importer.js +166 -0
- package/dist/import/archimate-importer.js.map +7 -0
- package/dist/import/index.js +47 -0
- package/dist/import/index.js.map +7 -0
- package/dist/import/openapi-importer.js +143 -0
- package/dist/import/openapi-importer.js.map +7 -0
- package/dist/import/types.js +1 -0
- package/dist/import/types.js.map +7 -0
- package/dist/integrations/base-manager.js +311 -0
- package/dist/integrations/base-manager.js.map +7 -0
- package/dist/integrations/claude-manager.js +360 -0
- package/dist/integrations/claude-manager.js.map +7 -0
- package/dist/integrations/claude_code/agents/dr-advisor.md +253 -0
- package/dist/integrations/claude_code/agents/dr-architect.md +278 -0
- package/dist/integrations/claude_code/agents/dr-extractor.md +286 -0
- package/dist/integrations/claude_code/commands/dr-changeset.md +657 -0
- package/dist/integrations/claude_code/commands/dr-design.md +373 -0
- package/dist/integrations/claude_code/commands/dr-info.md +132 -0
- package/dist/integrations/claude_code/commands/dr-init.md +251 -0
- package/dist/integrations/claude_code/commands/dr-map.md +936 -0
- package/dist/integrations/claude_code/commands/dr-model.md +493 -0
- package/dist/integrations/claude_code/commands/dr-relate.md +814 -0
- package/dist/integrations/claude_code/commands/dr-sync.md +279 -0
- package/dist/integrations/claude_code/commands/dr-validate.md +654 -0
- package/dist/integrations/claude_code/commands/dr-verify.md +559 -0
- package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +903 -0
- package/dist/integrations/claude_code/docs/QUICK_START.md +271 -0
- package/dist/integrations/claude_code/docs/README.md +347 -0
- package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +550 -0
- package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +620 -0
- package/dist/integrations/claude_code/skills/dr_03_security_layer/SKILL.md +642 -0
- package/dist/integrations/claude_code/skills/dr_04_application_layer/SKILL.md +911 -0
- package/dist/integrations/claude_code/skills/dr_05_technology_layer/SKILL.md +836 -0
- package/dist/integrations/claude_code/skills/dr_06_api_layer/SKILL.md +933 -0
- package/dist/integrations/claude_code/skills/dr_07_data_model_layer/SKILL.md +210 -0
- package/dist/integrations/claude_code/skills/dr_08_dataset_layer/SKILL.md +319 -0
- package/dist/integrations/claude_code/skills/dr_09_ux_layer/SKILL.md +319 -0
- package/dist/integrations/claude_code/skills/dr_10_navigation_layer/SKILL.md +318 -0
- package/dist/integrations/claude_code/skills/dr_11_apm_layer/SKILL.md +273 -0
- package/dist/integrations/claude_code/skills/dr_12_testing_layer/SKILL.md +273 -0
- package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +187 -0
- package/dist/integrations/claude_code/skills/dr_codebase_memory/SKILL.md +590 -0
- package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +295 -0
- package/dist/integrations/copilot-manager.js +328 -0
- package/dist/integrations/copilot-manager.js.map +7 -0
- package/dist/integrations/github_copilot/agents/dr-advisor.md +243 -0
- package/dist/integrations/github_copilot/agents/dr-architect.md +1567 -0
- package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +491 -0
- package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +539 -0
- package/dist/integrations/github_copilot/skills/dr_03_security_layer/SKILL.md +667 -0
- package/dist/integrations/github_copilot/skills/dr_04_application_layer/SKILL.md +670 -0
- package/dist/integrations/github_copilot/skills/dr_05_technology_layer/SKILL.md +660 -0
- package/dist/integrations/github_copilot/skills/dr_06_api_layer/SKILL.md +855 -0
- package/dist/integrations/github_copilot/skills/dr_07_data_model_layer/SKILL.md +171 -0
- package/dist/integrations/github_copilot/skills/dr_08_dataset_layer/SKILL.md +216 -0
- package/dist/integrations/github_copilot/skills/dr_09_ux_layer/SKILL.md +230 -0
- package/dist/integrations/github_copilot/skills/dr_10_navigation_layer/SKILL.md +228 -0
- package/dist/integrations/github_copilot/skills/dr_11_apm_layer/SKILL.md +234 -0
- package/dist/integrations/github_copilot/skills/dr_12_testing_layer/SKILL.md +230 -0
- package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +187 -0
- package/dist/integrations/hash-utils.js +51 -0
- package/dist/integrations/hash-utils.js.map +7 -0
- package/dist/integrations/types.js +16 -0
- package/dist/integrations/types.js.map +7 -0
- package/dist/reports/model-layer-report-generator.js +278 -0
- package/dist/reports/model-layer-report-generator.js.map +7 -0
- package/dist/reports/model-report-data.js +57 -0
- package/dist/reports/model-report-data.js.map +7 -0
- package/dist/reports/model-report-orchestrator.js +103 -0
- package/dist/reports/model-report-orchestrator.js.map +7 -0
- package/dist/schemas/bundled/analyzers/cbm.json +595 -0
- package/dist/schemas/bundled/analyzers/manifest.json +9 -0
- package/dist/schemas/bundled/api.json +3411 -0
- package/dist/schemas/bundled/apm.json +2371 -0
- package/dist/schemas/bundled/application.json +1253 -0
- package/dist/schemas/bundled/base.json +1622 -0
- package/dist/schemas/bundled/business.json +1279 -0
- package/dist/schemas/bundled/data-model.json +1298 -0
- package/dist/schemas/bundled/data-store.json +2025 -0
- package/dist/schemas/bundled/manifest.json +93 -0
- package/dist/schemas/bundled/motivation.json +1360 -0
- package/dist/schemas/bundled/navigation.json +1874 -0
- package/dist/schemas/bundled/security.json +3488 -0
- package/dist/schemas/bundled/technology.json +2067 -0
- package/dist/schemas/bundled/testing.json +3120 -0
- package/dist/schemas/bundled/ux.json +3592 -0
- package/dist/server/schemas.js +202 -0
- package/dist/server/schemas.js.map +7 -0
- package/dist/server/server.js +1336 -252
- package/dist/server/server.js.map +3 -3
- package/dist/server/telemetry-middleware.js +22 -15
- package/dist/server/telemetry-middleware.js.map +2 -2
- package/dist/server-entry.js +65 -0
- package/dist/server-entry.js.map +7 -0
- package/dist/telemetry/config.js +89 -0
- package/dist/telemetry/config.js.map +7 -0
- package/dist/telemetry/console-interceptor.js.map +1 -1
- package/dist/telemetry/detect.js +24 -0
- package/dist/telemetry/detect.js.map +7 -0
- package/dist/telemetry/fetch-otlp-exporter.js +112 -0
- package/dist/telemetry/fetch-otlp-exporter.js.map +7 -0
- package/dist/telemetry/index.js +153 -3
- package/dist/telemetry/index.js.map +2 -2
- package/dist/telemetry/resilient-exporter.js +22 -8
- package/dist/telemetry/resilient-exporter.js.map +2 -2
- package/dist/telemetry/resilient-log-exporter.js +17 -8
- package/dist/telemetry/resilient-log-exporter.js.map +2 -2
- package/dist/telemetry/test-instrumentation.js.map +2 -2
- package/dist/types/index.js +84 -0
- package/dist/types/index.js.map +3 -3
- package/dist/types/source-reference.js +1 -0
- package/dist/types/source-reference.js.map +7 -0
- package/dist/utils/chat-logger.js +292 -0
- package/dist/utils/chat-logger.js.map +7 -0
- package/dist/utils/claude-stream.js +8 -0
- package/dist/utils/claude-stream.js.map +7 -0
- package/dist/utils/date-utils.js +7 -0
- package/dist/utils/date-utils.js.map +7 -0
- package/dist/utils/element-utils.js.map +1 -1
- package/dist/utils/errors.js +88 -15
- package/dist/utils/errors.js.map +3 -3
- package/dist/utils/export-python-annotations.js +82 -0
- package/dist/utils/export-python-annotations.js.map +7 -0
- package/dist/utils/file-io.js +7 -2
- package/dist/utils/file-io.js.map +2 -2
- package/dist/utils/file-lock.js +156 -0
- package/dist/utils/file-lock.js.map +7 -0
- package/dist/utils/id-generator.js +18 -0
- package/dist/utils/id-generator.js.map +7 -0
- package/dist/utils/layer-name-formatter.js +16 -0
- package/dist/utils/layer-name-formatter.js.map +7 -0
- package/dist/utils/markdown-anchor.js +7 -0
- package/dist/utils/markdown-anchor.js.map +7 -0
- package/dist/utils/markdown-link.js +12 -0
- package/dist/utils/markdown-link.js.map +7 -0
- package/dist/utils/markdown-table.js +17 -0
- package/dist/utils/markdown-table.js.map +7 -0
- package/dist/utils/mermaid-utils.js +11 -0
- package/dist/utils/mermaid-utils.js.map +7 -0
- package/dist/utils/project-paths.js.map +2 -2
- package/dist/utils/source-reference.js +52 -0
- package/dist/utils/source-reference.js.map +7 -0
- package/dist/utils/spec-installer.js +40 -53
- package/dist/utils/spec-installer.js.map +2 -2
- package/dist/utils/spec-version.js +5 -1
- package/dist/utils/spec-version.js.map +2 -2
- package/dist/utils/string-utils.js +12 -0
- package/dist/utils/string-utils.js.map +7 -0
- package/dist/utils/table-formatting.js +19 -0
- package/dist/utils/table-formatting.js.map +7 -0
- package/dist/validators/index.js +4 -0
- package/dist/validators/index.js.map +2 -2
- package/dist/validators/naming-validator.js +20 -23
- package/dist/validators/naming-validator.js.map +2 -2
- package/dist/validators/reference-validator.js +23 -38
- package/dist/validators/reference-validator.js.map +2 -2
- package/dist/validators/relationship-schema-validator.js +243 -0
- package/dist/validators/relationship-schema-validator.js.map +7 -0
- package/dist/validators/schema-validator.js +168 -68
- package/dist/validators/schema-validator.js.map +2 -2
- package/dist/validators/semantic-validator.js +36 -60
- package/dist/validators/semantic-validator.js.map +2 -2
- package/dist/validators/types.js.map +2 -2
- package/dist/validators/validation-formatter.js +159 -0
- package/dist/validators/validation-formatter.js.map +7 -0
- package/dist/validators/validator.js +24 -38
- package/dist/validators/validator.js.map +2 -2
- package/dist/viewer/README.md +139 -0
- package/dist/viewer/assets/main-CY0Xufuj.css +1 -0
- package/dist/viewer/assets/main-DtgErnwF.js +81 -0
- package/dist/viewer/assets/vendor-CxKvDp2x.js +17 -0
- package/dist/viewer/favicon.svg +11 -0
- package/dist/viewer/fonts/inter/Inter-Black.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Bold.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-ExtraBold.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Light.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Medium.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Regular.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-SemiBold.woff2 +0 -0
- package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-Medium.woff2 +0 -0
- package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2 +0 -0
- package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-SemiBold.woff2 +0 -0
- package/dist/viewer/index.html +15 -0
- package/dist/viewer/manifest.json +99 -0
- package/dist/viewer/version.json +1 -0
- package/package.json +37 -13
- package/PYTHON_CLI_PARITY.md +0 -265
- package/PYTHON_CLI_STRUCTURE_UPDATE.md +0 -246
- package/biome.json +0 -42
- package/bunfig.toml +0 -3
- package/dist/ai/claude-client.js +0 -71
- package/dist/ai/claude-client.js.map +0 -7
- package/dist/ai/context-provider.js +0 -129
- package/dist/ai/context-provider.js.map +0 -7
- package/dist/ai/tools.js +0 -231
- package/dist/ai/tools.js.map +0 -7
- package/dist/commands/migrate.js +0 -36
- package/dist/commands/migrate.js.map +0 -7
- package/dist/commands/project.js +0 -74
- package/dist/commands/project.js.map +0 -7
- package/dist/core/active-changeset.js +0 -52
- package/dist/core/active-changeset.js.map +0 -7
- package/dist/core/projection-engine.js +0 -288
- package/dist/core/projection-engine.js.map +0 -7
- package/dist/schemas/bundled/01-motivation-layer.schema.json +0 -942
- package/dist/schemas/bundled/02-business-layer.schema.json +0 -1293
- package/dist/schemas/bundled/03-security-layer.schema.json +0 -2177
- package/dist/schemas/bundled/04-application-layer.schema.json +0 -1328
- package/dist/schemas/bundled/05-technology-layer.schema.json +0 -1465
- package/dist/schemas/bundled/06-api-layer.schema.json +0 -1743
- package/dist/schemas/bundled/07-data-model-layer.schema.json +0 -1253
- package/dist/schemas/bundled/08-datastore-layer.schema.json +0 -892
- package/dist/schemas/bundled/09-ux-layer.schema.json +0 -1506
- package/dist/schemas/bundled/10-navigation-layer.schema.json +0 -843
- package/dist/schemas/bundled/11-apm-observability-layer.schema.json +0 -1430
- package/dist/schemas/bundled/12-testing-layer.schema.json +0 -1091
- package/dist/schemas/bundled/common/layer-extensions.schema.json +0 -266
- package/dist/schemas/bundled/common/predicates.schema.json +0 -493
- package/dist/schemas/bundled/common/relationships.schema.json +0 -791
- package/dist/schemas/bundled/common/source-references.schema.json +0 -71
- package/dist/schemas/bundled/link-registry.json +0 -1839
- package/dist/schemas/bundled/link-registry.schema.json +0 -339
- package/dist/schemas/bundled/relationship-catalog.json +0 -1302
- package/dist/schemas/bundled/relationship-type.schema.json +0 -221
- package/dist/utils/model-path.js +0 -22
- package/dist/utils/model-path.js.map +0 -7
- package/docs/TEST-INSTRUMENTATION.md +0 -405
- package/docs/telemetry.md +0 -427
- package/test-debug.js +0 -33
- package/test-special.mjs +0 -46
- package/test_runner.ts +0 -7
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { RELATIONSHIPS_BY_SOURCE } from "../../../generated/relationship-index.js";
|
|
2
|
+
import { getAllLayers } from "../../../generated/layer-registry.js";
|
|
3
|
+
const DENSITY_TARGETS = {
|
|
4
|
+
structural: [2, 4],
|
|
5
|
+
// Entities, components
|
|
6
|
+
behavioral: [3, 5],
|
|
7
|
+
// Processes, services
|
|
8
|
+
enumeration: [1, 2],
|
|
9
|
+
// States, values
|
|
10
|
+
reference: [0, 1]
|
|
11
|
+
// Metadata, tags
|
|
12
|
+
};
|
|
13
|
+
class BalanceAssessor {
|
|
14
|
+
assessmentCache = null;
|
|
15
|
+
/**
|
|
16
|
+
* Assess balance for all layers
|
|
17
|
+
*/
|
|
18
|
+
assessAll() {
|
|
19
|
+
if (this.assessmentCache !== null)
|
|
20
|
+
return this.assessmentCache;
|
|
21
|
+
const layers = getAllLayers(), assessments = [];
|
|
22
|
+
for (const layer of layers) {
|
|
23
|
+
const layerAssessments = this.assessLayer(layer);
|
|
24
|
+
assessments.push(...layerAssessments);
|
|
25
|
+
}
|
|
26
|
+
return this.assessmentCache = assessments, assessments;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Assess balance for a single layer
|
|
30
|
+
*/
|
|
31
|
+
assessLayer(layer) {
|
|
32
|
+
const assessments = [];
|
|
33
|
+
for (const nodeType of layer.nodeTypes) {
|
|
34
|
+
const assessment = this.assessNodeType(nodeType, layer.id);
|
|
35
|
+
assessments.push(assessment);
|
|
36
|
+
}
|
|
37
|
+
return assessments;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Assess balance for a single node type
|
|
41
|
+
*/
|
|
42
|
+
assessNodeType(nodeType, layerId) {
|
|
43
|
+
const category = this.classifyNodeType(nodeType), currentCount = this.getRelationshipCount(nodeType), targetRange = DENSITY_TARGETS[category], status = this.determineStatus(currentCount, targetRange), recommendation = this.generateRecommendation(nodeType, category, currentCount, targetRange, status);
|
|
44
|
+
return {
|
|
45
|
+
nodeType,
|
|
46
|
+
layer: layerId,
|
|
47
|
+
category,
|
|
48
|
+
currentCount,
|
|
49
|
+
targetRange,
|
|
50
|
+
status,
|
|
51
|
+
recommendation
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Classify node type into category
|
|
56
|
+
*
|
|
57
|
+
* IMPORTANT: Categories are checked in precedence order:
|
|
58
|
+
* 1. Enumeration (most specific - uses endsWith)
|
|
59
|
+
* 2. Structural (uses includes - may match substrings)
|
|
60
|
+
* 3. Behavioral (uses includes - may match substrings)
|
|
61
|
+
* 4. Reference (default)
|
|
62
|
+
*
|
|
63
|
+
* The ordering matters because includes() can match substrings.
|
|
64
|
+
* For example, "businessservice" contains "service" (structural)
|
|
65
|
+
* but is behavioral by nature. The current implementation favors
|
|
66
|
+
* structural classification in such cases.
|
|
67
|
+
*/
|
|
68
|
+
classifyNodeType(specNodeId) {
|
|
69
|
+
const type = specNodeId.split(".")[1] || "";
|
|
70
|
+
return type ? type.endsWith("level") || type.endsWith("type") || type.endsWith("status") || type.endsWith("priority") || type.endsWith("scope") || type.endsWith("action") || type.endsWith("category") || type.endsWith("format") ? "enumeration" : type.includes("component") || type.includes("container") || type.includes("service") || type.includes("module") || type.includes("collaboration") || type.includes("interface") || type.includes("device") || type.includes("node") || type.includes("artifact") ? "structural" : type.includes("process") || type.includes("operation") || type.includes("event") || type.includes("flow") || type.includes("interaction") || type.includes("function") || type.includes("trigger") ? "behavioral" : "reference" : (console.warn(`Warning: Could not extract type from specNodeId '${specNodeId}', defaulting to 'reference' classification`), "reference");
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get relationship count for node type
|
|
74
|
+
*/
|
|
75
|
+
getRelationshipCount(nodeType) {
|
|
76
|
+
return (RELATIONSHIPS_BY_SOURCE.get(nodeType) || []).length;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Determine balance status
|
|
80
|
+
*/
|
|
81
|
+
determineStatus(count, targetRange) {
|
|
82
|
+
const [min, max] = targetRange;
|
|
83
|
+
return count < min ? "under" : count > max ? "over" : "balanced";
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Generate recommendation
|
|
87
|
+
*/
|
|
88
|
+
generateRecommendation(nodeType, category, currentCount, targetRange, status) {
|
|
89
|
+
const [min, max] = targetRange, typeName = nodeType.split(".").pop() || nodeType;
|
|
90
|
+
if (status === "under") {
|
|
91
|
+
const needed = min - currentCount;
|
|
92
|
+
return `Add ${needed} relationship${needed > 1 ? "s" : ""} to ${typeName} (${category} type) to reach minimum target`;
|
|
93
|
+
}
|
|
94
|
+
if (status === "over") {
|
|
95
|
+
const excess = currentCount - max;
|
|
96
|
+
return `Consider removing ${excess} relationship${excess > 1 ? "s" : ""} from ${typeName} or reviewing ${category} type classification`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get assessments by status
|
|
101
|
+
*/
|
|
102
|
+
assessByStatus(status) {
|
|
103
|
+
return this.assessAll().filter((a) => a.status === status);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get assessments by category
|
|
107
|
+
*/
|
|
108
|
+
assessByCategory(category) {
|
|
109
|
+
return this.assessAll().filter((a) => a.category === category);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export {
|
|
113
|
+
BalanceAssessor
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=balance-assessor.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/audit/relationships/analysis/balance-assessor.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Balance Assessor - Assesses relationship density balance\n *\n * Applies heuristics to determine if node types have appropriate\n * numbers of relationships based on their category:\n * - Structural (2-4 relationships): entities, components\n * - Behavioral (3-5 relationships): processes, services\n * - Enumeration (1-2 relationships): states, values\n * - Reference (0-1 relationships): metadata, tags\n */\n\nimport { RELATIONSHIPS_BY_SOURCE } from \"../../../generated/relationship-index.js\";\nimport {\n getAllLayers,\n type LayerMetadata,\n} from \"../../../generated/layer-registry.js\";\nimport type { BalanceAssessment } from \"../../types.js\";\n\n/**\n * Density targets for different node type categories\n */\nconst DENSITY_TARGETS: Record<string, [number, number]> = {\n structural: [2, 4], // Entities, components\n behavioral: [3, 5], // Processes, services\n enumeration: [1, 2], // States, values\n reference: [0, 1], // Metadata, tags\n};\n\n/**\n * Balance assessor for relationship density\n */\nexport class BalanceAssessor {\n private assessmentCache: BalanceAssessment[] | null = null;\n\n /**\n * Assess balance for all layers\n */\n assessAll(): BalanceAssessment[] {\n if (this.assessmentCache !== null) {\n return this.assessmentCache;\n }\n\n const layers = getAllLayers();\n const assessments: BalanceAssessment[] = [];\n\n for (const layer of layers) {\n const layerAssessments = this.assessLayer(layer);\n assessments.push(...layerAssessments);\n }\n\n this.assessmentCache = assessments;\n return assessments;\n }\n\n /**\n * Assess balance for a single layer\n */\n assessLayer(layer: LayerMetadata): BalanceAssessment[] {\n const assessments: BalanceAssessment[] = [];\n\n for (const nodeType of layer.nodeTypes) {\n const assessment = this.assessNodeType(nodeType, layer.id);\n assessments.push(assessment);\n }\n\n return assessments;\n }\n\n /**\n * Assess balance for a single node type\n */\n private assessNodeType(\n nodeType: string,\n layerId: string\n ): BalanceAssessment {\n const category = this.classifyNodeType(nodeType);\n const currentCount = this.getRelationshipCount(nodeType);\n const targetRange = DENSITY_TARGETS[category];\n const status = this.determineStatus(currentCount, targetRange);\n const recommendation = this.generateRecommendation(\n nodeType,\n category,\n currentCount,\n targetRange,\n status\n );\n\n return {\n nodeType,\n layer: layerId,\n category,\n currentCount,\n targetRange,\n status,\n recommendation,\n };\n }\n\n /**\n * Classify node type into category\n *\n * IMPORTANT: Categories are checked in precedence order:\n * 1. Enumeration (most specific - uses endsWith)\n * 2. Structural (uses includes - may match substrings)\n * 3. Behavioral (uses includes - may match substrings)\n * 4. Reference (default)\n *\n * The ordering matters because includes() can match substrings.\n * For example, \"businessservice\" contains \"service\" (structural)\n * but is behavioral by nature. The current implementation favors\n * structural classification in such cases.\n */\n private classifyNodeType(\n specNodeId: string\n ): \"structural\" | \"behavioral\" | \"enumeration\" | \"reference\" {\n const type = specNodeId.split(\".\")[1] || \"\";\n\n // Warn if type extraction fails (unexpected specNodeId format)\n if (!type) {\n console.warn(`Warning: Could not extract type from specNodeId '${specNodeId}', defaulting to 'reference' classification`);\n return \"reference\";\n }\n\n // Enumeration patterns - checked first (most specific, uses endsWith)\n if (\n type.endsWith(\"level\") ||\n type.endsWith(\"type\") ||\n type.endsWith(\"status\") ||\n type.endsWith(\"priority\") ||\n type.endsWith(\"scope\") ||\n type.endsWith(\"action\") ||\n type.endsWith(\"category\") ||\n type.endsWith(\"format\")\n ) {\n return \"enumeration\";\n }\n\n // Structural patterns - checked second\n // NOTE: Uses includes() which may match substrings (e.g., \"businessservice\" matches \"service\")\n if (\n type.includes(\"component\") ||\n type.includes(\"container\") ||\n type.includes(\"service\") ||\n type.includes(\"module\") ||\n type.includes(\"collaboration\") ||\n type.includes(\"interface\") ||\n type.includes(\"device\") ||\n type.includes(\"node\") ||\n type.includes(\"artifact\")\n ) {\n return \"structural\";\n }\n\n // Behavioral patterns - checked third\n if (\n type.includes(\"process\") ||\n type.includes(\"operation\") ||\n type.includes(\"event\") ||\n type.includes(\"flow\") ||\n type.includes(\"interaction\") ||\n type.includes(\"function\") ||\n type.includes(\"trigger\")\n ) {\n return \"behavioral\";\n }\n\n // Default to reference for unmatched types\n return \"reference\";\n }\n\n /**\n * Get relationship count for node type\n */\n private getRelationshipCount(nodeType: string): number {\n const relationships = RELATIONSHIPS_BY_SOURCE.get(nodeType) || [];\n return relationships.length;\n }\n\n /**\n * Determine balance status\n */\n private determineStatus(\n count: number,\n targetRange: [number, number]\n ): \"under\" | \"balanced\" | \"over\" {\n const [min, max] = targetRange;\n\n if (count < min) {\n return \"under\";\n }\n if (count > max) {\n return \"over\";\n }\n return \"balanced\";\n }\n\n /**\n * Generate recommendation\n */\n private generateRecommendation(\n nodeType: string,\n category: string,\n currentCount: number,\n targetRange: [number, number],\n status: \"under\" | \"balanced\" | \"over\"\n ): string | undefined {\n const [min, max] = targetRange;\n const typeName = nodeType.split(\".\").pop() || nodeType;\n\n if (status === \"under\") {\n const needed = min - currentCount;\n return `Add ${needed} relationship${needed > 1 ? \"s\" : \"\"} to ${typeName} (${category} type) to reach minimum target`;\n }\n\n if (status === \"over\") {\n const excess = currentCount - max;\n return `Consider removing ${excess} relationship${excess > 1 ? \"s\" : \"\"} from ${typeName} or reviewing ${category} type classification`;\n }\n\n return undefined;\n }\n\n /**\n * Get assessments by status\n */\n assessByStatus(\n status: \"under\" | \"balanced\" | \"over\"\n ): BalanceAssessment[] {\n const all = this.assessAll();\n return all.filter((a) => a.status === status);\n }\n\n /**\n * Get assessments by category\n */\n assessByCategory(\n category: \"structural\" | \"behavioral\" | \"enumeration\" | \"reference\"\n ): BalanceAssessment[] {\n const all = this.assessAll();\n return all.filter((a) => a.category === category);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { RELATIONSHIPS_BY_SOURCE } from "../../../generated/relationship-index.js";
|
|
2
|
+
import { getAllLayers } from "../../../generated/layer-registry.js";
|
|
3
|
+
import { LAYER_TEMPLATES } from "./layer-templates.js";
|
|
4
|
+
import { createPercentage } from "../../types.js";
|
|
5
|
+
class CoverageAnalyzer {
|
|
6
|
+
catalog;
|
|
7
|
+
constructor(catalog) {
|
|
8
|
+
this.catalog = catalog;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Analyze coverage for all layers
|
|
12
|
+
* @returns Result object indicating success/partial/failure with complete flag
|
|
13
|
+
*/
|
|
14
|
+
async analyzeAll() {
|
|
15
|
+
const layers = getAllLayers(), results = [], errors = [];
|
|
16
|
+
for (const layer of layers)
|
|
17
|
+
try {
|
|
18
|
+
const metrics = await this.analyzeLayer(layer);
|
|
19
|
+
results.push(metrics);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
errors.push({
|
|
22
|
+
layer: layer.id,
|
|
23
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (results.length === 0 && errors.length > 0)
|
|
27
|
+
throw errors[0].error;
|
|
28
|
+
if (errors.length > 0 && results.length > 0) {
|
|
29
|
+
console.error(`
|
|
30
|
+
\u26A0\uFE0F Warning: Coverage analysis failed for ${errors.length} layer(s):`);
|
|
31
|
+
for (const { layer, error } of errors)
|
|
32
|
+
console.error(` - ${layer}: ${error.message}`);
|
|
33
|
+
console.error(`
|
|
34
|
+
Successfully analyzed ${results.length}/${layers.length} layers.
|
|
35
|
+
`);
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
results,
|
|
39
|
+
failures: errors,
|
|
40
|
+
isComplete: errors.length === 0
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Analyze coverage for a single layer
|
|
45
|
+
*/
|
|
46
|
+
async analyzeLayer(layer) {
|
|
47
|
+
const nodeTypes = layer.nodeTypes, nodeTypeCount = nodeTypes.length, relationshipCounts = /* @__PURE__ */ new Map(), usedPredicatesSet = /* @__PURE__ */ new Set();
|
|
48
|
+
for (const nodeType of nodeTypes) {
|
|
49
|
+
const relationships = RELATIONSHIPS_BY_SOURCE.get(nodeType) || [];
|
|
50
|
+
relationshipCounts.set(nodeType, relationships.length);
|
|
51
|
+
for (const rel of relationships)
|
|
52
|
+
usedPredicatesSet.add(rel.predicate);
|
|
53
|
+
}
|
|
54
|
+
const relationshipCount = Array.from(relationshipCounts.values()).reduce((sum, count) => sum + count, 0), isolatedNodeTypes = nodeTypes.filter((type) => (relationshipCounts.get(type) || 0) === 0), isolationPercentage = createPercentage(nodeTypeCount > 0 ? isolatedNodeTypes.length / nodeTypeCount * 100 : 0), availablePredicates = await this.getAvailablePredicatesForLayer(layer.id), availablePredicateSet = new Set(availablePredicates), usedPredicates = Array.from(usedPredicatesSet).filter((p) => availablePredicateSet.has(p)), utilizationPercentage = createPercentage(availablePredicates.length > 0 ? usedPredicates.length / availablePredicates.length * 100 : 0), relationshipsPerNodeType = nodeTypeCount > 0 ? relationshipCount / nodeTypeCount : 0, standardAlignment = await this.analyzeStandardAlignment(layer);
|
|
55
|
+
return {
|
|
56
|
+
layer: layer.id,
|
|
57
|
+
nodeTypeCount,
|
|
58
|
+
relationshipCount,
|
|
59
|
+
interLayerRelationshipCount: 0,
|
|
60
|
+
isolatedNodeTypes,
|
|
61
|
+
isolationPercentage,
|
|
62
|
+
availablePredicates,
|
|
63
|
+
usedPredicates,
|
|
64
|
+
utilizationPercentage,
|
|
65
|
+
relationshipsPerNodeType,
|
|
66
|
+
standardAlignment
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get available predicates for a layer
|
|
71
|
+
*/
|
|
72
|
+
async getAvailablePredicatesForLayer(layerId) {
|
|
73
|
+
return this.catalog.getTypesForLayer(layerId).map((rt) => rt.predicate);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Analyze standard alignment for ArchiMate layers
|
|
77
|
+
*/
|
|
78
|
+
async analyzeStandardAlignment(layer) {
|
|
79
|
+
if (!layer.inspiredBy || layer.inspiredBy.standard !== "ArchiMate 3.2")
|
|
80
|
+
return;
|
|
81
|
+
const expectedPatterns = this.getArchimateExpectedPatterns(layer.id);
|
|
82
|
+
return {
|
|
83
|
+
standard: layer.inspiredBy.standard,
|
|
84
|
+
expectedRelationships: expectedPatterns.length,
|
|
85
|
+
missingFromStandard: expectedPatterns
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get expected ArchiMate relationship patterns for a layer
|
|
90
|
+
*/
|
|
91
|
+
getArchimateExpectedPatterns(layerId) {
|
|
92
|
+
const template = LAYER_TEMPLATES.find((t) => t.layer === layerId);
|
|
93
|
+
return template ? template.patterns.map((p) => `${p.sourcePattern}\u2192${p.predicate}\u2192${p.destinationPattern}`) : [];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
CoverageAnalyzer
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=coverage-analyzer.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/audit/relationships/analysis/coverage-analyzer.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Coverage Analyzer - Computes relationship coverage metrics\n *\n * Analyzes:\n * - Node isolation (node types with zero relationships)\n * - Predicate utilization (available vs. used predicates)\n * - Relationship density\n * - Standard alignment validation\n */\n\nimport { RelationshipCatalog } from \"../../../core/relationship-catalog.js\";\nimport { RELATIONSHIPS_BY_SOURCE } from \"../../../generated/relationship-index.js\";\nimport {\n getAllLayers,\n type LayerMetadata,\n} from \"../../../generated/layer-registry.js\";\nimport { LAYER_TEMPLATES } from \"./layer-templates.js\";\nimport type { CoverageMetrics } from \"../../types.js\";\nimport { createPercentage } from \"../../types.js\";\n\n/**\n * Result from coverage analysis indicating success/partial/failure status\n */\nexport interface CoverageAnalysisResult {\n /** Metrics for successfully analyzed layers */\n results: CoverageMetrics[];\n /** Failures encountered during analysis (if any) */\n failures: Array<{ layer: string; error: Error }>;\n /** Whether analysis completed for all layers */\n isComplete: boolean;\n}\n\n/**\n * Coverage analyzer for relationship metrics\n */\nexport class CoverageAnalyzer {\n constructor(private catalog: RelationshipCatalog) {}\n\n /**\n * Analyze coverage for all layers\n * @returns Result object indicating success/partial/failure with complete flag\n */\n async analyzeAll(): Promise<CoverageAnalysisResult> {\n const layers = getAllLayers();\n const results: CoverageMetrics[] = [];\n const errors: Array<{ layer: string; error: Error }> = [];\n\n for (const layer of layers) {\n try {\n const metrics = await this.analyzeLayer(layer);\n results.push(metrics);\n } catch (error) {\n errors.push({\n layer: layer.id,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n\n // If all layers failed, throw the first error\n if (results.length === 0 && errors.length > 0) {\n throw errors[0].error;\n }\n\n // Report partial failures to user\n if (errors.length > 0 && results.length > 0) {\n console.error(\n `\\n\u26A0\uFE0F Warning: Coverage analysis failed for ${errors.length} layer(s):`\n );\n for (const { layer, error } of errors) {\n console.error(` - ${layer}: ${error.message}`);\n }\n console.error(\n `\\nSuccessfully analyzed ${results.length}/${layers.length} layers.\\n`\n );\n }\n\n return {\n results,\n failures: errors,\n isComplete: errors.length === 0,\n };\n }\n\n /**\n * Analyze coverage for a single layer\n */\n async analyzeLayer(layer: LayerMetadata): Promise<CoverageMetrics> {\n const nodeTypes = layer.nodeTypes;\n const nodeTypeCount = nodeTypes.length;\n\n // Count relationships per node type\n const relationshipCounts = new Map<string, number>();\n const usedPredicatesSet = new Set<string>();\n\n for (const nodeType of nodeTypes) {\n const relationships = RELATIONSHIPS_BY_SOURCE.get(nodeType) || [];\n relationshipCounts.set(nodeType, relationships.length);\n\n // Track used predicates\n for (const rel of relationships) {\n usedPredicatesSet.add(rel.predicate);\n }\n }\n\n // Calculate total relationships\n const relationshipCount = Array.from(relationshipCounts.values()).reduce(\n (sum, count) => sum + count,\n 0\n );\n\n // Identify isolated node types (zero relationships)\n const isolatedNodeTypes = nodeTypes.filter(\n (type) => (relationshipCounts.get(type) || 0) === 0\n );\n const isolationPercentage = createPercentage(\n nodeTypeCount > 0 ? (isolatedNodeTypes.length / nodeTypeCount) * 100 : 0\n );\n\n // Get available predicates for this layer\n const availablePredicates = await this.getAvailablePredicatesForLayer(\n layer.id\n );\n // Filter used predicates to only include those defined in relationship schemas for this layer\n // This handles cases where relationship index contains predicates not yet formalized in schemas\n const availablePredicateSet = new Set(availablePredicates);\n const usedPredicates = Array.from(usedPredicatesSet).filter(\n (p) => availablePredicateSet.has(p)\n );\n const utilizationPercentage = createPercentage(\n availablePredicates.length > 0\n ? (usedPredicates.length / availablePredicates.length) * 100\n : 0\n );\n\n // Calculate density\n const relationshipsPerNodeType =\n nodeTypeCount > 0 ? relationshipCount / nodeTypeCount : 0;\n\n // Standard alignment (for ArchiMate layers)\n const standardAlignment = await this.analyzeStandardAlignment(layer);\n\n return {\n layer: layer.id,\n nodeTypeCount,\n relationshipCount,\n interLayerRelationshipCount: 0,\n isolatedNodeTypes,\n isolationPercentage,\n availablePredicates,\n usedPredicates,\n utilizationPercentage,\n relationshipsPerNodeType,\n standardAlignment,\n };\n }\n\n /**\n * Get available predicates for a layer\n */\n private async getAvailablePredicatesForLayer(\n layerId: string\n ): Promise<string[]> {\n const relationshipTypes = this.catalog.getTypesForLayer(layerId);\n return relationshipTypes.map((rt) => rt.predicate);\n }\n\n /**\n * Analyze standard alignment for ArchiMate layers\n */\n private async analyzeStandardAlignment(\n layer: LayerMetadata\n ): Promise<CoverageMetrics[\"standardAlignment\"] | undefined> {\n if (!layer.inspiredBy) {\n return undefined;\n }\n\n // Check if this is an ArchiMate layer\n if (layer.inspiredBy.standard !== \"ArchiMate 3.2\") {\n return undefined;\n }\n\n // ArchiMate 3.2 expected relationship patterns\n const expectedPatterns = this.getArchimateExpectedPatterns(layer.id);\n\n return {\n standard: layer.inspiredBy.standard,\n expectedRelationships: expectedPatterns.length,\n missingFromStandard: expectedPatterns,\n };\n }\n\n /**\n * Get expected ArchiMate relationship patterns for a layer\n */\n private getArchimateExpectedPatterns(layerId: string): string[] {\n const template = LAYER_TEMPLATES.find((t) => t.layer === layerId);\n if (!template) {\n return [];\n }\n\n return template.patterns.map(\n (p) => `${p.sourcePattern}\u2192${p.predicate}\u2192${p.destinationPattern}`\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { RELATIONSHIPS } from "../../../generated/relationship-index.js";
|
|
2
|
+
import { duplicateImpactScore } from "../../types.js";
|
|
3
|
+
class DuplicateDetector {
|
|
4
|
+
catalog;
|
|
5
|
+
duplicateCache = null;
|
|
6
|
+
constructor(catalog) {
|
|
7
|
+
this.catalog = catalog;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Detect all duplicate candidates
|
|
11
|
+
*/
|
|
12
|
+
detectDuplicates() {
|
|
13
|
+
if (this.duplicateCache !== null)
|
|
14
|
+
return this.duplicateCache;
|
|
15
|
+
const candidates = [], relationshipsByEndpoints = /* @__PURE__ */ new Map();
|
|
16
|
+
for (const rel of RELATIONSHIPS) {
|
|
17
|
+
const key = `${rel.sourceSpecNodeId}:${rel.destinationSpecNodeId}`, group = relationshipsByEndpoints.get(key) || [];
|
|
18
|
+
group.push(rel), relationshipsByEndpoints.set(key, group);
|
|
19
|
+
}
|
|
20
|
+
for (const [_, group] of relationshipsByEndpoints)
|
|
21
|
+
if (!(group.length < 2))
|
|
22
|
+
for (let i = 0; i < group.length; i++)
|
|
23
|
+
for (let j = i + 1; j < group.length; j++) {
|
|
24
|
+
const candidate = this.checkDuplicatePair(group[i], group[j]);
|
|
25
|
+
candidate && candidates.push(candidate);
|
|
26
|
+
}
|
|
27
|
+
return this.duplicateCache = candidates, candidates;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if two relationships are semantic duplicates
|
|
31
|
+
*/
|
|
32
|
+
checkDuplicatePair(rel1, rel2) {
|
|
33
|
+
const pred1 = this.catalog.getTypeByPredicate(rel1.predicate), pred2 = this.catalog.getTypeByPredicate(rel2.predicate);
|
|
34
|
+
if (!pred1 || !pred2)
|
|
35
|
+
return pred1 || console.warn(`[DuplicateDetector] Unknown predicate not found in catalog: ${rel1.predicate} (relationship: ${rel1.id})`), pred2 || console.warn(`[DuplicateDetector] Unknown predicate not found in catalog: ${rel2.predicate} (relationship: ${rel2.id})`), null;
|
|
36
|
+
if (pred1.category === pred2.category) {
|
|
37
|
+
const confidence = this.assessConfidence(pred1, pred2), reason = this.buildReason(pred1, pred2), impactScore = duplicateImpactScore(confidence);
|
|
38
|
+
return {
|
|
39
|
+
relationships: [rel1.id, rel2.id],
|
|
40
|
+
predicates: [rel1.predicate, rel2.predicate],
|
|
41
|
+
sourceNodeType: rel1.sourceSpecNodeId,
|
|
42
|
+
destinationNodeType: rel1.destinationSpecNodeId,
|
|
43
|
+
reason,
|
|
44
|
+
confidence,
|
|
45
|
+
impactScore,
|
|
46
|
+
alignmentScore: 100 - impactScore
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (pred1.inversePredicate === pred2.predicate || pred2.inversePredicate === pred1.predicate) {
|
|
50
|
+
const impactScore = duplicateImpactScore("high");
|
|
51
|
+
return {
|
|
52
|
+
relationships: [rel1.id, rel2.id],
|
|
53
|
+
predicates: [rel1.predicate, rel2.predicate],
|
|
54
|
+
sourceNodeType: rel1.sourceSpecNodeId,
|
|
55
|
+
destinationNodeType: rel1.destinationSpecNodeId,
|
|
56
|
+
reason: "Predicates are inverses of each other",
|
|
57
|
+
confidence: "high",
|
|
58
|
+
impactScore,
|
|
59
|
+
alignmentScore: 100 - impactScore
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Assess confidence level of duplicate detection
|
|
66
|
+
*/
|
|
67
|
+
assessConfidence(pred1, pred2) {
|
|
68
|
+
return !pred1 || !pred2 ? "low" : pred1.category === pred2.category && pred1.semantics.transitivity === pred2.semantics.transitivity && pred1.semantics.symmetry === pred2.semantics.symmetry ? "high" : pred1.category === pred2.category ? "medium" : "low";
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Build reason explanation for duplicate detection
|
|
72
|
+
*/
|
|
73
|
+
buildReason(pred1, pred2) {
|
|
74
|
+
if (!pred1 || !pred2)
|
|
75
|
+
return "Unknown";
|
|
76
|
+
const parts = [];
|
|
77
|
+
return pred1.category === pred2.category && parts.push(`Both predicates in "${pred1.category}" category`), pred1.semantics.transitivity && pred2.semantics.transitivity && parts.push("both transitive"), pred1.semantics.symmetry && pred2.semantics.symmetry && parts.push("both symmetric"), parts.join(", ");
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get duplicate candidates by layer
|
|
81
|
+
*/
|
|
82
|
+
detectDuplicatesByLayer(layerId) {
|
|
83
|
+
return this.detectDuplicates().filter((d) => d.sourceNodeType.startsWith(`${layerId}.`));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get duplicate candidates by confidence level
|
|
87
|
+
*/
|
|
88
|
+
detectDuplicatesByConfidence(confidence) {
|
|
89
|
+
return this.detectDuplicates().filter((d) => d.confidence === confidence);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
DuplicateDetector
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=duplicate-detector.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/audit/relationships/analysis/duplicate-detector.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Duplicate Detector - Identifies semantic duplicate relationships\n *\n * Detects relationships where multiple predicates express the same\n * architectural meaning using:\n * - Predicate category analysis\n * - Transitivity/symmetry semantics\n * - Source/destination endpoint matching\n */\n\nimport { RelationshipCatalog } from \"../../../core/relationship-catalog.js\";\nimport {\n RELATIONSHIPS,\n type RelationshipSpec,\n} from \"../../../generated/relationship-index.js\";\nimport { duplicateImpactScore, type DuplicateCandidate } from \"../../types.js\";\n\n/**\n * Duplicate detector for semantic relationship overlap\n */\nexport class DuplicateDetector {\n private duplicateCache: DuplicateCandidate[] | null = null;\n\n constructor(private catalog: RelationshipCatalog) {}\n\n /**\n * Detect all duplicate candidates\n */\n detectDuplicates(): DuplicateCandidate[] {\n // Return cached results if available\n if (this.duplicateCache !== null) {\n return this.duplicateCache;\n }\n const candidates: DuplicateCandidate[] = [];\n const relationshipsByEndpoints = new Map<\n string,\n RelationshipSpec[]\n >();\n\n // Group relationships by source+destination\n for (const rel of RELATIONSHIPS) {\n const key = `${rel.sourceSpecNodeId}:${rel.destinationSpecNodeId}`;\n const group = relationshipsByEndpoints.get(key) || [];\n group.push(rel);\n relationshipsByEndpoints.set(key, group);\n }\n\n // Check for predicate overlap within same endpoints\n for (const [_, group] of relationshipsByEndpoints) {\n if (group.length < 2) {\n continue;\n }\n\n // Check all pairs within the group\n for (let i = 0; i < group.length; i++) {\n for (let j = i + 1; j < group.length; j++) {\n const candidate = this.checkDuplicatePair(group[i], group[j]);\n if (candidate) {\n candidates.push(candidate);\n }\n }\n }\n }\n\n // Cache the results\n this.duplicateCache = candidates;\n\n return candidates;\n }\n\n /**\n * Check if two relationships are semantic duplicates\n */\n private checkDuplicatePair(\n rel1: RelationshipSpec,\n rel2: RelationshipSpec\n ): DuplicateCandidate | null {\n const pred1 = this.catalog.getTypeByPredicate(rel1.predicate);\n const pred2 = this.catalog.getTypeByPredicate(rel2.predicate);\n\n if (!pred1 || !pred2) {\n // Log unknown predicates for debugging\n if (!pred1) {\n console.warn(\n `[DuplicateDetector] Unknown predicate not found in catalog: ${rel1.predicate} (relationship: ${rel1.id})`\n );\n }\n if (!pred2) {\n console.warn(\n `[DuplicateDetector] Unknown predicate not found in catalog: ${rel2.predicate} (relationship: ${rel2.id})`\n );\n }\n return null;\n }\n\n // Check if predicates are in the same category\n if (pred1.category === pred2.category) {\n const confidence = this.assessConfidence(pred1, pred2);\n const reason = this.buildReason(pred1, pred2);\n const impactScore = duplicateImpactScore(confidence);\n\n return {\n relationships: [rel1.id, rel2.id],\n predicates: [rel1.predicate, rel2.predicate],\n sourceNodeType: rel1.sourceSpecNodeId,\n destinationNodeType: rel1.destinationSpecNodeId,\n reason,\n confidence,\n impactScore,\n alignmentScore: 100 - impactScore,\n };\n }\n\n // Check for inverse relationships (may indicate redundancy)\n if (\n pred1.inversePredicate === pred2.predicate ||\n pred2.inversePredicate === pred1.predicate\n ) {\n const impactScore = duplicateImpactScore(\"high\");\n return {\n relationships: [rel1.id, rel2.id],\n predicates: [rel1.predicate, rel2.predicate],\n sourceNodeType: rel1.sourceSpecNodeId,\n destinationNodeType: rel1.destinationSpecNodeId,\n reason: \"Predicates are inverses of each other\",\n confidence: \"high\",\n impactScore,\n alignmentScore: 100 - impactScore,\n };\n }\n\n return null;\n }\n\n /**\n * Assess confidence level of duplicate detection\n */\n private assessConfidence(\n pred1: ReturnType<RelationshipCatalog[\"getTypeByPredicate\"]>,\n pred2: ReturnType<RelationshipCatalog[\"getTypeByPredicate\"]>\n ): \"high\" | \"medium\" | \"low\" {\n if (!pred1 || !pred2) {\n return \"low\";\n }\n\n // High confidence: same category + same semantics\n if (\n pred1.category === pred2.category &&\n pred1.semantics.transitivity === pred2.semantics.transitivity &&\n pred1.semantics.symmetry === pred2.semantics.symmetry\n ) {\n return \"high\";\n }\n\n // Medium confidence: same category + different semantics\n if (pred1.category === pred2.category) {\n return \"medium\";\n }\n\n return \"low\";\n }\n\n /**\n * Build reason explanation for duplicate detection\n */\n private buildReason(\n pred1: ReturnType<RelationshipCatalog[\"getTypeByPredicate\"]>,\n pred2: ReturnType<RelationshipCatalog[\"getTypeByPredicate\"]>\n ): string {\n if (!pred1 || !pred2) {\n return \"Unknown\";\n }\n\n const parts: string[] = [];\n\n // Category overlap\n if (pred1.category === pred2.category) {\n parts.push(`Both predicates in \"${pred1.category}\" category`);\n }\n\n // Semantic overlap\n if (pred1.semantics.transitivity && pred2.semantics.transitivity) {\n parts.push(\"both transitive\");\n }\n if (pred1.semantics.symmetry && pred2.semantics.symmetry) {\n parts.push(\"both symmetric\");\n }\n\n return parts.join(\", \");\n }\n\n /**\n * Get duplicate candidates by layer\n */\n detectDuplicatesByLayer(layerId: string): DuplicateCandidate[] {\n const allDuplicates = this.detectDuplicates();\n return allDuplicates.filter((d) =>\n d.sourceNodeType.startsWith(`${layerId}.`)\n );\n }\n\n /**\n * Get duplicate candidates by confidence level\n */\n detectDuplicatesByConfidence(\n confidence: \"high\" | \"medium\" | \"low\"\n ): DuplicateCandidate[] {\n const allDuplicates = this.detectDuplicates();\n return allDuplicates.filter((d) => d.confidence === confidence);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { RELATIONSHIPS_BY_SOURCE } from "../../../generated/relationship-index.js";
|
|
2
|
+
import { getAllLayers } from "../../../generated/layer-registry.js";
|
|
3
|
+
import { LAYER_TEMPLATES } from "./layer-templates.js";
|
|
4
|
+
import { gapImpactScore } from "../../types.js";
|
|
5
|
+
class GapAnalyzer {
|
|
6
|
+
/**
|
|
7
|
+
* Analyze gaps for all layers
|
|
8
|
+
*/
|
|
9
|
+
analyzeAll() {
|
|
10
|
+
const layers = getAllLayers(), candidates = [];
|
|
11
|
+
for (const layer of layers) {
|
|
12
|
+
const layerGaps = this.analyzeLayer(layer);
|
|
13
|
+
candidates.push(...layerGaps);
|
|
14
|
+
}
|
|
15
|
+
return candidates;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Analyze gaps for a single layer with analysis status
|
|
19
|
+
*/
|
|
20
|
+
analyzeLayerWithStatus(layer) {
|
|
21
|
+
const patterns = this.getLayerTemplates(layer);
|
|
22
|
+
if (patterns.length === 0)
|
|
23
|
+
return {
|
|
24
|
+
analyzed: !1,
|
|
25
|
+
gaps: [],
|
|
26
|
+
reason: `No template available for layer '${layer.id}'`
|
|
27
|
+
};
|
|
28
|
+
const candidates = [];
|
|
29
|
+
for (const pattern of patterns) {
|
|
30
|
+
const sourceTypes = this.findMatchingNodeTypes(layer, pattern.sourceType), destinationTypes = this.findMatchingNodeTypes(layer, pattern.destinationType);
|
|
31
|
+
for (const sourceType of sourceTypes)
|
|
32
|
+
for (const destType of destinationTypes)
|
|
33
|
+
if (!this.relationshipExists(sourceType, destType, pattern.predicate)) {
|
|
34
|
+
const priority = this.assessPriority(layer, sourceType), impactScore = gapImpactScore(priority);
|
|
35
|
+
candidates.push({
|
|
36
|
+
sourceNodeType: sourceType,
|
|
37
|
+
destinationNodeType: destType,
|
|
38
|
+
suggestedPredicate: pattern.predicate,
|
|
39
|
+
reason: pattern.reason,
|
|
40
|
+
priority,
|
|
41
|
+
standardReference: pattern.standardReference,
|
|
42
|
+
impactScore,
|
|
43
|
+
alignmentScore: 100 - impactScore
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
analyzed: !0,
|
|
49
|
+
gaps: candidates
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Analyze gaps for a single layer (legacy method for backward compatibility)
|
|
54
|
+
*/
|
|
55
|
+
analyzeLayer(layer) {
|
|
56
|
+
return this.analyzeLayerWithStatus(layer).gaps;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get relationship templates for a layer
|
|
60
|
+
*/
|
|
61
|
+
getLayerTemplates(layer) {
|
|
62
|
+
const template = LAYER_TEMPLATES.find((t) => t.layer === layer.id);
|
|
63
|
+
return template ? template.patterns.map((p) => ({
|
|
64
|
+
sourceType: p.sourcePattern,
|
|
65
|
+
destinationType: p.destinationPattern,
|
|
66
|
+
predicate: p.predicate,
|
|
67
|
+
reason: p.description,
|
|
68
|
+
standardReference: `${template.standard}`
|
|
69
|
+
})) : [];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Find node types matching a pattern
|
|
73
|
+
*/
|
|
74
|
+
findMatchingNodeTypes(layer, pattern) {
|
|
75
|
+
return layer.nodeTypes.filter((nodeType) => {
|
|
76
|
+
const typeName = nodeType.split(".")[1];
|
|
77
|
+
return typeName?.includes(pattern) || typeName === pattern;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if a relationship exists
|
|
82
|
+
*/
|
|
83
|
+
relationshipExists(sourceType, destType, predicate) {
|
|
84
|
+
return (RELATIONSHIPS_BY_SOURCE.get(sourceType) || []).some((rel) => rel.destinationSpecNodeId === destType && rel.predicate === predicate);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Assess priority of a gap
|
|
88
|
+
*/
|
|
89
|
+
assessPriority(layer, sourceType) {
|
|
90
|
+
if (["security", "ux", "navigation"].includes(layer.id))
|
|
91
|
+
return "high";
|
|
92
|
+
const typeName = sourceType.split(".")[1] || "";
|
|
93
|
+
return typeName.includes("component") || typeName.includes("container") || typeName.includes("service") || typeName.includes("module") ? "medium" : "low";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
GapAnalyzer
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=gap-analyzer.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/audit/relationships/analysis/gap-analyzer.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Gap Analyzer - Identifies missing relationships based on layer-specific templates\n *\n * Uses standard-inspired templates to identify missing architectural\n * relationships that should exist based on:\n * - ArchiMate 3.2 metamodel patterns (layers 1, 2, 4, 5)\n * - OpenAPI 3.0 operation patterns (layer 6)\n * - NIST SP 800-53 control framework patterns (layer 3)\n * - React and router component patterns (layers 9, 10)\n *\n * Note: Gap detection is heuristic-based and patterns are inspired by these standards\n * and frameworks, not formally compliant implementations of them.\n */\n\nimport { RELATIONSHIPS_BY_SOURCE } from \"../../../generated/relationship-index.js\";\nimport {\n getAllLayers,\n type LayerMetadata,\n} from \"../../../generated/layer-registry.js\";\nimport { LAYER_TEMPLATES } from \"./layer-templates.js\";\nimport { gapImpactScore, type GapCandidate } from \"../../types.js\";\n\n/**\n * Expected relationship pattern template\n */\ninterface RelationshipPattern {\n sourceType: string; // Node type pattern (e.g., \"goal\", \"process\")\n destinationType: string;\n predicate: string;\n reason: string;\n standardReference?: string;\n}\n\n/**\n * Gap analysis result with analysis status\n */\nexport interface GapAnalysisResult {\n analyzed: boolean; // Whether the layer was analyzed\n gaps: GapCandidate[]; // Gap candidates (empty array if analyzed with no gaps, or if not analyzed)\n reason?: string; // Reason for not analyzing (e.g., \"No template available for layer\")\n}\n\n/**\n * Gap analyzer for missing relationships\n */\nexport class GapAnalyzer {\n /**\n * Analyze gaps for all layers\n */\n analyzeAll(): GapCandidate[] {\n const layers = getAllLayers();\n const candidates: GapCandidate[] = [];\n\n for (const layer of layers) {\n const layerGaps = this.analyzeLayer(layer);\n candidates.push(...layerGaps);\n }\n\n return candidates;\n }\n\n /**\n * Analyze gaps for a single layer with analysis status\n */\n analyzeLayerWithStatus(layer: LayerMetadata): GapAnalysisResult {\n const patterns = this.getLayerTemplates(layer);\n\n // Check if layer has templates\n if (patterns.length === 0) {\n return {\n analyzed: false,\n gaps: [],\n reason: `No template available for layer '${layer.id}'`,\n };\n }\n\n const candidates: GapCandidate[] = [];\n\n for (const pattern of patterns) {\n // Find matching node types\n const sourceTypes = this.findMatchingNodeTypes(\n layer,\n pattern.sourceType\n );\n const destinationTypes = this.findMatchingNodeTypes(\n layer,\n pattern.destinationType\n );\n\n // Check for missing relationships\n for (const sourceType of sourceTypes) {\n for (const destType of destinationTypes) {\n const exists = this.relationshipExists(\n sourceType,\n destType,\n pattern.predicate\n );\n\n if (!exists) {\n const priority = this.assessPriority(layer, sourceType);\n const impactScore = gapImpactScore(priority);\n candidates.push({\n sourceNodeType: sourceType,\n destinationNodeType: destType,\n suggestedPredicate: pattern.predicate,\n reason: pattern.reason,\n priority,\n standardReference: pattern.standardReference,\n impactScore,\n alignmentScore: 100 - impactScore,\n });\n }\n }\n }\n }\n\n return {\n analyzed: true,\n gaps: candidates,\n };\n }\n\n /**\n * Analyze gaps for a single layer (legacy method for backward compatibility)\n */\n analyzeLayer(layer: LayerMetadata): GapCandidate[] {\n const result = this.analyzeLayerWithStatus(layer);\n return result.gaps;\n }\n\n /**\n * Get relationship templates for a layer\n */\n private getLayerTemplates(layer: LayerMetadata): RelationshipPattern[] {\n const template = LAYER_TEMPLATES.find((t) => t.layer === layer.id);\n if (!template) {\n return [];\n }\n\n return template.patterns.map((p) => ({\n sourceType: p.sourcePattern,\n destinationType: p.destinationPattern,\n predicate: p.predicate,\n reason: p.description,\n standardReference: `${template.standard}`,\n }));\n }\n\n /**\n * Find node types matching a pattern\n */\n private findMatchingNodeTypes(\n layer: LayerMetadata,\n pattern: string\n ): string[] {\n return layer.nodeTypes.filter((nodeType) => {\n const typeName = nodeType.split(\".\")[1];\n return typeName?.includes(pattern) || typeName === pattern;\n });\n }\n\n /**\n * Check if a relationship exists\n */\n private relationshipExists(\n sourceType: string,\n destType: string,\n predicate: string\n ): boolean {\n const relationships = RELATIONSHIPS_BY_SOURCE.get(sourceType) || [];\n return relationships.some(\n (rel) =>\n rel.destinationSpecNodeId === destType && rel.predicate === predicate\n );\n }\n\n /**\n * Assess priority of a gap\n */\n private assessPriority(\n layer: LayerMetadata,\n sourceType: string\n ): \"high\" | \"medium\" | \"low\" {\n // High priority: zero-relationship layers\n if ([\"security\", \"ux\", \"navigation\"].includes(layer.id)) {\n return \"high\";\n }\n\n // Medium priority: container/composition types\n const typeName = sourceType.split(\".\")[1] || \"\";\n if (\n typeName.includes(\"component\") ||\n typeName.includes(\"container\") ||\n typeName.includes(\"service\") ||\n typeName.includes(\"module\")\n ) {\n return \"medium\";\n }\n\n // Low priority: all other patterns\n return \"low\";\n }\n}\n"],
|
|
5
|
+
"mappings": "AAcA,SAAS,+BAA+B;AACxC,SACE,oBAEK;AACP,SAAS,uBAAuB;AAChC,SAAS,sBAAyC;AAyB5C,MAAO,YAAW;;;;EAItB,aAAU;AACR,UAAM,SAAS,aAAY,GACrB,aAA6B,CAAA;AAEnC,eAAW,SAAS,QAAQ;AAC1B,YAAM,YAAY,KAAK,aAAa,KAAK;AACzC,iBAAW,KAAK,GAAG,SAAS;IAC9B;AAEA,WAAO;EACT;;;;EAKA,uBAAuB,OAAoB;AACzC,UAAM,WAAW,KAAK,kBAAkB,KAAK;AAG7C,QAAI,SAAS,WAAW;AACtB,aAAO;QACL,UAAU;QACV,MAAM,CAAA;QACN,QAAQ,oCAAoC,MAAM,EAAE;;AAIxD,UAAM,aAA6B,CAAA;AAEnC,eAAW,WAAW,UAAU;AAE9B,YAAM,cAAc,KAAK,sBACvB,OACA,QAAQ,UAAU,GAEd,mBAAmB,KAAK,sBAC5B,OACA,QAAQ,eAAe;AAIzB,iBAAW,cAAc;AACvB,mBAAW,YAAY;AAOrB,cAAI,CANW,KAAK,mBAClB,YACA,UACA,QAAQ,SAAS,GAGN;AACX,kBAAM,WAAW,KAAK,eAAe,OAAO,UAAU,GAChD,cAAc,eAAe,QAAQ;AAC3C,uBAAW,KAAK;cACd,gBAAgB;cAChB,qBAAqB;cACrB,oBAAoB,QAAQ;cAC5B,QAAQ,QAAQ;cAChB;cACA,mBAAmB,QAAQ;cAC3B;cACA,gBAAgB,MAAM;aACvB;UACH;IAGN;AAEA,WAAO;MACL,UAAU;MACV,MAAM;;EAEV;;;;EAKA,aAAa,OAAoB;AAE/B,WADe,KAAK,uBAAuB,KAAK,EAClC;EAChB;;;;EAKQ,kBAAkB,OAAoB;AAC5C,UAAM,WAAW,gBAAgB,KAAK,CAAC,MAAM,EAAE,UAAU,MAAM,EAAE;AACjE,WAAK,WAIE,SAAS,SAAS,IAAI,CAAC,OAAO;MACnC,YAAY,EAAE;MACd,iBAAiB,EAAE;MACnB,WAAW,EAAE;MACb,QAAQ,EAAE;MACV,mBAAmB,GAAG,SAAS,QAAQ;MACvC,IATO,CAAA;EAUX;;;;EAKQ,sBACN,OACA,SAAe;AAEf,WAAO,MAAM,UAAU,OAAO,CAAC,aAAY;AACzC,YAAM,WAAW,SAAS,MAAM,GAAG,EAAE,CAAC;AACtC,aAAO,UAAU,SAAS,OAAO,KAAK,aAAa;IACrD,CAAC;EACH;;;;EAKQ,mBACN,YACA,UACA,WAAiB;AAGjB,YADsB,wBAAwB,IAAI,UAAU,KAAK,CAAA,GAC5C,KACnB,CAAC,QACC,IAAI,0BAA0B,YAAY,IAAI,cAAc,SAAS;EAE3E;;;;EAKQ,eACN,OACA,YAAkB;AAGlB,QAAI,CAAC,YAAY,MAAM,YAAY,EAAE,SAAS,MAAM,EAAE;AACpD,aAAO;AAIT,UAAM,WAAW,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK;AAC7C,WACE,SAAS,SAAS,WAAW,KAC7B,SAAS,SAAS,WAAW,KAC7B,SAAS,SAAS,SAAS,KAC3B,SAAS,SAAS,QAAQ,IAEnB,WAIF;EACT;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|