@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
package/dist/commands/delete.js
CHANGED
|
@@ -1,26 +1,140 @@
|
|
|
1
1
|
import { confirm } from "@clack/prompts";
|
|
2
2
|
import ansis from "ansis";
|
|
3
3
|
import { Model } from "../core/model.js";
|
|
4
|
+
import { MutationHandler } from "../core/mutation-handler.js";
|
|
5
|
+
import { ReferenceRegistry } from "../core/reference-registry.js";
|
|
6
|
+
import { DependencyTracker, TraceDirection } from "../core/dependency-tracker.js";
|
|
4
7
|
import { findElementLayer } from "../utils/element-utils.js";
|
|
8
|
+
import { CLIError, handleError, handleSuccess, ErrorCategory, ModelNotFoundError } from "../utils/errors.js";
|
|
5
9
|
import { startSpan, endSpan } from "../telemetry/index.js";
|
|
10
|
+
import { getErrorMessage } from "../utils/errors.js";
|
|
6
11
|
const isTelemetryEnabled = !1;
|
|
7
12
|
async function deleteCommand(id, options) {
|
|
8
13
|
const span = isTelemetryEnabled ? startSpan("element.delete", {
|
|
9
14
|
"element.id": id,
|
|
10
|
-
"element.force": !!options.force
|
|
15
|
+
"element.force": !!options.force,
|
|
16
|
+
"element.cascade": !!options.cascade,
|
|
17
|
+
"element.dryRun": !!options.dryRun
|
|
11
18
|
}) : null;
|
|
12
19
|
try {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
let model;
|
|
21
|
+
try {
|
|
22
|
+
model = await Model.load();
|
|
23
|
+
} catch (error) {
|
|
24
|
+
const message = getErrorMessage(error);
|
|
25
|
+
throw message.includes("No DR project") || message.includes("Model not found") ? new ModelNotFoundError() : error;
|
|
26
|
+
}
|
|
27
|
+
const layerName = await findElementLayer(model, id);
|
|
28
|
+
if (!layerName)
|
|
29
|
+
throw new CLIError(`Element ${id} not found`, ErrorCategory.USER, [
|
|
30
|
+
`Use "dr search ${id}" to find similar elements`,
|
|
31
|
+
'Use "dr list <layer>" to list all elements in a layer'
|
|
32
|
+
]);
|
|
33
|
+
const element = (await model.getLayer(layerName)).getElement(id);
|
|
34
|
+
if (!element)
|
|
35
|
+
throw new CLIError(`Element ${id} not found`, ErrorCategory.USER, [
|
|
36
|
+
`Use "dr search ${id}" to find similar elements`,
|
|
37
|
+
'Use "dr list <layer>" to list all elements in a layer'
|
|
38
|
+
]);
|
|
39
|
+
const registry = new ReferenceRegistry();
|
|
40
|
+
for (const layer2 of model.layers.values())
|
|
41
|
+
for (const element2 of layer2.listElements())
|
|
42
|
+
registry.registerElement(element2);
|
|
43
|
+
const tracker = new DependencyTracker(registry, model), dependents = tracker.traceDependencies(id, TraceDirection.DOWN, null);
|
|
44
|
+
if (console.log(""), console.log(ansis.bold(`Removing element: ${ansis.yellow(id)}`)), console.log(ansis.dim(` Layer: ${layerName}`)), console.log(ansis.dim(` Type: ${element.type || "unknown"}`)), element.name && console.log(ansis.dim(` Name: ${element.name}`)), dependents.length > 0) {
|
|
45
|
+
console.log(""), console.log(ansis.yellow(`\u26A0 Warning: This element has ${dependents.length} dependent element(s):`));
|
|
46
|
+
const directDependents = tracker.traceDependencies(id, TraceDirection.DOWN, 1);
|
|
47
|
+
for (const dep of directDependents.slice(0, 5)) {
|
|
48
|
+
const depLayer = model.getElementById(dep)?.layer || "unknown";
|
|
49
|
+
console.log(ansis.dim(` - ${dep} (${depLayer})`));
|
|
50
|
+
}
|
|
51
|
+
if (directDependents.length > 5 && console.log(ansis.dim(` ... and ${directDependents.length - 5} more direct dependents`)), dependents.length > directDependents.length && console.log(ansis.dim(` (${dependents.length - directDependents.length} transitive dependents not shown)`)), !options.cascade && !options.force) {
|
|
52
|
+
console.log(""), console.log(ansis.red("\u2717 Cannot remove element with dependencies.")), console.log(ansis.dim("Use --cascade to remove all dependent elements")), console.log(ansis.dim("or --force to skip dependency checks"));
|
|
53
|
+
const suggestions = [
|
|
54
|
+
"Use --dry-run with --cascade to preview what would be deleted",
|
|
55
|
+
'Review dependencies before deletion using "dr show <element>"',
|
|
56
|
+
"Use --cascade to automatically remove all dependent elements",
|
|
57
|
+
"Or use --force to remove only this element (dependencies will reference a non-existent element)"
|
|
58
|
+
];
|
|
59
|
+
throw new CLIError("Element has dependencies", ErrorCategory.USER, suggestions, {
|
|
60
|
+
operation: "delete",
|
|
61
|
+
relatedElements: directDependents.slice(0, 10),
|
|
62
|
+
context: `Element ${id} has ${dependents.length} dependent elements`
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const elementsToRemove = options.cascade ? [id, ...dependents] : [id];
|
|
67
|
+
if (options.dryRun) {
|
|
68
|
+
if (console.log(""), console.log(ansis.yellow("Dry run - not removing")), console.log(ansis.dim(`Would remove ${elementsToRemove.length} element(s)`)), options.cascade && dependents.length > 0) {
|
|
69
|
+
console.log(""), console.log(ansis.dim("Elements that would be removed:")), console.log(ansis.dim(` - ${id} (target)`));
|
|
70
|
+
for (const dep of dependents.slice(0, 10))
|
|
71
|
+
console.log(ansis.dim(` - ${dep} (dependent)`));
|
|
72
|
+
dependents.length > 10 && console.log(ansis.dim(` ... and ${dependents.length - 10} more`));
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (!options.force)
|
|
77
|
+
if (!(process.stdin.isTTY && process.stdout.isTTY))
|
|
78
|
+
console.log(ansis.dim("Non-interactive environment detected - proceeding without confirmation"));
|
|
79
|
+
else {
|
|
80
|
+
const message = options.cascade && dependents.length > 0 ? `Delete ${ansis.bold(id)} and ${ansis.bold(String(dependents.length))} dependent element(s)? This cannot be undone.` : `Delete element ${ansis.bold(id)}? This cannot be undone.`;
|
|
81
|
+
if (!await confirm({
|
|
82
|
+
message,
|
|
83
|
+
initialValue: !1
|
|
84
|
+
})) {
|
|
85
|
+
console.log(ansis.dim("Cancelled"));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
let deletedCount = 0;
|
|
90
|
+
try {
|
|
91
|
+
if (options.cascade && dependents.length > 0) {
|
|
92
|
+
const sortedDependents = [...dependents].reverse();
|
|
93
|
+
for (const depId of sortedDependents)
|
|
94
|
+
try {
|
|
95
|
+
const depLayerName = await findElementLayer(model, depId);
|
|
96
|
+
if (!depLayerName)
|
|
97
|
+
continue;
|
|
98
|
+
const depElement = (await model.getLayer(depLayerName)).getElement(depId);
|
|
99
|
+
await new MutationHandler(model, depId, depLayerName).executeDelete(depElement), deletedCount++, options.verbose && console.log(ansis.dim(` Deleted dependent: ${depId}`));
|
|
100
|
+
} catch {
|
|
101
|
+
const suggestions = [
|
|
102
|
+
`${deletedCount} dependent element(s) were deleted before the error`,
|
|
103
|
+
'Check the model state with "dr validate" to identify any broken references',
|
|
104
|
+
'You may need to manually delete remaining elements or use "dr show" to inspect'
|
|
105
|
+
];
|
|
106
|
+
throw new CLIError(`Failed to delete dependent element ${depId}`, ErrorCategory.SYSTEM, suggestions, {
|
|
107
|
+
operation: "delete (cascade)",
|
|
108
|
+
partialProgress: { completed: deletedCount, total: sortedDependents.length },
|
|
109
|
+
relatedElements: [id, ...sortedDependents.slice(0, 5)]
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (options.cascade && deletedCount > 0 && !(error instanceof CLIError)) {
|
|
115
|
+
const suggestions = [
|
|
116
|
+
`${deletedCount} dependent element(s) were successfully deleted`,
|
|
117
|
+
'Use "dr validate" to check for broken references',
|
|
118
|
+
"The target element was not deleted - you can retry the operation"
|
|
119
|
+
];
|
|
120
|
+
throw new CLIError("Cascade deletion was partially completed but encountered an error", ErrorCategory.SYSTEM, suggestions, {
|
|
121
|
+
operation: "delete (cascade)",
|
|
122
|
+
partialProgress: { completed: deletedCount, total: dependents.length }
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
const handler = new MutationHandler(model, id, layerName);
|
|
128
|
+
if (await handler.executeDelete(element), isTelemetryEnabled && span && (span.setAttribute("layer.name", layerName), span.setAttribute("element.dependents", dependents.length), span.setAttribute("element.totalDeleted", elementsToRemove.length)), handler.getBeforeState()) {
|
|
129
|
+
const activeChangeset = await handler.getStagingManager().getActive();
|
|
130
|
+
activeChangeset && activeChangeset.status === "staged" ? handleSuccess(`Staged deletion of element ${ansis.bold(id)} to ${ansis.bold(activeChangeset.name)}`, {
|
|
131
|
+
status: "staged",
|
|
132
|
+
changeset: activeChangeset.name
|
|
133
|
+
}) : (elementsToRemove.reduce((n, eid) => n + model.relationships.deleteForElement(eid), 0) > 0 && await model.saveRelationships(), console.log(""), console.log(ansis.green(`\u2713 Deleted element ${ansis.bold(id)}`)), options.cascade && dependents.length > 0 && console.log(ansis.green(`\u2713 Deleted ${dependents.length} dependent element(s)`)), options.verbose && (console.log(ansis.dim(` Layer: ${layerName}`)), console.log(ansis.dim(` Total elements deleted: ${elementsToRemove.length}`))));
|
|
134
|
+
} else
|
|
135
|
+
elementsToRemove.reduce((n, eid) => n + model.relationships.deleteForElement(eid), 0) > 0 && await model.saveRelationships(), console.log(""), console.log(ansis.green(`\u2713 Deleted element ${ansis.bold(id)}`)), options.cascade && dependents.length > 0 && console.log(ansis.green(`\u2713 Deleted ${dependents.length} dependent element(s)`)), options.verbose && (console.log(ansis.dim(` Layer: ${layerName}`)), console.log(ansis.dim(` Total elements deleted: ${elementsToRemove.length}`)));
|
|
20
136
|
} catch (error) {
|
|
21
|
-
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({ code: 2, message: error.message }));
|
|
22
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
23
|
-
console.error(ansis.red(`Error: ${message}`)), process.exit(1);
|
|
137
|
+
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({ code: 2, message: error.message })), handleError(error);
|
|
24
138
|
} finally {
|
|
25
139
|
isTelemetryEnabled && endSpan(span);
|
|
26
140
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/delete.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Delete an element\n */\n\nimport { confirm } from '@clack/prompts';\nimport ansis from 'ansis';\nimport { Model } from '../core/model.js';\nimport { findElementLayer } from '../utils/element-utils.js';\nimport { startSpan, endSpan } from '../telemetry/index.js';\n\ndeclare const TELEMETRY_ENABLED: boolean | undefined;\nconst isTelemetryEnabled = typeof TELEMETRY_ENABLED !== 'undefined' ? TELEMETRY_ENABLED : false;\n\nexport interface DeleteOptions {\n force?: boolean;\n verbose?: boolean;\n debug?: boolean;\n}\n\nexport async function deleteCommand(id: string, options: DeleteOptions): Promise<void> {\n const span = isTelemetryEnabled ? startSpan('element.delete', {\n 'element.id': id,\n 'element.force': !!options.force,\n }) : null;\n\n try {\n // Load model\n const model = await Model.load();\n\n // Find element\n const layerName = await findElementLayer(model, id);\n if (!layerName) {\n console.error(ansis.red(`Error: Element ${id} not found`));\n process.exit(1);\n }\n\n // Confirm deletion unless --force\n if (!options.force) {\n const confirmed = await confirm({\n message: `Delete element ${ansis.bold(id)}? This cannot be undone.`,\n initialValue: false,\n });\n\n if (!confirmed) {\n console.log(ansis.dim('Cancelled'));\n process.exit(0);\n }\n }\n\n const layer = (await model.getLayer(layerName))!;\n\n // Capture element state for changeset tracking before deletion\n const element = layer.getElement(id)!;\n const beforeState = element.toJSON();\n\n // Delete element\n const deleted = layer.deleteElement(id);\n if (!deleted) {\n console.error(ansis.red(`Error: Failed to delete element ${id}`));\n process.exit(1);\n }\n\n // Delete all relationships involving this element\n model.relationships.deleteForElement(id);\n\n // Track change in active changeset if present\n const activeChangeset = model.getActiveChangesetContext();\n await activeChangeset.trackChange(\n 'delete',\n id,\n layerName,\n beforeState as unknown as Record<string, unknown>,\n undefined\n );\n\n // Save layer and manifest\n await model.saveLayer(layerName);\n\n // Only save relationships if they were modified\n if (model.relationships.isDirty()) {\n await model.saveRelationships();\n }\n\n await model.saveManifest();\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute('layer.name', layerName);\n }\n\n console.log(ansis.green(`\u2713 Deleted element ${ansis.bold(id)}`));\n if (options.verbose) {\n console.log(ansis.dim(` Layer: ${layerName}`));\n }\n } catch (error) {\n if (isTelemetryEnabled && span) {\n (span as any).recordException(error as Error);\n (span as any).setStatus({ code: 2, message: (error as Error).message });\n }\n const message = error instanceof Error ? error.message : String(error);\n console.error(ansis.red(`Error: ${message}`));\n process.exit(1);\n } finally {\n if (isTelemetryEnabled) {\n endSpan(span);\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "AAIA,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,SAAS,aAAa;AACtB,SAAS,wBAAwB;AACjC,SAAS,WAAW,eAAe;
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["/**\n * Delete an element\n */\n\nimport { confirm } from \"@clack/prompts\";\nimport ansis from \"ansis\";\nimport { Model } from \"../core/model.js\";\nimport { MutationHandler } from \"../core/mutation-handler.js\";\nimport { ReferenceRegistry } from \"../core/reference-registry.js\";\nimport { DependencyTracker, TraceDirection } from \"../core/dependency-tracker.js\";\nimport { findElementLayer } from \"../utils/element-utils.js\";\nimport { CLIError, handleError, handleSuccess, ErrorCategory, ModelNotFoundError } from \"../utils/errors.js\";\nimport { startSpan, endSpan } from \"../telemetry/index.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\n\ndeclare const TELEMETRY_ENABLED: boolean | undefined;\nconst isTelemetryEnabled = typeof TELEMETRY_ENABLED !== \"undefined\" ? TELEMETRY_ENABLED : false;\n\nexport interface DeleteOptions {\n force?: boolean;\n verbose?: boolean;\n debug?: boolean;\n cascade?: boolean;\n dryRun?: boolean;\n}\n\nexport async function deleteCommand(id: string, options: DeleteOptions): Promise<void> {\n const span = isTelemetryEnabled\n ? startSpan(\"element.delete\", {\n \"element.id\": id,\n \"element.force\": !!options.force,\n \"element.cascade\": !!options.cascade,\n \"element.dryRun\": !!options.dryRun,\n })\n : null;\n\n try {\n // Load model (with error handling for missing models)\n let model: Model;\n try {\n model = await Model.load();\n } catch (error) {\n const message = getErrorMessage(error);\n if (message.includes(\"No DR project\") || message.includes(\"Model not found\")) {\n throw new ModelNotFoundError();\n }\n throw error;\n }\n\n // Find element\n const layerName = await findElementLayer(model, id);\n if (!layerName) {\n throw new CLIError(`Element ${id} not found`, ErrorCategory.USER, [\n `Use \"dr search ${id}\" to find similar elements`,\n 'Use \"dr list <layer>\" to list all elements in a layer',\n ]);\n }\n\n const layer = (await model.getLayer(layerName))!;\n const element = layer.getElement(id);\n\n if (!element) {\n throw new CLIError(`Element ${id} not found`, ErrorCategory.USER, [\n `Use \"dr search ${id}\" to find similar elements`,\n 'Use \"dr list <layer>\" to list all elements in a layer',\n ]);\n }\n\n // Build reference registry to track dependencies\n const registry = new ReferenceRegistry();\n for (const layer of model.layers.values()) {\n for (const element of layer.listElements()) {\n registry.registerElement(element);\n }\n }\n\n // Create dependency tracker\n const tracker = new DependencyTracker(registry, model);\n\n // Find all elements that depend on this element (would be orphaned)\n const dependents = tracker.traceDependencies(id, TraceDirection.DOWN, null);\n\n // Display element information\n console.log(\"\");\n console.log(ansis.bold(`Removing element: ${ansis.yellow(id)}`));\n console.log(ansis.dim(` Layer: ${layerName}`));\n console.log(ansis.dim(` Type: ${element.type || \"unknown\"}`));\n if (element.name) {\n console.log(ansis.dim(` Name: ${element.name}`));\n }\n\n // Display dependencies if any exist\n if (dependents.length > 0) {\n console.log(\"\");\n console.log(\n ansis.yellow(`\u26A0 Warning: This element has ${dependents.length} dependent element(s):`)\n );\n\n const directDependents = tracker.traceDependencies(id, TraceDirection.DOWN, 1);\n\n // Show direct dependents\n for (const dep of directDependents.slice(0, 5)) {\n const depElement = model.getElementById(dep);\n const depLayer = depElement?.layer || \"unknown\";\n console.log(ansis.dim(` - ${dep} (${depLayer})`));\n }\n\n if (directDependents.length > 5) {\n console.log(ansis.dim(` ... and ${directDependents.length - 5} more direct dependents`));\n }\n\n if (dependents.length > directDependents.length) {\n console.log(\n ansis.dim(\n ` (${dependents.length - directDependents.length} transitive dependents not shown)`\n )\n );\n }\n\n // Check if cascade or force is enabled\n if (!options.cascade && !options.force) {\n console.log(\"\");\n console.log(ansis.red(\"\u2717 Cannot remove element with dependencies.\"));\n console.log(ansis.dim(\"Use --cascade to remove all dependent elements\"));\n console.log(ansis.dim(\"or --force to skip dependency checks\"));\n const suggestions = [\n `Use --dry-run with --cascade to preview what would be deleted`,\n 'Review dependencies before deletion using \"dr show <element>\"',\n \"Use --cascade to automatically remove all dependent elements\",\n \"Or use --force to remove only this element (dependencies will reference a non-existent element)\",\n ];\n throw new CLIError(\"Element has dependencies\", ErrorCategory.USER, suggestions, {\n operation: \"delete\",\n relatedElements: directDependents.slice(0, 10),\n context: `Element ${id} has ${dependents.length} dependent elements`,\n });\n }\n }\n\n // Calculate total elements to remove\n const elementsToRemove = options.cascade ? [id, ...dependents] : [id];\n\n // Display dry-run summary\n if (options.dryRun) {\n console.log(\"\");\n console.log(ansis.yellow(`Dry run - not removing`));\n console.log(ansis.dim(`Would remove ${elementsToRemove.length} element(s)`));\n\n if (options.cascade && dependents.length > 0) {\n console.log(\"\");\n console.log(ansis.dim(\"Elements that would be removed:\"));\n console.log(ansis.dim(` - ${id} (target)`));\n for (const dep of dependents.slice(0, 10)) {\n console.log(ansis.dim(` - ${dep} (dependent)`));\n }\n if (dependents.length > 10) {\n console.log(ansis.dim(` ... and ${dependents.length - 10} more`));\n }\n }\n\n return;\n }\n\n // Confirm deletion unless --force\n if (!options.force) {\n const isInteractive = process.stdin.isTTY && process.stdout.isTTY;\n if (!isInteractive) {\n console.log(ansis.dim(\"Non-interactive environment detected - proceeding without confirmation\"));\n } else {\n const message =\n options.cascade && dependents.length > 0\n ? `Delete ${ansis.bold(id)} and ${ansis.bold(String(dependents.length))} dependent element(s)? This cannot be undone.`\n : `Delete element ${ansis.bold(id)}? This cannot be undone.`;\n\n const confirmed = await confirm({\n message,\n initialValue: false,\n });\n\n if (!confirmed) {\n console.log(ansis.dim(\"Cancelled\"));\n return;\n }\n }\n }\n\n // Execute deletion with error recovery guidance\n let deletedCount = 0;\n try {\n if (options.cascade && dependents.length > 0) {\n // Delete dependents first (reverse dependency order to avoid orphaned references)\n const sortedDependents = [...dependents].reverse();\n\n for (const depId of sortedDependents) {\n try {\n const depLayerName = await findElementLayer(model, depId);\n if (!depLayerName) continue;\n\n const depLayer = (await model.getLayer(depLayerName))!;\n const depElement = depLayer.getElement(depId)!;\n\n const handler = new MutationHandler(model, depId, depLayerName);\n await handler.executeDelete(depElement);\n deletedCount++;\n\n if (options.verbose) {\n console.log(ansis.dim(` Deleted dependent: ${depId}`));\n }\n } catch (depError) {\n // Track partial progress for error recovery\n const suggestions = [\n `${deletedCount} dependent element(s) were deleted before the error`,\n 'Check the model state with \"dr validate\" to identify any broken references',\n 'You may need to manually delete remaining elements or use \"dr show\" to inspect',\n ];\n throw new CLIError(\n `Failed to delete dependent element ${depId}`,\n ErrorCategory.SYSTEM,\n suggestions,\n {\n operation: \"delete (cascade)\",\n partialProgress: { completed: deletedCount, total: sortedDependents.length },\n relatedElements: [id, ...sortedDependents.slice(0, 5)],\n }\n );\n }\n }\n }\n } catch (error) {\n // If we're in the middle of cascade deletion, provide recovery info\n if (options.cascade && deletedCount > 0 && !(error instanceof CLIError)) {\n const suggestions = [\n `${deletedCount} dependent element(s) were successfully deleted`,\n 'Use \"dr validate\" to check for broken references',\n \"The target element was not deleted - you can retry the operation\",\n ];\n throw new CLIError(\n \"Cascade deletion was partially completed but encountered an error\",\n ErrorCategory.SYSTEM,\n suggestions,\n {\n operation: \"delete (cascade)\",\n partialProgress: { completed: deletedCount, total: dependents.length },\n }\n );\n }\n throw error;\n }\n\n // Delete the target element\n const handler = new MutationHandler(model, id, layerName);\n await handler.executeDelete(element);\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"layer.name\", layerName);\n (span as any).setAttribute(\"element.dependents\", dependents.length);\n (span as any).setAttribute(\"element.totalDeleted\", elementsToRemove.length);\n }\n\n // Check if operation was staged or applied to base model\n const beforeState = handler.getBeforeState();\n if (beforeState) {\n // Check if we went through staging path\n const stagingManager = handler.getStagingManager();\n const activeChangeset = await stagingManager.getActive();\n if (activeChangeset && activeChangeset.status === \"staged\") {\n // Staging path\n handleSuccess(\n `Staged deletion of element ${ansis.bold(id)} to ${ansis.bold(activeChangeset.name)}`,\n {\n status: \"staged\",\n changeset: activeChangeset.name,\n }\n );\n } else {\n // Base model path: purge any stale relationships MutationHandler may have missed\n const staleBase = elementsToRemove.reduce(\n (n, eid) => n + model.relationships.deleteForElement(eid), 0\n );\n if (staleBase > 0) await model.saveRelationships();\n\n console.log(\"\");\n console.log(ansis.green(`\u2713 Deleted element ${ansis.bold(id)}`));\n\n if (options.cascade && dependents.length > 0) {\n console.log(ansis.green(`\u2713 Deleted ${dependents.length} dependent element(s)`));\n }\n\n if (options.verbose) {\n console.log(ansis.dim(` Layer: ${layerName}`));\n console.log(ansis.dim(` Total elements deleted: ${elementsToRemove.length}`));\n }\n }\n } else {\n // Fallback success message if before state is not available\n // This should rarely occur, but ensures user always gets feedback\n const staleFallback = elementsToRemove.reduce(\n (n, eid) => n + model.relationships.deleteForElement(eid), 0\n );\n if (staleFallback > 0) await model.saveRelationships();\n\n console.log(\"\");\n console.log(ansis.green(`\u2713 Deleted element ${ansis.bold(id)}`));\n\n if (options.cascade && dependents.length > 0) {\n console.log(ansis.green(`\u2713 Deleted ${dependents.length} dependent element(s)`));\n }\n\n if (options.verbose) {\n console.log(ansis.dim(` Layer: ${layerName}`));\n console.log(ansis.dim(` Total elements deleted: ${elementsToRemove.length}`));\n }\n }\n } catch (error) {\n if (isTelemetryEnabled && span) {\n (span as any).recordException(error as Error);\n (span as any).setStatus({ code: 2, message: (error as Error).message });\n }\n handleError(error);\n } finally {\n if (isTelemetryEnabled) {\n endSpan(span);\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["layer", "element"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { MappingLoader } from "../analyzers/mapping-loader.js";
|
|
2
|
+
async function performDiscover(registry, options = {}) {
|
|
3
|
+
const analyzerNames = await registry.getAnalyzerNames();
|
|
4
|
+
if (analyzerNames.length === 0)
|
|
5
|
+
throw new Error("No analyzers registered in the specification");
|
|
6
|
+
const analyzerOptions = [];
|
|
7
|
+
for (const name of analyzerNames)
|
|
8
|
+
try {
|
|
9
|
+
const backend = await registry.getAnalyzer(name);
|
|
10
|
+
if (!backend)
|
|
11
|
+
continue;
|
|
12
|
+
const detection = await backend.detect(), metadata = (await MappingLoader.load(name)).getAnalyzerMetadata();
|
|
13
|
+
analyzerOptions.push({
|
|
14
|
+
backend,
|
|
15
|
+
detection,
|
|
16
|
+
metadata
|
|
17
|
+
});
|
|
18
|
+
} catch (error) {
|
|
19
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
20
|
+
console.error(`Failed to discover analyzer "${name}": ${errorMsg}`);
|
|
21
|
+
}
|
|
22
|
+
const installed = analyzerOptions.filter((a) => a.detection.installed), discoveryResult = {
|
|
23
|
+
found: analyzerOptions.map((a) => ({
|
|
24
|
+
name: a.backend.name,
|
|
25
|
+
display_name: a.backend.displayName,
|
|
26
|
+
description: a.metadata?.description || "",
|
|
27
|
+
homepage: a.metadata?.homepage || "",
|
|
28
|
+
installed: a.detection.installed
|
|
29
|
+
})),
|
|
30
|
+
installed_count: installed.length
|
|
31
|
+
};
|
|
32
|
+
let selectedAnalyzer, shouldWriteSession = !1;
|
|
33
|
+
return options.json ? !options.isTTY && installed.length > 0 && (selectedAnalyzer = installed[0].backend.name, shouldWriteSession = !0, discoveryResult.selected = selectedAnalyzer) : !options.isTTY && installed.length > 0 ? (selectedAnalyzer = installed[0].backend.name, shouldWriteSession = !0) : installed.length > 0 && options.isTTY && (shouldWriteSession = !1), {
|
|
34
|
+
discoveryResult,
|
|
35
|
+
installed,
|
|
36
|
+
analyzerOptions,
|
|
37
|
+
selectedAnalyzer,
|
|
38
|
+
shouldWriteSession
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
performDiscover
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=discover-logic.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/commands/discover-logic.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Core discover logic - separated from CLI I/O for testability\n *\n * This module contains the business logic for analyzer discovery,\n * separated from CLI output and user interaction.\n */\n\nimport { AnalyzerRegistry } from \"../analyzers/registry.js\";\nimport { MappingLoader } from \"../analyzers/mapping-loader.js\";\nimport type { DiscoveryResult, AvailableAnalyzer } from \"../analyzers/types.js\";\n\nexport interface DiscoverOptions {\n json?: boolean;\n reselect?: boolean;\n isTTY?: boolean;\n}\n\nexport interface DiscoverAnalyzerOption {\n backend: any;\n detection: any;\n metadata: any;\n}\n\n/**\n * Core discover logic - discovers installed analyzers and determines what action to take\n *\n * Returns:\n * - discoveryResult: The JSON-serializable discovery result\n * - installed: Array of installed analyzers\n * - analyzerOptions: All discovered analyzers (installed and uninstalled)\n */\nexport async function performDiscover(\n registry: AnalyzerRegistry,\n options: DiscoverOptions = {}\n): Promise<{\n discoveryResult: DiscoveryResult;\n installed: DiscoverAnalyzerOption[];\n analyzerOptions: DiscoverAnalyzerOption[];\n selectedAnalyzer?: string;\n shouldWriteSession: boolean;\n}> {\n const analyzerNames = await registry.getAnalyzerNames();\n\n if (analyzerNames.length === 0) {\n throw new Error(\"No analyzers registered in the specification\");\n }\n\n // Get metadata for each analyzer\n const analyzerOptions: DiscoverAnalyzerOption[] = [];\n for (const name of analyzerNames) {\n try {\n const backend = await registry.getAnalyzer(name);\n if (!backend) continue;\n\n const detection = await backend.detect();\n const mapper = await MappingLoader.load(name);\n const metadata = mapper.getAnalyzerMetadata();\n\n analyzerOptions.push({\n backend,\n detection,\n metadata,\n });\n } catch (error) {\n // Log error but continue discovering other analyzers\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.error(`Failed to discover analyzer \"${name}\": ${errorMsg}`);\n }\n }\n\n // Find installed analyzers\n const installed = analyzerOptions.filter((a) => a.detection.installed);\n\n // Build the discovery result (used for JSON output)\n const found: AvailableAnalyzer[] = analyzerOptions.map((a) => ({\n name: a.backend.name,\n display_name: a.backend.displayName,\n description: a.metadata?.description || \"\",\n homepage: a.metadata?.homepage || \"\",\n installed: a.detection.installed,\n }));\n\n const discoveryResult: DiscoveryResult = {\n found,\n installed_count: installed.length,\n };\n\n let selectedAnalyzer: string | undefined;\n let shouldWriteSession = false;\n\n // Determine session and selection behavior\n if (options.json) {\n // JSON mode: auto-select in non-TTY only if analyzers are installed\n if (!options.isTTY && installed.length > 0) {\n selectedAnalyzer = installed[0].backend.name;\n shouldWriteSession = true;\n discoveryResult.selected = selectedAnalyzer;\n }\n // TTY mode or no installed analyzers: don't set selected field\n } else {\n // Text mode: in non-TTY, auto-select only if analyzers are installed\n if (!options.isTTY && installed.length > 0) {\n selectedAnalyzer = installed[0].backend.name;\n shouldWriteSession = true;\n } else if (installed.length > 0 && options.isTTY) {\n // TTY mode with installed analyzers: will prompt, session will be written after selection\n shouldWriteSession = false; // CLI handler will write after prompt\n }\n // If no analyzers installed: don't select or write session\n }\n\n return {\n discoveryResult,\n installed,\n analyzerOptions,\n selectedAnalyzer,\n shouldWriteSession,\n };\n}\n"],
|
|
5
|
+
"mappings": "AAQA,SAAS,qBAAqB;AAuB9B,eAAsB,gBACpB,UACA,UAA2B,CAAA,GAAE;AAQ7B,QAAM,gBAAgB,MAAM,SAAS,iBAAgB;AAErD,MAAI,cAAc,WAAW;AAC3B,UAAM,IAAI,MAAM,8CAA8C;AAIhE,QAAM,kBAA4C,CAAA;AAClD,aAAW,QAAQ;AACjB,QAAI;AACF,YAAM,UAAU,MAAM,SAAS,YAAY,IAAI;AAC/C,UAAI,CAAC;AAAS;AAEd,YAAM,YAAY,MAAM,QAAQ,OAAM,GAEhC,YADS,MAAM,cAAc,KAAK,IAAI,GACpB,oBAAmB;AAE3C,sBAAgB,KAAK;QACnB;QACA;QACA;OACD;IACH,SAAS,OAAO;AAEd,YAAM,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACtE,cAAQ,MAAM,gCAAgC,IAAI,MAAM,QAAQ,EAAE;IACpE;AAIF,QAAM,YAAY,gBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,SAAS,GAW/D,kBAAmC;IACvC,OATiC,gBAAgB,IAAI,CAAC,OAAO;MAC7D,MAAM,EAAE,QAAQ;MAChB,cAAc,EAAE,QAAQ;MACxB,aAAa,EAAE,UAAU,eAAe;MACxC,UAAU,EAAE,UAAU,YAAY;MAClC,WAAW,EAAE,UAAU;MACvB;IAIA,iBAAiB,UAAU;;AAG7B,MAAI,kBACA,qBAAqB;AAGzB,SAAI,QAAQ,OAEN,CAAC,QAAQ,SAAS,UAAU,SAAS,MACvC,mBAAmB,UAAU,CAAC,EAAE,QAAQ,MACxC,qBAAqB,IACrB,gBAAgB,WAAW,oBAKzB,CAAC,QAAQ,SAAS,UAAU,SAAS,KACvC,mBAAmB,UAAU,CAAC,EAAE,QAAQ,MACxC,qBAAqB,MACZ,UAAU,SAAS,KAAK,QAAQ,UAEzC,qBAAqB,KAKlB;IACL;IACA;IACA;IACA;IACA;;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { execFileSync } from "child_process";
|
|
4
|
+
import { fileExists, ensureDir } from "../utils/file-io.js";
|
|
5
|
+
import { existsSync } from "fs";
|
|
6
|
+
import { isValidLayer, getAllLayerIds } from "../generated/layer-registry.js";
|
|
7
|
+
async function docsGenerateCommand(options) {
|
|
8
|
+
const projectRoot = process.cwd(), specDir = path.join(projectRoot, "spec");
|
|
9
|
+
if (!existsSync(specDir))
|
|
10
|
+
throw new Error(`Specification directory not found at ${specDir}. Are you in a Documentation Robotics project?`);
|
|
11
|
+
if (options.layer && !isValidLayer(options.layer))
|
|
12
|
+
throw new Error(`Invalid layer name: ${options.layer}. Must be one of: ${getAllLayerIds().join(", ")}`);
|
|
13
|
+
const outputDir = options.output ? path.resolve(options.output) : specDir;
|
|
14
|
+
if (!path.resolve(outputDir).startsWith(projectRoot))
|
|
15
|
+
throw new Error(`Output directory must be within project root. Requested: ${outputDir}, Project root: ${projectRoot}`);
|
|
16
|
+
await ensureDir(outputDir);
|
|
17
|
+
try {
|
|
18
|
+
const args = ["run", "scripts/generate-layer-docs.ts"];
|
|
19
|
+
options.layer && args.push("--layer", options.layer), outputDir !== specDir && args.push("--output", outputDir), console.log("\u{1F4DA} Generating documentation..."), execFileSync("bun", args, { cwd: projectRoot, stdio: "inherit" }), console.log(`
|
|
20
|
+
\u2705 Documentation generation complete at: ${outputDir}`);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
throw error instanceof Error ? new Error(`Documentation generation failed: ${error.message}`) : error;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async function docsValidateCommand(options) {
|
|
26
|
+
const projectRoot = process.cwd(), specDir = path.join(projectRoot, "spec"), layersDir = path.join(specDir, "layers");
|
|
27
|
+
if (!existsSync(specDir))
|
|
28
|
+
throw new Error(`Specification directory not found at ${specDir}. Are you in a Documentation Robotics project?`);
|
|
29
|
+
console.log("\u{1F50D} Validating documentation sync with schemas...");
|
|
30
|
+
const tempDir = path.join(projectRoot, ".tmp-doc-validation");
|
|
31
|
+
await ensureDir(tempDir);
|
|
32
|
+
try {
|
|
33
|
+
try {
|
|
34
|
+
execFileSync("bun", ["run", "scripts/generate-layer-docs.ts", "--output", tempDir], {
|
|
35
|
+
cwd: projectRoot,
|
|
36
|
+
stdio: "pipe"
|
|
37
|
+
});
|
|
38
|
+
} catch (error) {
|
|
39
|
+
const stderr = error.stderr?.toString() || error.message || String(error);
|
|
40
|
+
throw new Error(`Failed to generate documentation for validation: ${stderr}`);
|
|
41
|
+
}
|
|
42
|
+
const generatedFiles = fs.readdirSync(tempDir).filter((f) => f.endsWith(".md"));
|
|
43
|
+
let hasDiscrepancies = !1;
|
|
44
|
+
const discrepancies = [];
|
|
45
|
+
for (const file of generatedFiles) {
|
|
46
|
+
if (file === "INDEX.md")
|
|
47
|
+
continue;
|
|
48
|
+
const existingPath = path.join(layersDir, file), generatedPath = path.join(tempDir, file);
|
|
49
|
+
if (!await fileExists(existingPath)) {
|
|
50
|
+
discrepancies.push(`\u274C Missing file: ${file}`), hasDiscrepancies = !0;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const existingContent = fs.readFileSync(existingPath, "utf-8"), generatedContent = fs.readFileSync(generatedPath, "utf-8");
|
|
54
|
+
existingContent !== generatedContent && (discrepancies.push(`\u274C File out of sync: ${file} (generated content differs from existing)`), hasDiscrepancies = !0);
|
|
55
|
+
}
|
|
56
|
+
hasDiscrepancies ? (console.log(`
|
|
57
|
+
\u274C Documentation is out of sync with schemas:
|
|
58
|
+
`), discrepancies.forEach((d) => console.log(` ${d}`)), console.log(`
|
|
59
|
+
Run 'dr docs generate' to update documentation.`), options.strict && process.exit(1)) : console.log(`
|
|
60
|
+
\u2705 Documentation is in sync with schemas!`);
|
|
61
|
+
} finally {
|
|
62
|
+
existsSync(tempDir) && fs.rmSync(tempDir, { recursive: !0 });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function docsCommands(program) {
|
|
66
|
+
const docsCommand = program.command("docs").description("Manage documentation generation and validation");
|
|
67
|
+
docsCommand.command("generate").description("Generate markdown documentation from schema definitions").option("--layer <layer>", "Generate specific layer (optional)").option("--output <dir>", "Output directory (defaults to spec/layers/)").addHelpText("after", `
|
|
68
|
+
Examples:
|
|
69
|
+
$ dr docs generate # Generate all layer docs
|
|
70
|
+
$ dr docs generate --layer motivation # Generate motivation layer only
|
|
71
|
+
$ dr docs generate --output ./docs/ # Output to custom directory
|
|
72
|
+
|
|
73
|
+
Note: Requires spec/layers/*.layer.json and spec/schemas/nodes/**/*.node.schema.json files.
|
|
74
|
+
The generation script reads these spec instances and creates markdown documentation.`).action(docsGenerateCommand), docsCommand.command("validate").description("Validate that documentation is in sync with schema definitions").option("--strict", "Exit with error code if documentation is out of sync").addHelpText("after", `
|
|
75
|
+
Examples:
|
|
76
|
+
$ dr docs validate # Check if docs are in sync
|
|
77
|
+
$ dr docs validate --strict # Exit with error if out of sync (for CI)
|
|
78
|
+
|
|
79
|
+
This command generates documentation from schemas and compares it with existing
|
|
80
|
+
documentation to ensure they are in sync.`).action(docsValidateCommand);
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
docsCommands,
|
|
84
|
+
docsGenerateCommand,
|
|
85
|
+
docsValidateCommand
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=docs.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/commands/docs.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Documentation Generation Commands\n *\n * Implements schema-driven documentation generation:\n * - `dr docs generate` - Generate markdown documentation from spec instances\n * - `dr docs validate` - Validate that documentation is in sync with schemas\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { execFileSync } from \"child_process\";\nimport { fileExists, ensureDir } from \"../utils/file-io.js\";\nimport { existsSync } from \"fs\";\nimport { isValidLayer, getAllLayerIds } from \"../generated/layer-registry.js\";\n\ninterface GenerateOptions {\n output?: string;\n layer?: string;\n}\n\ninterface ValidateOptions {\n strict?: boolean;\n}\n\n/**\n * Generate documentation from schema definitions\n */\nexport async function docsGenerateCommand(options: GenerateOptions): Promise<void> {\n const projectRoot = process.cwd();\n const specDir = path.join(projectRoot, \"spec\");\n\n // Validate spec directory exists\n if (!existsSync(specDir)) {\n throw new Error(\n `Specification directory not found at ${specDir}. Are you in a Documentation Robotics project?`\n );\n }\n\n // Validate layer name if provided\n if (options.layer && !isValidLayer(options.layer)) {\n throw new Error(\n `Invalid layer name: ${options.layer}. ` +\n `Must be one of: ${getAllLayerIds().join(\", \")}`\n );\n }\n\n // Determine output directory\n const outputDir = options.output ? path.resolve(options.output) : specDir;\n\n // Validate output directory path to prevent path traversal\n const resolvedOutputDir = path.resolve(outputDir);\n if (!resolvedOutputDir.startsWith(projectRoot)) {\n throw new Error(\n `Output directory must be within project root. ` +\n `Requested: ${outputDir}, Project root: ${projectRoot}`\n );\n }\n\n // Ensure output directory exists\n await ensureDir(outputDir);\n\n try {\n // Build command arguments safely without shell string concatenation\n const args = [\"run\", \"scripts/generate-layer-docs.ts\"];\n\n if (options.layer) {\n args.push(\"--layer\", options.layer);\n }\n\n if (outputDir !== specDir) {\n args.push(\"--output\", outputDir);\n }\n\n console.log(`\uD83D\uDCDA Generating documentation...`);\n execFileSync(\"bun\", args, { cwd: projectRoot, stdio: \"inherit\" });\n console.log(`\\n\u2705 Documentation generation complete at: ${outputDir}`);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Documentation generation failed: ${error.message}`);\n }\n throw error;\n }\n}\n\n/**\n * Validate that documentation is in sync with schemas\n */\nexport async function docsValidateCommand(options: ValidateOptions): Promise<void> {\n const projectRoot = process.cwd();\n const specDir = path.join(projectRoot, \"spec\");\n const layersDir = path.join(specDir, \"layers\");\n\n // Validate spec directory exists\n if (!existsSync(specDir)) {\n throw new Error(\n `Specification directory not found at ${specDir}. Are you in a Documentation Robotics project?`\n );\n }\n\n console.log(`\uD83D\uDD0D Validating documentation sync with schemas...`);\n\n // Create temporary directory for generated docs\n const tempDir = path.join(projectRoot, \".tmp-doc-validation\");\n await ensureDir(tempDir);\n\n try {\n // Generate documentation to temp directory using safe argument passing\n try {\n execFileSync(\"bun\", [\"run\", \"scripts/generate-layer-docs.ts\", \"--output\", tempDir], {\n cwd: projectRoot,\n stdio: \"pipe\",\n });\n } catch (error) {\n const stderr = (error as any).stderr?.toString() || (error as Error).message || String(error);\n throw new Error(`Failed to generate documentation for validation: ${stderr}`);\n }\n\n // Compare generated docs with existing docs\n const generatedFiles = fs.readdirSync(tempDir).filter((f) => f.endsWith(\".md\"));\n\n let hasDiscrepancies = false;\n const discrepancies: string[] = [];\n\n // Check for missing files\n for (const file of generatedFiles) {\n if (file === \"INDEX.md\") continue; // Skip index file in validation\n\n const existingPath = path.join(layersDir, file);\n const generatedPath = path.join(tempDir, file);\n\n if (!(await fileExists(existingPath))) {\n discrepancies.push(`\u274C Missing file: ${file}`);\n hasDiscrepancies = true;\n continue;\n }\n\n // Compare content\n const existingContent = fs.readFileSync(existingPath, \"utf-8\");\n const generatedContent = fs.readFileSync(generatedPath, \"utf-8\");\n\n if (existingContent !== generatedContent) {\n discrepancies.push(\n `\u274C File out of sync: ${file} (generated content differs from existing)`\n );\n hasDiscrepancies = true;\n }\n }\n\n // Report results\n if (hasDiscrepancies) {\n console.log(`\\n\u274C Documentation is out of sync with schemas:\\n`);\n discrepancies.forEach((d) => console.log(` ${d}`));\n console.log(`\\nRun 'dr docs generate' to update documentation.`);\n\n if (options.strict) {\n process.exit(1);\n }\n } else {\n console.log(`\\n\u2705 Documentation is in sync with schemas!`);\n }\n } finally {\n // Clean up temporary directory\n if (existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true });\n }\n }\n}\n\n/**\n * Register docs commands with Commander\n */\nexport function docsCommands(program: any): void {\n const docsCommand = program\n .command(\"docs\")\n .description(\"Manage documentation generation and validation\");\n\n docsCommand\n .command(\"generate\")\n .description(\"Generate markdown documentation from schema definitions\")\n .option(\"--layer <layer>\", \"Generate specific layer (optional)\")\n .option(\"--output <dir>\", \"Output directory (defaults to spec/layers/)\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr docs generate # Generate all layer docs\n $ dr docs generate --layer motivation # Generate motivation layer only\n $ dr docs generate --output ./docs/ # Output to custom directory\n\nNote: Requires spec/layers/*.layer.json and spec/schemas/nodes/**/*.node.schema.json files.\nThe generation script reads these spec instances and creates markdown documentation.`\n )\n .action(docsGenerateCommand);\n\n docsCommand\n .command(\"validate\")\n .description(\"Validate that documentation is in sync with schema definitions\")\n .option(\"--strict\", \"Exit with error code if documentation is out of sync\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr docs validate # Check if docs are in sync\n $ dr docs validate --strict # Exit with error if out of sync (for CI)\n\nThis command generates documentation from schemas and compares it with existing\ndocumentation to ensure they are in sync.`\n )\n .action(docsValidateCommand);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/commands/element.js
CHANGED
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
import { addCommand } from "./add.js";
|
|
2
|
-
import { updateCommand } from "./update.js";
|
|
3
|
-
import { deleteCommand } from "./delete.js";
|
|
4
|
-
import { showCommand } from "./show.js";
|
|
5
2
|
import { listCommand } from "./list.js";
|
|
3
|
+
import { showCommand } from "./show.js";
|
|
4
|
+
import { deleteCommand } from "./delete.js";
|
|
5
|
+
import { updateCommand } from "./update.js";
|
|
6
6
|
function elementCommands(program) {
|
|
7
|
-
program.command("add <layer> <type> <
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
$ dr element show api-endpoint-create-customer
|
|
19
|
-
$ dr element show business-service-order-mgmt`).action(showCommand), program.command("list <layer>").description("List elements in a layer").option("--type <type>", "Filter by element type").option("--json", "Output as JSON").addHelpText("after", `
|
|
20
|
-
Examples:
|
|
21
|
-
$ dr element list api
|
|
22
|
-
$ dr element list business --type business-service
|
|
23
|
-
$ dr element list api --json`).action(listCommand);
|
|
7
|
+
program.command("add <layer> <type> <name>").description("Add an element to a layer").option("--name <name>", "Element display name (optional, defaults to provided name)").option("--description <description>", "Element description").option("--attributes <json>", "Element attributes as JSON (type-specific properties)").option("--source-file <path>", "Source file path").option("--source-symbol <symbol>", "Source symbol or line number").option("--source-provenance <provenance>", "Source provenance (manual or generated)").option("--source-repo-remote <remote>", "Source repository remote").option("--source-repo-commit <commit>", "Source repository commit hash").option("--verbose", "Show detailed output").option("--debug", "Enable debug output").action(async (layer, type, name, options) => {
|
|
8
|
+
await addCommand(layer, type, name, options);
|
|
9
|
+
}), program.command("list <layer>").description("List elements in a layer").option("--type <type>", "Filter by element type").option("--json", "Output as JSON").option("--verbose", "Show detailed output").option("--debug", "Enable debug output").action(async (layer, options) => {
|
|
10
|
+
await listCommand(layer, options);
|
|
11
|
+
}), program.command("show <id>").description("Display element details").option("--verbose", "Show detailed output").option("--debug", "Enable debug output").action(async (id, options) => {
|
|
12
|
+
await showCommand(id, options);
|
|
13
|
+
}), program.command("delete <id>").description("Delete an element").option("--force", "Skip confirmation prompt").option("--cascade", "Remove dependent elements automatically").option("--verbose", "Show detailed output").option("--debug", "Enable debug output").action(async (id, options) => {
|
|
14
|
+
await deleteCommand(id, options);
|
|
15
|
+
}), program.command("update <id>").description("Update an element").option("--name <name>", "New element name").option("--description <description>", "New description").option("--attributes <json>", "Element attributes as JSON (type-specific properties)").option("--source-file <path>", "Source file path").option("--source-symbol <symbol>", "Source symbol or line number").option("--source-provenance <provenance>", "Source provenance (manual or generated)").option("--source-repo-remote <remote>", "Source repository remote").option("--source-repo-commit <commit>", "Source repository commit hash").option("--clear-source-reference", "Remove source reference from element").option("--verbose", "Show detailed output").option("--debug", "Enable debug output").action(async (id, options) => {
|
|
16
|
+
await updateCommand(id, options);
|
|
17
|
+
});
|
|
24
18
|
}
|
|
25
19
|
export {
|
|
26
20
|
elementCommands
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/element.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Element subcommands\n *
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/**\n * Element subcommands for managing model elements\n * Provides an alternative way to access add, list, show, delete, and update commands\n * via an \"element\" subcommand group\n */\n\nimport { Command } from \"commander\";\nimport { addCommand } from \"./add.js\";\nimport { listCommand } from \"./list.js\";\nimport { showCommand } from \"./show.js\";\nimport { deleteCommand } from \"./delete.js\";\nimport { updateCommand } from \"./update.js\";\n\nexport function elementCommands(program: Command): void {\n // element add <layer> <type> <name> [options]\n program\n .command(\"add <layer> <type> <name>\")\n .description(\"Add an element to a layer\")\n .option(\"--name <name>\", \"Element display name (optional, defaults to provided name)\")\n .option(\"--description <description>\", \"Element description\")\n .option(\"--attributes <json>\", \"Element attributes as JSON (type-specific properties)\")\n .option(\"--source-file <path>\", \"Source file path\")\n .option(\"--source-symbol <symbol>\", \"Source symbol or line number\")\n .option(\"--source-provenance <provenance>\", \"Source provenance (manual or generated)\")\n .option(\"--source-repo-remote <remote>\", \"Source repository remote\")\n .option(\"--source-repo-commit <commit>\", \"Source repository commit hash\")\n .option(\"--verbose\", \"Show detailed output\")\n .option(\"--debug\", \"Enable debug output\")\n .action(async (layer, type, name, options) => {\n await addCommand(layer, type, name, options);\n });\n\n // element list <layer> [options]\n program\n .command(\"list <layer>\")\n .description(\"List elements in a layer\")\n .option(\"--type <type>\", \"Filter by element type\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--verbose\", \"Show detailed output\")\n .option(\"--debug\", \"Enable debug output\")\n .action(async (layer, options) => {\n await listCommand(layer, options);\n });\n\n // element show <id> [options]\n program\n .command(\"show <id>\")\n .description(\"Display element details\")\n .option(\"--verbose\", \"Show detailed output\")\n .option(\"--debug\", \"Enable debug output\")\n .action(async (id, options) => {\n await showCommand(id, options);\n });\n\n // element delete <id> [options]\n program\n .command(\"delete <id>\")\n .description(\"Delete an element\")\n .option(\"--force\", \"Skip confirmation prompt\")\n .option(\"--cascade\", \"Remove dependent elements automatically\")\n .option(\"--verbose\", \"Show detailed output\")\n .option(\"--debug\", \"Enable debug output\")\n .action(async (id, options) => {\n await deleteCommand(id, options);\n });\n\n // element update <id> [options]\n program\n .command(\"update <id>\")\n .description(\"Update an element\")\n .option(\"--name <name>\", \"New element name\")\n .option(\"--description <description>\", \"New description\")\n .option(\"--attributes <json>\", \"Element attributes as JSON (type-specific properties)\")\n .option(\"--source-file <path>\", \"Source file path\")\n .option(\"--source-symbol <symbol>\", \"Source symbol or line number\")\n .option(\"--source-provenance <provenance>\", \"Source provenance (manual or generated)\")\n .option(\"--source-repo-remote <remote>\", \"Source repository remote\")\n .option(\"--source-repo-commit <commit>\", \"Source repository commit hash\")\n .option(\"--clear-source-reference\", \"Remove source reference from element\")\n .option(\"--verbose\", \"Show detailed output\")\n .option(\"--debug\", \"Enable debug output\")\n .action(async (id, options) => {\n await updateCommand(id, options);\n });\n}\n"],
|
|
5
|
+
"mappings": "AAOA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAExB,SAAU,gBAAgB,SAAgB;AAE9C,UACG,QAAQ,2BAA2B,EACnC,YAAY,2BAA2B,EACvC,OAAO,iBAAiB,4DAA4D,EACpF,OAAO,+BAA+B,qBAAqB,EAC3D,OAAO,uBAAuB,uDAAuD,EACrF,OAAO,wBAAwB,kBAAkB,EACjD,OAAO,4BAA4B,8BAA8B,EACjE,OAAO,oCAAoC,yCAAyC,EACpF,OAAO,iCAAiC,0BAA0B,EAClE,OAAO,iCAAiC,+BAA+B,EACvE,OAAO,aAAa,sBAAsB,EAC1C,OAAO,WAAW,qBAAqB,EACvC,OAAO,OAAO,OAAO,MAAM,MAAM,YAAW;AAC3C,UAAM,WAAW,OAAO,MAAM,MAAM,OAAO;EAC7C,CAAC,GAGH,QACG,QAAQ,cAAc,EACtB,YAAY,0BAA0B,EACtC,OAAO,iBAAiB,wBAAwB,EAChD,OAAO,UAAU,gBAAgB,EACjC,OAAO,aAAa,sBAAsB,EAC1C,OAAO,WAAW,qBAAqB,EACvC,OAAO,OAAO,OAAO,YAAW;AAC/B,UAAM,YAAY,OAAO,OAAO;EAClC,CAAC,GAGH,QACG,QAAQ,WAAW,EACnB,YAAY,yBAAyB,EACrC,OAAO,aAAa,sBAAsB,EAC1C,OAAO,WAAW,qBAAqB,EACvC,OAAO,OAAO,IAAI,YAAW;AAC5B,UAAM,YAAY,IAAI,OAAO;EAC/B,CAAC,GAGH,QACG,QAAQ,aAAa,EACrB,YAAY,mBAAmB,EAC/B,OAAO,WAAW,0BAA0B,EAC5C,OAAO,aAAa,yCAAyC,EAC7D,OAAO,aAAa,sBAAsB,EAC1C,OAAO,WAAW,qBAAqB,EACvC,OAAO,OAAO,IAAI,YAAW;AAC5B,UAAM,cAAc,IAAI,OAAO;EACjC,CAAC,GAGH,QACG,QAAQ,aAAa,EACrB,YAAY,mBAAmB,EAC/B,OAAO,iBAAiB,kBAAkB,EAC1C,OAAO,+BAA+B,iBAAiB,EACvD,OAAO,uBAAuB,uDAAuD,EACrF,OAAO,wBAAwB,kBAAkB,EACjD,OAAO,4BAA4B,8BAA8B,EACjE,OAAO,oCAAoC,yCAAyC,EACpF,OAAO,iCAAiC,0BAA0B,EAClE,OAAO,iCAAiC,+BAA+B,EACvE,OAAO,4BAA4B,sCAAsC,EACzE,OAAO,aAAa,sBAAsB,EAC1C,OAAO,WAAW,qBAAqB,EACvC,OAAO,OAAO,IAAI,YAAW;AAC5B,UAAM,cAAc,IAAI,OAAO;EACjC,CAAC;AACL;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/commands/export.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import ansis from "ansis";
|
|
2
2
|
import { Model } from "../core/model.js";
|
|
3
|
-
import { ExportManager, ArchiMateExporter, OpenAPIExporter, JsonSchemaExporter, PlantUMLExporter, GraphMLExporter, MarkdownExporter } from "../export/index.js";
|
|
3
|
+
import { ExportManager, ArchiMateExporter, OpenAPIExporter, JsonSchemaExporter, PlantUMLExporter, GraphMLExporter, MarkdownExporter, MermaidMarkdownExporter } from "../export/index.js";
|
|
4
|
+
import { Validator } from "../validators/validator.js";
|
|
4
5
|
import { writeFile } from "../utils/file-io.js";
|
|
5
6
|
import * as path from "path";
|
|
6
7
|
import { startSpan, endSpan } from "../telemetry/index.js";
|
|
8
|
+
import { getErrorMessage } from "../utils/errors.js";
|
|
7
9
|
const isTelemetryEnabled = !1;
|
|
8
10
|
async function exportCommand(options) {
|
|
9
11
|
const span = isTelemetryEnabled ? startSpan("export.execute", {
|
|
@@ -34,8 +36,15 @@ async function exportCommand(options) {
|
|
|
34
36
|
}), manager.register("markdown", new MarkdownExporter(), {
|
|
35
37
|
description: "Markdown documentation",
|
|
36
38
|
mimeType: "text/markdown"
|
|
39
|
+
}), manager.register("mermaid-markdown", new MermaidMarkdownExporter(), {
|
|
40
|
+
description: "Markdown with Mermaid diagrams and formatted tables",
|
|
41
|
+
mimeType: "text/markdown"
|
|
37
42
|
});
|
|
38
43
|
const format = options.format.toLowerCase();
|
|
44
|
+
if (["openapi", "archimate", "jsonschema", "json-schema"].includes(format)) {
|
|
45
|
+
const validationResult = await new Validator().validateModel(model);
|
|
46
|
+
validationResult.isValid() || (console.warn(ansis.yellow(`\u26A0 Warning: model has ${validationResult.errors.length} validation error(s). Export output may be incomplete or incorrect.`)), console.warn(ansis.dim(' Run "dr validate" for details.')));
|
|
47
|
+
}
|
|
39
48
|
if (!manager.hasFormat(format)) {
|
|
40
49
|
console.error(ansis.red(`Error: Unknown export format: ${format}`)), console.error(""), console.error("Available formats:");
|
|
41
50
|
for (const info of manager.getAllFormats())
|
|
@@ -44,7 +53,8 @@ async function exportCommand(options) {
|
|
|
44
53
|
}
|
|
45
54
|
const result = await manager.export(model, format, {
|
|
46
55
|
layers: options.layers,
|
|
47
|
-
outputPath: options.output
|
|
56
|
+
outputPath: options.output,
|
|
57
|
+
includeSources: options.includeSources
|
|
48
58
|
});
|
|
49
59
|
if (isTelemetryEnabled && span && span.setAttribute("export.result_size", result.length), options.output) {
|
|
50
60
|
const outputPath = path.isAbsolute(options.output) ? options.output : path.join(process.cwd(), options.output);
|
|
@@ -53,7 +63,7 @@ async function exportCommand(options) {
|
|
|
53
63
|
console.log(result);
|
|
54
64
|
} catch (error) {
|
|
55
65
|
isTelemetryEnabled && span && (span.recordException(error), span.setStatus({ code: 2, message: error.message }));
|
|
56
|
-
const message =
|
|
66
|
+
const message = getErrorMessage(error);
|
|
57
67
|
console.error(ansis.red(`Error: ${message}`)), process.exit(1);
|
|
58
68
|
} finally {
|
|
59
69
|
isTelemetryEnabled && endSpan(span);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/commands/export.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Export the architecture model to various formats\n */\n\nimport ansis from \"ansis\";\nimport { Model } from \"../core/model.js\";\nimport {\n ExportManager,\n ArchiMateExporter,\n OpenAPIExporter,\n JsonSchemaExporter,\n PlantUMLExporter,\n GraphMLExporter,\n MarkdownExporter,\n} from \"../export/index.js\";\nimport { writeFile } from \"../utils/file-io.js\";\nimport * as path from \"path\";\nimport { startSpan, endSpan } from \"../telemetry/index.js\";\n\ndeclare const TELEMETRY_ENABLED: boolean | undefined;\nconst isTelemetryEnabled = typeof TELEMETRY_ENABLED !==
|
|
5
|
-
"mappings": "AAIA,OAAO,WAAW;AAClB,SAAS,aAAa;AACtB,SACE,eACA,mBACA,iBACA,oBACA,kBACA,iBACA,
|
|
4
|
+
"sourcesContent": ["/**\n * Export the architecture model to various formats\n */\n\nimport ansis from \"ansis\";\nimport { Model } from \"../core/model.js\";\nimport {\n ExportManager,\n ArchiMateExporter,\n OpenAPIExporter,\n JsonSchemaExporter,\n PlantUMLExporter,\n GraphMLExporter,\n MarkdownExporter,\n MermaidMarkdownExporter,\n} from \"../export/index.js\";\nimport { Validator } from \"../validators/validator.js\";\nimport { writeFile } from \"../utils/file-io.js\";\nimport * as path from \"path\";\nimport { startSpan, endSpan } from \"../telemetry/index.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\n\ndeclare const TELEMETRY_ENABLED: boolean | undefined;\nconst isTelemetryEnabled = typeof TELEMETRY_ENABLED !== \"undefined\" ? TELEMETRY_ENABLED : false;\n\nexport interface ExportOptions {\n format: string;\n output?: string;\n layers?: string[];\n model?: string;\n includeSources?: boolean;\n}\n\nexport async function exportCommand(options: ExportOptions): Promise<void> {\n const span = isTelemetryEnabled\n ? startSpan(\"export.execute\", {\n \"export.format\": options.format,\n \"export.layer_count\": options.layers?.length || 0,\n \"export.has_output\": !!options.output,\n })\n : null;\n\n try {\n // Load model\n const model = await Model.load(options.model);\n\n // Initialize ExportManager and register all exporters\n const manager = new ExportManager();\n\n manager.register(\"archimate\", new ArchiMateExporter(), {\n description: \"ArchiMate 3.2 XML format\",\n mimeType: \"application/xml\",\n });\n\n manager.register(\"openapi\", new OpenAPIExporter(), {\n description: \"OpenAPI 3.0 specification\",\n mimeType: \"application/json\",\n });\n\n manager.register(\"json-schema\", new JsonSchemaExporter(), {\n description: \"JSON Schema Draft 7\",\n mimeType: \"application/json\",\n });\n\n // Register alias for jsonschema (without hyphen)\n manager.register(\"jsonschema\", new JsonSchemaExporter(), {\n description: \"JSON Schema Draft 7\",\n mimeType: \"application/json\",\n });\n\n manager.register(\"plantuml\", new PlantUMLExporter(), {\n description: \"PlantUML diagram format\",\n mimeType: \"text/plain\",\n });\n\n manager.register(\"graphml\", new GraphMLExporter(), {\n description: \"GraphML graph format\",\n mimeType: \"application/xml\",\n });\n\n manager.register(\"markdown\", new MarkdownExporter(), {\n description: \"Markdown documentation\",\n mimeType: \"text/markdown\",\n });\n\n manager.register(\"mermaid-markdown\", new MermaidMarkdownExporter(), {\n description: \"Markdown with Mermaid diagrams and formatted tables\",\n mimeType: \"text/markdown\",\n });\n\n // Validate format\n const format = options.format.toLowerCase();\n\n // For semantic exporters, warn if the model has validation errors\n const semanticFormats = [\"openapi\", \"archimate\", \"jsonschema\", \"json-schema\"];\n if (semanticFormats.includes(format)) {\n const validator = new Validator();\n const validationResult = await validator.validateModel(model);\n if (!validationResult.isValid()) {\n console.warn(\n ansis.yellow(\n `\u26A0 Warning: model has ${validationResult.errors.length} validation error(s). Export output may be incomplete or incorrect.`\n )\n );\n console.warn(ansis.dim(' Run \"dr validate\" for details.'));\n }\n }\n\n if (!manager.hasFormat(format)) {\n console.error(ansis.red(`Error: Unknown export format: ${format}`));\n console.error(\"\");\n console.error(\"Available formats:\");\n for (const info of manager.getAllFormats()) {\n console.error(` - ${ansis.cyan(info.format)}: ${info.description}`);\n console.error(` Supported layers: ${info.supportedLayers.join(\", \")}`);\n }\n process.exit(1);\n }\n\n // Perform export\n const result = await manager.export(model, format, {\n layers: options.layers,\n outputPath: options.output,\n includeSources: options.includeSources,\n });\n\n if (isTelemetryEnabled && span) {\n (span as any).setAttribute(\"export.result_size\", result.length);\n }\n\n if (options.output) {\n // Write to file\n // For relative paths, use current working directory instead of rootPath\n // This allows tests to detect file creation in their working directory\n const outputPath = path.isAbsolute(options.output)\n ? options.output\n : path.join(process.cwd(), options.output);\n\n await writeFile(outputPath, result);\n\n console.log(ansis.green(`\u2713 Exported to ${ansis.cyan(outputPath)}`));\n } else {\n // Output to stdout\n console.log(result);\n }\n } catch (error) {\n if (isTelemetryEnabled && span) {\n (span as any).recordException(error as Error);\n (span as any).setStatus({ code: 2, message: (error as Error).message });\n }\n const message = getErrorMessage(error);\n console.error(ansis.red(`Error: ${message}`));\n process.exit(1);\n } finally {\n if (isTelemetryEnabled) {\n endSpan(span);\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|