@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.
Files changed (510) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +466 -693
  3. package/dist/analysis/data-model-analyzer.js +189 -0
  4. package/dist/analysis/data-model-analyzer.js.map +7 -0
  5. package/dist/analysis/index.js +3 -0
  6. package/dist/analysis/index.js.map +7 -0
  7. package/dist/analysis/relationship-classifier.js +181 -0
  8. package/dist/analysis/relationship-classifier.js.map +7 -0
  9. package/dist/analyzers/base-analyzer.js +1 -0
  10. package/dist/analyzers/base-analyzer.js.map +7 -0
  11. package/dist/analyzers/call-graph-utils.js +39 -0
  12. package/dist/analyzers/call-graph-utils.js.map +7 -0
  13. package/dist/analyzers/cbm-analyzer.js +1205 -0
  14. package/dist/analyzers/cbm-analyzer.js.map +7 -0
  15. package/dist/analyzers/heuristic-utils.js +55 -0
  16. package/dist/analyzers/heuristic-utils.js.map +7 -0
  17. package/dist/analyzers/mapping-loader.js +146 -0
  18. package/dist/analyzers/mapping-loader.js.map +7 -0
  19. package/dist/analyzers/registry.js +124 -0
  20. package/dist/analyzers/registry.js.map +7 -0
  21. package/dist/analyzers/session-state.js +176 -0
  22. package/dist/analyzers/session-state.js.map +7 -0
  23. package/dist/analyzers/stdio-client.js +206 -0
  24. package/dist/analyzers/stdio-client.js.map +7 -0
  25. package/dist/analyzers/types.js +15 -0
  26. package/dist/analyzers/types.js.map +7 -0
  27. package/dist/analyzers/verify-engine.js +209 -0
  28. package/dist/analyzers/verify-engine.js.map +7 -0
  29. package/dist/analyzers/verify-ignore.js +130 -0
  30. package/dist/analyzers/verify-ignore.js.map +7 -0
  31. package/dist/analyzers/version.js +8 -0
  32. package/dist/analyzers/version.js.map +7 -0
  33. package/dist/audit/ai/runner.js +41 -0
  34. package/dist/audit/ai/runner.js.map +7 -0
  35. package/dist/audit/differential-analyzer.js +183 -0
  36. package/dist/audit/differential-analyzer.js.map +7 -0
  37. package/dist/audit/index.js +32 -0
  38. package/dist/audit/index.js.map +7 -0
  39. package/dist/audit/nodes/ai/evaluator.js +49 -0
  40. package/dist/audit/nodes/ai/evaluator.js.map +7 -0
  41. package/dist/audit/nodes/ai/parser.js +55 -0
  42. package/dist/audit/nodes/ai/parser.js.map +7 -0
  43. package/dist/audit/nodes/ai/prompts.js +103 -0
  44. package/dist/audit/nodes/ai/prompts.js.map +7 -0
  45. package/dist/audit/nodes/analysis/node-completeness-checker.js +32 -0
  46. package/dist/audit/nodes/analysis/node-completeness-checker.js.map +7 -0
  47. package/dist/audit/nodes/analysis/node-definition-analyzer.js +47 -0
  48. package/dist/audit/nodes/analysis/node-definition-analyzer.js.map +7 -0
  49. package/dist/audit/nodes/analysis/node-overlap-detector.js +79 -0
  50. package/dist/audit/nodes/analysis/node-overlap-detector.js.map +7 -0
  51. package/dist/audit/nodes/model/orchestrator.js +82 -0
  52. package/dist/audit/nodes/model/orchestrator.js.map +7 -0
  53. package/dist/audit/nodes/spec/loader.js +116 -0
  54. package/dist/audit/nodes/spec/loader.js.map +7 -0
  55. package/dist/audit/nodes/spec/orchestrator.js +68 -0
  56. package/dist/audit/nodes/spec/orchestrator.js.map +7 -0
  57. package/dist/audit/nodes/types.js +1 -0
  58. package/dist/audit/nodes/types.js.map +7 -0
  59. package/dist/audit/pipeline/index.js +5 -0
  60. package/dist/audit/pipeline/index.js.map +7 -0
  61. package/dist/audit/pipeline/pipeline-orchestrator.js +218 -0
  62. package/dist/audit/pipeline/pipeline-orchestrator.js.map +7 -0
  63. package/dist/audit/relationships/ai/evaluator.js +235 -0
  64. package/dist/audit/relationships/ai/evaluator.js.map +7 -0
  65. package/dist/audit/relationships/ai/parser.js +197 -0
  66. package/dist/audit/relationships/ai/parser.js.map +7 -0
  67. package/dist/audit/relationships/ai/prompts.js +274 -0
  68. package/dist/audit/relationships/ai/prompts.js.map +7 -0
  69. package/dist/audit/relationships/analysis/balance-assessor.js +115 -0
  70. package/dist/audit/relationships/analysis/balance-assessor.js.map +7 -0
  71. package/dist/audit/relationships/analysis/coverage-analyzer.js +99 -0
  72. package/dist/audit/relationships/analysis/coverage-analyzer.js.map +7 -0
  73. package/dist/audit/relationships/analysis/duplicate-detector.js +95 -0
  74. package/dist/audit/relationships/analysis/duplicate-detector.js.map +7 -0
  75. package/dist/audit/relationships/analysis/gap-analyzer.js +99 -0
  76. package/dist/audit/relationships/analysis/gap-analyzer.js.map +7 -0
  77. package/dist/audit/relationships/analysis/layer-templates.js +294 -0
  78. package/dist/audit/relationships/analysis/layer-templates.js.map +7 -0
  79. package/dist/audit/relationships/graph/connectivity.js +129 -0
  80. package/dist/audit/relationships/graph/connectivity.js.map +7 -0
  81. package/dist/audit/relationships/graph/relationship-graph.js +179 -0
  82. package/dist/audit/relationships/graph/relationship-graph.js.map +7 -0
  83. package/dist/audit/relationships/model/balance-assessor.js +49 -0
  84. package/dist/audit/relationships/model/balance-assessor.js.map +7 -0
  85. package/dist/audit/relationships/model/coverage-analyzer.js +34 -0
  86. package/dist/audit/relationships/model/coverage-analyzer.js.map +7 -0
  87. package/dist/audit/relationships/model/duplicate-detector.js +68 -0
  88. package/dist/audit/relationships/model/duplicate-detector.js.map +7 -0
  89. package/dist/audit/relationships/model/gap-analyzer.js +41 -0
  90. package/dist/audit/relationships/model/gap-analyzer.js.map +7 -0
  91. package/dist/audit/relationships/model/orchestrator.js +126 -0
  92. package/dist/audit/relationships/model/orchestrator.js.map +7 -0
  93. package/dist/audit/relationships/spec/orchestrator.js +157 -0
  94. package/dist/audit/relationships/spec/orchestrator.js.map +7 -0
  95. package/dist/audit/reports/index.js +5 -0
  96. package/dist/audit/reports/index.js.map +7 -0
  97. package/dist/audit/reports/report-generator.js +118 -0
  98. package/dist/audit/reports/report-generator.js.map +7 -0
  99. package/dist/audit/snapshot-storage.js +163 -0
  100. package/dist/audit/snapshot-storage.js.map +7 -0
  101. package/dist/audit/types.js +21 -0
  102. package/dist/audit/types.js.map +7 -0
  103. package/dist/cli.js +223 -92
  104. package/dist/cli.js.map +3 -3
  105. package/dist/coding-agents/agents/claude-code.js +147 -0
  106. package/dist/coding-agents/agents/claude-code.js.map +7 -0
  107. package/dist/coding-agents/agents/index.js +5 -0
  108. package/dist/coding-agents/agents/index.js.map +7 -0
  109. package/dist/coding-agents/agents/types.js +1 -0
  110. package/dist/coding-agents/agents/types.js.map +7 -0
  111. package/dist/coding-agents/base-chat-client.js +45 -0
  112. package/dist/coding-agents/base-chat-client.js.map +7 -0
  113. package/dist/coding-agents/chat-utils.js +23 -0
  114. package/dist/coding-agents/chat-utils.js.map +7 -0
  115. package/dist/coding-agents/claude-code-client.js +246 -0
  116. package/dist/coding-agents/claude-code-client.js.map +7 -0
  117. package/dist/coding-agents/copilot-client.js +209 -0
  118. package/dist/coding-agents/copilot-client.js.map +7 -0
  119. package/dist/commands/add.js +95 -33
  120. package/dist/commands/add.js.map +2 -2
  121. package/dist/commands/analyzer.js +511 -0
  122. package/dist/commands/analyzer.js.map +7 -0
  123. package/dist/commands/audit-diff.js +49 -0
  124. package/dist/commands/audit-diff.js.map +7 -0
  125. package/dist/commands/audit-snapshots.js +62 -0
  126. package/dist/commands/audit-snapshots.js.map +7 -0
  127. package/dist/commands/audit.js +81 -0
  128. package/dist/commands/audit.js.map +7 -0
  129. package/dist/commands/catalog.js +248 -0
  130. package/dist/commands/catalog.js.map +7 -0
  131. package/dist/commands/changeset.js +577 -66
  132. package/dist/commands/changeset.js.map +2 -2
  133. package/dist/commands/chat.js +106 -83
  134. package/dist/commands/chat.js.map +2 -2
  135. package/dist/commands/claude.js +74 -0
  136. package/dist/commands/claude.js.map +7 -0
  137. package/dist/commands/conformance.js +71 -68
  138. package/dist/commands/conformance.js.map +2 -2
  139. package/dist/commands/copilot.js +75 -0
  140. package/dist/commands/copilot.js.map +7 -0
  141. package/dist/commands/delete.js +125 -11
  142. package/dist/commands/delete.js.map +3 -3
  143. package/dist/commands/discover-logic.js +44 -0
  144. package/dist/commands/discover-logic.js.map +7 -0
  145. package/dist/commands/docs.js +87 -0
  146. package/dist/commands/docs.js.map +7 -0
  147. package/dist/commands/element.js +14 -20
  148. package/dist/commands/element.js.map +2 -2
  149. package/dist/commands/export.js +13 -3
  150. package/dist/commands/export.js.map +2 -2
  151. package/dist/commands/import.js +51 -0
  152. package/dist/commands/import.js.map +7 -0
  153. package/dist/commands/info.js +30 -24
  154. package/dist/commands/info.js.map +2 -2
  155. package/dist/commands/init.js +27 -11
  156. package/dist/commands/init.js.map +2 -2
  157. package/dist/commands/list.js +63 -13
  158. package/dist/commands/list.js.map +3 -3
  159. package/dist/commands/relationship.js +225 -37
  160. package/dist/commands/relationship.js.map +2 -2
  161. package/dist/commands/report.js +54 -0
  162. package/dist/commands/report.js.map +7 -0
  163. package/dist/commands/reports.js +45 -0
  164. package/dist/commands/reports.js.map +7 -0
  165. package/dist/commands/schema.js +135 -0
  166. package/dist/commands/schema.js.map +7 -0
  167. package/dist/commands/search.js +40 -12
  168. package/dist/commands/search.js.map +2 -2
  169. package/dist/commands/show.js +58 -27
  170. package/dist/commands/show.js.map +2 -2
  171. package/dist/commands/stats.js +35 -0
  172. package/dist/commands/stats.js.map +7 -0
  173. package/dist/commands/trace.js +39 -16
  174. package/dist/commands/trace.js.map +2 -2
  175. package/dist/commands/update.js +141 -14
  176. package/dist/commands/update.js.map +2 -2
  177. package/dist/commands/upgrade.js +210 -46
  178. package/dist/commands/upgrade.js.map +3 -3
  179. package/dist/commands/validate.js +142 -23
  180. package/dist/commands/validate.js.map +3 -3
  181. package/dist/commands/version.js +8 -12
  182. package/dist/commands/version.js.map +2 -2
  183. package/dist/commands/visualize.js +155 -25
  184. package/dist/commands/visualize.js.map +2 -2
  185. package/dist/core/base-snapshot-manager.js +84 -0
  186. package/dist/core/base-snapshot-manager.js.map +7 -0
  187. package/dist/core/changeset-exporter.js +305 -0
  188. package/dist/core/changeset-exporter.js.map +7 -0
  189. package/dist/core/changeset-validator.js +41 -0
  190. package/dist/core/changeset-validator.js.map +7 -0
  191. package/dist/core/changeset.js +88 -173
  192. package/dist/core/changeset.js.map +2 -2
  193. package/dist/core/dependency-tracker.js +4 -2
  194. package/dist/core/dependency-tracker.js.map +2 -2
  195. package/dist/core/element.js +98 -27
  196. package/dist/core/element.js.map +2 -2
  197. package/dist/core/golden-copy-cache.js +290 -0
  198. package/dist/core/golden-copy-cache.js.map +7 -0
  199. package/dist/core/graph-model.js +266 -0
  200. package/dist/core/graph-model.js.map +7 -0
  201. package/dist/core/layer.js +159 -16
  202. package/dist/core/layer.js.map +2 -2
  203. package/dist/core/layers.js +32 -0
  204. package/dist/core/layers.js.map +7 -0
  205. package/dist/core/manifest.js +32 -11
  206. package/dist/core/manifest.js.map +2 -2
  207. package/dist/core/migration-registry.js +56 -1
  208. package/dist/core/migration-registry.js.map +2 -2
  209. package/dist/core/model.js +424 -217
  210. package/dist/core/model.js.map +3 -3
  211. package/dist/core/mutation-handler.js +179 -0
  212. package/dist/core/mutation-handler.js.map +7 -0
  213. package/dist/core/reference-registry.js +29 -21
  214. package/dist/core/reference-registry.js.map +2 -2
  215. package/dist/core/relationship-catalog.js +189 -0
  216. package/dist/core/relationship-catalog.js.map +7 -0
  217. package/dist/core/relationship-registry.js.map +2 -2
  218. package/dist/core/relationships.js.map +1 -1
  219. package/dist/core/report-data-model.js +285 -0
  220. package/dist/core/report-data-model.js.map +7 -0
  221. package/dist/core/spec-data-service.js +185 -0
  222. package/dist/core/spec-data-service.js.map +7 -0
  223. package/dist/core/spec-loader-types.js +1 -0
  224. package/dist/core/spec-loader-types.js.map +7 -0
  225. package/dist/core/spec-loader.js +234 -0
  226. package/dist/core/spec-loader.js.map +7 -0
  227. package/dist/core/staged-changeset-storage.js +282 -0
  228. package/dist/core/staged-changeset-storage.js.map +7 -0
  229. package/dist/core/staging-area.js +1002 -0
  230. package/dist/core/staging-area.js.map +7 -0
  231. package/dist/core/stats-collector.js +169 -0
  232. package/dist/core/stats-collector.js.map +7 -0
  233. package/dist/core/virtual-projection.js +443 -0
  234. package/dist/core/virtual-projection.js.map +7 -0
  235. package/dist/export/archimate-exporter.js +99 -60
  236. package/dist/export/archimate-exporter.js.map +2 -2
  237. package/dist/export/audit-formatters.js +479 -0
  238. package/dist/export/audit-formatters.js.map +7 -0
  239. package/dist/export/diff-formatters.js +99 -0
  240. package/dist/export/diff-formatters.js.map +7 -0
  241. package/dist/export/export-manager.js.map +2 -2
  242. package/dist/export/graphml-exporter.js +44 -27
  243. package/dist/export/graphml-exporter.js.map +2 -2
  244. package/dist/export/index.js +4 -0
  245. package/dist/export/index.js.map +2 -2
  246. package/dist/export/json-schema-exporter.js +55 -42
  247. package/dist/export/json-schema-exporter.js.map +2 -2
  248. package/dist/export/markdown-exporter.js +92 -70
  249. package/dist/export/markdown-exporter.js.map +2 -2
  250. package/dist/export/markdown-generator.js +248 -0
  251. package/dist/export/markdown-generator.js.map +7 -0
  252. package/dist/export/markdown-utils.js +30 -0
  253. package/dist/export/markdown-utils.js.map +7 -0
  254. package/dist/export/mermaid-markdown-exporter.js +37 -0
  255. package/dist/export/mermaid-markdown-exporter.js.map +7 -0
  256. package/dist/export/openapi-exporter.js +119 -71
  257. package/dist/export/openapi-exporter.js.map +2 -2
  258. package/dist/export/plantuml-exporter.js +104 -39
  259. package/dist/export/plantuml-exporter.js.map +2 -2
  260. package/dist/export/report-formatters.js +111 -0
  261. package/dist/export/report-formatters.js.map +7 -0
  262. package/dist/export/stats-formatters.js +98 -0
  263. package/dist/export/stats-formatters.js.map +7 -0
  264. package/dist/export/types.js +2 -14
  265. package/dist/export/types.js.map +2 -2
  266. package/dist/export/verify-formatters.js +153 -0
  267. package/dist/export/verify-formatters.js.map +7 -0
  268. package/dist/generated/compiled-validators.js +17 -0
  269. package/dist/generated/compiled-validators.js.map +7 -0
  270. package/dist/generated/index.js +31 -0
  271. package/dist/generated/index.js.map +7 -0
  272. package/dist/generated/layer-registry.js +190 -0
  273. package/dist/generated/layer-registry.js.map +7 -0
  274. package/dist/generated/layer-types.js +7 -0
  275. package/dist/generated/layer-types.js.map +7 -0
  276. package/dist/generated/node-types.js +1719 -0
  277. package/dist/generated/node-types.js.map +7 -0
  278. package/dist/generated/relationship-index.js +14552 -0
  279. package/dist/generated/relationship-index.js.map +7 -0
  280. package/dist/import/archimate-importer.js +166 -0
  281. package/dist/import/archimate-importer.js.map +7 -0
  282. package/dist/import/index.js +47 -0
  283. package/dist/import/index.js.map +7 -0
  284. package/dist/import/openapi-importer.js +143 -0
  285. package/dist/import/openapi-importer.js.map +7 -0
  286. package/dist/import/types.js +1 -0
  287. package/dist/import/types.js.map +7 -0
  288. package/dist/integrations/base-manager.js +311 -0
  289. package/dist/integrations/base-manager.js.map +7 -0
  290. package/dist/integrations/claude-manager.js +360 -0
  291. package/dist/integrations/claude-manager.js.map +7 -0
  292. package/dist/integrations/claude_code/agents/dr-advisor.md +253 -0
  293. package/dist/integrations/claude_code/agents/dr-architect.md +278 -0
  294. package/dist/integrations/claude_code/agents/dr-extractor.md +286 -0
  295. package/dist/integrations/claude_code/commands/dr-changeset.md +657 -0
  296. package/dist/integrations/claude_code/commands/dr-design.md +373 -0
  297. package/dist/integrations/claude_code/commands/dr-info.md +132 -0
  298. package/dist/integrations/claude_code/commands/dr-init.md +251 -0
  299. package/dist/integrations/claude_code/commands/dr-map.md +936 -0
  300. package/dist/integrations/claude_code/commands/dr-model.md +493 -0
  301. package/dist/integrations/claude_code/commands/dr-relate.md +814 -0
  302. package/dist/integrations/claude_code/commands/dr-sync.md +279 -0
  303. package/dist/integrations/claude_code/commands/dr-validate.md +654 -0
  304. package/dist/integrations/claude_code/commands/dr-verify.md +559 -0
  305. package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +903 -0
  306. package/dist/integrations/claude_code/docs/QUICK_START.md +271 -0
  307. package/dist/integrations/claude_code/docs/README.md +347 -0
  308. package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +550 -0
  309. package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +620 -0
  310. package/dist/integrations/claude_code/skills/dr_03_security_layer/SKILL.md +642 -0
  311. package/dist/integrations/claude_code/skills/dr_04_application_layer/SKILL.md +911 -0
  312. package/dist/integrations/claude_code/skills/dr_05_technology_layer/SKILL.md +836 -0
  313. package/dist/integrations/claude_code/skills/dr_06_api_layer/SKILL.md +933 -0
  314. package/dist/integrations/claude_code/skills/dr_07_data_model_layer/SKILL.md +210 -0
  315. package/dist/integrations/claude_code/skills/dr_08_dataset_layer/SKILL.md +319 -0
  316. package/dist/integrations/claude_code/skills/dr_09_ux_layer/SKILL.md +319 -0
  317. package/dist/integrations/claude_code/skills/dr_10_navigation_layer/SKILL.md +318 -0
  318. package/dist/integrations/claude_code/skills/dr_11_apm_layer/SKILL.md +273 -0
  319. package/dist/integrations/claude_code/skills/dr_12_testing_layer/SKILL.md +273 -0
  320. package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +187 -0
  321. package/dist/integrations/claude_code/skills/dr_codebase_memory/SKILL.md +590 -0
  322. package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +295 -0
  323. package/dist/integrations/copilot-manager.js +328 -0
  324. package/dist/integrations/copilot-manager.js.map +7 -0
  325. package/dist/integrations/github_copilot/agents/dr-advisor.md +243 -0
  326. package/dist/integrations/github_copilot/agents/dr-architect.md +1567 -0
  327. package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +491 -0
  328. package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +539 -0
  329. package/dist/integrations/github_copilot/skills/dr_03_security_layer/SKILL.md +667 -0
  330. package/dist/integrations/github_copilot/skills/dr_04_application_layer/SKILL.md +670 -0
  331. package/dist/integrations/github_copilot/skills/dr_05_technology_layer/SKILL.md +660 -0
  332. package/dist/integrations/github_copilot/skills/dr_06_api_layer/SKILL.md +855 -0
  333. package/dist/integrations/github_copilot/skills/dr_07_data_model_layer/SKILL.md +171 -0
  334. package/dist/integrations/github_copilot/skills/dr_08_dataset_layer/SKILL.md +216 -0
  335. package/dist/integrations/github_copilot/skills/dr_09_ux_layer/SKILL.md +230 -0
  336. package/dist/integrations/github_copilot/skills/dr_10_navigation_layer/SKILL.md +228 -0
  337. package/dist/integrations/github_copilot/skills/dr_11_apm_layer/SKILL.md +234 -0
  338. package/dist/integrations/github_copilot/skills/dr_12_testing_layer/SKILL.md +230 -0
  339. package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +187 -0
  340. package/dist/integrations/hash-utils.js +51 -0
  341. package/dist/integrations/hash-utils.js.map +7 -0
  342. package/dist/integrations/types.js +16 -0
  343. package/dist/integrations/types.js.map +7 -0
  344. package/dist/reports/model-layer-report-generator.js +278 -0
  345. package/dist/reports/model-layer-report-generator.js.map +7 -0
  346. package/dist/reports/model-report-data.js +57 -0
  347. package/dist/reports/model-report-data.js.map +7 -0
  348. package/dist/reports/model-report-orchestrator.js +103 -0
  349. package/dist/reports/model-report-orchestrator.js.map +7 -0
  350. package/dist/schemas/bundled/analyzers/cbm.json +595 -0
  351. package/dist/schemas/bundled/analyzers/manifest.json +9 -0
  352. package/dist/schemas/bundled/api.json +3411 -0
  353. package/dist/schemas/bundled/apm.json +2371 -0
  354. package/dist/schemas/bundled/application.json +1253 -0
  355. package/dist/schemas/bundled/base.json +1622 -0
  356. package/dist/schemas/bundled/business.json +1279 -0
  357. package/dist/schemas/bundled/data-model.json +1298 -0
  358. package/dist/schemas/bundled/data-store.json +2025 -0
  359. package/dist/schemas/bundled/manifest.json +93 -0
  360. package/dist/schemas/bundled/motivation.json +1360 -0
  361. package/dist/schemas/bundled/navigation.json +1874 -0
  362. package/dist/schemas/bundled/security.json +3488 -0
  363. package/dist/schemas/bundled/technology.json +2067 -0
  364. package/dist/schemas/bundled/testing.json +3120 -0
  365. package/dist/schemas/bundled/ux.json +3592 -0
  366. package/dist/server/schemas.js +202 -0
  367. package/dist/server/schemas.js.map +7 -0
  368. package/dist/server/server.js +1336 -252
  369. package/dist/server/server.js.map +3 -3
  370. package/dist/server/telemetry-middleware.js +22 -15
  371. package/dist/server/telemetry-middleware.js.map +2 -2
  372. package/dist/server-entry.js +65 -0
  373. package/dist/server-entry.js.map +7 -0
  374. package/dist/telemetry/config.js +89 -0
  375. package/dist/telemetry/config.js.map +7 -0
  376. package/dist/telemetry/console-interceptor.js.map +1 -1
  377. package/dist/telemetry/detect.js +24 -0
  378. package/dist/telemetry/detect.js.map +7 -0
  379. package/dist/telemetry/fetch-otlp-exporter.js +112 -0
  380. package/dist/telemetry/fetch-otlp-exporter.js.map +7 -0
  381. package/dist/telemetry/index.js +153 -3
  382. package/dist/telemetry/index.js.map +2 -2
  383. package/dist/telemetry/resilient-exporter.js +22 -8
  384. package/dist/telemetry/resilient-exporter.js.map +2 -2
  385. package/dist/telemetry/resilient-log-exporter.js +17 -8
  386. package/dist/telemetry/resilient-log-exporter.js.map +2 -2
  387. package/dist/telemetry/test-instrumentation.js.map +2 -2
  388. package/dist/types/index.js +84 -0
  389. package/dist/types/index.js.map +3 -3
  390. package/dist/types/source-reference.js +1 -0
  391. package/dist/types/source-reference.js.map +7 -0
  392. package/dist/utils/chat-logger.js +292 -0
  393. package/dist/utils/chat-logger.js.map +7 -0
  394. package/dist/utils/claude-stream.js +8 -0
  395. package/dist/utils/claude-stream.js.map +7 -0
  396. package/dist/utils/date-utils.js +7 -0
  397. package/dist/utils/date-utils.js.map +7 -0
  398. package/dist/utils/element-utils.js.map +1 -1
  399. package/dist/utils/errors.js +88 -15
  400. package/dist/utils/errors.js.map +3 -3
  401. package/dist/utils/export-python-annotations.js +82 -0
  402. package/dist/utils/export-python-annotations.js.map +7 -0
  403. package/dist/utils/file-io.js +7 -2
  404. package/dist/utils/file-io.js.map +2 -2
  405. package/dist/utils/file-lock.js +156 -0
  406. package/dist/utils/file-lock.js.map +7 -0
  407. package/dist/utils/id-generator.js +18 -0
  408. package/dist/utils/id-generator.js.map +7 -0
  409. package/dist/utils/layer-name-formatter.js +16 -0
  410. package/dist/utils/layer-name-formatter.js.map +7 -0
  411. package/dist/utils/markdown-anchor.js +7 -0
  412. package/dist/utils/markdown-anchor.js.map +7 -0
  413. package/dist/utils/markdown-link.js +12 -0
  414. package/dist/utils/markdown-link.js.map +7 -0
  415. package/dist/utils/markdown-table.js +17 -0
  416. package/dist/utils/markdown-table.js.map +7 -0
  417. package/dist/utils/mermaid-utils.js +11 -0
  418. package/dist/utils/mermaid-utils.js.map +7 -0
  419. package/dist/utils/project-paths.js.map +2 -2
  420. package/dist/utils/source-reference.js +52 -0
  421. package/dist/utils/source-reference.js.map +7 -0
  422. package/dist/utils/spec-installer.js +40 -53
  423. package/dist/utils/spec-installer.js.map +2 -2
  424. package/dist/utils/spec-version.js +5 -1
  425. package/dist/utils/spec-version.js.map +2 -2
  426. package/dist/utils/string-utils.js +12 -0
  427. package/dist/utils/string-utils.js.map +7 -0
  428. package/dist/utils/table-formatting.js +19 -0
  429. package/dist/utils/table-formatting.js.map +7 -0
  430. package/dist/validators/index.js +4 -0
  431. package/dist/validators/index.js.map +2 -2
  432. package/dist/validators/naming-validator.js +20 -23
  433. package/dist/validators/naming-validator.js.map +2 -2
  434. package/dist/validators/reference-validator.js +23 -38
  435. package/dist/validators/reference-validator.js.map +2 -2
  436. package/dist/validators/relationship-schema-validator.js +243 -0
  437. package/dist/validators/relationship-schema-validator.js.map +7 -0
  438. package/dist/validators/schema-validator.js +168 -68
  439. package/dist/validators/schema-validator.js.map +2 -2
  440. package/dist/validators/semantic-validator.js +36 -60
  441. package/dist/validators/semantic-validator.js.map +2 -2
  442. package/dist/validators/types.js.map +2 -2
  443. package/dist/validators/validation-formatter.js +159 -0
  444. package/dist/validators/validation-formatter.js.map +7 -0
  445. package/dist/validators/validator.js +24 -38
  446. package/dist/validators/validator.js.map +2 -2
  447. package/dist/viewer/README.md +139 -0
  448. package/dist/viewer/assets/main-CY0Xufuj.css +1 -0
  449. package/dist/viewer/assets/main-DtgErnwF.js +81 -0
  450. package/dist/viewer/assets/vendor-CxKvDp2x.js +17 -0
  451. package/dist/viewer/favicon.svg +11 -0
  452. package/dist/viewer/fonts/inter/Inter-Black.woff2 +0 -0
  453. package/dist/viewer/fonts/inter/Inter-Bold.woff2 +0 -0
  454. package/dist/viewer/fonts/inter/Inter-ExtraBold.woff2 +0 -0
  455. package/dist/viewer/fonts/inter/Inter-Light.woff2 +0 -0
  456. package/dist/viewer/fonts/inter/Inter-Medium.woff2 +0 -0
  457. package/dist/viewer/fonts/inter/Inter-Regular.woff2 +0 -0
  458. package/dist/viewer/fonts/inter/Inter-SemiBold.woff2 +0 -0
  459. package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-Medium.woff2 +0 -0
  460. package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2 +0 -0
  461. package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-SemiBold.woff2 +0 -0
  462. package/dist/viewer/index.html +15 -0
  463. package/dist/viewer/manifest.json +99 -0
  464. package/dist/viewer/version.json +1 -0
  465. package/package.json +37 -13
  466. package/PYTHON_CLI_PARITY.md +0 -265
  467. package/PYTHON_CLI_STRUCTURE_UPDATE.md +0 -246
  468. package/biome.json +0 -42
  469. package/bunfig.toml +0 -3
  470. package/dist/ai/claude-client.js +0 -71
  471. package/dist/ai/claude-client.js.map +0 -7
  472. package/dist/ai/context-provider.js +0 -129
  473. package/dist/ai/context-provider.js.map +0 -7
  474. package/dist/ai/tools.js +0 -231
  475. package/dist/ai/tools.js.map +0 -7
  476. package/dist/commands/migrate.js +0 -36
  477. package/dist/commands/migrate.js.map +0 -7
  478. package/dist/commands/project.js +0 -74
  479. package/dist/commands/project.js.map +0 -7
  480. package/dist/core/active-changeset.js +0 -52
  481. package/dist/core/active-changeset.js.map +0 -7
  482. package/dist/core/projection-engine.js +0 -288
  483. package/dist/core/projection-engine.js.map +0 -7
  484. package/dist/schemas/bundled/01-motivation-layer.schema.json +0 -942
  485. package/dist/schemas/bundled/02-business-layer.schema.json +0 -1293
  486. package/dist/schemas/bundled/03-security-layer.schema.json +0 -2177
  487. package/dist/schemas/bundled/04-application-layer.schema.json +0 -1328
  488. package/dist/schemas/bundled/05-technology-layer.schema.json +0 -1465
  489. package/dist/schemas/bundled/06-api-layer.schema.json +0 -1743
  490. package/dist/schemas/bundled/07-data-model-layer.schema.json +0 -1253
  491. package/dist/schemas/bundled/08-datastore-layer.schema.json +0 -892
  492. package/dist/schemas/bundled/09-ux-layer.schema.json +0 -1506
  493. package/dist/schemas/bundled/10-navigation-layer.schema.json +0 -843
  494. package/dist/schemas/bundled/11-apm-observability-layer.schema.json +0 -1430
  495. package/dist/schemas/bundled/12-testing-layer.schema.json +0 -1091
  496. package/dist/schemas/bundled/common/layer-extensions.schema.json +0 -266
  497. package/dist/schemas/bundled/common/predicates.schema.json +0 -493
  498. package/dist/schemas/bundled/common/relationships.schema.json +0 -791
  499. package/dist/schemas/bundled/common/source-references.schema.json +0 -71
  500. package/dist/schemas/bundled/link-registry.json +0 -1839
  501. package/dist/schemas/bundled/link-registry.schema.json +0 -339
  502. package/dist/schemas/bundled/relationship-catalog.json +0 -1302
  503. package/dist/schemas/bundled/relationship-type.schema.json +0 -221
  504. package/dist/utils/model-path.js +0 -22
  505. package/dist/utils/model-path.js.map +0 -7
  506. package/docs/TEST-INSTRUMENTATION.md +0 -405
  507. package/docs/telemetry.md +0 -427
  508. package/test-debug.js +0 -33
  509. package/test-special.mjs +0 -46
  510. package/test_runner.ts +0 -7
