@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,282 @@
|
|
|
1
|
+
import { readFile, writeFile, readdir, rm } from "fs/promises";
|
|
2
|
+
import { fileExists, ensureDir } from "../utils/file-io.js";
|
|
3
|
+
import { FileLock } from "../utils/file-lock.js";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import yaml from "yaml";
|
|
6
|
+
import ansis from "ansis";
|
|
7
|
+
import { Changeset } from "./changeset.js";
|
|
8
|
+
import { getErrorMessage } from "../utils/errors.js";
|
|
9
|
+
class StagedChangesetStorage {
|
|
10
|
+
changesetsDir;
|
|
11
|
+
constructor(rootPath) {
|
|
12
|
+
this.changesetsDir = path.join(rootPath, "documentation-robotics", "changesets");
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a new staged changeset directory structure
|
|
16
|
+
*/
|
|
17
|
+
async create(id, name, description, baseSnapshot) {
|
|
18
|
+
const now = (/* @__PURE__ */ new Date()).toISOString(), sanitizedId = this.sanitizeId(id), changesetPath = path.join(this.changesetsDir, sanitizedId);
|
|
19
|
+
await ensureDir(changesetPath);
|
|
20
|
+
const metadata = {
|
|
21
|
+
id: sanitizedId,
|
|
22
|
+
name,
|
|
23
|
+
description,
|
|
24
|
+
created: now,
|
|
25
|
+
modified: now,
|
|
26
|
+
status: "staged",
|
|
27
|
+
baseSnapshot,
|
|
28
|
+
stats: {
|
|
29
|
+
additions: 0,
|
|
30
|
+
modifications: 0,
|
|
31
|
+
deletions: 0
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
return await writeFile(path.join(changesetPath, "metadata.yaml"), yaml.stringify(metadata), "utf-8"), await writeFile(path.join(changesetPath, "changes.yaml"), yaml.stringify([]), "utf-8"), new Changeset({
|
|
35
|
+
id: sanitizedId,
|
|
36
|
+
name,
|
|
37
|
+
description,
|
|
38
|
+
created: now,
|
|
39
|
+
modified: now,
|
|
40
|
+
status: "staged",
|
|
41
|
+
baseSnapshot,
|
|
42
|
+
changes: [],
|
|
43
|
+
stats: metadata.stats
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Load a staged changeset from YAML files
|
|
48
|
+
*/
|
|
49
|
+
async load(id) {
|
|
50
|
+
const sanitizedId = this.sanitizeId(id), changesetPath = path.join(this.changesetsDir, sanitizedId), metadataPath = path.join(changesetPath, "metadata.yaml"), changesPath = path.join(changesetPath, "changes.yaml");
|
|
51
|
+
if (!await fileExists(changesetPath))
|
|
52
|
+
return null;
|
|
53
|
+
const metadataExists = await fileExists(metadataPath), changesExists = await fileExists(changesPath);
|
|
54
|
+
if (!metadataExists || !changesExists)
|
|
55
|
+
throw new Error(`Changeset '${id}' is corrupted (missing ${metadataExists ? "changes.yaml" : "metadata.yaml"}). Location: ${changesetPath}
|
|
56
|
+
This may indicate disk failure or incomplete write. Check disk health and restore from backup if available.`);
|
|
57
|
+
try {
|
|
58
|
+
const metadataContent = await readFile(metadataPath, "utf-8"), metadata = yaml.parse(metadataContent), changesContent = await readFile(changesPath, "utf-8"), changes = yaml.parse(changesContent) || [], data = {
|
|
59
|
+
id: metadata.id,
|
|
60
|
+
name: metadata.name,
|
|
61
|
+
description: metadata.description,
|
|
62
|
+
created: metadata.created,
|
|
63
|
+
modified: metadata.modified,
|
|
64
|
+
status: metadata.status,
|
|
65
|
+
baseSnapshot: metadata.baseSnapshot,
|
|
66
|
+
changes,
|
|
67
|
+
stats: metadata.stats || { additions: 0, modifications: 0, deletions: 0 }
|
|
68
|
+
};
|
|
69
|
+
return Changeset.fromJSON(data);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
throw new Error(`Failed to load changeset '${id}': YAML parsing failed.
|
|
72
|
+
Error: ${getErrorMessage(error)}
|
|
73
|
+
Location: ${metadataPath}
|
|
74
|
+
This indicates file corruption. Try:
|
|
75
|
+
1. Validate YAML syntax with: yamllint ${metadataPath}
|
|
76
|
+
2. Restore from backup if available
|
|
77
|
+
3. Manually edit to fix syntax errors`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Save a staged changeset to YAML files
|
|
82
|
+
*/
|
|
83
|
+
async save(changeset) {
|
|
84
|
+
if (!changeset.id)
|
|
85
|
+
throw new Error("Changeset must have an id to be saved in YAML format");
|
|
86
|
+
const sanitizedId = this.sanitizeId(changeset.id), changesetPath = path.join(this.changesetsDir, sanitizedId);
|
|
87
|
+
await ensureDir(changesetPath);
|
|
88
|
+
const metadata = {
|
|
89
|
+
id: changeset.id,
|
|
90
|
+
name: changeset.name,
|
|
91
|
+
description: changeset.description,
|
|
92
|
+
created: changeset.created,
|
|
93
|
+
modified: changeset.modified,
|
|
94
|
+
status: changeset.status,
|
|
95
|
+
baseSnapshot: changeset.baseSnapshot,
|
|
96
|
+
stats: changeset.stats || { additions: 0, modifications: 0, deletions: 0 }
|
|
97
|
+
};
|
|
98
|
+
await writeFile(path.join(changesetPath, "metadata.yaml"), yaml.stringify(metadata), "utf-8"), await writeFile(path.join(changesetPath, "changes.yaml"), yaml.stringify(changeset.changes), "utf-8");
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* List all staged changesets
|
|
102
|
+
*/
|
|
103
|
+
async list() {
|
|
104
|
+
if (!await fileExists(this.changesetsDir))
|
|
105
|
+
return [];
|
|
106
|
+
try {
|
|
107
|
+
const entries = await readdir(this.changesetsDir, { withFileTypes: !0 }), changesets = [];
|
|
108
|
+
let skippedCount = 0;
|
|
109
|
+
for (const entry of entries)
|
|
110
|
+
if (entry.isDirectory())
|
|
111
|
+
try {
|
|
112
|
+
const changeset = await this.load(entry.name);
|
|
113
|
+
changeset ? changesets.push(changeset) : (console.warn(ansis.yellow(`\u26A0 Warning: Changeset directory '${entry.name}' exists but could not be loaded (may be corrupted)`)), skippedCount++);
|
|
114
|
+
} catch (loadError) {
|
|
115
|
+
console.warn(ansis.yellow(`\u26A0 Warning: Failed to load changeset '${entry.name}': ${loadError instanceof Error ? loadError.message : String(loadError)}`)), skippedCount++;
|
|
116
|
+
}
|
|
117
|
+
return skippedCount > 0 && console.warn(ansis.yellow(`
|
|
118
|
+
\u26A0 ${skippedCount} changeset(s) could not be loaded and were skipped.`) + ansis.dim(`
|
|
119
|
+
Run 'dr changeset validate' to check for corruption and repair options.`)), changesets;
|
|
120
|
+
} catch (error) {
|
|
121
|
+
throw new Error(`Failed to list changesets: ${getErrorMessage(error)}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Delete a staged changeset
|
|
126
|
+
*/
|
|
127
|
+
async delete(id) {
|
|
128
|
+
const sanitizedId = this.sanitizeId(id), changesetPath = path.join(this.changesetsDir, sanitizedId);
|
|
129
|
+
if (!await fileExists(changesetPath)) {
|
|
130
|
+
const availableIds = (await this.list()).map((cs) => cs.id).join(", ");
|
|
131
|
+
throw new Error(`Changeset '${id}' not found.
|
|
132
|
+
Available changesets: ${availableIds || "(none)"}
|
|
133
|
+
Run 'dr changeset list' to see all changesets.`);
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
await rm(changesetPath, { recursive: !0, force: !0 });
|
|
137
|
+
} catch (error) {
|
|
138
|
+
throw new Error(`Failed to delete changeset '${id}': ${getErrorMessage(error)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Add or update a change in the changeset's changes.yaml
|
|
143
|
+
*
|
|
144
|
+
* Uses file locking to prevent concurrent modification race conditions
|
|
145
|
+
* Assigns sequence number atomically inside the lock to prevent duplicates
|
|
146
|
+
*
|
|
147
|
+
* @returns The assigned sequence number for the change
|
|
148
|
+
* @throws {Error} If lock acquisition, changeset load, save, or lock release fails
|
|
149
|
+
*/
|
|
150
|
+
async addChange(id, change) {
|
|
151
|
+
const changesetPath = this.getChangesetPath(id), lock = new FileLock(changesetPath);
|
|
152
|
+
try {
|
|
153
|
+
return await lock.withLock(async () => {
|
|
154
|
+
const changeset = await this.load(id);
|
|
155
|
+
if (!changeset)
|
|
156
|
+
throw new Error(`Changeset '${id}' not found`);
|
|
157
|
+
const sequenceNumber = changeset.changes.length, stagedChange = {
|
|
158
|
+
...change,
|
|
159
|
+
sequenceNumber
|
|
160
|
+
};
|
|
161
|
+
return changeset.changes.push(stagedChange), changeset.updateModified(), await this.save(changeset), sequenceNumber;
|
|
162
|
+
});
|
|
163
|
+
} catch (error) {
|
|
164
|
+
const errorMessage = getErrorMessage(error);
|
|
165
|
+
if (errorMessage.includes("lock") || errorMessage.includes("timeout")) {
|
|
166
|
+
const lockFilePath = path.join(changesetPath, ".lock");
|
|
167
|
+
throw new Error(`Failed to add change to changeset '${id}': Lock acquisition failed.
|
|
168
|
+
Error: ${errorMessage}
|
|
169
|
+
|
|
170
|
+
This usually means another dr process is modifying this changeset.
|
|
171
|
+
If no other processes are running, a stale lock file may exist.
|
|
172
|
+
|
|
173
|
+
To resolve:
|
|
174
|
+
1. Wait for other operations to complete
|
|
175
|
+
2. Check for running dr processes: ps aux | grep dr
|
|
176
|
+
3. If no processes found, remove stale lock: rm "${lockFilePath}"
|
|
177
|
+
4. Retry the operation`);
|
|
178
|
+
}
|
|
179
|
+
throw new Error(`Failed to add change to changeset '${id}': ${errorMessage}
|
|
180
|
+
Changeset path: ${changesetPath}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Remove a change by element ID
|
|
185
|
+
*
|
|
186
|
+
* Uses file locking to prevent concurrent modification race conditions
|
|
187
|
+
*
|
|
188
|
+
* @throws {Error} If lock acquisition, changeset load, save, or lock release fails
|
|
189
|
+
*/
|
|
190
|
+
async removeChange(id, elementId) {
|
|
191
|
+
const changesetPath = this.getChangesetPath(id), lock = new FileLock(changesetPath);
|
|
192
|
+
try {
|
|
193
|
+
await lock.withLock(async () => {
|
|
194
|
+
const changeset = await this.load(id);
|
|
195
|
+
if (!changeset)
|
|
196
|
+
throw new Error(`Changeset '${id}' not found`);
|
|
197
|
+
const filtered = changeset.changes.filter((c) => c.elementId !== elementId);
|
|
198
|
+
changeset.changes = filtered.map((c, idx) => ({
|
|
199
|
+
...c,
|
|
200
|
+
sequenceNumber: idx
|
|
201
|
+
})), changeset.updateModified(), await this.save(changeset);
|
|
202
|
+
});
|
|
203
|
+
} catch (error) {
|
|
204
|
+
const errorMessage = getErrorMessage(error);
|
|
205
|
+
if (errorMessage.includes("lock") || errorMessage.includes("timeout")) {
|
|
206
|
+
const lockFilePath = path.join(changesetPath, ".lock");
|
|
207
|
+
throw new Error(`Failed to remove change from changeset '${id}': Lock acquisition failed.
|
|
208
|
+
Error: ${errorMessage}
|
|
209
|
+
|
|
210
|
+
This usually means another dr process is modifying this changeset.
|
|
211
|
+
If no other processes are running, a stale lock file may exist.
|
|
212
|
+
|
|
213
|
+
To resolve:
|
|
214
|
+
1. Wait for other operations to complete
|
|
215
|
+
2. Check for running dr processes: ps aux | grep dr
|
|
216
|
+
3. If no processes found, remove stale lock: rm "${lockFilePath}"
|
|
217
|
+
4. Retry the operation`);
|
|
218
|
+
}
|
|
219
|
+
throw new Error(`Failed to remove change from changeset '${id}': ${errorMessage}
|
|
220
|
+
Changeset path: ${changesetPath}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Update an existing change in-place within the changeset's changes.yaml
|
|
225
|
+
*
|
|
226
|
+
* Atomically replaces the change for the given elementId under a single file lock,
|
|
227
|
+
* preventing data loss if the process is interrupted between a remove and add.
|
|
228
|
+
* The original sequence number is preserved so commit-ordering is unaffected.
|
|
229
|
+
*
|
|
230
|
+
* @throws {Error} If changeset not found, elementId not found in changes, or I/O error
|
|
231
|
+
*/
|
|
232
|
+
async updateChange(id, elementId, updated) {
|
|
233
|
+
const changesetPath = this.getChangesetPath(id), lock = new FileLock(changesetPath);
|
|
234
|
+
try {
|
|
235
|
+
await lock.withLock(async () => {
|
|
236
|
+
const changeset = await this.load(id);
|
|
237
|
+
if (!changeset)
|
|
238
|
+
throw new Error(`Changeset '${id}' not found`);
|
|
239
|
+
const index = changeset.changes.findIndex((c) => c.elementId === elementId);
|
|
240
|
+
if (index === -1)
|
|
241
|
+
throw new Error(`No change for element '${elementId}' in changeset '${id}'`);
|
|
242
|
+
const existing = changeset.changes[index];
|
|
243
|
+
changeset.changes[index] = {
|
|
244
|
+
...existing,
|
|
245
|
+
...updated,
|
|
246
|
+
sequenceNumber: existing.sequenceNumber ?? index
|
|
247
|
+
}, changeset.updateModified(), await this.save(changeset);
|
|
248
|
+
});
|
|
249
|
+
} catch (error) {
|
|
250
|
+
const errorMessage = getErrorMessage(error);
|
|
251
|
+
throw new Error(`Failed to update change in changeset '${id}': ${errorMessage}
|
|
252
|
+
Changeset path: ${changesetPath}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Get the storage path for a changeset
|
|
257
|
+
*/
|
|
258
|
+
getChangesetPath(id) {
|
|
259
|
+
const sanitizedId = this.sanitizeId(id);
|
|
260
|
+
return path.join(this.changesetsDir, sanitizedId);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Get the root changesets directory
|
|
264
|
+
*/
|
|
265
|
+
getChangesetsDir() {
|
|
266
|
+
return this.changesetsDir;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Sanitize changeset ID for safe use in file paths
|
|
270
|
+
* Prevents path traversal by removing special characters and path separators
|
|
271
|
+
*/
|
|
272
|
+
sanitizeId(id) {
|
|
273
|
+
const sanitized = id.replace(/\.\./g, "").replace(/^\/+/, "").replace(/^[A-Z]:\\/g, "").toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
|
|
274
|
+
if (!sanitized)
|
|
275
|
+
throw new Error(`Invalid changeset ID '${id}': results in empty string after sanitization. ID must contain at least one alphanumeric character.`);
|
|
276
|
+
return sanitized;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
export {
|
|
280
|
+
StagedChangesetStorage
|
|
281
|
+
};
|
|
282
|
+
//# sourceMappingURL=staged-changeset-storage.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/core/staged-changeset-storage.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * StagedChangesetStorage - Handles YAML-based storage for staged changesets\n *\n * Manages the new storage structure:\n * documentation-robotics/changesets/{changeset-id}/\n * \u251C\u2500\u2500 metadata.yaml # Name, description, dates, status, base snapshot\n * \u2514\u2500\u2500 changes.yaml # Delta-only change records\n */\n\nimport { readFile, writeFile, readdir, rm } from \"fs/promises\";\nimport { fileExists, ensureDir } from \"../utils/file-io.js\";\nimport { FileLock } from \"../utils/file-lock.js\";\nimport path from \"path\";\nimport yaml from \"yaml\";\nimport ansis from \"ansis\";\nimport type { StagedChangesetData, StagedChange } from \"./changeset.js\";\nimport { Changeset } from \"./changeset.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\n\n/**\n * Storage manager for staged changesets using YAML format\n */\nexport class StagedChangesetStorage {\n private changesetsDir: string;\n\n constructor(rootPath: string) {\n // Store changesets in documentation-robotics/changesets/ directory\n this.changesetsDir = path.join(rootPath, \"documentation-robotics\", \"changesets\");\n }\n\n /**\n * Create a new staged changeset directory structure\n */\n async create(\n id: string,\n name: string,\n description: string | undefined,\n baseSnapshot: string\n ): Promise<Changeset> {\n const now = new Date().toISOString();\n const sanitizedId = this.sanitizeId(id);\n const changesetPath = path.join(this.changesetsDir, sanitizedId);\n\n // Create directory structure\n await ensureDir(changesetPath);\n\n // Create metadata\n const metadata: Omit<StagedChangesetData, \"changes\"> = {\n id: sanitizedId,\n name,\n description,\n created: now,\n modified: now,\n status: \"staged\",\n baseSnapshot,\n stats: {\n additions: 0,\n modifications: 0,\n deletions: 0,\n },\n };\n\n // Write metadata.yaml\n await writeFile(path.join(changesetPath, \"metadata.yaml\"), yaml.stringify(metadata), \"utf-8\");\n\n // Write empty changes.yaml\n await writeFile(path.join(changesetPath, \"changes.yaml\"), yaml.stringify([]), \"utf-8\");\n\n // Return constructed changeset object\n return new Changeset({\n id: sanitizedId,\n name,\n description,\n created: now,\n modified: now,\n status: \"staged\",\n baseSnapshot,\n changes: [],\n stats: metadata.stats,\n });\n }\n\n /**\n * Load a staged changeset from YAML files\n */\n async load(id: string): Promise<Changeset | null> {\n const sanitizedId = this.sanitizeId(id);\n const changesetPath = path.join(this.changesetsDir, sanitizedId);\n const metadataPath = path.join(changesetPath, \"metadata.yaml\");\n const changesPath = path.join(changesetPath, \"changes.yaml\");\n\n // Check if changeset directory exists\n if (!(await fileExists(changesetPath))) {\n return null; // Changeset doesn't exist - this is OK\n }\n\n // Changeset directory exists - files SHOULD be present\n const metadataExists = await fileExists(metadataPath);\n const changesExists = await fileExists(changesPath);\n\n if (!metadataExists || !changesExists) {\n // Changeset directory exists but required files are missing - this is corruption\n throw new Error(\n `Changeset '${id}' is corrupted (missing ${!metadataExists ? \"metadata.yaml\" : \"changes.yaml\"}). ` +\n `Location: ${changesetPath}\\n` +\n `This may indicate disk failure or incomplete write. Check disk health and restore from backup if available.`\n );\n }\n\n try {\n // Load metadata\n const metadataContent = await readFile(metadataPath, \"utf-8\");\n const metadata = yaml.parse(metadataContent);\n\n // Load changes\n const changesContent = await readFile(changesPath, \"utf-8\");\n const changes = yaml.parse(changesContent) || [];\n\n // Construct changeset object\n const data: StagedChangesetData = {\n id: metadata.id,\n name: metadata.name,\n description: metadata.description,\n created: metadata.created,\n modified: metadata.modified,\n status: metadata.status,\n baseSnapshot: metadata.baseSnapshot,\n changes: changes as StagedChange[],\n stats: metadata.stats || { additions: 0, modifications: 0, deletions: 0 },\n };\n\n return Changeset.fromJSON(data);\n } catch (error) {\n // YAML parsing or file read error - provide detailed guidance\n throw new Error(\n `Failed to load changeset '${id}': YAML parsing failed.\\n` +\n `Error: ${getErrorMessage(error)}\\n` +\n `Location: ${metadataPath}\\n` +\n `This indicates file corruption. Try:\\n` +\n ` 1. Validate YAML syntax with: yamllint ${metadataPath}\\n` +\n ` 2. Restore from backup if available\\n` +\n ` 3. Manually edit to fix syntax errors`\n );\n }\n }\n\n /**\n * Save a staged changeset to YAML files\n */\n async save(changeset: Changeset): Promise<void> {\n if (!changeset.id) {\n throw new Error(\"Changeset must have an id to be saved in YAML format\");\n }\n\n const sanitizedId = this.sanitizeId(changeset.id);\n const changesetPath = path.join(this.changesetsDir, sanitizedId);\n await ensureDir(changesetPath);\n\n // Prepare metadata (all fields except changes)\n const metadata = {\n id: changeset.id,\n name: changeset.name,\n description: changeset.description,\n created: changeset.created,\n modified: changeset.modified,\n status: changeset.status,\n baseSnapshot: changeset.baseSnapshot,\n stats: changeset.stats || { additions: 0, modifications: 0, deletions: 0 },\n };\n\n // Write metadata.yaml\n await writeFile(path.join(changesetPath, \"metadata.yaml\"), yaml.stringify(metadata), \"utf-8\");\n\n // Write changes.yaml\n await writeFile(\n path.join(changesetPath, \"changes.yaml\"),\n yaml.stringify(changeset.changes),\n \"utf-8\"\n );\n }\n\n /**\n * List all staged changesets\n */\n async list(): Promise<Changeset[]> {\n if (!(await fileExists(this.changesetsDir))) {\n return [];\n }\n\n try {\n const entries = await readdir(this.changesetsDir, { withFileTypes: true });\n const changesets: Changeset[] = [];\n let skippedCount = 0;\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n try {\n const changeset = await this.load(entry.name);\n if (changeset) {\n changesets.push(changeset);\n } else {\n // load() returned null - directory exists but no valid changeset\n console.warn(\n ansis.yellow(\n `\u26A0 Warning: Changeset directory '${entry.name}' exists but could not be loaded (may be corrupted)`\n )\n );\n skippedCount++;\n }\n } catch (loadError) {\n // load() threw an error - this is a corrupted changeset\n console.warn(\n ansis.yellow(\n `\u26A0 Warning: Failed to load changeset '${entry.name}': ${loadError instanceof Error ? loadError.message : String(loadError)}`\n )\n );\n skippedCount++;\n }\n }\n }\n\n // Show summary if any were skipped\n if (skippedCount > 0) {\n console.warn(\n ansis.yellow(`\\n\u26A0 ${skippedCount} changeset(s) could not be loaded and were skipped.`) +\n ansis.dim(`\\nRun 'dr changeset validate' to check for corruption and repair options.`)\n );\n }\n\n return changesets;\n } catch (error) {\n throw new Error(\n `Failed to list changesets: ${getErrorMessage(error)}`\n );\n }\n }\n\n /**\n * Delete a staged changeset\n */\n async delete(id: string): Promise<void> {\n const sanitizedId = this.sanitizeId(id);\n const changesetPath = path.join(this.changesetsDir, sanitizedId);\n\n if (!(await fileExists(changesetPath))) {\n // List available changesets to help user\n const available = await this.list();\n const availableIds = available.map((cs) => cs.id).join(\", \");\n\n throw new Error(\n `Changeset '${id}' not found.\\n` +\n `Available changesets: ${availableIds || \"(none)\"}\\n` +\n `Run 'dr changeset list' to see all changesets.`\n );\n }\n\n try {\n await rm(changesetPath, { recursive: true, force: true });\n } catch (error) {\n throw new Error(\n `Failed to delete changeset '${id}': ${getErrorMessage(error)}`\n );\n }\n }\n\n /**\n * Add or update a change in the changeset's changes.yaml\n *\n * Uses file locking to prevent concurrent modification race conditions\n * Assigns sequence number atomically inside the lock to prevent duplicates\n *\n * @returns The assigned sequence number for the change\n * @throws {Error} If lock acquisition, changeset load, save, or lock release fails\n */\n async addChange(id: string, change: Omit<StagedChange, \"sequenceNumber\">): Promise<number> {\n const changesetPath = this.getChangesetPath(id);\n const lock = new FileLock(changesetPath);\n\n try {\n return await lock.withLock(async () => {\n const changeset = await this.load(id);\n if (!changeset) {\n throw new Error(`Changeset '${id}' not found`);\n }\n\n // Assign sequence number atomically inside the lock\n // This prevents race conditions when multiple concurrent operations\n // try to add changes at the same time\n const sequenceNumber = changeset.changes.length;\n const stagedChange: StagedChange = {\n ...change,\n sequenceNumber,\n };\n\n changeset.changes.push(stagedChange);\n changeset.updateModified();\n\n await this.save(changeset);\n\n return sequenceNumber;\n });\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n // Detect lock-specific errors\n if (errorMessage.includes(\"lock\") || errorMessage.includes(\"timeout\")) {\n const lockFilePath = path.join(changesetPath, \".lock\");\n\n throw new Error(\n `Failed to add change to changeset '${id}': Lock acquisition failed.\\n` +\n `Error: ${errorMessage}\\n\\n` +\n `This usually means another dr process is modifying this changeset.\\n` +\n `If no other processes are running, a stale lock file may exist.\\n\\n` +\n `To resolve:\\n` +\n ` 1. Wait for other operations to complete\\n` +\n ` 2. Check for running dr processes: ps aux | grep dr\\n` +\n ` 3. If no processes found, remove stale lock: rm \"${lockFilePath}\"\\n` +\n ` 4. Retry the operation`\n );\n }\n\n // Generic error with context\n throw new Error(\n `Failed to add change to changeset '${id}': ${errorMessage}\\n` +\n `Changeset path: ${changesetPath}`\n );\n }\n }\n\n /**\n * Remove a change by element ID\n *\n * Uses file locking to prevent concurrent modification race conditions\n *\n * @throws {Error} If lock acquisition, changeset load, save, or lock release fails\n */\n async removeChange(id: string, elementId: string): Promise<void> {\n const changesetPath = this.getChangesetPath(id);\n const lock = new FileLock(changesetPath);\n\n try {\n await lock.withLock(async () => {\n const changeset = await this.load(id);\n if (!changeset) {\n throw new Error(`Changeset '${id}' not found`);\n }\n\n // Filter out changes for this element\n const filtered = changeset.changes.filter((c) => c.elementId !== elementId);\n\n // Reconstruct changes with updated sequence numbers\n changeset.changes = filtered.map((c, idx) => ({\n ...c,\n sequenceNumber: idx,\n }));\n\n changeset.updateModified();\n\n await this.save(changeset);\n });\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n\n // Detect lock-specific errors\n if (errorMessage.includes(\"lock\") || errorMessage.includes(\"timeout\")) {\n const lockFilePath = path.join(changesetPath, \".lock\");\n\n throw new Error(\n `Failed to remove change from changeset '${id}': Lock acquisition failed.\\n` +\n `Error: ${errorMessage}\\n\\n` +\n `This usually means another dr process is modifying this changeset.\\n` +\n `If no other processes are running, a stale lock file may exist.\\n\\n` +\n `To resolve:\\n` +\n ` 1. Wait for other operations to complete\\n` +\n ` 2. Check for running dr processes: ps aux | grep dr\\n` +\n ` 3. If no processes found, remove stale lock: rm \"${lockFilePath}\"\\n` +\n ` 4. Retry the operation`\n );\n }\n\n // Generic error with context\n throw new Error(\n `Failed to remove change from changeset '${id}': ${errorMessage}\\n` +\n `Changeset path: ${changesetPath}`\n );\n }\n }\n\n /**\n * Update an existing change in-place within the changeset's changes.yaml\n *\n * Atomically replaces the change for the given elementId under a single file lock,\n * preventing data loss if the process is interrupted between a remove and add.\n * The original sequence number is preserved so commit-ordering is unaffected.\n *\n * @throws {Error} If changeset not found, elementId not found in changes, or I/O error\n */\n async updateChange(\n id: string,\n elementId: string,\n updated: Omit<StagedChange, \"sequenceNumber\">\n ): Promise<void> {\n const changesetPath = this.getChangesetPath(id);\n const lock = new FileLock(changesetPath);\n\n try {\n await lock.withLock(async () => {\n const changeset = await this.load(id);\n if (!changeset) {\n throw new Error(`Changeset '${id}' not found`);\n }\n\n const index = changeset.changes.findIndex((c) => c.elementId === elementId);\n if (index === -1) {\n throw new Error(`No change for element '${elementId}' in changeset '${id}'`);\n }\n\n // Spread existing entry first so runtime fields like sequenceNumber and timestamp\n // are preserved. Then apply the updated fields. Since `updated` is\n // Omit<StagedChange, \"sequenceNumber\">, it will not overwrite sequenceNumber.\n const existing = changeset.changes[index] as any;\n changeset.changes[index] = {\n ...existing,\n ...updated,\n sequenceNumber: existing.sequenceNumber ?? index,\n } as any;\n\n changeset.updateModified();\n await this.save(changeset);\n });\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n throw new Error(\n `Failed to update change in changeset '${id}': ${errorMessage}\\n` +\n `Changeset path: ${changesetPath}`\n );\n }\n }\n\n /**\n * Get the storage path for a changeset\n */\n getChangesetPath(id: string): string {\n const sanitizedId = this.sanitizeId(id);\n return path.join(this.changesetsDir, sanitizedId);\n }\n\n /**\n * Get the root changesets directory\n */\n getChangesetsDir(): string {\n return this.changesetsDir;\n }\n\n /**\n * Sanitize changeset ID for safe use in file paths\n * Prevents path traversal by removing special characters and path separators\n */\n private sanitizeId(id: string): string {\n const sanitized = id\n .replace(/\\.\\./g, \"\") // Remove .. (parent directory)\n .replace(/^\\/+/, \"\") // Remove leading slashes\n .replace(/^[A-Z]:\\\\/g, \"\") // Remove Windows drive letters\n .toLowerCase()\n .replace(/\\s+/g, \"-\") // Replace spaces with hyphens\n .replace(/[^a-z0-9-]/g, \"\"); // Keep only alphanumeric and hyphens\n\n if (!sanitized) {\n throw new Error(\n `Invalid changeset ID '${id}': results in empty string after sanitization. ` +\n `ID must contain at least one alphanumeric character.`\n );\n }\n\n return sanitized;\n }\n}\n"],
|
|
5
|
+
"mappings": "AASA,SAAS,UAAU,WAAW,SAAS,UAAU;AACjD,SAAS,YAAY,iBAAiB;AACtC,SAAS,gBAAgB;AACzB,OAAO,UAAU;AACjB,OAAO,UAAU;AACjB,OAAO,WAAW;AAElB,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAK1B,MAAO,uBAAsB;EACzB;EAER,YAAY,UAAgB;AAE1B,SAAK,gBAAgB,KAAK,KAAK,UAAU,0BAA0B,YAAY;EACjF;;;;EAKA,MAAM,OACJ,IACA,MACA,aACA,cAAoB;AAEpB,UAAM,OAAM,oBAAI,KAAI,GAAG,YAAW,GAC5B,cAAc,KAAK,WAAW,EAAE,GAChC,gBAAgB,KAAK,KAAK,KAAK,eAAe,WAAW;AAG/D,UAAM,UAAU,aAAa;AAG7B,UAAM,WAAiD;MACrD,IAAI;MACJ;MACA;MACA,SAAS;MACT,UAAU;MACV,QAAQ;MACR;MACA,OAAO;QACL,WAAW;QACX,eAAe;QACf,WAAW;;;AAKf,iBAAM,UAAU,KAAK,KAAK,eAAe,eAAe,GAAG,KAAK,UAAU,QAAQ,GAAG,OAAO,GAG5F,MAAM,UAAU,KAAK,KAAK,eAAe,cAAc,GAAG,KAAK,UAAU,CAAA,CAAE,GAAG,OAAO,GAG9E,IAAI,UAAU;MACnB,IAAI;MACJ;MACA;MACA,SAAS;MACT,UAAU;MACV,QAAQ;MACR;MACA,SAAS,CAAA;MACT,OAAO,SAAS;KACjB;EACH;;;;EAKA,MAAM,KAAK,IAAU;AACnB,UAAM,cAAc,KAAK,WAAW,EAAE,GAChC,gBAAgB,KAAK,KAAK,KAAK,eAAe,WAAW,GACzD,eAAe,KAAK,KAAK,eAAe,eAAe,GACvD,cAAc,KAAK,KAAK,eAAe,cAAc;AAG3D,QAAI,CAAE,MAAM,WAAW,aAAa;AAClC,aAAO;AAIT,UAAM,iBAAiB,MAAM,WAAW,YAAY,GAC9C,gBAAgB,MAAM,WAAW,WAAW;AAElD,QAAI,CAAC,kBAAkB,CAAC;AAEtB,YAAM,IAAI,MACR,cAAc,EAAE,2BAA4B,iBAAmC,iBAAlB,eAAgC,gBAC9E,aAAa;4GACmF;AAInH,QAAI;AAEF,YAAM,kBAAkB,MAAM,SAAS,cAAc,OAAO,GACtD,WAAW,KAAK,MAAM,eAAe,GAGrC,iBAAiB,MAAM,SAAS,aAAa,OAAO,GACpD,UAAU,KAAK,MAAM,cAAc,KAAK,CAAA,GAGxC,OAA4B;QAChC,IAAI,SAAS;QACb,MAAM,SAAS;QACf,aAAa,SAAS;QACtB,SAAS,SAAS;QAClB,UAAU,SAAS;QACnB,QAAQ,SAAS;QACjB,cAAc,SAAS;QACvB;QACA,OAAO,SAAS,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,WAAW,EAAC;;AAGzE,aAAO,UAAU,SAAS,IAAI;IAChC,SAAS,OAAO;AAEd,YAAM,IAAI,MACR,6BAA6B,EAAE;SACnB,gBAAgB,KAAK,CAAC;YACnB,YAAY;;2CAEmB,YAAY;;wCAEf;IAE/C;EACF;;;;EAKA,MAAM,KAAK,WAAoB;AAC7B,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,sDAAsD;AAGxE,UAAM,cAAc,KAAK,WAAW,UAAU,EAAE,GAC1C,gBAAgB,KAAK,KAAK,KAAK,eAAe,WAAW;AAC/D,UAAM,UAAU,aAAa;AAG7B,UAAM,WAAW;MACf,IAAI,UAAU;MACd,MAAM,UAAU;MAChB,aAAa,UAAU;MACvB,SAAS,UAAU;MACnB,UAAU,UAAU;MACpB,QAAQ,UAAU;MAClB,cAAc,UAAU;MACxB,OAAO,UAAU,SAAS,EAAE,WAAW,GAAG,eAAe,GAAG,WAAW,EAAC;;AAI1E,UAAM,UAAU,KAAK,KAAK,eAAe,eAAe,GAAG,KAAK,UAAU,QAAQ,GAAG,OAAO,GAG5F,MAAM,UACJ,KAAK,KAAK,eAAe,cAAc,GACvC,KAAK,UAAU,UAAU,OAAO,GAChC,OAAO;EAEX;;;;EAKA,MAAM,OAAI;AACR,QAAI,CAAE,MAAM,WAAW,KAAK,aAAa;AACvC,aAAO,CAAA;AAGT,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,KAAK,eAAe,EAAE,eAAe,GAAI,CAAE,GACnE,aAA0B,CAAA;AAChC,UAAI,eAAe;AAEnB,iBAAW,SAAS;AAClB,YAAI,MAAM,YAAW;AACnB,cAAI;AACF,kBAAM,YAAY,MAAM,KAAK,KAAK,MAAM,IAAI;AAC5C,YAAI,YACF,WAAW,KAAK,SAAS,KAGzB,QAAQ,KACN,MAAM,OACJ,wCAAmC,MAAM,IAAI,qDAAqD,CACnG,GAEH;UAEJ,SAAS,WAAW;AAElB,oBAAQ,KACN,MAAM,OACJ,6CAAwC,MAAM,IAAI,MAAM,qBAAqB,QAAQ,UAAU,UAAU,OAAO,SAAS,CAAC,EAAE,CAC7H,GAEH;UACF;AAKJ,aAAI,eAAe,KACjB,QAAQ,KACN,MAAM,OAAO;SAAO,YAAY,qDAAqD,IACnF,MAAM,IAAI;wEAA2E,CAAC,GAIrF;IACT,SAAS,OAAO;AACd,YAAM,IAAI,MACR,8BAA8B,gBAAgB,KAAK,CAAC,EAAE;IAE1D;EACF;;;;EAKA,MAAM,OAAO,IAAU;AACrB,UAAM,cAAc,KAAK,WAAW,EAAE,GAChC,gBAAgB,KAAK,KAAK,KAAK,eAAe,WAAW;AAE/D,QAAI,CAAE,MAAM,WAAW,aAAa,GAAI;AAGtC,YAAM,gBADY,MAAM,KAAK,KAAI,GACF,IAAI,CAAC,OAAO,GAAG,EAAE,EAAE,KAAK,IAAI;AAE3D,YAAM,IAAI,MACR,cAAc,EAAE;wBACW,gBAAgB,QAAQ;+CACD;IAEtD;AAEA,QAAI;AACF,YAAM,GAAG,eAAe,EAAE,WAAW,IAAM,OAAO,GAAI,CAAE;IAC1D,SAAS,OAAO;AACd,YAAM,IAAI,MACR,+BAA+B,EAAE,MAAM,gBAAgB,KAAK,CAAC,EAAE;IAEnE;EACF;;;;;;;;;;EAWA,MAAM,UAAU,IAAY,QAA4C;AACtE,UAAM,gBAAgB,KAAK,iBAAiB,EAAE,GACxC,OAAO,IAAI,SAAS,aAAa;AAEvC,QAAI;AACF,aAAO,MAAM,KAAK,SAAS,YAAW;AACpC,cAAM,YAAY,MAAM,KAAK,KAAK,EAAE;AACpC,YAAI,CAAC;AACH,gBAAM,IAAI,MAAM,cAAc,EAAE,aAAa;AAM/C,cAAM,iBAAiB,UAAU,QAAQ,QACnC,eAA6B;UACjC,GAAG;UACH;;AAGF,yBAAU,QAAQ,KAAK,YAAY,GACnC,UAAU,eAAc,GAExB,MAAM,KAAK,KAAK,SAAS,GAElB;MACT,CAAC;IACH,SAAS,OAAO;AACd,YAAM,eAAe,gBAAgB,KAAK;AAG1C,UAAI,aAAa,SAAS,MAAM,KAAK,aAAa,SAAS,SAAS,GAAG;AACrE,cAAM,eAAe,KAAK,KAAK,eAAe,OAAO;AAErD,cAAM,IAAI,MACR,sCAAsC,EAAE;SAC5B,YAAY;;;;;;;;qDAMgC,YAAY;yBACxC;MAEhC;AAGA,YAAM,IAAI,MACR,sCAAsC,EAAE,MAAM,YAAY;kBACrC,aAAa,EAAE;IAExC;EACF;;;;;;;;EASA,MAAM,aAAa,IAAY,WAAiB;AAC9C,UAAM,gBAAgB,KAAK,iBAAiB,EAAE,GACxC,OAAO,IAAI,SAAS,aAAa;AAEvC,QAAI;AACF,YAAM,KAAK,SAAS,YAAW;AAC7B,cAAM,YAAY,MAAM,KAAK,KAAK,EAAE;AACpC,YAAI,CAAC;AACH,gBAAM,IAAI,MAAM,cAAc,EAAE,aAAa;AAI/C,cAAM,WAAW,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,cAAc,SAAS;AAG1E,kBAAU,UAAU,SAAS,IAAI,CAAC,GAAG,SAAS;UAC5C,GAAG;UACH,gBAAgB;UAChB,GAEF,UAAU,eAAc,GAExB,MAAM,KAAK,KAAK,SAAS;MAC3B,CAAC;IACH,SAAS,OAAO;AACd,YAAM,eAAe,gBAAgB,KAAK;AAG1C,UAAI,aAAa,SAAS,MAAM,KAAK,aAAa,SAAS,SAAS,GAAG;AACrE,cAAM,eAAe,KAAK,KAAK,eAAe,OAAO;AAErD,cAAM,IAAI,MACR,2CAA2C,EAAE;SACjC,YAAY;;;;;;;;qDAMgC,YAAY;yBACxC;MAEhC;AAGA,YAAM,IAAI,MACR,2CAA2C,EAAE,MAAM,YAAY;kBAC1C,aAAa,EAAE;IAExC;EACF;;;;;;;;;;EAWA,MAAM,aACJ,IACA,WACA,SAA6C;AAE7C,UAAM,gBAAgB,KAAK,iBAAiB,EAAE,GACxC,OAAO,IAAI,SAAS,aAAa;AAEvC,QAAI;AACF,YAAM,KAAK,SAAS,YAAW;AAC7B,cAAM,YAAY,MAAM,KAAK,KAAK,EAAE;AACpC,YAAI,CAAC;AACH,gBAAM,IAAI,MAAM,cAAc,EAAE,aAAa;AAG/C,cAAM,QAAQ,UAAU,QAAQ,UAAU,CAAC,MAAM,EAAE,cAAc,SAAS;AAC1E,YAAI,UAAU;AACZ,gBAAM,IAAI,MAAM,0BAA0B,SAAS,mBAAmB,EAAE,GAAG;AAM7E,cAAM,WAAW,UAAU,QAAQ,KAAK;AACxC,kBAAU,QAAQ,KAAK,IAAI;UACzB,GAAG;UACH,GAAG;UACH,gBAAgB,SAAS,kBAAkB;WAG7C,UAAU,eAAc,GACxB,MAAM,KAAK,KAAK,SAAS;MAC3B,CAAC;IACH,SAAS,OAAO;AACd,YAAM,eAAe,gBAAgB,KAAK;AAC1C,YAAM,IAAI,MACR,yCAAyC,EAAE,MAAM,YAAY;kBACxC,aAAa,EAAE;IAExC;EACF;;;;EAKA,iBAAiB,IAAU;AACzB,UAAM,cAAc,KAAK,WAAW,EAAE;AACtC,WAAO,KAAK,KAAK,KAAK,eAAe,WAAW;EAClD;;;;EAKA,mBAAgB;AACd,WAAO,KAAK;EACd;;;;;EAMQ,WAAW,IAAU;AAC3B,UAAM,YAAY,GACf,QAAQ,SAAS,EAAE,EACnB,QAAQ,QAAQ,EAAE,EAClB,QAAQ,cAAc,EAAE,EACxB,YAAW,EACX,QAAQ,QAAQ,GAAG,EACnB,QAAQ,eAAe,EAAE;AAE5B,QAAI,CAAC;AACH,YAAM,IAAI,MACR,yBAAyB,EAAE,qGAC6B;AAI5D,WAAO;EACT;;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|