@@ -0,0 +1,135 @@
1
+ import ansis from "ansis";
2
+ import { CLIError, ErrorCategory, handleError } from "../utils/errors.js";
3
+ import { getAllLayerIds, getLayerById } from "../generated/layer-registry.js";
4
+ import { getNodeType, getNodeTypesForLayer, isValidSpecNodeId } from "../generated/node-types.js";
5
+ import { getValidRelationships } from "../generated/relationship-index.js";
6
+ async function schemaLayersCommand() {
7
+ try {
8
+ console.log(ansis.bold(`
9
+ Architecture Layers:
10
+ `));
11
+ for (const layerId of getAllLayerIds()) {
12
+ const layer = getLayerById(layerId);
13
+ if (!layer)
14
+ continue;
15
+ const nodeTypes = getNodeTypesForLayer(layerId);
16
+ console.log(ansis.cyan(`${layer.number}. ${layer.name}`) + ansis.gray(` (${layerId})`)), console.log(` ${layer.description}`), console.log(` Node types: ${ansis.yellow(nodeTypes.length.toString())}`), layer.inspiredBy && console.log(` Standard: ${layer.inspiredBy.standard} ${layer.inspiredBy.version}`), console.log();
17
+ }
18
+ } catch (error) {
19
+ handleError(error);
20
+ }
21
+ }
22
+ async function schemaTypesCommand(layerId) {
23
+ try {
24
+ const layer = getLayerById(layerId);
25
+ if (!layer) {
26
+ const validLayers = getAllLayerIds().join(", ");
27
+ throw new CLIError(`Unknown layer: ${layerId}`, ErrorCategory.USER, [`Valid layers: ${validLayers}`]);
28
+ }
29
+ const nodeTypes = getNodeTypesForLayer(layerId);
30
+ console.log(ansis.bold(`
31
+ Node Types for ${layer.name}:
32
+ `));
33
+ for (const nodeType of nodeTypes)
34
+ console.log(ansis.cyan(` ${nodeType.type}`) + ansis.gray(` (${nodeType.specNodeId})`)), console.log(` ${nodeType.title}`), nodeType.requiredAttributes && nodeType.requiredAttributes.length > 0 && console.log(` Required: ${ansis.yellow(nodeType.requiredAttributes.join(", "))}`), nodeType.optionalAttributes && nodeType.optionalAttributes.length > 0 && console.log(` Optional: ${ansis.gray(nodeType.optionalAttributes.join(", "))}`), console.log();
35
+ } catch (error) {
36
+ handleError(error);
37
+ }
38
+ }
39
+ async function schemaNodeCommand(specNodeId) {
40
+ try {
41
+ if (!isValidSpecNodeId(specNodeId))
42
+ throw new CLIError(`Invalid spec node ID format: ${specNodeId}`, ErrorCategory.USER, ["Expected format: {layer}.{type} (e.g., motivation.goal, api.endpoint)"]);
43
+ const nodeType = getNodeType(specNodeId);
44
+ if (!nodeType)
45
+ throw new CLIError(`Unknown node type: ${specNodeId}`, ErrorCategory.USER, ["Use `dr schema types <layer>` to list valid types"]);
46
+ if (console.log(ansis.bold(`
47
+ ${nodeType.title}
48
+ `)), console.log(`Spec Node ID: ${ansis.cyan(nodeType.specNodeId)}`), console.log(`Layer: ${nodeType.layer}`), console.log(`Type: ${nodeType.type}`), console.log(), nodeType.requiredAttributes && nodeType.requiredAttributes.length > 0) {
49
+ console.log(ansis.yellow("Required Attributes:"));
50
+ for (const attr of nodeType.requiredAttributes) {
51
+ const constraint = nodeType.attributeConstraints?.[attr];
52
+ console.log(` - ${attr}: ${formatAttributeConstraint(constraint)}`);
53
+ }
54
+ console.log();
55
+ }
56
+ if (nodeType.optionalAttributes && nodeType.optionalAttributes.length > 0) {
57
+ console.log(ansis.gray("Optional Attributes:"));
58
+ for (const attr of nodeType.optionalAttributes) {
59
+ const constraint = nodeType.attributeConstraints?.[attr];
60
+ console.log(` - ${attr}: ${formatAttributeConstraint(constraint)}`);
61
+ }
62
+ console.log();
63
+ }
64
+ } catch (error) {
65
+ handleError(error);
66
+ }
67
+ }
68
+ async function schemaRelationshipCommand(sourceType, predicate) {
69
+ try {
70
+ if (!isValidSpecNodeId(sourceType)) {
71
+ const hints = ["Expected format: {layer}.{type} (e.g., motivation.goal, api.endpoint)"], matches = [];
72
+ for (const layerId of getAllLayerIds())
73
+ for (const nodeType of getNodeTypesForLayer(layerId))
74
+ nodeType.type === sourceType.toLowerCase() && matches.push(nodeType.specNodeId);
75
+ throw matches.length === 1 ? hints.push(`Did you mean: ${matches[0]}?`) : matches.length > 1 && hints.push(`Did you mean one of: ${matches.join(", ")}?`), new CLIError(`Invalid spec node ID format: ${sourceType}`, ErrorCategory.USER, hints);
76
+ }
77
+ const relationships = predicate ? getValidRelationships(sourceType, predicate) : getValidRelationships(sourceType);
78
+ if (relationships.length === 0) {
79
+ const msg = predicate ? `No relationships found for ${sourceType} --[${predicate}]-->` : `No relationships found for ${sourceType}`;
80
+ console.log(msg);
81
+ return;
82
+ }
83
+ console.log(ansis.bold(`
84
+ Valid Relationships for ${sourceType}:
85
+ `));
86
+ const byPredicate = /* @__PURE__ */ new Map();
87
+ for (const rel of relationships) {
88
+ byPredicate.has(rel.predicate) || byPredicate.set(rel.predicate, []);
89
+ const predicateRels = byPredicate.get(rel.predicate);
90
+ predicateRels && predicateRels.push(rel);
91
+ }
92
+ for (const [pred, rels] of byPredicate) {
93
+ console.log(ansis.cyan(` --[${pred}]-->`));
94
+ for (const rel of rels) {
95
+ const strength = formatStrength(rel.strength), cardinality = ansis.gray(`(${rel.cardinality})`);
96
+ console.log(` ${rel.destinationSpecNodeId} ${strength} ${cardinality}`);
97
+ }
98
+ console.log();
99
+ }
100
+ } catch (error) {
101
+ handleError(error);
102
+ }
103
+ }
104
+ function formatAttributeConstraint(constraint) {
105
+ if (!constraint)
106
+ return "any";
107
+ if (typeof constraint == "string")
108
+ return constraint;
109
+ const c = constraint;
110
+ if (c.type) {
111
+ let result = String(c.type);
112
+ return c.enum && Array.isArray(c.enum) && (result += ` [${c.enum.join(" | ")}]`), c.pattern && (result += ` (pattern: ${c.pattern})`), result;
113
+ }
114
+ return "object";
115
+ }
116
+ function formatStrength(strength) {
117
+ return {
118
+ critical: (s) => ansis.red(s),
119
+ high: (s) => ansis.yellow(s),
120
+ medium: (s) => ansis.blue(s),
121
+ low: (s) => ansis.gray(s)
122
+ }[strength]?.(strength) || strength;
123
+ }
124
+ function schemaCommands(program) {
125
+ const schemaCmd = program.command("schema").description("Inspect schema metadata (layers, types, relationships)");
126
+ schemaCmd.command("layers").description("List all layers with node type counts").action(schemaLayersCommand), schemaCmd.command("types <layer>").description("List valid node types for a layer").action(schemaTypesCommand), schemaCmd.command("node <spec_node_id>").description("Show detailed schema for a node type").action(schemaNodeCommand), schemaCmd.command("relationship <source_type> [predicate]").description("Show valid relationships for a node type").action(schemaRelationshipCommand);
127
+ }
128
+ export {
129
+ schemaCommands,
130
+ schemaLayersCommand,
131
+ schemaNodeCommand,
132
+ schemaRelationshipCommand,
133
+ schemaTypesCommand
134
+ };
135
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/commands/schema.ts"],
4
+ "sourcesContent": ["/**\n * Schema introspection commands for viewing layer and type metadata\n * Provides detailed schema information directly from generated registries\n */\n\nimport ansis from \"ansis\";\nimport { CLIError, ErrorCategory, handleError } from \"../utils/errors.js\";\nimport {\n getAllLayerIds,\n getLayerById,\n} from \"../generated/layer-registry.js\";\nimport {\n getNodeType,\n getNodeTypesForLayer,\n isValidSpecNodeId,\n} from \"../generated/node-types.js\";\nimport {\n getValidRelationships,\n type RelationshipSpec,\n} from \"../generated/relationship-index.js\";\nimport { Command } from \"commander\";\n\n/**\n * dr schema layers - List all layers with node type counts\n */\nexport async function schemaLayersCommand(): Promise<void> {\n try {\n console.log(ansis.bold(\"\\nArchitecture Layers:\\n\"));\n\n for (const layerId of getAllLayerIds()) {\n const layer = getLayerById(layerId);\n if (!layer) continue;\n\n const nodeTypes = getNodeTypesForLayer(layerId);\n\n console.log(\n ansis.cyan(`${layer.number}. ${layer.name}`) +\n ansis.gray(` (${layerId})`)\n );\n console.log(` ${layer.description}`);\n console.log(\n ` Node types: ${ansis.yellow(nodeTypes.length.toString())}`\n );\n\n if (layer.inspiredBy) {\n console.log(\n ` Standard: ${layer.inspiredBy.standard} ${layer.inspiredBy.version}`\n );\n }\n\n console.log();\n }\n } catch (error) {\n handleError(error);\n }\n}\n\n/**\n * dr schema types <layer> - List valid types for a layer\n */\nexport async function schemaTypesCommand(layerId: string): Promise<void> {\n try {\n const layer = getLayerById(layerId);\n\n if (!layer) {\n const validLayers = getAllLayerIds().join(\", \");\n throw new CLIError(\n `Unknown layer: ${layerId}`,\n ErrorCategory.USER,\n [`Valid layers: ${validLayers}`]\n );\n }\n\n const nodeTypes = getNodeTypesForLayer(layerId);\n\n console.log(ansis.bold(`\\nNode Types for ${layer.name}:\\n`));\n\n for (const nodeType of nodeTypes) {\n console.log(\n ansis.cyan(` ${nodeType.type}`) +\n ansis.gray(` (${nodeType.specNodeId})`)\n );\n console.log(` ${nodeType.title}`);\n\n if (\n nodeType.requiredAttributes &&\n nodeType.requiredAttributes.length > 0\n ) {\n console.log(\n ` Required: ${ansis.yellow(nodeType.requiredAttributes.join(\", \"))}`\n );\n }\n\n if (\n nodeType.optionalAttributes &&\n nodeType.optionalAttributes.length > 0\n ) {\n console.log(\n ` Optional: ${ansis.gray(nodeType.optionalAttributes.join(\", \"))}`\n );\n }\n\n console.log();\n }\n } catch (error) {\n handleError(error);\n }\n}\n\n/**\n * dr schema node <spec_node_id> - Show node schema details\n */\nexport async function schemaNodeCommand(specNodeId: string): Promise<void> {\n try {\n if (!isValidSpecNodeId(specNodeId)) {\n throw new CLIError(\n `Invalid spec node ID format: ${specNodeId}`,\n ErrorCategory.USER,\n [\"Expected format: {layer}.{type} (e.g., motivation.goal, api.endpoint)\"]\n );\n }\n\n const nodeType = getNodeType(specNodeId);\n\n if (!nodeType) {\n throw new CLIError(\n `Unknown node type: ${specNodeId}`,\n ErrorCategory.USER,\n [\"Use `dr schema types <layer>` to list valid types\"]\n );\n }\n\n console.log(ansis.bold(`\\n${nodeType.title}\\n`));\n console.log(`Spec Node ID: ${ansis.cyan(nodeType.specNodeId)}`);\n console.log(`Layer: ${nodeType.layer}`);\n console.log(`Type: ${nodeType.type}`);\n console.log();\n\n if (\n nodeType.requiredAttributes &&\n nodeType.requiredAttributes.length > 0\n ) {\n console.log(ansis.yellow(\"Required Attributes:\"));\n for (const attr of nodeType.requiredAttributes) {\n const constraint = nodeType.attributeConstraints?.[attr];\n console.log(` - ${attr}: ${formatAttributeConstraint(constraint)}`);\n }\n console.log();\n }\n\n if (\n nodeType.optionalAttributes &&\n nodeType.optionalAttributes.length > 0\n ) {\n console.log(ansis.gray(\"Optional Attributes:\"));\n for (const attr of nodeType.optionalAttributes) {\n const constraint = nodeType.attributeConstraints?.[attr];\n console.log(` - ${attr}: ${formatAttributeConstraint(constraint)}`);\n }\n console.log();\n }\n } catch (error) {\n handleError(error);\n }\n}\n\n/**\n * dr schema relationship <source_type> [predicate] - Show valid relationships\n */\nexport async function schemaRelationshipCommand(\n sourceType: string,\n predicate?: string\n): Promise<void> {\n try {\n if (!isValidSpecNodeId(sourceType)) {\n const hints = [\"Expected format: {layer}.{type} (e.g., motivation.goal, api.endpoint)\"];\n\n const matches: string[] = [];\n for (const layerId of getAllLayerIds()) {\n for (const nodeType of getNodeTypesForLayer(layerId)) {\n if (nodeType.type === sourceType.toLowerCase()) {\n matches.push(nodeType.specNodeId);\n }\n }\n }\n if (matches.length === 1) {\n hints.push(`Did you mean: ${matches[0]}?`);\n } else if (matches.length > 1) {\n hints.push(`Did you mean one of: ${matches.join(\", \")}?`);\n }\n\n throw new CLIError(\n `Invalid spec node ID format: ${sourceType}`,\n ErrorCategory.USER,\n hints\n );\n }\n\n const relationships = predicate\n ? getValidRelationships(sourceType, predicate)\n : getValidRelationships(sourceType);\n\n if (relationships.length === 0) {\n const msg = predicate\n ? `No relationships found for ${sourceType} --[${predicate}]-->`\n : `No relationships found for ${sourceType}`;\n console.log(msg);\n return;\n }\n\n console.log(\n ansis.bold(`\\nValid Relationships for ${sourceType}:\\n`)\n );\n\n // Group by predicate\n const byPredicate = new Map<string, RelationshipSpec[]>();\n for (const rel of relationships) {\n if (!byPredicate.has(rel.predicate)) {\n byPredicate.set(rel.predicate, []);\n }\n const predicateRels = byPredicate.get(rel.predicate);\n if (predicateRels) {\n predicateRels.push(rel);\n }\n }\n\n for (const [pred, rels] of byPredicate) {\n console.log(ansis.cyan(` --[${pred}]-->`));\n\n for (const rel of rels) {\n const strength = formatStrength(rel.strength);\n const cardinality = ansis.gray(`(${rel.cardinality})`);\n console.log(\n ` ${rel.destinationSpecNodeId} ${strength} ${cardinality}`\n );\n }\n\n console.log();\n }\n } catch (error) {\n handleError(error);\n }\n}\n\n/**\n * Represents a constraint on an attribute\n */\ninterface AttributeConstraint {\n type?: string;\n enum?: unknown[];\n pattern?: string;\n [key: string]: unknown;\n}\n\n/**\n * Format attribute constraint for display\n */\nfunction formatAttributeConstraint(constraint: unknown): string {\n if (!constraint) return \"any\";\n\n if (typeof constraint === \"string\") {\n return constraint;\n }\n\n const c = constraint as AttributeConstraint;\n\n if (c.type) {\n let result = String(c.type);\n\n if (c.enum && Array.isArray(c.enum)) {\n result += ` [${c.enum.join(\" | \")}]`;\n }\n\n if (c.pattern) {\n result += ` (pattern: ${c.pattern})`;\n }\n\n return result;\n }\n\n return \"object\";\n}\n\n/**\n * Format relationship strength with color\n */\nfunction formatStrength(strength: string): string {\n const colors: Record<string, (s: string) => string> = {\n critical: (s: string) => ansis.red(s),\n high: (s: string) => ansis.yellow(s),\n medium: (s: string) => ansis.blue(s),\n low: (s: string) => ansis.gray(s),\n };\n\n return colors[strength]?.(strength) || strength;\n}\n\n/**\n * Register schema commands with commander\n */\nexport function schemaCommands(program: Command): void {\n const schemaCmd = program\n .command(\"schema\")\n .description(\"Inspect schema metadata (layers, types, relationships)\");\n\n schemaCmd\n .command(\"layers\")\n .description(\"List all layers with node type counts\")\n .action(schemaLayersCommand);\n\n schemaCmd\n .command(\"types <layer>\")\n .description(\"List valid node types for a layer\")\n .action(schemaTypesCommand);\n\n schemaCmd\n .command(\"node <spec_node_id>\")\n .description(\"Show detailed schema for a node type\")\n .action(schemaNodeCommand);\n\n schemaCmd\n .command(\"relationship <source_type> [predicate]\")\n .description(\"Show valid relationships for a node type\")\n .action(schemaRelationshipCommand);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,8 +1,22 @@
1
1
  import ansis from "ansis";
2
2
  import { Model } from "../core/model.js";
3
+ import { getActiveSpan } from "../telemetry/index.js";
4
+ import { getErrorMessage } from "../utils/errors.js";
5
+ import { TABLE_COLUMN_WIDTHS, TABLE_SEPARATOR } from "../utils/table-formatting.js";
6
+ function normalizePath(path) {
7
+ return path.replace(/^\.\//, "").replace(/\\/g, "/");
8
+ }
9
+ function matchesSourceFile(element, sourceFilePath) {
10
+ const sourceRef = element.getSourceReference();
11
+ if (!sourceRef)
12
+ return !1;
13
+ const normalizedQuery = normalizePath(sourceFilePath);
14
+ return (sourceRef.locations ?? []).some((loc) => normalizePath(loc.file) === normalizedQuery);
15
+ }
3
16
  async function searchCommand(query, options) {
17
+ const span = getActiveSpan();
4
18
  try {
5
- const model = await Model.load(), results = [], queryLower = query.toLowerCase();
19
+ const model = await Model.load(), results = [], queryLower = query.toLowerCase(), isSourceFileSearch = !!options.sourceFile;
6
20
  for (const layerName of model.getLayerNames()) {
7
21
  if (options.layer && layerName !== options.layer)
8
22
  continue;
@@ -11,34 +25,48 @@ async function searchCommand(query, options) {
11
25
  for (const element of layerObj.listElements()) {
12
26
  if (options.type && element.type !== options.type)
13
27
  continue;
14
- const idMatch = element.id.toLowerCase().includes(queryLower), nameMatch = element.name.toLowerCase().includes(queryLower);
15
- (idMatch || nameMatch) && results.push({
28
+ if (isSourceFileSearch) {
29
+ if (!matchesSourceFile(element, options.sourceFile))
30
+ continue;
31
+ } else {
32
+ const idMatch = (element.path || element.id).toLowerCase().includes(queryLower), nameMatch = element.name.toLowerCase().includes(queryLower);
33
+ if (!idMatch && !nameMatch)
34
+ continue;
35
+ }
36
+ let sourceFile, sourceSymbol;
37
+ const sourceRef = element.getSourceReference();
38
+ sourceRef && sourceRef.locations && sourceRef.locations.length > 0 && (sourceFile = sourceRef.locations[0].file, sourceSymbol = sourceRef.locations[0].symbol), results.push({
16
39
  layer: layerName,
17
- id: element.id,
40
+ id: element.path || element.id,
18
41
  type: element.type,
19
42
  name: element.name,
20
- description: element.description
43
+ description: element.description,
44
+ sourceFile,
45
+ sourceSymbol
21
46
  });
22
47
  }
23
48
  }
24
- if (options.json) {
49
+ if (span?.setAttribute("search.resultCount", results.length), options.json) {
25
50
  console.log(JSON.stringify(results, null, 2));
26
51
  return;
27
52
  }
28
53
  if (results.length === 0) {
29
- console.log(ansis.yellow(`No elements matching "${query}"`));
54
+ console.log(isSourceFileSearch ? ansis.yellow(`No elements found referencing source file: ${options.sourceFile}`) : ansis.yellow(`No elements matching "${query}"`));
30
55
  return;
31
56
  }
32
- console.log(""), console.log(ansis.bold(`Found ${results.length} element(s) matching "${query}":`)), console.log(ansis.dim("\u2500".repeat(80)));
33
- const layerWidth = 12, idWidth = 28, typeWidth = 12, nameWidth = 28;
34
- console.log(`${ansis.cyan("LAYER".padEnd(layerWidth))} ${ansis.cyan("ID".padEnd(idWidth))} ${ansis.cyan("TYPE".padEnd(typeWidth))} ${ansis.cyan("NAME")}`), console.log(ansis.dim("\u2500".repeat(80)));
57
+ console.log(""), console.log(isSourceFileSearch ? ansis.bold(`Found ${results.length} element(s) referencing ${options.sourceFile}:`) : ansis.bold(`Found ${results.length} element(s) matching "${query}":`)), console.log(ansis.dim(TABLE_SEPARATOR));
58
+ const layerWidth = TABLE_COLUMN_WIDTHS.SEARCH_LAYER_WIDTH, idWidth = TABLE_COLUMN_WIDTHS.SEARCH_ID_WIDTH, typeWidth = TABLE_COLUMN_WIDTHS.SEARCH_TYPE_WIDTH, nameWidth = TABLE_COLUMN_WIDTHS.SEARCH_NAME_WIDTH;
59
+ console.log(`${ansis.cyan("LAYER".padEnd(layerWidth))} ${ansis.cyan("ID".padEnd(idWidth))} ${ansis.cyan("TYPE".padEnd(typeWidth))} ${ansis.cyan("NAME")}`), console.log(ansis.dim(TABLE_SEPARATOR));
35
60
  for (const result of results) {
36
61
  const layer = result.layer.substring(0, layerWidth - 1).padEnd(layerWidth), id = result.id.substring(0, idWidth - 1).padEnd(idWidth), type = result.type.substring(0, typeWidth - 1).padEnd(typeWidth), name = result.name.substring(0, nameWidth);
37
- console.log(`${ansis.blue(layer)} ${id} ${type} ${name}`), options.verbose && result.description && console.log(ansis.dim(` \u2514\u2500 ${result.description}`));
62
+ if (console.log(`${ansis.blue(layer)} ${id} ${type} ${name}`), (options.verbose || isSourceFileSearch) && (result.description && console.log(ansis.dim(` \u2514\u2500 Description: ${result.description}`)), result.sourceFile)) {
63
+ const symbol = result.sourceSymbol ? ` | Symbol: ${result.sourceSymbol}` : "";
64
+ console.log(ansis.dim(` \u2514\u2500 Source: ${result.sourceFile}${symbol}`));
65
+ }
38
66
  }
39
67
  console.log(ansis.dim("\u2500".repeat(80))), console.log("");
40
68
  } catch (error) {
41
- const message = error instanceof Error ? error.message : String(error);
69
+ const message = getErrorMessage(error);
42
70
  console.error(ansis.red(`Error: ${message}`)), process.exit(1);
43
71
  }
44
72
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/search.ts"],
4
- "sourcesContent": ["/**\n * Search for elements across the model\n */\n\nimport ansis from 'ansis';\nimport { Model } from '../core/model.js';\n\nexport interface SearchOptions {\n layer?: string;\n type?: string;\n json?: boolean;\n verbose?: boolean;\n debug?: boolean;\n}\n\nexport async function searchCommand(query: string, options: SearchOptions): Promise<void> {\n try {\n // Load model\n const model = await Model.load();\n\n // Collect all matching elements\n const results: Array<{\n layer: string;\n id: string;\n type: string;\n name: string;\n description?: string;\n }> = [];\n\n const queryLower = query.toLowerCase();\n\n for (const layerName of model.getLayerNames()) {\n // Skip if layer filter specified and doesn't match\n if (options.layer && layerName !== options.layer) {\n continue;\n }\n\n const layerObj = await model.getLayer(layerName);\n if (!layerObj) continue;\n\n for (const element of layerObj.listElements()) {\n // Apply filters\n if (options.type && element.type !== options.type) {\n continue;\n }\n\n // Match query against id and name\n const idMatch = element.id.toLowerCase().includes(queryLower);\n const nameMatch = element.name.toLowerCase().includes(queryLower);\n\n if (idMatch || nameMatch) {\n results.push({\n layer: layerName,\n id: element.id,\n type: element.type,\n name: element.name,\n description: element.description,\n });\n }\n }\n }\n\n // Output as JSON if requested\n if (options.json) {\n console.log(JSON.stringify(results, null, 2));\n return;\n }\n\n // Display results\n if (results.length === 0) {\n console.log(ansis.yellow(`No elements matching \"${query}\"`));\n return;\n }\n\n console.log('');\n console.log(ansis.bold(`Found ${results.length} element(s) matching \"${query}\":`));\n console.log(ansis.dim('\u2500'.repeat(80)));\n\n // Print header\n const layerWidth = 12;\n const idWidth = 28;\n const typeWidth = 12;\n const nameWidth = 28;\n\n console.log(\n `${ansis.cyan('LAYER'.padEnd(layerWidth))} ${ansis.cyan('ID'.padEnd(idWidth))} ${ansis.cyan('TYPE'.padEnd(typeWidth))} ${ansis.cyan('NAME')}`\n );\n console.log(ansis.dim('\u2500'.repeat(80)));\n\n // Print rows\n for (const result of results) {\n const layer = result.layer.substring(0, layerWidth - 1).padEnd(layerWidth);\n const id = result.id.substring(0, idWidth - 1).padEnd(idWidth);\n const type = result.type.substring(0, typeWidth - 1).padEnd(typeWidth);\n const name = result.name.substring(0, nameWidth);\n\n console.log(`${ansis.blue(layer)} ${id} ${type} ${name}`);\n\n if (options.verbose && result.description) {\n console.log(ansis.dim(` \u2514\u2500 ${result.description}`));\n }\n }\n\n console.log(ansis.dim('\u2500'.repeat(80)));\n console.log('');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(ansis.red(`Error: ${message}`));\n process.exit(1);\n }\n}\n"],
5
- "mappings": "AAIA,OAAO,WAAW;AAClB,SAAS,aAAa;AAUtB,eAAsB,cAAc,OAAe,SAAsB;AACvE,MAAI;AAEF,UAAM,QAAQ,MAAM,MAAM,KAAI,GAGxB,UAMD,CAAA,GAEC,aAAa,MAAM,YAAW;AAEpC,eAAW,aAAa,MAAM,cAAa,GAAI;AAE7C,UAAI,QAAQ,SAAS,cAAc,QAAQ;AACzC;AAGF,YAAM,WAAW,MAAM,MAAM,SAAS,SAAS;AAC/C,UAAK;AAEL,mBAAW,WAAW,SAAS,aAAY,GAAI;AAE7C,cAAI,QAAQ,QAAQ,QAAQ,SAAS,QAAQ;AAC3C;AAIF,gBAAM,UAAU,QAAQ,GAAG,YAAW,EAAG,SAAS,UAAU,GACtD,YAAY,QAAQ,KAAK,YAAW,EAAG,SAAS,UAAU;AAEhE,WAAI,WAAW,cACb,QAAQ,KAAK;YACX,OAAO;YACP,IAAI,QAAQ;YACZ,MAAM,QAAQ;YACd,MAAM,QAAQ;YACd,aAAa,QAAQ;WACtB;QAEL;IACF;AAGA,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAC5C;IACF;AAGA,QAAI,QAAQ,WAAW,GAAG;AACxB,cAAQ,IAAI,MAAM,OAAO,yBAAyB,KAAK,GAAG,CAAC;AAC3D;IACF;AAEA,YAAQ,IAAI,EAAE,GACd,QAAQ,IAAI,MAAM,KAAK,SAAS,QAAQ,MAAM,yBAAyB,KAAK,IAAI,CAAC,GACjF,QAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC;AAGrC,UAAM,aAAa,IACb,UAAU,IACV,YAAY,IACZ,YAAY;AAElB,YAAQ,IACN,GAAG,MAAM,KAAK,QAAQ,OAAO,UAAU,CAAC,CAAC,IAAI,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC,CAAC,IAAI,MAAM,KAAK,OAAO,OAAO,SAAS,CAAC,CAAC,IAAI,MAAM,KAAK,MAAM,CAAC,EAAE,GAE/I,QAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC;AAGrC,eAAW,UAAU,SAAS;AAC5B,YAAM,QAAQ,OAAO,MAAM,UAAU,GAAG,aAAa,CAAC,EAAE,OAAO,UAAU,GACnE,KAAK,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC,EAAE,OAAO,OAAO,GACvD,OAAO,OAAO,KAAK,UAAU,GAAG,YAAY,CAAC,EAAE,OAAO,SAAS,GAC/D,OAAO,OAAO,KAAK,UAAU,GAAG,SAAS;AAE/C,cAAQ,IAAI,GAAG,MAAM,KAAK,KAAK,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,EAAE,GAEpD,QAAQ,WAAW,OAAO,eAC5B,QAAQ,IAAI,MAAM,IAAI,kBAAQ,OAAO,WAAW,EAAE,CAAC;IAEvD;AAEA,YAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC,GACrC,QAAQ,IAAI,EAAE;EAChB,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,YAAQ,MAAM,MAAM,IAAI,UAAU,OAAO,EAAE,CAAC,GAC5C,QAAQ,KAAK,CAAC;EAChB;AACF;",
4
+ "sourcesContent": ["/**\n * Search for elements across the model\n */\n\nimport ansis from \"ansis\";\nimport { Model } from \"../core/model.js\";\nimport type { Element } from \"../core/element.js\";\nimport { getActiveSpan } from \"../telemetry/index.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { TABLE_COLUMN_WIDTHS, TABLE_SEPARATOR } from \"../utils/table-formatting.js\";\n\nexport interface SearchOptions {\n layer?: string;\n type?: string;\n sourceFile?: string;\n json?: boolean;\n verbose?: boolean;\n debug?: boolean;\n}\n\n/**\n * Normalize a file path for comparison\n * - Removes leading ./\n * - Converts backslashes to forward slashes\n */\nfunction normalizePath(path: string): string {\n return path.replace(/^\\.\\//, \"\").replace(/\\\\/g, \"/\");\n}\n\n/**\n * Check if an element matches the source file query\n */\nfunction matchesSourceFile(element: Element, sourceFilePath: string): boolean {\n const sourceRef = element.getSourceReference();\n if (!sourceRef) {\n return false;\n }\n\n const normalizedQuery = normalizePath(sourceFilePath);\n\n // Check if any location matches the queried file\n return (sourceRef.locations ?? []).some((loc) => {\n const normalizedLoc = normalizePath(loc.file);\n return normalizedLoc === normalizedQuery;\n });\n}\n\nexport async function searchCommand(query: string, options: SearchOptions): Promise<void> {\n const span = getActiveSpan();\n\n try {\n // Load model\n const model = await Model.load();\n\n // Collect all matching elements with source reference info\n const results: Array<{\n layer: string;\n id: string;\n type: string;\n name: string;\n description?: string;\n sourceFile?: string;\n sourceSymbol?: string;\n }> = [];\n\n const queryLower = query.toLowerCase();\n const isSourceFileSearch = !!options.sourceFile;\n\n for (const layerName of model.getLayerNames()) {\n // Skip if layer filter specified and doesn't match\n if (options.layer && layerName !== options.layer) {\n continue;\n }\n\n const layerObj = await model.getLayer(layerName);\n if (!layerObj) continue;\n\n for (const element of layerObj.listElements()) {\n // Apply type filter\n if (options.type && element.type !== options.type) {\n continue;\n }\n\n // If source file search, use different matching logic\n if (isSourceFileSearch) {\n if (!matchesSourceFile(element, options.sourceFile!)) {\n continue;\n }\n } else {\n // Match query against path/id and name\n const displayId = element.path || element.id;\n const idMatch = displayId.toLowerCase().includes(queryLower);\n const nameMatch = element.name.toLowerCase().includes(queryLower);\n\n if (!idMatch && !nameMatch) {\n continue;\n }\n }\n\n // Extract source reference info if present\n let sourceFile: string | undefined;\n let sourceSymbol: string | undefined;\n const sourceRef = element.getSourceReference();\n if (sourceRef && sourceRef.locations && sourceRef.locations.length > 0) {\n sourceFile = sourceRef.locations[0].file;\n sourceSymbol = sourceRef.locations[0].symbol;\n }\n\n results.push({\n layer: layerName,\n id: element.path || element.id,\n type: element.type,\n name: element.name,\n description: element.description,\n sourceFile,\n sourceSymbol,\n });\n }\n }\n\n span?.setAttribute(\"search.resultCount\", results.length);\n\n // Output as JSON if requested\n if (options.json) {\n console.log(JSON.stringify(results, null, 2));\n return;\n }\n\n // Display results\n if (results.length === 0) {\n if (isSourceFileSearch) {\n console.log(\n ansis.yellow(`No elements found referencing source file: ${options.sourceFile}`)\n );\n } else {\n console.log(ansis.yellow(`No elements matching \"${query}\"`));\n }\n return;\n }\n\n console.log(\"\");\n if (isSourceFileSearch) {\n console.log(\n ansis.bold(`Found ${results.length} element(s) referencing ${options.sourceFile}:`)\n );\n } else {\n console.log(ansis.bold(`Found ${results.length} element(s) matching \"${query}\":`));\n }\n console.log(ansis.dim(TABLE_SEPARATOR));\n\n // Print header\n const layerWidth = TABLE_COLUMN_WIDTHS.SEARCH_LAYER_WIDTH;\n const idWidth = TABLE_COLUMN_WIDTHS.SEARCH_ID_WIDTH;\n const typeWidth = TABLE_COLUMN_WIDTHS.SEARCH_TYPE_WIDTH;\n const nameWidth = TABLE_COLUMN_WIDTHS.SEARCH_NAME_WIDTH;\n\n console.log(\n `${ansis.cyan(\"LAYER\".padEnd(layerWidth))} ${ansis.cyan(\"ID\".padEnd(idWidth))} ${ansis.cyan(\"TYPE\".padEnd(typeWidth))} ${ansis.cyan(\"NAME\")}`\n );\n console.log(ansis.dim(TABLE_SEPARATOR));\n\n // Print rows\n for (const result of results) {\n const layer = result.layer.substring(0, layerWidth - 1).padEnd(layerWidth);\n const id = result.id.substring(0, idWidth - 1).padEnd(idWidth);\n const type = result.type.substring(0, typeWidth - 1).padEnd(typeWidth);\n const name = result.name.substring(0, nameWidth);\n\n console.log(`${ansis.blue(layer)} ${id} ${type} ${name}`);\n\n // Show description and source info in verbose mode or for source file searches\n if (options.verbose || isSourceFileSearch) {\n if (result.description) {\n console.log(ansis.dim(` \u2514\u2500 Description: ${result.description}`));\n }\n if (result.sourceFile) {\n const symbol = result.sourceSymbol ? ` | Symbol: ${result.sourceSymbol}` : \"\";\n console.log(ansis.dim(` \u2514\u2500 Source: ${result.sourceFile}${symbol}`));\n }\n }\n }\n\n console.log(ansis.dim(\"\u2500\".repeat(80)));\n console.log(\"\");\n } catch (error) {\n const message = getErrorMessage(error);\n console.error(ansis.red(`Error: ${message}`));\n process.exit(1);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,36 +1,67 @@
1
1
  import ansis from "ansis";
2
2
  import { Model } from "../core/model.js";
3
3
  import { findElementLayer } from "../utils/element-utils.js";
4
+ import { CLIError, ErrorCategory, handleError } from "../utils/errors.js";
5
+ import { isTelemetryEnabled, startActiveSpan } from "../telemetry/index.js";
6
+ import { getErrorMessage } from "../utils/errors.js";
4
7
  async function showCommand(id, options = {}) {
5
- try {
6
- const model = await Model.load(options.model), layerName = await findElementLayer(model, id);
7
- layerName || (console.error(ansis.red(`Error: Element ${id} not found`)), process.exit(1));
8
- const element = (await model.getLayer(layerName)).getElement(id);
9
- if (console.log(""), console.log(ansis.bold(`${ansis.blue("Element:")} ${id}`)), console.log(ansis.dim("\u2500".repeat(60))), console.log(`${ansis.gray("Layer:")} ${layerName}`), console.log(`${ansis.gray("Type:")} ${element.type}`), console.log(`${ansis.gray("Name:")} ${element.name}`), element.description && console.log(`${ansis.gray("Description:")} ${element.description}`), Object.keys(element.properties).length > 0) {
10
- console.log(""), console.log(ansis.bold("Properties:"));
11
- for (const [key, value] of Object.entries(element.properties)) {
12
- const displayValue = typeof value == "string" ? value : JSON.stringify(value, null, 2);
13
- console.log(` ${ansis.cyan(key)}: ${displayValue}`);
14
- }
15
- }
16
- if (element.references && element.references.length > 0) {
17
- console.log(""), console.log(ansis.bold("References:"));
18
- for (const ref of element.references)
19
- console.log(` \u2192 ${ansis.yellow(ref.target)} (${ref.type})`), ref.description && console.log(` ${ansis.dim(ref.description)}`);
20
- }
21
- if (element.relationships && element.relationships.length > 0) {
22
- console.log(""), console.log(ansis.bold("Relationships:"));
23
- for (const rel of element.relationships)
24
- if (console.log(` ${ansis.magenta(rel.predicate)}: ${rel.target}`), rel.properties) {
25
- const propStr = Object.entries(rel.properties).map(([k, v]) => `${k}=${v}`).join(", ");
26
- console.log(` ${ansis.dim(propStr)}`);
8
+ const inferredLayer = id.includes(".") ? id.split(".")[0] : void 0;
9
+ await startActiveSpan("show.execute", async (span) => {
10
+ try {
11
+ const model = await Model.load(options.model, inferredLayer ? { layers: [inferredLayer] } : {}), layerName = await findElementLayer(model, id);
12
+ if (!layerName)
13
+ throw isTelemetryEnabled && span.setAttribute("show.found", !1), new CLIError(`Element ${id} not found`, ErrorCategory.USER, [
14
+ `Use "dr search ${id}" to find similar elements`,
15
+ 'Use "dr list <layer>" to list all elements in a layer'
16
+ ]);
17
+ const layer = await model.getLayer(layerName);
18
+ if (!layer)
19
+ throw new CLIError(`Layer ${layerName} not found`, ErrorCategory.USER, [
20
+ 'Use "dr schema layers" to list all available layers'
21
+ ]);
22
+ const element = layer.getElement(id);
23
+ if (!element)
24
+ throw new CLIError(`Element ${id} not found`, ErrorCategory.USER, [
25
+ `Use "dr search ${id}" to find similar elements`,
26
+ 'Use "dr list <layer>" to list all elements in a layer'
27
+ ]);
28
+ const elementId = element.path || element.id, { outgoing, incoming } = model.relationships.getForElement(elementId), hasRelationships = outgoing.length > 0 || incoming.length > 0;
29
+ if (isTelemetryEnabled && (span.setAttribute("show.found", !0), span.setAttribute("show.layer", layerName), span.setAttribute("show.type", element.type), span.setAttribute("show.hasReferences", element.references && element.references.length > 0), span.setAttribute("show.hasRelationships", hasRelationships), span.setAttribute("show.outgoingRelationships", outgoing.length), span.setAttribute("show.incomingRelationships", incoming.length)), console.log(""), console.log(ansis.bold(`${ansis.blue("Element:")} ${id}`)), console.log(ansis.dim("\u2500".repeat(60))), console.log(`${ansis.gray("Layer:")} ${layerName}`), console.log(`${ansis.gray("Type:")} ${element.type}`), console.log(`${ansis.gray("Name:")} ${element.name}`), element.description && console.log(`${ansis.gray("Description:")} ${element.description}`), Object.keys(element.attributes).length > 0) {
30
+ console.log(""), console.log(ansis.bold("Properties:"));
31
+ for (const [key, value] of Object.entries(element.attributes)) {
32
+ const displayValue = typeof value == "string" ? value : JSON.stringify(value, null, 2);
33
+ console.log(` ${ansis.cyan(key)}: ${displayValue}`);
27
34
  }
35
+ }
36
+ if (element.references && element.references.length > 0) {
37
+ console.log(""), console.log(ansis.bold("References:"));
38
+ for (const ref of element.references)
39
+ console.log(` \u2192 ${ansis.yellow(ref.target)} (${ref.type})`), ref.description && console.log(` ${ansis.dim(ref.description)}`);
40
+ }
41
+ if (outgoing.length > 0) {
42
+ console.log(""), console.log(ansis.bold("Relationships (outgoing):"));
43
+ for (const rel of outgoing)
44
+ if (console.log(` ${ansis.magenta(rel.predicate)} \u2192 ${rel.target}`), rel.properties && Object.keys(rel.properties).length > 0) {
45
+ const propStr = Object.entries(rel.properties).map(([k, v]) => `${k}=${v}`).join(", ");
46
+ console.log(` ${ansis.dim(propStr)}`);
47
+ }
48
+ }
49
+ if (incoming.length > 0) {
50
+ console.log(""), console.log(ansis.bold("Relationships (incoming):"));
51
+ for (const rel of incoming)
52
+ console.log(` ${ansis.magenta(rel.predicate)} \u2190 ${rel.source}`);
53
+ }
54
+ const sourceRef = element.getSourceReference();
55
+ sourceRef && (console.log(""), console.log(ansis.bold("Source Code Location:")), console.log(` ${ansis.gray("Provenance:")} ${sourceRef.provenance}`), (sourceRef.locations ?? []).forEach((loc, idx) => {
56
+ console.log(` ${ansis.gray("Location " + (idx + 1) + ":")}`), console.log(` File: ${ansis.cyan(loc.file)}`), loc.symbol && console.log(` Symbol: ${ansis.cyan(loc.symbol)}`);
57
+ }), sourceRef.repository && (console.log(` ${ansis.gray("Repository Context:")}`), sourceRef.repository.url && console.log(` Remote: ${ansis.cyan(sourceRef.repository.url)}`), sourceRef.repository.commit && console.log(` Commit: ${ansis.cyan(sourceRef.repository.commit)}`))), console.log(""), isTelemetryEnabled && span.setStatus({ code: 0 });
58
+ } catch (error) {
59
+ isTelemetryEnabled && (span.recordException(error), span.setStatus({
60
+ code: 2,
61
+ message: getErrorMessage(error)
62
+ })), handleError(error);
28
63
  }
29
- console.log("");
30
- } catch (error) {
31
- const message = error instanceof Error ? error.message : String(error);
32
- console.error(ansis.red(`Error: ${message}`)), process.exit(1);
33
- }
64
+ }, { "show.elementId": id });
34
65
  }
35
66
  export {
36
67
  showCommand
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/show.ts"],
4
- "sourcesContent": ["/**\n * Show detailed information about an element\n */\n\nimport ansis from 'ansis';\nimport { Model } from '../core/model.js';\nimport { findElementLayer } from '../utils/element-utils.js';\n\nexport async function showCommand(id: string, options: { model?: string } = {}): Promise<void> {\n try {\n // Load model (optionally from specified path)\n const model = await Model.load(options.model);\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 const layer = (await model.getLayer(layerName))!;\n const element = layer.getElement(id)!;\n\n // Display element information\n console.log('');\n console.log(ansis.bold(`${ansis.blue('Element:')} ${id}`));\n console.log(ansis.dim('\u2500'.repeat(60)));\n console.log(`${ansis.gray('Layer:')} ${layerName}`);\n console.log(`${ansis.gray('Type:')} ${element.type}`);\n console.log(`${ansis.gray('Name:')} ${element.name}`);\n\n if (element.description) {\n console.log(`${ansis.gray('Description:')} ${element.description}`);\n }\n\n // Display properties\n if (Object.keys(element.properties).length > 0) {\n console.log('');\n console.log(ansis.bold('Properties:'));\n for (const [key, value] of Object.entries(element.properties)) {\n const displayValue =\n typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n console.log(` ${ansis.cyan(key)}: ${displayValue}`);\n }\n }\n\n // Display references\n if (element.references && element.references.length > 0) {\n console.log('');\n console.log(ansis.bold('References:'));\n for (const ref of element.references) {\n console.log(` \u2192 ${ansis.yellow(ref.target)} (${ref.type})`);\n if (ref.description) {\n console.log(` ${ansis.dim(ref.description)}`);\n }\n }\n }\n\n // Display relationships\n if (element.relationships && element.relationships.length > 0) {\n console.log('');\n console.log(ansis.bold('Relationships:'));\n for (const rel of element.relationships) {\n console.log(` ${ansis.magenta(rel.predicate)}: ${rel.target}`);\n if (rel.properties) {\n const propStr = Object.entries(rel.properties)\n .map(([k, v]) => `${k}=${v}`)\n .join(', ');\n console.log(` ${ansis.dim(propStr)}`);\n }\n }\n }\n\n console.log('');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(ansis.red(`Error: ${message}`));\n process.exit(1);\n }\n}\n"],
5
- "mappings": "AAIA,OAAO,WAAW;AAClB,SAAS,aAAa;AACtB,SAAS,wBAAwB;AAEjC,eAAsB,YAAY,IAAY,UAA8B,CAAA,GAAE;AAC5E,MAAI;AAEF,UAAM,QAAQ,MAAM,MAAM,KAAK,QAAQ,KAAK,GAGtC,YAAY,MAAM,iBAAiB,OAAO,EAAE;AAClD,IAAK,cACH,QAAQ,MAAM,MAAM,IAAI,kBAAkB,EAAE,YAAY,CAAC,GACzD,QAAQ,KAAK,CAAC;AAIhB,UAAM,WADS,MAAM,MAAM,SAAS,SAAS,GACvB,WAAW,EAAE;AAenC,QAZA,QAAQ,IAAI,EAAE,GACd,QAAQ,IAAI,MAAM,KAAK,GAAG,MAAM,KAAK,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,GACzD,QAAQ,IAAI,MAAM,IAAI,SAAI,OAAO,EAAE,CAAC,CAAC,GACrC,QAAQ,IAAI,GAAG,MAAM,KAAK,QAAQ,CAAC,UAAU,SAAS,EAAE,GACxD,QAAQ,IAAI,GAAG,MAAM,KAAK,OAAO,CAAC,WAAW,QAAQ,IAAI,EAAE,GAC3D,QAAQ,IAAI,GAAG,MAAM,KAAK,OAAO,CAAC,WAAW,QAAQ,IAAI,EAAE,GAEvD,QAAQ,eACV,QAAQ,IAAI,GAAG,MAAM,KAAK,cAAc,CAAC,IAAI,QAAQ,WAAW,EAAE,GAIhE,OAAO,KAAK,QAAQ,UAAU,EAAE,SAAS,GAAG;AAC9C,cAAQ,IAAI,EAAE,GACd,QAAQ,IAAI,MAAM,KAAK,aAAa,CAAC;AACrC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,UAAU,GAAG;AAC7D,cAAM,eACJ,OAAO,SAAU,WAAW,QAAQ,KAAK,UAAU,OAAO,MAAM,CAAC;AACnE,gBAAQ,IAAI,KAAK,MAAM,KAAK,GAAG,CAAC,KAAK,YAAY,EAAE;MACrD;IACF;AAGA,QAAI,QAAQ,cAAc,QAAQ,WAAW,SAAS,GAAG;AACvD,cAAQ,IAAI,EAAE,GACd,QAAQ,IAAI,MAAM,KAAK,aAAa,CAAC;AACrC,iBAAW,OAAO,QAAQ;AACxB,gBAAQ,IAAI,YAAO,MAAM,OAAO,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,GAAG,GACvD,IAAI,eACN,QAAQ,IAAI,OAAO,MAAM,IAAI,IAAI,WAAW,CAAC,EAAE;IAGrD;AAGA,QAAI,QAAQ,iBAAiB,QAAQ,cAAc,SAAS,GAAG;AAC7D,cAAQ,IAAI,EAAE,GACd,QAAQ,IAAI,MAAM,KAAK,gBAAgB,CAAC;AACxC,iBAAW,OAAO,QAAQ;AAExB,YADA,QAAQ,IAAI,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,KAAK,IAAI,MAAM,EAAE,GAC1D,IAAI,YAAY;AAClB,gBAAM,UAAU,OAAO,QAAQ,IAAI,UAAU,EAC1C,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,EAC3B,KAAK,IAAI;AACZ,kBAAQ,IAAI,OAAO,MAAM,IAAI,OAAO,CAAC,EAAE;QACzC;IAEJ;AAEA,YAAQ,IAAI,EAAE;EAChB,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,YAAQ,MAAM,MAAM,IAAI,UAAU,OAAO,EAAE,CAAC,GAC5C,QAAQ,KAAK,CAAC;EAChB;AACF;",
4
+ "sourcesContent": ["/**\n * Show detailed information about an element\n */\n\nimport ansis from \"ansis\";\nimport { Model } from \"../core/model.js\";\nimport { findElementLayer } from \"../utils/element-utils.js\";\nimport { CLIError, ErrorCategory, handleError } from \"../utils/errors.js\";\nimport { isTelemetryEnabled, startActiveSpan } from \"../telemetry/index.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\n\nexport async function showCommand(id: string, options: { model?: string } = {}): Promise<void> {\n // Infer the layer from the element ID prefix (e.g. \"api.operation.foo\" \u2192 load only \"api\" layer)\n // Falls back to loading all layers if the ID doesn't contain a layer prefix.\n const inferredLayer = id.includes(\".\") ? id.split(\".\")[0] : undefined;\n\n await startActiveSpan(\n \"show.execute\",\n async (span) => {\n try {\n // Load only the inferred layer when possible (performance: avoids loading all 12 layers)\n const model = await Model.load(\n options.model,\n inferredLayer ? { layers: [inferredLayer] } : {}\n );\n\n // Find element\n const layerName = await findElementLayer(model, id);\n if (!layerName) {\n if (isTelemetryEnabled) {\n (span as any).setAttribute(\"show.found\", false);\n }\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 if (!layer) {\n throw new CLIError(`Layer ${layerName} not found`, ErrorCategory.USER, [\n 'Use \"dr schema layers\" to list all available layers',\n ]);\n }\n\n const element = layer.getElement(id);\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 // Query relationships from the central store (element.relationships is always empty\n // for modern elements since relationships moved to relationships.yaml)\n const elementId = element.path || element.id;\n const { outgoing, incoming } = model.relationships.getForElement(elementId);\n const hasRelationships = outgoing.length > 0 || incoming.length > 0;\n\n if (isTelemetryEnabled) {\n (span as any).setAttribute(\"show.found\", true);\n (span as any).setAttribute(\"show.layer\", layerName);\n (span as any).setAttribute(\"show.type\", element.type);\n (span as any).setAttribute(\n \"show.hasReferences\",\n element.references && element.references.length > 0\n );\n (span as any).setAttribute(\"show.hasRelationships\", hasRelationships);\n (span as any).setAttribute(\"show.outgoingRelationships\", outgoing.length);\n (span as any).setAttribute(\"show.incomingRelationships\", incoming.length);\n }\n\n // Display element information\n console.log(\"\");\n console.log(ansis.bold(`${ansis.blue(\"Element:\")} ${id}`));\n console.log(ansis.dim(\"\u2500\".repeat(60)));\n console.log(`${ansis.gray(\"Layer:\")} ${layerName}`);\n console.log(`${ansis.gray(\"Type:\")} ${element.type}`);\n console.log(`${ansis.gray(\"Name:\")} ${element.name}`);\n\n if (element.description) {\n console.log(`${ansis.gray(\"Description:\")} ${element.description}`);\n }\n\n // Display properties (attributes)\n if (Object.keys(element.attributes).length > 0) {\n console.log(\"\");\n console.log(ansis.bold(\"Properties:\"));\n for (const [key, value] of Object.entries(element.attributes)) {\n const displayValue = typeof value === \"string\" ? value : JSON.stringify(value, null, 2);\n console.log(` ${ansis.cyan(key)}: ${displayValue}`);\n }\n }\n\n // Display references (inline, legacy format)\n if (element.references && element.references.length > 0) {\n console.log(\"\");\n console.log(ansis.bold(\"References:\"));\n for (const ref of element.references) {\n console.log(` \u2192 ${ansis.yellow(ref.target)} (${ref.type})`);\n if (ref.description) {\n console.log(` ${ansis.dim(ref.description)}`);\n }\n }\n }\n\n // Display relationships from the central relationships store\n if (outgoing.length > 0) {\n console.log(\"\");\n console.log(ansis.bold(\"Relationships (outgoing):\"));\n for (const rel of outgoing) {\n console.log(` ${ansis.magenta(rel.predicate)} \u2192 ${rel.target}`);\n if (rel.properties && Object.keys(rel.properties).length > 0) {\n const propStr = Object.entries(rel.properties)\n .map(([k, v]) => `${k}=${v}`)\n .join(\", \");\n console.log(` ${ansis.dim(propStr)}`);\n }\n }\n }\n\n if (incoming.length > 0) {\n console.log(\"\");\n console.log(ansis.bold(\"Relationships (incoming):\"));\n for (const rel of incoming) {\n console.log(` ${ansis.magenta(rel.predicate)} \u2190 ${rel.source}`);\n }\n }\n\n // Display source code location if present\n const sourceRef = element.getSourceReference();\n if (sourceRef) {\n console.log(\"\");\n console.log(ansis.bold(\"Source Code Location:\"));\n console.log(` ${ansis.gray(\"Provenance:\")} ${sourceRef.provenance}`);\n\n (sourceRef.locations ?? []).forEach((loc, idx) => {\n console.log(` ${ansis.gray(\"Location \" + (idx + 1) + \":\")}`);\n console.log(` File: ${ansis.cyan(loc.file)}`);\n if (loc.symbol) {\n console.log(` Symbol: ${ansis.cyan(loc.symbol)}`);\n }\n });\n\n if (sourceRef.repository) {\n console.log(` ${ansis.gray(\"Repository Context:\")}`);\n if (sourceRef.repository.url) {\n console.log(` Remote: ${ansis.cyan(sourceRef.repository.url)}`);\n }\n if (sourceRef.repository.commit) {\n console.log(` Commit: ${ansis.cyan(sourceRef.repository.commit)}`);\n }\n }\n }\n\n console.log(\"\");\n\n if (isTelemetryEnabled) {\n (span as any).setStatus({ code: 0 });\n }\n } catch (error) {\n if (isTelemetryEnabled) {\n (span as any).recordException(error as Error);\n (span as any).setStatus({\n code: 2,\n message: getErrorMessage(error),\n });\n }\n handleError(error);\n }\n },\n { \"show.elementId\": id }\n );\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,35 @@
1
+ import ansis from "ansis";
2
+ import { writeFile, ensureDir } from "../utils/file-io.js";
3
+ import { Model } from "../core/model.js";
4
+ import { StatsCollector } from "../core/stats-collector.js";
5
+ import { formatStats } from "../export/stats-formatters.js";
6
+ import path from "path";
7
+ import { getErrorMessage } from "../utils/errors.js";
8
+ async function statsCommand(options) {
9
+ try {
10
+ const model = await Model.load(options.model), stats = await new StatsCollector(model).collect();
11
+ let format = options.format || "text";
12
+ if (options.output) {
13
+ const ext = path.extname(options.output).toLowerCase();
14
+ ext === ".json" ? format = "json" : ext === ".md" && (format = "markdown");
15
+ }
16
+ options.compact && (format = "compact");
17
+ const output = formatStats(stats, {
18
+ format,
19
+ compact: options.compact,
20
+ verbose: options.verbose
21
+ });
22
+ if (options.output) {
23
+ const outputPath = path.resolve(process.cwd(), options.output), outputDir = path.dirname(outputPath);
24
+ await ensureDir(outputDir), await writeFile(outputPath, output), console.log(ansis.green(`\u2713 Statistics written to ${options.output}`));
25
+ } else
26
+ console.log(output);
27
+ } catch (error) {
28
+ const message = getErrorMessage(error);
29
+ console.error(ansis.red(`Error: ${message}`)), process.exit(1);
30
+ }
31
+ }
32
+ export {
33
+ statsCommand
34
+ };
35
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/commands/stats.ts"],
4
+ "sourcesContent": ["/**\n * Display statistics about the architecture model\n */\n\nimport ansis from \"ansis\";\nimport { writeFile, ensureDir } from \"../utils/file-io.js\";\nimport { Model } from \"../core/model.js\";\nimport { StatsCollector } from \"../core/stats-collector.js\";\nimport { formatStats, StatsFormat } from \"../export/stats-formatters.js\";\nimport path from \"path\";\nimport { getErrorMessage } from \"../utils/errors.js\";\n\nexport interface StatsOptions {\n format?: StatsFormat;\n output?: string;\n compact?: boolean;\n verbose?: boolean;\n model?: string;\n debug?: boolean;\n}\n\n/**\n * Run the stats command\n */\nexport async function statsCommand(options: StatsOptions): Promise<void> {\n try {\n // Load model\n const model = await Model.load(options.model);\n\n // Collect statistics\n const collector = new StatsCollector(model);\n const stats = await collector.collect();\n\n // Determine output format\n let format: StatsFormat = options.format || \"text\";\n\n // Auto-detect format from output file extension\n if (options.output) {\n const ext = path.extname(options.output).toLowerCase();\n if (ext === \".json\") {\n format = \"json\";\n } else if (ext === \".md\") {\n format = \"markdown\";\n }\n }\n\n // Use compact format if requested\n if (options.compact) {\n format = \"compact\";\n }\n\n // Format output\n const output = formatStats(stats, {\n format,\n compact: options.compact,\n verbose: options.verbose,\n });\n\n // Write to file or stdout\n if (options.output) {\n const outputPath = path.resolve(process.cwd(), options.output);\n const outputDir = path.dirname(outputPath);\n\n // Ensure output directory exists\n await ensureDir(outputDir);\n\n // Write file\n await writeFile(outputPath, output);\n\n console.log(ansis.green(`\u2713 Statistics written to ${options.output}`));\n } else {\n // Print to stdout\n console.log(output);\n }\n } catch (error) {\n const message = getErrorMessage(error);\n console.error(ansis.red(`Error: ${message}`));\n process.exit(1);\n }\n}\n"],
5
+ "mappings": "AAIA,OAAO,WAAW;AAClB,SAAS,WAAW,iBAAiB;AACrC,SAAS,aAAa;AACtB,SAAS,sBAAsB;AAC/B,SAAS,mBAAgC;AACzC,OAAO,UAAU;AACjB,SAAS,uBAAuB;AAchC,eAAsB,aAAa,SAAqB;AACtD,MAAI;AAEF,UAAM,QAAQ,MAAM,MAAM,KAAK,QAAQ,KAAK,GAItC,QAAQ,MADI,IAAI,eAAe,KAAK,EACZ,QAAO;AAGrC,QAAI,SAAsB,QAAQ,UAAU;AAG5C,QAAI,QAAQ,QAAQ;AAClB,YAAM,MAAM,KAAK,QAAQ,QAAQ,MAAM,EAAE,YAAW;AACpD,MAAI,QAAQ,UACV,SAAS,SACA,QAAQ,UACjB,SAAS;IAEb;AAGA,IAAI,QAAQ,YACV,SAAS;AAIX,UAAM,SAAS,YAAY,OAAO;MAChC;MACA,SAAS,QAAQ;MACjB,SAAS,QAAQ;KAClB;AAGD,QAAI,QAAQ,QAAQ;AAClB,YAAM,aAAa,KAAK,QAAQ,QAAQ,IAAG,GAAI,QAAQ,MAAM,GACvD,YAAY,KAAK,QAAQ,UAAU;AAGzC,YAAM,UAAU,SAAS,GAGzB,MAAM,UAAU,YAAY,MAAM,GAElC,QAAQ,IAAI,MAAM,MAAM,gCAA2B,QAAQ,MAAM,EAAE,CAAC;IACtE;AAEE,cAAQ,IAAI,MAAM;EAEtB,SAAS,OAAO;AACd,UAAM,UAAU,gBAAgB,KAAK;AACrC,YAAQ,MAAM,MAAM,IAAI,UAAU,OAAO,EAAE,CAAC,GAC5C,QAAQ,KAAK,CAAC;EAChB;AACF;",
6
+ "names": []
7
+ }
@@ -3,18 +3,34 @@ import { Model } from "../core/model.js";
3
3
  import { ReferenceRegistry } from "../core/reference-registry.js";
4
4
  import { DependencyTracker, TraceDirection } from "../core/dependency-tracker.js";
5
5
  import { findElementLayer } from "../utils/element-utils.js";
6
+ import { isTelemetryEnabled, startSpan, endSpan } from "../telemetry/index.js";
7
+ import { CLIError } from "../utils/errors.js";
8
+ import { getErrorMessage } from "../utils/errors.js";
6
9
  async function traceCommand(elementId, options = {}) {
10
+ const direction = options.direction || "both", span = isTelemetryEnabled ? startSpan("trace.execute", {
11
+ "trace.elementId": elementId,
12
+ "trace.direction": direction,
13
+ "trace.hasDepthLimit": options.depth !== void 0,
14
+ "trace.depth": options.depth
15
+ }) : null;
7
16
  try {
8
- const model = await Model.load(options.model);
9
- await findElementLayer(model, elementId) || (console.error(ansis.red(`Error: Element ${elementId} not found`)), process.exit(1));
17
+ const model = await Model.load(options.model), layerName = await findElementLayer(model, elementId);
18
+ if (!layerName)
19
+ throw isTelemetryEnabled && span && span.setAttribute("trace.found", !1), new CLIError(`Element ${elementId} not found`, 1);
20
+ isTelemetryEnabled && span && (span.setAttribute("trace.found", !0), span.setAttribute("trace.layer", layerName));
10
21
  const registry = new ReferenceRegistry();
11
22
  for (const layer of model.layers.values())
12
23
  for (const element of layer.listElements())
13
24
  registry.registerElement(element);
14
- const tracker = new DependencyTracker(registry), direction = options.direction || "both";
25
+ const graph = registry.getDependencyGraph();
26
+ for (const rel of model.relationships.getAll())
27
+ graph.hasNode(rel.source) || graph.addNode(rel.source), graph.hasNode(rel.target) || graph.addNode(rel.target), graph.hasEdge(rel.source, rel.target) || graph.addEdge(rel.source, rel.target, { type: rel.predicate });
28
+ const tracker = new DependencyTracker(graph, model);
15
29
  if (console.log(""), console.log(ansis.bold(`${ansis.blue("Dependency Trace:")} ${ansis.yellow(elementId)}`)), console.log(ansis.dim("\u2500".repeat(80))), direction === "up" || direction === "both") {
16
30
  const transitiveDependents = tracker.traceDependencies(elementId, TraceDirection.DOWN, null), directDependents = tracker.traceDependencies(elementId, TraceDirection.DOWN, 1);
17
- if (console.log(""), console.log(ansis.cyan(`Dependents (${directDependents.length} direct, ${transitiveDependents.length} transitive):`)), directDependents.length === 0)
31
+ isTelemetryEnabled && span && (span.setAttribute("trace.directDependents", directDependents.length), span.setAttribute("trace.transitiveDependents", transitiveDependents.length));
32
+ const transitiveOnlyDependents = transitiveDependents.filter((d) => !directDependents.includes(d));
33
+ if (console.log(""), console.log(ansis.cyan(`Dependents (${directDependents.length} direct, ${transitiveOnlyDependents.length} transitive):`)), directDependents.length === 0)
18
34
  console.log(ansis.dim(" (none)"));
19
35
  else {
20
36
  console.log(ansis.gray(" Direct:"));
@@ -22,17 +38,18 @@ async function traceCommand(elementId, options = {}) {
22
38
  console.log(` ${ansis.yellow("\u2190")} ${ansis.green(dep)}`);
23
39
  directDependents.length > 10 && console.log(ansis.dim(` ... and ${directDependents.length - 10} more`));
24
40
  }
25
- if (transitiveDependents.length > 0 && directDependents.length > 0) {
41
+ if (transitiveOnlyDependents.length > 0) {
26
42
  console.log(ansis.gray(" Transitive:"));
27
- const transitiveOnly = transitiveDependents.filter((d) => !directDependents.includes(d));
28
- for (const dep of transitiveOnly.slice(0, 10))
43
+ for (const dep of transitiveOnlyDependents.slice(0, 10))
29
44
  console.log(` ${ansis.yellow("\u2196")} ${ansis.dim(dep)}`);
30
- transitiveOnly.length > 10 && console.log(ansis.dim(` ... and ${transitiveOnly.length - 10} more`));
45
+ transitiveOnlyDependents.length > 10 && console.log(ansis.dim(` ... and ${transitiveOnlyDependents.length - 10} more`));
31
46
  }
32
47
  }
33
48
  if (direction === "down" || direction === "both") {
34
49
  const transitiveDependencies = tracker.traceDependencies(elementId, TraceDirection.UP, null), directDependencies = tracker.traceDependencies(elementId, TraceDirection.UP, 1);
35
- if (console.log(""), console.log(ansis.cyan(`Dependencies (${directDependencies.length} direct, ${transitiveDependencies.length} transitive):`)), directDependencies.length === 0)
50
+ isTelemetryEnabled && span && (span.setAttribute("trace.directDependencies", directDependencies.length), span.setAttribute("trace.transitiveDependencies", transitiveDependencies.length));
51
+ const transitiveOnlyDependencies = transitiveDependencies.filter((d) => !directDependencies.includes(d));
52
+ if (console.log(""), console.log(ansis.cyan(`Dependencies (${directDependencies.length} direct, ${transitiveOnlyDependencies.length} transitive):`)), directDependencies.length === 0)
36
53
  console.log(ansis.dim(" (none)"));
37
54
  else {
38
55
  console.log(ansis.gray(" Direct:"));
@@ -40,18 +57,24 @@ async function traceCommand(elementId, options = {}) {
40
57
  console.log(` ${ansis.yellow("\u2192")} ${ansis.green(dep)}`);
41
58
  directDependencies.length > 10 && console.log(ansis.dim(` ... and ${directDependencies.length - 10} more`));
42
59
  }
43
- if (transitiveDependencies.length > 0 && directDependencies.length > 0) {
60
+ if (transitiveOnlyDependencies.length > 0) {
44
61
  console.log(ansis.gray(" Transitive:"));
45
- const transitiveOnly = transitiveDependencies.filter((d) => !directDependencies.includes(d));
46
- for (const dep of transitiveOnly.slice(0, 10))
62
+ for (const dep of transitiveOnlyDependencies.slice(0, 10))
47
63
  console.log(` ${ansis.yellow("\u2198")} ${ansis.dim(dep)}`);
48
- transitiveOnly.length > 10 && console.log(ansis.dim(` ... and ${transitiveOnly.length - 10} more`));
64
+ transitiveOnlyDependencies.length > 10 && console.log(ansis.dim(` ... and ${transitiveOnlyDependencies.length - 10} more`));
49
65
  }
50
66
  }
51
- console.log("");
67
+ console.log(""), isTelemetryEnabled && span && span.setStatus({ code: 0 });
52
68
  } catch (error) {
53
- const message = error instanceof Error ? error.message : String(error);
54
- console.error(ansis.red(`Error: ${message}`)), process.exit(1);
69
+ if (isTelemetryEnabled && span && (span.recordException(error), span.setStatus({
70
+ code: 2,
71
+ message: getErrorMessage(error)
72
+ })), error instanceof CLIError)
73
+ throw error;
74
+ const message = getErrorMessage(error);
75
+ throw new CLIError(message, 1);
76
+ } finally {
77
+ endSpan(span);
55
78
  }
56
79
  }
57
80
  export {