@documentation-robotics/cli 0.1.13 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/README.md +74 -2
  2. package/dist/analysis/relationship-classifier.js +2 -9
  3. package/dist/analysis/relationship-classifier.js.map +2 -2
  4. package/dist/analyzers/call-graph-utils.js +2 -2
  5. package/dist/analyzers/call-graph-utils.js.map +2 -2
  6. package/dist/analyzers/cards/build.js +171 -0
  7. package/dist/analyzers/cards/build.js.map +7 -0
  8. package/dist/analyzers/cards/classify.js +42 -0
  9. package/dist/analyzers/cards/classify.js.map +7 -0
  10. package/dist/analyzers/cards/edge-index.js +44 -0
  11. package/dist/analyzers/cards/edge-index.js.map +7 -0
  12. package/dist/analyzers/cards/facts.js +46 -0
  13. package/dist/analyzers/cards/facts.js.map +7 -0
  14. package/dist/analyzers/cards/graph.js +42 -0
  15. package/dist/analyzers/cards/graph.js.map +7 -0
  16. package/dist/analyzers/cards/index.js +8 -0
  17. package/dist/analyzers/cards/index.js.map +7 -0
  18. package/dist/analyzers/cards/tier0.js +18 -0
  19. package/dist/analyzers/cards/tier0.js.map +7 -0
  20. package/dist/analyzers/cards/types.js +1 -0
  21. package/dist/analyzers/cards/types.js.map +7 -0
  22. package/dist/analyzers/cbm-analyzer.js +195 -171
  23. package/dist/analyzers/cbm-analyzer.js.map +2 -2
  24. package/dist/analyzers/cbm-responses.js +336 -0
  25. package/dist/analyzers/cbm-responses.js.map +7 -0
  26. package/dist/analyzers/edge-relationships.js +45 -0
  27. package/dist/analyzers/edge-relationships.js.map +7 -0
  28. package/dist/analyzers/mapping-loader.js +9 -0
  29. package/dist/analyzers/mapping-loader.js.map +2 -2
  30. package/dist/analyzers/tier0-rules.js +153 -0
  31. package/dist/analyzers/tier0-rules.js.map +7 -0
  32. package/dist/analyzers/types.js.map +1 -1
  33. package/dist/analyzers/verify-engine.js +22 -19
  34. package/dist/analyzers/verify-engine.js.map +2 -2
  35. package/dist/audit/relationships/ai/prompts.js +10 -10
  36. package/dist/audit/relationships/ai/prompts.js.map +2 -2
  37. package/dist/audit/relationships/analysis/layer-templates.js +52 -52
  38. package/dist/audit/relationships/analysis/layer-templates.js.map +1 -1
  39. package/dist/cli.js +112 -28
  40. package/dist/cli.js.map +3 -3
  41. package/dist/coding-agents/agents/claude-code.js +3 -1
  42. package/dist/coding-agents/agents/claude-code.js.map +2 -2
  43. package/dist/coding-agents/claude-code-client.js +2 -1
  44. package/dist/coding-agents/claude-code-client.js.map +2 -2
  45. package/dist/coding-agents/copilot-client.js +17 -12
  46. package/dist/coding-agents/copilot-client.js.map +2 -2
  47. package/dist/coding-agents/default-permissions.js +152 -0
  48. package/dist/coding-agents/default-permissions.js.map +7 -0
  49. package/dist/coding-agents/drbot-mcp.js +167 -0
  50. package/dist/coding-agents/drbot-mcp.js.map +7 -0
  51. package/dist/commands/add.js +12 -7
  52. package/dist/commands/add.js.map +2 -2
  53. package/dist/commands/analyzer.js +134 -23
  54. package/dist/commands/analyzer.js.map +2 -2
  55. package/dist/commands/audit.js +6 -6
  56. package/dist/commands/audit.js.map +2 -2
  57. package/dist/commands/changeset-verify.js +55 -0
  58. package/dist/commands/changeset-verify.js.map +7 -0
  59. package/dist/commands/changeset.js +261 -147
  60. package/dist/commands/changeset.js.map +2 -2
  61. package/dist/commands/delete.js +52 -19
  62. package/dist/commands/delete.js.map +3 -3
  63. package/dist/commands/element.js +3 -2
  64. package/dist/commands/element.js.map +2 -2
  65. package/dist/commands/farm.js +773 -0
  66. package/dist/commands/farm.js.map +7 -0
  67. package/dist/commands/init.js +11 -1
  68. package/dist/commands/init.js.map +2 -2
  69. package/dist/commands/mcp.js +122 -0
  70. package/dist/commands/mcp.js.map +7 -0
  71. package/dist/commands/relationship.js +251 -47
  72. package/dist/commands/relationship.js.map +2 -2
  73. package/dist/commands/reports.js +1 -1
  74. package/dist/commands/reports.js.map +2 -2
  75. package/dist/commands/update.js +56 -24
  76. package/dist/commands/update.js.map +2 -2
  77. package/dist/commands/upgrade.js +99 -11
  78. package/dist/commands/upgrade.js.map +3 -3
  79. package/dist/commands/validate.js +41 -3
  80. package/dist/commands/validate.js.map +2 -2
  81. package/dist/commands/version.js +2 -2
  82. package/dist/commands/version.js.map +2 -2
  83. package/dist/commands/visualize.js +4 -3
  84. package/dist/commands/visualize.js.map +2 -2
  85. package/dist/config.js +83 -0
  86. package/dist/config.js.map +7 -0
  87. package/dist/core/annotation-store.js +138 -0
  88. package/dist/core/annotation-store.js.map +7 -0
  89. package/dist/core/catalog-migration.js +33 -0
  90. package/dist/core/catalog-migration.js.map +7 -0
  91. package/dist/core/changeset-analysis.js +421 -0
  92. package/dist/core/changeset-analysis.js.map +7 -0
  93. package/dist/core/changeset-base-index.js +153 -0
  94. package/dist/core/changeset-base-index.js.map +7 -0
  95. package/dist/core/changeset-brief-delta.js +102 -0
  96. package/dist/core/changeset-brief-delta.js.map +7 -0
  97. package/dist/core/changeset-graph.js +281 -0
  98. package/dist/core/changeset-graph.js.map +7 -0
  99. package/dist/core/changeset-only-guard.js +32 -0
  100. package/dist/core/changeset-only-guard.js.map +7 -0
  101. package/dist/core/changeset-summary.js +68 -0
  102. package/dist/core/changeset-summary.js.map +7 -0
  103. package/dist/core/changeset-validator.js +66 -20
  104. package/dist/core/changeset-validator.js.map +2 -2
  105. package/dist/core/changeset-verify.js +518 -0
  106. package/dist/core/changeset-verify.js.map +7 -0
  107. package/dist/core/changeset.js +56 -9
  108. package/dist/core/changeset.js.map +2 -2
  109. package/dist/core/element-type-migration.js +145 -0
  110. package/dist/core/element-type-migration.js.map +7 -0
  111. package/dist/core/farm-manifest.js +140 -0
  112. package/dist/core/farm-manifest.js.map +7 -0
  113. package/dist/core/farm-sync-engine.js +346 -0
  114. package/dist/core/farm-sync-engine.js.map +7 -0
  115. package/dist/core/farm-sync-state.js +167 -0
  116. package/dist/core/farm-sync-state.js.map +7 -0
  117. package/dist/core/manifest.js +6 -3
  118. package/dist/core/manifest.js.map +2 -2
  119. package/dist/core/migration-registry.js +84 -1
  120. package/dist/core/migration-registry.js.map +2 -2
  121. package/dist/core/model-upgrade.js +102 -0
  122. package/dist/core/model-upgrade.js.map +7 -0
  123. package/dist/core/model.js +257 -44
  124. package/dist/core/model.js.map +3 -3
  125. package/dist/core/mutation-handler.js +71 -6
  126. package/dist/core/mutation-handler.js.map +2 -2
  127. package/dist/core/relationship-migration-table.js +6639 -0
  128. package/dist/core/relationship-migration-table.js.map +7 -0
  129. package/dist/core/relationship-migration.js +272 -0
  130. package/dist/core/relationship-migration.js.map +7 -0
  131. package/dist/core/relationship-prune.js +49 -0
  132. package/dist/core/relationship-prune.js.map +7 -0
  133. package/dist/core/relationship-staging.js +68 -0
  134. package/dist/core/relationship-staging.js.map +7 -0
  135. package/dist/core/relationships.js +26 -4
  136. package/dist/core/relationships.js.map +2 -2
  137. package/dist/core/report-data-model.js +7 -13
  138. package/dist/core/report-data-model.js.map +2 -2
  139. package/dist/core/staged-changeset-storage.js +64 -17
  140. package/dist/core/staged-changeset-storage.js.map +2 -2
  141. package/dist/core/staged-source-reference.js +28 -0
  142. package/dist/core/staged-source-reference.js.map +7 -0
  143. package/dist/core/staging-area.js +83 -18
  144. package/dist/core/staging-area.js.map +2 -2
  145. package/dist/core/virtual-projection.js +14 -5
  146. package/dist/core/virtual-projection.js.map +2 -2
  147. package/dist/export/archimate-exporter.js +1 -0
  148. package/dist/export/archimate-exporter.js.map +2 -2
  149. package/dist/generated/compiled-validators.js +2 -2
  150. package/dist/generated/compiled-validators.js.map +2 -2
  151. package/dist/generated/layer-registry.js +16 -16
  152. package/dist/generated/layer-registry.js.map +2 -2
  153. package/dist/generated/node-types.js +186 -168
  154. package/dist/generated/node-types.js.map +2 -2
  155. package/dist/generated/relationship-index.js +2209 -7727
  156. package/dist/generated/relationship-index.js.map +2 -2
  157. package/dist/integrations/claude_code/agents/dr-architect.md +16 -3
  158. package/dist/integrations/claude_code/agents/dr-extractor.md +1 -1
  159. package/dist/integrations/claude_code/commands/dr-analyzer.md +565 -0
  160. package/dist/integrations/claude_code/commands/dr-map.md +13 -0
  161. package/dist/integrations/claude_code/commands/dr-plan.md +40 -0
  162. package/dist/integrations/claude_code/commands/dr-relate.md +106 -96
  163. package/dist/integrations/claude_code/commands/dr-verify.md +45 -2
  164. package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +14 -0
  165. package/dist/integrations/claude_code/docs/MCP_SERVER.md +79 -0
  166. package/dist/integrations/claude_code/docs/QUICK_START.md +37 -8
  167. package/dist/integrations/claude_code/docs/README.md +52 -1
  168. package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +93 -72
  169. package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +163 -126
  170. package/dist/integrations/claude_code/skills/dr_03_product_layer/SKILL.md +161 -126
  171. package/dist/integrations/claude_code/skills/dr_04_security_layer/SKILL.md +153 -133
  172. package/dist/integrations/claude_code/skills/dr_05_application_layer/SKILL.md +129 -100
  173. package/dist/integrations/claude_code/skills/dr_06_technology_layer/SKILL.md +111 -94
  174. package/dist/integrations/claude_code/skills/dr_07_api_layer/SKILL.md +143 -157
  175. package/dist/integrations/claude_code/skills/dr_08_data_model_layer/SKILL.md +117 -33
  176. package/dist/integrations/claude_code/skills/dr_09_dataset_layer/SKILL.md +74 -25
  177. package/dist/integrations/claude_code/skills/dr_10_ux_layer/SKILL.md +88 -12
  178. package/dist/integrations/claude_code/skills/dr_11_navigation_layer/SKILL.md +83 -24
  179. package/dist/integrations/claude_code/skills/dr_12_apm_layer/SKILL.md +57 -12
  180. package/dist/integrations/claude_code/skills/dr_13_testing_layer/SKILL.md +92 -15
  181. package/dist/integrations/claude_code/skills/dr_change_planning/SKILL.md +119 -0
  182. package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +3 -0
  183. package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +1 -1
  184. package/dist/integrations/github_copilot/agents/dr-architect.md +1 -1
  185. package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +182 -102
  186. package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +266 -148
  187. package/dist/integrations/github_copilot/skills/dr_03_product_layer/SKILL.md +547 -86
  188. package/dist/integrations/github_copilot/skills/dr_04_security_layer/SKILL.md +164 -169
  189. package/dist/integrations/github_copilot/skills/dr_05_application_layer/SKILL.md +420 -150
  190. package/dist/integrations/github_copilot/skills/dr_06_technology_layer/SKILL.md +331 -138
  191. package/dist/integrations/github_copilot/skills/dr_07_api_layer/SKILL.md +265 -201
  192. package/dist/integrations/github_copilot/skills/dr_08_data_model_layer/SKILL.md +181 -58
  193. package/dist/integrations/github_copilot/skills/dr_09_dataset_layer/SKILL.md +209 -57
  194. package/dist/integrations/github_copilot/skills/dr_10_ux_layer/SKILL.md +277 -112
  195. package/dist/integrations/github_copilot/skills/dr_11_navigation_layer/SKILL.md +219 -70
  196. package/dist/integrations/github_copilot/skills/dr_12_apm_layer/SKILL.md +189 -105
  197. package/dist/integrations/github_copilot/skills/dr_13_testing_layer/SKILL.md +222 -102
  198. package/dist/integrations/github_copilot/skills/dr_change_planning/SKILL.md +119 -0
  199. package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +3 -0
  200. package/dist/integrations/hash-utils.js.map +2 -2
  201. package/dist/mcp/api-key-manager.js +111 -0
  202. package/dist/mcp/api-key-manager.js.map +7 -0
  203. package/dist/mcp/changeset-only.js +34 -0
  204. package/dist/mcp/changeset-only.js.map +7 -0
  205. package/dist/mcp/http-transport.js +176 -0
  206. package/dist/mcp/http-transport.js.map +7 -0
  207. package/dist/mcp/resource-registry.js +97 -0
  208. package/dist/mcp/resource-registry.js.map +7 -0
  209. package/dist/mcp/tool-registry.js +60 -0
  210. package/dist/mcp/tool-registry.js.map +7 -0
  211. package/dist/mcp/tools/annotation-create.js +39 -0
  212. package/dist/mcp/tools/annotation-create.js.map +7 -0
  213. package/dist/mcp/tools/annotation-delete.js +29 -0
  214. package/dist/mcp/tools/annotation-delete.js.map +7 -0
  215. package/dist/mcp/tools/annotation-get.js +29 -0
  216. package/dist/mcp/tools/annotation-get.js.map +7 -0
  217. package/dist/mcp/tools/annotation-list.js +24 -0
  218. package/dist/mcp/tools/annotation-list.js.map +7 -0
  219. package/dist/mcp/tools/annotation-reply.js +34 -0
  220. package/dist/mcp/tools/annotation-reply.js.map +7 -0
  221. package/dist/mcp/tools/annotation-shared.js +10 -0
  222. package/dist/mcp/tools/annotation-shared.js.map +7 -0
  223. package/dist/mcp/tools/annotation-update.js +39 -0
  224. package/dist/mcp/tools/annotation-update.js.map +7 -0
  225. package/dist/mcp/tools/changeset-analysis-tools.js +78 -0
  226. package/dist/mcp/tools/changeset-analysis-tools.js.map +7 -0
  227. package/dist/mcp/tools/changeset-editing.js +184 -0
  228. package/dist/mcp/tools/changeset-editing.js.map +7 -0
  229. package/dist/mcp/tools/changeset-lifecycle.js +83 -0
  230. package/dist/mcp/tools/changeset-lifecycle.js.map +7 -0
  231. package/dist/mcp/tools/changeset-list.js +33 -0
  232. package/dist/mcp/tools/changeset-list.js.map +7 -0
  233. package/dist/mcp/tools/changeset-shared.js +31 -0
  234. package/dist/mcp/tools/changeset-shared.js.map +7 -0
  235. package/dist/mcp/tools/changeset-show.js +55 -0
  236. package/dist/mcp/tools/changeset-show.js.map +7 -0
  237. package/dist/mcp/tools/changeset-verify.js +43 -0
  238. package/dist/mcp/tools/changeset-verify.js.map +7 -0
  239. package/dist/mcp/tools/chat-launch.js +50 -0
  240. package/dist/mcp/tools/chat-launch.js.map +7 -0
  241. package/dist/mcp/tools/chat-status.js +26 -0
  242. package/dist/mcp/tools/chat-status.js.map +7 -0
  243. package/dist/mcp/tools/index.js +65 -0
  244. package/dist/mcp/tools/index.js.map +7 -0
  245. package/dist/mcp/tools/model-add.js +107 -0
  246. package/dist/mcp/tools/model-add.js.map +7 -0
  247. package/dist/mcp/tools/model-delete.js +99 -0
  248. package/dist/mcp/tools/model-delete.js.map +7 -0
  249. package/dist/mcp/tools/model-export.js +72 -0
  250. package/dist/mcp/tools/model-export.js.map +7 -0
  251. package/dist/mcp/tools/model-info.js +51 -0
  252. package/dist/mcp/tools/model-info.js.map +7 -0
  253. package/dist/mcp/tools/model-list.js +53 -0
  254. package/dist/mcp/tools/model-list.js.map +7 -0
  255. package/dist/mcp/tools/model-reload.js +34 -0
  256. package/dist/mcp/tools/model-reload.js.map +7 -0
  257. package/dist/mcp/tools/model-search.js +102 -0
  258. package/dist/mcp/tools/model-search.js.map +7 -0
  259. package/dist/mcp/tools/model-show.js +68 -0
  260. package/dist/mcp/tools/model-show.js.map +7 -0
  261. package/dist/mcp/tools/model-stats.js +22 -0
  262. package/dist/mcp/tools/model-stats.js.map +7 -0
  263. package/dist/mcp/tools/model-trace.js +118 -0
  264. package/dist/mcp/tools/model-trace.js.map +7 -0
  265. package/dist/mcp/tools/model-update.js +121 -0
  266. package/dist/mcp/tools/model-update.js.map +7 -0
  267. package/dist/mcp/tools/model-validate.js +78 -0
  268. package/dist/mcp/tools/model-validate.js.map +7 -0
  269. package/dist/mcp/tools/relationship-tools.js +98 -0
  270. package/dist/mcp/tools/relationship-tools.js.map +7 -0
  271. package/dist/mcp/tools/shared.js +126 -0
  272. package/dist/mcp/tools/shared.js.map +7 -0
  273. package/dist/mcp/tools/spec-type.js +90 -0
  274. package/dist/mcp/tools/spec-type.js.map +7 -0
  275. package/dist/reports/model-layer-report-generator.js +5 -3
  276. package/dist/reports/model-layer-report-generator.js.map +2 -2
  277. package/dist/reports/model-readme-generator.js +116 -0
  278. package/dist/reports/model-readme-generator.js.map +7 -0
  279. package/dist/reports/model-report-data.js +37 -1
  280. package/dist/reports/model-report-data.js.map +2 -2
  281. package/dist/reports/model-report-orchestrator.js +29 -6
  282. package/dist/reports/model-report-orchestrator.js.map +2 -2
  283. package/dist/reports/model-report-utils.js +9 -0
  284. package/dist/reports/model-report-utils.js.map +7 -0
  285. package/dist/schemas/bundled/analyzers/cbm.json +1186 -68
  286. package/dist/schemas/bundled/analyzers/manifest.json +2 -2
  287. package/dist/schemas/bundled/api.json +1029 -1658
  288. package/dist/schemas/bundled/apm.json +499 -734
  289. package/dist/schemas/bundled/application.json +745 -370
  290. package/dist/schemas/bundled/base.json +3 -220
  291. package/dist/schemas/bundled/business.json +452 -366
  292. package/dist/schemas/bundled/data-model.json +403 -383
  293. package/dist/schemas/bundled/data-store.json +334 -558
  294. package/dist/schemas/bundled/manifest.json +18 -18
  295. package/dist/schemas/bundled/motivation.json +349 -368
  296. package/dist/schemas/bundled/navigation.json +415 -731
  297. package/dist/schemas/bundled/product.json +325 -159
  298. package/dist/schemas/bundled/security.json +864 -1232
  299. package/dist/schemas/bundled/technology.json +574 -703
  300. package/dist/schemas/bundled/testing.json +718 -1643
  301. package/dist/schemas/bundled/ux.json +739 -1352
  302. package/dist/server/schemas.js +8 -0
  303. package/dist/server/schemas.js.map +2 -2
  304. package/dist/server/server.js +234 -31
  305. package/dist/server/server.js.map +2 -2
  306. package/dist/server-entry.js +2 -1
  307. package/dist/server-entry.js.map +2 -2
  308. package/dist/telemetry/config.js +2 -40
  309. package/dist/telemetry/config.js.map +2 -2
  310. package/dist/telemetry/index.js +1 -1
  311. package/dist/types/index.js.map +2 -2
  312. package/dist/utils/ansi-suppressor.js +23 -0
  313. package/dist/utils/ansi-suppressor.js.map +7 -0
  314. package/dist/utils/attribute-patch.js +41 -0
  315. package/dist/utils/attribute-patch.js.map +7 -0
  316. package/dist/utils/color-utils.js +34 -0
  317. package/dist/utils/color-utils.js.map +7 -0
  318. package/dist/utils/element-reference-shape.js +15 -1
  319. package/dist/utils/element-reference-shape.js.map +3 -3
  320. package/dist/utils/error-hints.js +29 -0
  321. package/dist/utils/error-hints.js.map +7 -0
  322. package/dist/utils/errors.js +75 -10
  323. package/dist/utils/errors.js.map +2 -2
  324. package/dist/utils/globals.js +17 -1
  325. package/dist/utils/globals.js.map +2 -2
  326. package/dist/utils/project-paths.js +50 -3
  327. package/dist/utils/project-paths.js.map +2 -2
  328. package/dist/utils/reference-path-parser.js +49 -0
  329. package/dist/utils/reference-path-parser.js.map +7 -0
  330. package/dist/utils/source-reference.js +17 -10
  331. package/dist/utils/source-reference.js.map +2 -2
  332. package/dist/utils/spec-version.js +10 -2
  333. package/dist/utils/spec-version.js.map +2 -2
  334. package/dist/validators/composed-reference-validator.js +240 -0
  335. package/dist/validators/composed-reference-validator.js.map +7 -0
  336. package/dist/validators/reference-validator.js +57 -13
  337. package/dist/validators/reference-validator.js.map +3 -3
  338. package/dist/validators/relationship-schema-validator.js +33 -5
  339. package/dist/validators/relationship-schema-validator.js.map +3 -3
  340. package/dist/validators/schema-validator.js +27 -9
  341. package/dist/validators/schema-validator.js.map +2 -2
  342. package/dist/validators/types.js.map +1 -1
  343. package/dist/viewer/README.md +6 -6
  344. package/dist/viewer/assets/main-CxzcuU_o.js +84 -0
  345. package/dist/viewer/assets/main-j-7ULYpm.css +1 -0
  346. package/dist/viewer/index.html +2 -2
  347. package/dist/viewer/manifest.json +10 -10
  348. package/dist/viewer/version.json +1 -1
  349. package/package.json +7 -3
  350. package/dist/viewer/assets/main-B7AOQXXX.js +0 -81
  351. package/dist/viewer/assets/main-vdrFrG7q.css +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/analyzer.ts"],
4
- "sourcesContent": ["/**\n * Analyzer Commands - CLI surface for analyzer discovery, status, indexing, and querying\n *\n * Implements ten subcommands:\n * - discover: Scan for installed analyzers and select active analyzer\n * - status: Report analyzer detection and project index state\n * - index: Index the current project with the active analyzer\n * - endpoints: List discovered API endpoints from indexed project\n * - services: Query for services/components in the indexed project\n * - datastores: Query for datastores/databases inferred from code analysis\n * - callers: Query for callers of a specific function or symbol\n * - callees: Query for callees of a specific function or symbol\n * - query: Execute a raw query against the analyzer's graph\n * - verify: Verify that graph-discovered routes align with model endpoints\n */\n\nimport { Command } from \"commander\";\nimport { intro, outro, select, isCancel } from \"@clack/prompts\";\nimport ansis from \"ansis\";\nimport { promises as fs } from \"fs\";\nimport * as path from \"path\";\nimport { AnalyzerRegistry } from \"../analyzers/registry.js\";\nimport { MappingLoader } from \"../analyzers/mapping-loader.js\";\nimport { readSession, writeSession, writeStatus, readIndexMeta } from \"../analyzers/session-state.js\";\nimport { CLIError, ModelNotFoundError, ErrorCategory, categorizeError } from \"../utils/errors.js\";\nimport { findProjectRoot } from \"../utils/project-paths.js\";\nimport { performDiscover } from \"./discover-logic.js\";\nimport { formatVerifyReport } from \"../export/verify-formatters.js\";\nimport type { SessionState, AnalyzerStatus } from \"../analyzers/types.js\";\n\n/**\n * Register all analyzer subcommands\n */\nexport function analyzerCommands(program: Command): void {\n const analyzer = program.command(\"analyzer\").description(\"Manage analyzer discovery and indexing\");\n\n /**\n * Discover subcommand - scan for installed analyzers\n *\n * Iterates through all registered analyzers, detects which are installed,\n * and prompts for selection if needed. Persists selection to session.json.\n */\n analyzer\n .command(\"discover\")\n .description(\"Discover and select an analyzer\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--reselect\", \"Force re-selection even if analyzer already selected\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer discover # Scan and select analyzer\n $ dr analyzer discover --reselect # Force re-selection\n $ dr analyzer discover --json # Output discovery results as JSON`\n )\n .action(async (options) => {\n try {\n // Resolve project root for consistent session state path\n const projectRoot = (await findProjectRoot()) || process.cwd();\n\n // Initialize registry\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n\n // Check if session already exists and not reselecting\n if (!options.reselect) {\n const session = await readSession(projectRoot);\n if (session) {\n if (options.json) {\n // JSON mode: return discovery results with existing session as selected\n const analyzerNames = await registry.getAnalyzerNames();\n const analyzerOptions: any[] = [];\n\n for (const name of analyzerNames) {\n try {\n const backend = await registry.getAnalyzer(name);\n if (!backend) continue;\n const detection = await backend.detect();\n const mapper = await MappingLoader.load(name);\n const metadata = mapper.getAnalyzerMetadata();\n analyzerOptions.push({ backend, detection, metadata });\n } catch (error) {\n // Log error but continue discovering other analyzers\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.error(`Failed to discover analyzer \"${name}\": ${errorMsg}`);\n }\n }\n\n const installed = analyzerOptions.filter((a) => a.detection.installed);\n const discoveryResult: any = {\n found: analyzerOptions.map((a) => ({\n name: a.backend.name,\n display_name: a.backend.displayName,\n description: a.metadata?.description || \"\",\n homepage: a.metadata?.homepage || \"\",\n installed: a.detection.installed,\n })),\n installed_count: installed.length,\n selected: session.active_analyzer,\n };\n\n console.log(JSON.stringify(discoveryResult, null, 2));\n return;\n } else {\n // Text mode: show message and return\n console.log(\n ansis.green(`\u2713 Using analyzer: ${session.active_analyzer} (use --reselect to change)`)\n );\n return;\n }\n }\n }\n\n // Run core discover logic\n const discoverResult = await performDiscover(registry, {\n json: options.json,\n reselect: options.reselect,\n isTTY: process.stdin.isTTY,\n });\n\n const { discoveryResult, installed, analyzerOptions, selectedAnalyzer, shouldWriteSession } = discoverResult;\n\n // JSON output mode\n if (options.json) {\n // Only write session if an analyzer was actually selected\n // (selectedAnalyzer is only set if analyzers are installed)\n if (selectedAnalyzer && shouldWriteSession) {\n const state: SessionState = {\n active_analyzer: selectedAnalyzer,\n selected_at: new Date().toISOString(),\n };\n await writeSession(state, projectRoot);\n discoveryResult.selected = selectedAnalyzer;\n }\n\n console.log(JSON.stringify(discoveryResult, null, 2));\n return;\n }\n\n // Text output mode - show all analyzers with install status\n if (installed.length === 0) {\n intro(ansis.blue(\"\uD83D\uDCCA Analyzer Discovery\"));\n console.log(\"\");\n console.log(ansis.yellow(\"No analyzers installed. Install one of the following:\"));\n console.log(\"\");\n\n for (const opt of analyzerOptions) {\n const name = ansis.bold(opt.backend.displayName);\n const homepage = opt.metadata?.homepage || \"(homepage not available)\";\n console.log(` ${name} ${ansis.dim(`(${homepage})`)}`);\n }\n\n console.log(\"\");\n outro(ansis.dim(\"To install: follow the links above or use your package manager\"));\n\n return;\n }\n\n // Prompt for selection\n intro(ansis.blue(\"\uD83D\uDCCA Analyzer Selection\"));\n\n if (process.stdin.isTTY) {\n const selectedName = await select({\n message: \"Select an analyzer\",\n options: installed.map((a) => ({\n value: a.backend.name,\n label: a.backend.displayName,\n hint: a.metadata?.description || \"\",\n })),\n });\n\n if (isCancel(selectedName)) {\n outro(ansis.dim(\"Cancelled\"));\n return;\n }\n\n // Write session\n const state: SessionState = {\n active_analyzer: selectedName as string,\n selected_at: new Date().toISOString(),\n };\n await writeSession(state, projectRoot);\n\n outro(\n ansis.green(\n `\u2713 Selected analyzer: ${selectedName} (saved to .dr/analyzers/session.json)`\n )\n );\n } else {\n // Non-TTY: auto-select first installed analyzer\n if (selectedAnalyzer) {\n const state: SessionState = {\n active_analyzer: selectedAnalyzer,\n selected_at: new Date().toISOString(),\n };\n await writeSession(state, projectRoot);\n\n console.log(\n ansis.green(`\u2713 Selected analyzer: ${selectedAnalyzer} (non-interactive mode)`)\n );\n outro(ansis.dim(\"Saved to .dr/analyzers/session.json\"));\n }\n }\n } catch (error) {\n if (error instanceof CLIError) throw error;\n\n const category = categorizeError(error);\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n category\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Status subcommand - report analyzer detection and project index state\n */\n analyzer\n .command(\"status\")\n .description(\"Check analyzer detection and project index status\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer status # Show status of active analyzer\n $ dr analyzer status --name cbm # Show status of specific analyzer\n $ dr analyzer status --json # Output as JSON`\n )\n .action(async (options) => {\n try {\n // Resolve project root for consistent session state path\n const projectRoot = (await findProjectRoot()) || process.cwd();\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND,\n [\"Check the analyzer name with `dr analyzer discover`\"]\n );\n }\n\n // Get status (use project root from findProjectRoot for backend operations)\n const actualProjectRoot = await findProjectRoot();\n let status: AnalyzerStatus;\n if (actualProjectRoot) {\n status = await backend.status(actualProjectRoot);\n } else {\n const detected = await backend.detect();\n status = {\n detected,\n indexed: false,\n fresh: false,\n } as AnalyzerStatus;\n }\n\n // JSON output\n if (options.json) {\n console.log(JSON.stringify(status, null, 2));\n if (actualProjectRoot) {\n await writeStatus(status, actualProjectRoot, analyzerName);\n }\n return;\n }\n\n // Text output\n console.log(\"\");\n console.log(ansis.bold(\"Analyzer Status\"));\n console.log(ansis.dim(\"\u2500\".repeat(40)));\n\n console.log(\n `Installed: ${status.detected.installed ? ansis.green(\"\u2713 Yes\") : ansis.red(\"\u2717 No\")}`\n );\n\n if (status.detected.binary_path) {\n console.log(`Binary: ${ansis.dim(status.detected.binary_path)}`);\n }\n\n if (status.detected.version) {\n console.log(`Version: ${ansis.dim(status.detected.version)}`);\n }\n\n // Only show MCP and contract info if analyzer is installed\n if (status.detected.installed) {\n console.log(\n `MCP Registered: ${status.detected.mcp_registered ? ansis.green(\"\u2713 Yes\") : ansis.yellow(\"\u2717 No\")}`\n );\n\n console.log(\n `Contract Valid: ${status.detected.contract_ok ? ansis.green(\"\u2713 Yes\") : ansis.yellow(\"\u2717 No\")}`\n );\n }\n\n if (actualProjectRoot) {\n console.log(\n `Indexed: ${status.indexed ? ansis.green(\"\u2713 Yes\") : ansis.yellow(\"\u2717 No\")}`\n );\n\n if (status.indexed) {\n console.log(\n `Fresh: ${status.fresh ? ansis.green(\"\u2713 Yes\") : ansis.yellow(\"\u2717 No (use --force to reindex)\")}`\n );\n\n if (status.last_indexed) {\n console.log(`Last indexed: ${ansis.dim(status.last_indexed)}`);\n }\n } else {\n console.log(ansis.dim(\"Run `dr analyzer index` to index the project\"));\n }\n }\n\n console.log(\"\");\n\n // Write status file\n if (actualProjectRoot) {\n await writeStatus(status, actualProjectRoot, analyzerName);\n }\n } catch (error) {\n if (error instanceof CLIError) throw error;\n\n const category = categorizeError(error);\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n category\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Index subcommand - index the current project\n */\n analyzer\n .command(\"index\")\n .description(\"Index the current project with the analyzer\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--force\", \"Force re-indexing even if index is fresh\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer index # Index with active analyzer\n $ dr analyzer index --force # Force re-index\n $ dr analyzer index --name cbm # Index with specific analyzer`\n )\n .action(async (options) => {\n try {\n // Find project root - required for indexing\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND,\n [\"Check the analyzer name with `dr analyzer discover`\"]\n );\n }\n\n // Check if installed\n const detection = await backend.detect();\n if (!detection.installed) {\n // Get analyzer metadata for suggestions\n const mapper = await MappingLoader.load(analyzerName);\n const metadata = mapper.getAnalyzerMetadata();\n const homepageUrl = metadata?.homepage || \"https://github.com/search?q=codebase-memory\";\n\n throw new CLIError(\n `Analyzer not installed: ${analyzerName}`,\n ErrorCategory.USER,\n [\n \"Run `dr analyzer discover` to find available analyzers and installation instructions\",\n `Visit: ${homepageUrl}`,\n ]\n );\n }\n\n // Index the project\n console.log(`Indexing project with ${analyzerName}...`);\n const result = await backend.index(projectRoot, { force: options.force });\n\n console.log(ansis.green(`\u2713 Indexing complete`));\n console.log(` Nodes: ${result.node_count}`);\n console.log(` Edges: ${result.edge_count}`);\n console.log(` Git HEAD: ${result.git_head}`);\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n ErrorCategory.SYSTEM\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Endpoints subcommand - list API endpoints from indexed project\n */\n analyzer\n .command(\"endpoints\")\n .description(\"List discovered API endpoints from indexed project\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer endpoints # List endpoints from active analyzer\n $ dr analyzer endpoints --json # Output as JSON\n $ dr analyzer endpoints --name cbm # List endpoints from specific analyzer`\n )\n .action(async (options) => {\n try {\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Check if project is indexed\n const status = await backend.status(projectRoot);\n if (!status.indexed) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` to index the project first\"]\n );\n }\n\n // Query for endpoints\n const endpoints = await backend.endpoints(projectRoot);\n\n // JSON output\n if (options.json) {\n console.log(JSON.stringify(endpoints, null, 2));\n return;\n }\n\n // Table output\n if (endpoints.length === 0) {\n console.log(ansis.yellow(\"No endpoints found\"));\n return;\n }\n\n console.log(\"\");\n console.log(ansis.bold(`API Endpoints (${endpoints.length} found):`));\n console.log(ansis.dim(\"\u2500\".repeat(135)));\n\n // Print header\n const methodWidth = 8;\n const pathWidth = 20;\n const nameWidth = 18;\n const idFragmentWidth = 18;\n const symbolWidth = 18;\n const confidenceWidth = 12;\n const fileWidth = 25;\n\n console.log(\n ansis.cyan(\n `${\"Method\".padEnd(methodWidth)} ${\"Path\".padEnd(pathWidth)} ${\"Name\".padEnd(nameWidth)} ${\"ID Fragment\".padEnd(idFragmentWidth)} ${\"Symbol\".padEnd(symbolWidth)} ${\"Confidence\".padEnd(confidenceWidth)} File`\n )\n );\n console.log(ansis.dim(\"\u2500\".repeat(135)));\n\n // Print each endpoint\n for (const endpoint of endpoints) {\n const method = endpoint.http_method.padEnd(methodWidth);\n const path = endpoint.http_path.substring(0, pathWidth).padEnd(pathWidth);\n const name = endpoint.suggested_name.substring(0, nameWidth).padEnd(nameWidth);\n const idFragment = endpoint.suggested_id_fragment.substring(0, idFragmentWidth).padEnd(idFragmentWidth);\n const symbol = endpoint.source_symbol.substring(0, symbolWidth).padEnd(symbolWidth);\n const confidence = endpoint.confidence.toUpperCase().padEnd(confidenceWidth);\n const file = endpoint.source_file.substring(0, fileWidth);\n\n console.log(`${method} ${path} ${name} ${idFragment} ${symbol} ${confidence} ${ansis.dim(file)}`);\n }\n\n console.log(ansis.dim(\"\u2500\".repeat(135)));\n console.log(ansis.dim(`Total: ${endpoints.length} endpoint(s)`));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Services subcommand - query for services/components in indexed project\n */\n analyzer\n .command(\"services\")\n .description(\"Query for services/components in the indexed project\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--layer <layer>\", \"Filter by layer (e.g., 'application')\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer services # List all services\n $ dr analyzer services --layer application\n $ dr analyzer services --json # Output as JSON`\n )\n .action(async (options) => {\n try {\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Query for services\n let services = await backend.services(projectRoot);\n\n // Filter by layer if specified\n if (options.layer) {\n services = services.filter(s => s.suggested_layer === options.layer);\n }\n\n // JSON output\n if (options.json) {\n console.log(JSON.stringify(services, null, 2));\n return;\n }\n\n // Table output\n if (services.length === 0) {\n console.log(ansis.yellow(\"No services found\"));\n return;\n }\n\n console.log(\"\");\n console.log(ansis.bold(`Services (${services.length} found):`));\n console.log(ansis.dim(\"\u2500\".repeat(120)));\n\n // Print header\n const nameWidth = 20;\n const layerWidth = 15;\n const typeWidth = 18;\n const symbolWidth = 20;\n const confidenceWidth = 12;\n const fileWidth = 25;\n\n console.log(\n ansis.cyan(\n `${\"Name\".padEnd(nameWidth)} ${\"Layer\".padEnd(layerWidth)} ${\"Type\".padEnd(typeWidth)} ${\"Symbol\".padEnd(symbolWidth)} ${\"Confidence\".padEnd(confidenceWidth)} File`\n )\n );\n console.log(ansis.dim(\"\u2500\".repeat(120)));\n\n // Print each service\n for (const service of services) {\n const name = service.suggested_name.substring(0, nameWidth).padEnd(nameWidth);\n const layer = service.suggested_layer.substring(0, layerWidth).padEnd(layerWidth);\n const type = service.suggested_element_type.substring(0, typeWidth).padEnd(typeWidth);\n const symbol = service.source_symbol.substring(0, symbolWidth).padEnd(symbolWidth);\n const confidence = service.confidence.toUpperCase().padEnd(confidenceWidth);\n const file = service.source_file.substring(0, fileWidth);\n\n console.log(`${name} ${layer} ${type} ${symbol} ${confidence} ${ansis.dim(file)}`);\n }\n\n console.log(ansis.dim(\"\u2500\".repeat(120)));\n console.log(ansis.dim(`Total: ${services.length} service(s)`));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Datastores subcommand - query for datastores/databases inferred from code\n */\n analyzer\n .command(\"datastores\")\n .description(\"Query for datastores/databases inferred from code analysis\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer datastores # List all inferred datastores\n $ dr analyzer datastores --json # Output as JSON`\n )\n .action(async (options) => {\n try {\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Query for datastores\n const datastores = await backend.datastores(projectRoot);\n\n // JSON output\n if (options.json) {\n console.log(JSON.stringify(datastores, null, 2));\n return;\n }\n\n // Table output\n if (datastores.length === 0) {\n console.log(ansis.yellow(\"No datastores found\"));\n return;\n }\n\n console.log(\"\");\n console.log(ansis.bold(`Datastores (${datastores.length} found):`));\n console.log(ansis.dim(\"\u2500\".repeat(100)));\n\n // Print each datastore\n for (const ds of datastores) {\n console.log(` ${ansis.cyan(ds.suggested_name)}`);\n console.log(` Inferred from:`);\n for (const evidence of ds.inferred_from) {\n console.log(` - ${evidence.source_file}: ${evidence.import_pattern}`);\n }\n if (ds.notes) {\n console.log(` Notes: ${ds.notes}`);\n }\n console.log(\"\");\n }\n\n console.log(ansis.dim(`Total: ${datastores.length} datastore(s)`));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Callers subcommand - query for callers of a specific symbol\n */\n analyzer\n .command(\"callers <qualified-name>\")\n .description(\"Query for callers of a specific function or symbol\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--depth <n>\", \"Maximum depth for call graph traversal (default: 3, max: 10)\", \"3\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer callers com.example.Service.handleRequest\n $ dr analyzer callers com.example.Service.handleRequest --depth 5\n $ dr analyzer callers com.example.Service.handleRequest --json`\n )\n .action(async (qualifiedName, options) => {\n try {\n // Validate depth\n const depth = parseInt(options.depth, 10);\n if (isNaN(depth) || depth < 1) {\n throw new CLIError(\n \"Invalid --depth value: must be a positive integer\",\n ErrorCategory.USER\n );\n }\n\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Query for callers\n const callers = await backend.callers(projectRoot, qualifiedName, depth);\n\n // JSON output\n if (options.json) {\n console.log(JSON.stringify(callers, null, 2));\n return;\n }\n\n // Table output\n if (callers.length === 0) {\n console.log(ansis.yellow(`No callers found for ${qualifiedName}`));\n return;\n }\n\n console.log(\"\");\n console.log(ansis.bold(`Callers of ${ansis.cyan(qualifiedName)} (${callers.length} found):`));\n console.log(ansis.dim(\"\u2500\".repeat(100)));\n\n // Print each caller\n for (const caller of callers) {\n console.log(` ${ansis.bold(caller.qualified_name)}`);\n console.log(` File: ${caller.source_file}`);\n console.log(` Symbol: ${caller.source_symbol}`);\n console.log(` Depth: ${caller.depth}`);\n console.log(` Edge: ${caller.edge_type}`);\n console.log(\"\");\n }\n\n console.log(ansis.dim(`Total: ${callers.length} caller(s)`));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Callees subcommand - query for callees of a specific symbol\n */\n analyzer\n .command(\"callees <qualified-name>\")\n .description(\"Query for callees of a specific function or symbol\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--depth <n>\", \"Maximum depth for call graph traversal (default: 3, max: 10)\", \"3\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer callees com.example.Service.handleRequest\n $ dr analyzer callees com.example.Service.handleRequest --depth 5\n $ dr analyzer callees com.example.Service.handleRequest --json`\n )\n .action(async (qualifiedName, options) => {\n try {\n // Validate depth\n const depth = parseInt(options.depth, 10);\n if (isNaN(depth) || depth < 1) {\n throw new CLIError(\n \"Invalid --depth value: must be a positive integer\",\n ErrorCategory.USER\n );\n }\n\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Query for callees\n const callees = await backend.callees(projectRoot, qualifiedName, depth);\n\n // JSON output\n if (options.json) {\n console.log(JSON.stringify(callees, null, 2));\n return;\n }\n\n // Table output\n if (callees.length === 0) {\n console.log(ansis.yellow(`No callees found for ${qualifiedName}`));\n return;\n }\n\n console.log(\"\");\n console.log(ansis.bold(`Callees of ${ansis.cyan(qualifiedName)} (${callees.length} found):`));\n console.log(ansis.dim(\"\u2500\".repeat(100)));\n\n // Print each callee\n for (const callee of callees) {\n console.log(` ${ansis.bold(callee.qualified_name)}`);\n console.log(` File: ${callee.source_file}`);\n console.log(` Symbol: ${callee.source_symbol}`);\n console.log(` Depth: ${callee.depth}`);\n console.log(` Edge: ${callee.edge_type}`);\n console.log(\"\");\n }\n\n console.log(ansis.dim(`Total: ${callees.length} callee(s)`));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Query subcommand - execute a raw query against the analyzer's graph\n * Documented as an advanced escape hatch for graph queries (not recommended for scripting)\n */\n analyzer\n .command(\"query <cypher>\")\n .description(\"Execute a raw Cypher query against the analyzer graph (advanced escape hatch)\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--json\", \"Output as JSON (default format for query results)\")\n .addHelpText(\n \"before\",\n `Advanced Escape Hatch: This command directly executes graph queries without validation or wrapping.\nUse for advanced analysis when standard commands don't meet your needs.\\n`\n )\n .addHelpText(\n \"after\",\n `\nQuery syntax depends on the analyzer backend (e.g., Cypher for graph analyzers).\nResults are always output as JSON.\n\nExamples:\n $ dr analyzer query \"MATCH (n) RETURN n LIMIT 10\"\n $ dr analyzer query \"MATCH (n:Service) RETURN n.name\"\n $ dr analyzer query \"MATCH (n) RETURN n LIMIT 10\" --json`\n )\n .action(async (cypher, options) => {\n try {\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Execute query\n const result = await backend.query(projectRoot, cypher);\n\n // Output format: JSON is the only reasonable format for arbitrary query results\n // The --json flag is accepted for consistency, but JSON is always the output format\n // (the flag currently has no effect as all query output is JSON)\n if (options.json === false) {\n // Explicit no-op: --json flag or its absence doesn't change behavior\n // Query results are always output as JSON regardless of flag\n }\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Verify subcommand - verify that graph-discovered routes align with model endpoints\n */\n analyzer\n .command(\"verify\")\n .description(\"Verify that graph-discovered routes align with model endpoints\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--layer <layer>\", \"Layer(s) to verify (can be used multiple times)\", (value, previous: string[] | undefined) => {\n return previous ? [...previous, value] : [value];\n })\n .option(\"--json\", \"Output as JSON\")\n .option(\"--format <format>\", \"Output format: text, json, markdown (default: text)\")\n .option(\"--output <path>\", \"Write report to file\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer verify # Verify api layer (default)\n $ dr analyzer verify --layer api # Explicitly specify api layer\n $ dr analyzer verify --json # Output as JSON to stdout\n $ dr analyzer verify --format markdown # Output as Markdown to stdout\n $ dr analyzer verify --output report.json # Save report to file (format inferred as JSON)\n $ dr analyzer verify --output report.md # Save report as Markdown`\n )\n .action(async (options) => {\n try {\n // Determine output format from --json flag, --format flag, or --output file extension\n let format: \"text\" | \"json\" | \"markdown\" = \"text\";\n if (options.json) {\n // Warn if both --json and --format are provided\n if (options.format) {\n console.warn(ansis.yellow(`\u26A0 Both --json and --format \"${options.format}\" were provided. Using --json format (--format is ignored).`));\n }\n format = \"json\";\n } else if (options.format) {\n const validFormats = [\"text\", \"json\", \"markdown\"];\n if (!validFormats.includes(options.format)) {\n throw new CLIError(\n `Invalid format: \"${options.format}\". Valid values are: ${validFormats.join(\", \")}.`,\n ErrorCategory.USER\n );\n }\n format = options.format as \"text\" | \"json\" | \"markdown\";\n } else 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 } else if (ext) {\n // Warn if file has unrecognized extension\n console.warn(ansis.yellow(`\u26A0 Unrecognized file extension \"${ext}\" in --output. Using text format by default.`));\n }\n }\n\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Validate layers - only api is supported in v1\n const requestedLayers = options.layer || [\"api\"];\n const apiLayers = requestedLayers.filter((layer: string) => layer === \"api\");\n const nonApiLayers = requestedLayers.filter((layer: string) => layer !== \"api\");\n\n // Report non-api layers as not available\n for (const layer of nonApiLayers) {\n console.log(ansis.dim(`No verification available for layer '${layer}'`));\n }\n\n // If no api layers to verify, exit cleanly\n if (apiLayers.length === 0) {\n return;\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Execute verification with changeset awareness enabled by default\n const report = await backend.verify(projectRoot, {\n layers: apiLayers,\n changesetAware: true,\n });\n\n const formatted = formatVerifyReport(report, { format });\n\n // Write to file if --output specified\n if (options.output) {\n const outputPath = path.resolve(options.output);\n await fs.writeFile(outputPath, formatted, \"utf-8\");\n console.log(ansis.green(`\u2713 Report written to ${outputPath}`));\n return;\n }\n\n // Print to stdout\n console.log(formatted);\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Analyzer Commands - CLI surface for analyzer discovery, status, indexing, and querying\n *\n * Implements eleven subcommands:\n * - discover: Scan for installed analyzers and select active analyzer\n * - status: Report analyzer detection and project index state\n * - index: Index the current project with the active analyzer\n * - endpoints: List discovered API endpoints from indexed project\n * - services: Query for services/components in the indexed project\n * - datastores: Query for datastores/databases inferred from code analysis\n * - callers: Query for callers of a specific function or symbol\n * - callees: Query for callees of a specific function or symbol\n * - query: Execute a raw query against the analyzer's graph\n * - verify: Verify that graph-discovered routes align with model endpoints\n * - classify: Tier-0 classification of the indexed project's symbols (no model calls)\n */\n\nimport { Command } from \"commander\";\nimport { intro, outro, select, isCancel } from \"@clack/prompts\";\nimport ansis from \"ansis\";\nimport { promises as fs } from \"fs\";\nimport * as path from \"path\";\nimport { AnalyzerRegistry } from \"../analyzers/registry.js\";\nimport { MappingLoader } from \"../analyzers/mapping-loader.js\";\nimport { readSession, writeSession, writeStatus, readIndexMeta } from \"../analyzers/session-state.js\";\nimport { CLIError, ModelNotFoundError, ErrorCategory, categorizeError } from \"../utils/errors.js\";\nimport { findProjectRoot } from \"../utils/project-paths.js\";\nimport { performDiscover } from \"./discover-logic.js\";\nimport { formatVerifyReport } from \"../export/verify-formatters.js\";\nimport { Model } from \"../core/model.js\";\nimport type { SessionState, AnalyzerStatus } from \"../analyzers/types.js\";\n\n/**\n * Register all analyzer subcommands\n */\nexport function analyzerCommands(program: Command): void {\n const analyzer = program.command(\"analyzer\").description(\"Manage analyzer discovery and indexing\");\n\n /**\n * Discover subcommand - scan for installed analyzers\n *\n * Iterates through all registered analyzers, detects which are installed,\n * and prompts for selection if needed. Persists selection to session.json.\n */\n analyzer\n .command(\"discover\")\n .description(\"Discover and select an analyzer\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--reselect\", \"Force re-selection even if analyzer already selected\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer discover # Scan and select analyzer\n $ dr analyzer discover --reselect # Force re-selection\n $ dr analyzer discover --json # Output discovery results as JSON`\n )\n .action(async (options) => {\n // Merge global --json flag if local one isn't set\n const jsonMode = options.json ?? program.opts().json;\n try {\n // Resolve project root for consistent session state path\n const projectRoot = (await findProjectRoot()) || process.cwd();\n\n // Initialize registry\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n\n // Check if session already exists and not reselecting\n if (!options.reselect) {\n const session = await readSession(projectRoot);\n if (session) {\n if (jsonMode) {\n // JSON mode: return discovery results with existing session as selected\n const analyzerNames = await registry.getAnalyzerNames();\n const analyzerOptions: any[] = [];\n\n for (const name of analyzerNames) {\n try {\n const backend = await registry.getAnalyzer(name);\n if (!backend) continue;\n const detection = await backend.detect();\n const mapper = await MappingLoader.load(name);\n const metadata = mapper.getAnalyzerMetadata();\n analyzerOptions.push({ backend, detection, metadata });\n } catch (error) {\n // Log error but continue discovering other analyzers\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.error(`Failed to discover analyzer \"${name}\": ${errorMsg}`);\n }\n }\n\n const installed = analyzerOptions.filter((a) => a.detection.installed);\n const discoveryResult: any = {\n found: analyzerOptions.map((a) => ({\n name: a.backend.name,\n display_name: a.backend.displayName,\n description: a.metadata?.description || \"\",\n homepage: a.metadata?.homepage || \"\",\n installed: a.detection.installed,\n })),\n installed_count: installed.length,\n selected: session.active_analyzer,\n };\n\n console.log(JSON.stringify(discoveryResult, null, 2));\n return;\n } else {\n // Text mode: show message and return\n console.log(\n ansis.green(`\u2713 Using analyzer: ${session.active_analyzer} (use --reselect to change)`)\n );\n return;\n }\n }\n }\n\n // Run core discover logic\n const discoverResult = await performDiscover(registry, {\n json: jsonMode,\n reselect: options.reselect,\n isTTY: process.stdin.isTTY,\n });\n\n const { discoveryResult, installed, analyzerOptions, selectedAnalyzer, shouldWriteSession } = discoverResult;\n\n // JSON output mode\n if (jsonMode) {\n // Only write session if an analyzer was actually selected\n // (selectedAnalyzer is only set if analyzers are installed)\n if (selectedAnalyzer && shouldWriteSession) {\n const state: SessionState = {\n active_analyzer: selectedAnalyzer,\n selected_at: new Date().toISOString(),\n };\n await writeSession(state, projectRoot);\n discoveryResult.selected = selectedAnalyzer;\n }\n\n console.log(JSON.stringify(discoveryResult, null, 2));\n return;\n }\n\n // Text output mode - show all analyzers with install status\n if (installed.length === 0) {\n intro(ansis.blue(\"\uD83D\uDCCA Analyzer Discovery\"));\n console.log(\"\");\n console.log(ansis.yellow(\"No analyzers installed. Install one of the following:\"));\n console.log(\"\");\n\n for (const opt of analyzerOptions) {\n const name = ansis.bold(opt.backend.displayName);\n const homepage = opt.metadata?.homepage || \"(homepage not available)\";\n console.log(` ${name} ${ansis.dim(`(${homepage})`)}`);\n }\n\n console.log(\"\");\n outro(ansis.dim(\"To install: follow the links above or use your package manager\"));\n\n return;\n }\n\n // Prompt for selection\n intro(ansis.blue(\"\uD83D\uDCCA Analyzer Selection\"));\n\n if (process.stdin.isTTY) {\n const selectedName = await select({\n message: \"Select an analyzer\",\n options: installed.map((a) => ({\n value: a.backend.name,\n label: a.backend.displayName,\n hint: a.metadata?.description || \"\",\n })),\n });\n\n if (isCancel(selectedName)) {\n outro(ansis.dim(\"Cancelled\"));\n return;\n }\n\n // Write session\n const state: SessionState = {\n active_analyzer: selectedName as string,\n selected_at: new Date().toISOString(),\n };\n await writeSession(state, projectRoot);\n\n outro(\n ansis.green(\n `\u2713 Selected analyzer: ${selectedName} (saved to .dr/analyzers/session.json)`\n )\n );\n } else {\n // Non-TTY: auto-select first installed analyzer\n if (selectedAnalyzer) {\n const state: SessionState = {\n active_analyzer: selectedAnalyzer,\n selected_at: new Date().toISOString(),\n };\n await writeSession(state, projectRoot);\n\n console.log(\n ansis.green(`\u2713 Selected analyzer: ${selectedAnalyzer} (non-interactive mode)`)\n );\n outro(ansis.dim(\"Saved to .dr/analyzers/session.json\"));\n }\n }\n } catch (error) {\n if (error instanceof CLIError) throw error;\n\n const category = categorizeError(error);\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n category\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Status subcommand - report analyzer detection and project index state\n */\n analyzer\n .command(\"status\")\n .description(\"Check analyzer detection and project index status\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer status # Show status of active analyzer\n $ dr analyzer status --name cbm # Show status of specific analyzer\n $ dr analyzer status --json # Output as JSON`\n )\n .action(async (options) => {\n // Merge global --json flag if local one isn't set\n const jsonMode = options.json ?? program.opts().json;\n try {\n // Resolve project root for consistent session state path\n const projectRoot = (await findProjectRoot()) || process.cwd();\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND,\n [\"Check the analyzer name with `dr analyzer discover`\"]\n );\n }\n\n // Get status (use project root from findProjectRoot for backend operations)\n const actualProjectRoot = await findProjectRoot();\n let status: AnalyzerStatus;\n if (actualProjectRoot) {\n // Load model to get codebase root\n const model = await Model.load(actualProjectRoot);\n status = await backend.status(actualProjectRoot, { codebaseRoot: model.codebaseRoot });\n } else {\n const detected = await backend.detect();\n status = {\n detected,\n indexed: false,\n fresh: false,\n } as AnalyzerStatus;\n }\n\n // JSON output\n if (jsonMode) {\n console.log(JSON.stringify(status, null, 2));\n if (actualProjectRoot) {\n await writeStatus(status, actualProjectRoot, analyzerName);\n }\n return;\n }\n\n // Text output\n console.log(\"\");\n console.log(ansis.bold(\"Analyzer Status\"));\n console.log(ansis.dim(\"\u2500\".repeat(40)));\n\n console.log(\n `Installed: ${status.detected.installed ? ansis.green(\"\u2713 Yes\") : ansis.red(\"\u2717 No\")}`\n );\n\n if (status.detected.binary_path) {\n console.log(`Binary: ${ansis.dim(status.detected.binary_path)}`);\n }\n\n if (status.detected.version) {\n console.log(`Version: ${ansis.dim(status.detected.version)}`);\n }\n\n // Only show MCP and contract info if analyzer is installed\n if (status.detected.installed) {\n console.log(\n `MCP Registered: ${status.detected.mcp_registered ? ansis.green(\"\u2713 Yes\") : ansis.yellow(\"\u2717 No\")}`\n );\n\n console.log(\n `Contract Valid: ${status.detected.contract_ok ? ansis.green(\"\u2713 Yes\") : ansis.yellow(\"\u2717 No\")}`\n );\n }\n\n if (actualProjectRoot) {\n console.log(\n `Indexed: ${status.indexed ? ansis.green(\"\u2713 Yes\") : ansis.yellow(\"\u2717 No\")}`\n );\n\n if (status.indexed) {\n console.log(\n `Fresh: ${status.fresh ? ansis.green(\"\u2713 Yes\") : ansis.yellow(\"\u2717 No (use --force to reindex)\")}`\n );\n\n if (status.last_indexed) {\n console.log(`Last indexed: ${ansis.dim(status.last_indexed)}`);\n }\n } else {\n console.log(ansis.dim(\"Run `dr analyzer index` to index the project\"));\n }\n }\n\n console.log(\"\");\n\n // Write status file\n if (actualProjectRoot) {\n await writeStatus(status, actualProjectRoot, analyzerName);\n }\n } catch (error) {\n if (error instanceof CLIError) throw error;\n\n const category = categorizeError(error);\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n category\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Index subcommand - index the current project\n */\n analyzer\n .command(\"index\")\n .description(\"Index the current project with the analyzer\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--force\", \"Force re-indexing even if index is fresh\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer index # Index with active analyzer\n $ dr analyzer index --force # Force re-index\n $ dr analyzer index --name cbm # Index with specific analyzer`\n )\n .action(async (options) => {\n try {\n // Find project root - required for indexing\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND,\n [\"Check the analyzer name with `dr analyzer discover`\"]\n );\n }\n\n // Check if installed\n const detection = await backend.detect();\n if (!detection.installed) {\n // Get analyzer metadata for suggestions\n const mapper = await MappingLoader.load(analyzerName);\n const metadata = mapper.getAnalyzerMetadata();\n const homepageUrl = metadata?.homepage || \"https://github.com/search?q=codebase-memory\";\n\n throw new CLIError(\n `Analyzer not installed: ${analyzerName}`,\n ErrorCategory.USER,\n [\n \"Run `dr analyzer discover` to find available analyzers and installation instructions\",\n `Visit: ${homepageUrl}`,\n ]\n );\n }\n\n // Load model to get codebase root\n const model = await Model.load(projectRoot);\n\n // Index the project\n console.log(`Indexing project with ${analyzerName}...`);\n const result = await backend.index(projectRoot, { force: options.force, codebaseRoot: model.codebaseRoot });\n\n console.log(ansis.green(`\u2713 Indexing complete`));\n console.log(` Nodes: ${result.node_count}`);\n console.log(` Edges: ${result.edge_count}`);\n console.log(` Git HEAD: ${result.git_head}`);\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n ErrorCategory.SYSTEM\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Endpoints subcommand - list API endpoints from indexed project\n */\n analyzer\n .command(\"endpoints\")\n .description(\"List discovered API endpoints from indexed project\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer endpoints # List endpoints from active analyzer\n $ dr analyzer endpoints --json # Output as JSON\n $ dr analyzer endpoints --name cbm # List endpoints from specific analyzer`\n )\n .action(async (options) => {\n // Merge global --json flag if local one isn't set\n const jsonMode = options.json ?? program.opts().json;\n try {\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Load model to get codebase root\n const model = await Model.load(projectRoot);\n\n // Check if project is indexed\n const status = await backend.status(projectRoot, { codebaseRoot: model.codebaseRoot });\n if (!status.indexed) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` to index the project first\"]\n );\n }\n\n // Query for endpoints\n const endpoints = await backend.endpoints(projectRoot, { codebaseRoot: model.codebaseRoot });\n\n // JSON output\n if (jsonMode) {\n console.log(JSON.stringify(endpoints, null, 2));\n return;\n }\n\n // Table output\n if (endpoints.length === 0) {\n console.log(ansis.yellow(\"No endpoints found\"));\n return;\n }\n\n console.log(\"\");\n console.log(ansis.bold(`API Endpoints (${endpoints.length} found):`));\n console.log(ansis.dim(\"\u2500\".repeat(135)));\n\n // Print header\n const methodWidth = 8;\n const pathWidth = 20;\n const nameWidth = 18;\n const idFragmentWidth = 18;\n const symbolWidth = 18;\n const confidenceWidth = 12;\n const fileWidth = 25;\n\n console.log(\n ansis.cyan(\n `${\"Method\".padEnd(methodWidth)} ${\"Path\".padEnd(pathWidth)} ${\"Name\".padEnd(nameWidth)} ${\"ID Fragment\".padEnd(idFragmentWidth)} ${\"Symbol\".padEnd(symbolWidth)} ${\"Confidence\".padEnd(confidenceWidth)} File`\n )\n );\n console.log(ansis.dim(\"\u2500\".repeat(135)));\n\n // Print each endpoint\n for (const endpoint of endpoints) {\n const method = endpoint.http_method.padEnd(methodWidth);\n const path = endpoint.http_path.substring(0, pathWidth).padEnd(pathWidth);\n const name = endpoint.suggested_name.substring(0, nameWidth).padEnd(nameWidth);\n const idFragment = endpoint.suggested_id_fragment.substring(0, idFragmentWidth).padEnd(idFragmentWidth);\n const symbol = endpoint.source_symbol.substring(0, symbolWidth).padEnd(symbolWidth);\n const confidence = endpoint.confidence.toUpperCase().padEnd(confidenceWidth);\n const file = endpoint.source_file.substring(0, fileWidth);\n\n console.log(`${method} ${path} ${name} ${idFragment} ${symbol} ${confidence} ${ansis.dim(file)}`);\n }\n\n console.log(ansis.dim(\"\u2500\".repeat(135)));\n console.log(ansis.dim(`Total: ${endpoints.length} endpoint(s)`));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Services subcommand - query for services/components in indexed project\n */\n analyzer\n .command(\"services\")\n .description(\"Query for services/components in the indexed project\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--layer <layer>\", \"Filter by layer (e.g., 'application')\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer services # List all services\n $ dr analyzer services --layer application\n $ dr analyzer services --json # Output as JSON`\n )\n .action(async (options) => {\n // Merge global --json flag if local one isn't set\n const jsonMode = options.json ?? program.opts().json;\n try {\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Load model to get codebase root\n const model = await Model.load(projectRoot);\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Query for services\n let services = await backend.services(projectRoot, { codebaseRoot: model.codebaseRoot });\n\n // Filter by layer if specified\n if (options.layer) {\n services = services.filter(s => s.suggested_layer === options.layer);\n }\n\n // JSON output\n if (jsonMode) {\n console.log(JSON.stringify(services, null, 2));\n return;\n }\n\n // Table output\n if (services.length === 0) {\n console.log(ansis.yellow(\"No services found\"));\n return;\n }\n\n console.log(\"\");\n console.log(ansis.bold(`Services (${services.length} found):`));\n console.log(ansis.dim(\"\u2500\".repeat(120)));\n\n // Print header\n const nameWidth = 20;\n const layerWidth = 15;\n const typeWidth = 18;\n const symbolWidth = 20;\n const confidenceWidth = 12;\n const fileWidth = 25;\n\n console.log(\n ansis.cyan(\n `${\"Name\".padEnd(nameWidth)} ${\"Layer\".padEnd(layerWidth)} ${\"Type\".padEnd(typeWidth)} ${\"Symbol\".padEnd(symbolWidth)} ${\"Confidence\".padEnd(confidenceWidth)} File`\n )\n );\n console.log(ansis.dim(\"\u2500\".repeat(120)));\n\n // Print each service\n for (const service of services) {\n const name = service.suggested_name.substring(0, nameWidth).padEnd(nameWidth);\n const layer = service.suggested_layer.substring(0, layerWidth).padEnd(layerWidth);\n const type = service.suggested_element_type.substring(0, typeWidth).padEnd(typeWidth);\n const symbol = service.source_symbol.substring(0, symbolWidth).padEnd(symbolWidth);\n const confidence = service.confidence.toUpperCase().padEnd(confidenceWidth);\n const file = service.source_file.substring(0, fileWidth);\n\n console.log(`${name} ${layer} ${type} ${symbol} ${confidence} ${ansis.dim(file)}`);\n }\n\n console.log(ansis.dim(\"\u2500\".repeat(120)));\n console.log(ansis.dim(`Total: ${services.length} service(s)`));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Datastores subcommand - query for datastores/databases inferred from code\n */\n analyzer\n .command(\"datastores\")\n .description(\"Query for datastores/databases inferred from code analysis\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer datastores # List all inferred datastores\n $ dr analyzer datastores --json # Output as JSON`\n )\n .action(async (options) => {\n // Merge global --json flag if local one isn't set\n const jsonMode = options.json ?? program.opts().json;\n try {\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Load model to get codebase root\n const model = await Model.load(projectRoot);\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Query for datastores\n const datastores = await backend.datastores(projectRoot, { codebaseRoot: model.codebaseRoot });\n\n // JSON output\n if (jsonMode) {\n console.log(JSON.stringify(datastores, null, 2));\n return;\n }\n\n // Table output\n if (datastores.length === 0) {\n console.log(ansis.yellow(\"No datastores found\"));\n return;\n }\n\n console.log(\"\");\n console.log(ansis.bold(`Datastores (${datastores.length} found):`));\n console.log(ansis.dim(\"\u2500\".repeat(100)));\n\n // Print each datastore\n for (const ds of datastores) {\n console.log(` ${ansis.cyan(ds.suggested_name)}`);\n console.log(` Inferred from:`);\n for (const evidence of ds.inferred_from) {\n console.log(` - ${evidence.source_file}: ${evidence.import_pattern}`);\n }\n if (ds.notes) {\n console.log(` Notes: ${ds.notes}`);\n }\n console.log(\"\");\n }\n\n console.log(ansis.dim(`Total: ${datastores.length} datastore(s)`));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Callers subcommand - query for callers of a specific symbol\n */\n analyzer\n .command(\"callers <qualified-name>\")\n .description(\"Query for callers of a specific function or symbol\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--depth <n>\", \"Maximum depth for call graph traversal (default: 3, max: 10)\", \"3\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer callers com.example.Service.handleRequest\n $ dr analyzer callers com.example.Service.handleRequest --depth 5\n $ dr analyzer callers com.example.Service.handleRequest --json`\n )\n .action(async (qualifiedName, options) => {\n // Merge global --json flag if local one isn't set\n const jsonMode = options.json ?? program.opts().json;\n try {\n // Validate depth\n const depth = parseInt(options.depth, 10);\n if (isNaN(depth) || depth < 1) {\n throw new CLIError(\n \"Invalid --depth value: must be a positive integer\",\n ErrorCategory.USER\n );\n }\n\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Load model to get codebase root\n const model = await Model.load(projectRoot);\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Query for callers\n const callers = await backend.callers(projectRoot, qualifiedName, depth, { codebaseRoot: model.codebaseRoot });\n\n // JSON output\n if (jsonMode) {\n console.log(JSON.stringify(callers, null, 2));\n return;\n }\n\n // Table output\n if (callers.length === 0) {\n console.log(ansis.yellow(`No callers found for ${qualifiedName}`));\n return;\n }\n\n console.log(\"\");\n console.log(ansis.bold(`Callers of ${ansis.cyan(qualifiedName)} (${callers.length} found):`));\n console.log(ansis.dim(\"\u2500\".repeat(100)));\n\n // Print each caller\n for (const caller of callers) {\n console.log(` ${ansis.bold(caller.qualified_name)}`);\n console.log(` File: ${caller.source_file}`);\n console.log(` Symbol: ${caller.source_symbol}`);\n console.log(` Depth: ${caller.depth}`);\n console.log(` Edge: ${caller.edge_type}`);\n console.log(\"\");\n }\n\n console.log(ansis.dim(`Total: ${callers.length} caller(s)`));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Callees subcommand - query for callees of a specific symbol\n */\n analyzer\n .command(\"callees <qualified-name>\")\n .description(\"Query for callees of a specific function or symbol\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--depth <n>\", \"Maximum depth for call graph traversal (default: 3, max: 10)\", \"3\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer callees com.example.Service.handleRequest\n $ dr analyzer callees com.example.Service.handleRequest --depth 5\n $ dr analyzer callees com.example.Service.handleRequest --json`\n )\n .action(async (qualifiedName, options) => {\n // Merge global --json flag if local one isn't set\n const jsonMode = options.json ?? program.opts().json;\n try {\n // Validate depth\n const depth = parseInt(options.depth, 10);\n if (isNaN(depth) || depth < 1) {\n throw new CLIError(\n \"Invalid --depth value: must be a positive integer\",\n ErrorCategory.USER\n );\n }\n\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Load model to get codebase root\n const model = await Model.load(projectRoot);\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Query for callees\n const callees = await backend.callees(projectRoot, qualifiedName, depth, { codebaseRoot: model.codebaseRoot });\n\n // JSON output\n if (jsonMode) {\n console.log(JSON.stringify(callees, null, 2));\n return;\n }\n\n // Table output\n if (callees.length === 0) {\n console.log(ansis.yellow(`No callees found for ${qualifiedName}`));\n return;\n }\n\n console.log(\"\");\n console.log(ansis.bold(`Callees of ${ansis.cyan(qualifiedName)} (${callees.length} found):`));\n console.log(ansis.dim(\"\u2500\".repeat(100)));\n\n // Print each callee\n for (const callee of callees) {\n console.log(` ${ansis.bold(callee.qualified_name)}`);\n console.log(` File: ${callee.source_file}`);\n console.log(` Symbol: ${callee.source_symbol}`);\n console.log(` Depth: ${callee.depth}`);\n console.log(` Edge: ${callee.edge_type}`);\n console.log(\"\");\n }\n\n console.log(ansis.dim(`Total: ${callees.length} callee(s)`));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Query subcommand - execute a raw query against the analyzer's graph\n * Documented as an advanced escape hatch for graph queries (not recommended for scripting)\n */\n analyzer\n .command(\"query <cypher>\")\n .description(\"Execute a raw Cypher query against the analyzer graph (advanced escape hatch)\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--json\", \"Output as JSON (default format for query results)\")\n .addHelpText(\n \"before\",\n `Advanced Escape Hatch: This command directly executes graph queries without validation or wrapping.\nUse for advanced analysis when standard commands don't meet your needs.\\n`\n )\n .addHelpText(\n \"after\",\n `\nQuery syntax depends on the analyzer backend (e.g., Cypher for graph analyzers).\nResults are always output as JSON.\n\nExamples:\n $ dr analyzer query \"MATCH (n) RETURN n LIMIT 10\"\n $ dr analyzer query \"MATCH (n:Service) RETURN n.name\"\n $ dr analyzer query \"MATCH (n) RETURN n LIMIT 10\" --json`\n )\n .action(async (cypher, options) => {\n try {\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Load model to get codebase root\n const model = await Model.load(projectRoot);\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Execute query\n const result = await backend.query(projectRoot, cypher, { codebaseRoot: model.codebaseRoot });\n\n // Output format: JSON is the only reasonable format for arbitrary query results\n // The --json flag is accepted for consistency, but JSON is always the output format\n // (the flag currently has no effect as all query output is JSON)\n if (options.json === false) {\n // Explicit no-op: --json flag or its absence doesn't change behavior\n // Query results are always output as JSON regardless of flag\n }\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Verify subcommand - verify that graph-discovered routes align with model endpoints\n */\n analyzer\n .command(\"verify\")\n .description(\"Verify that graph-discovered routes align with model endpoints\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--layer <layer>\", \"Layer(s) to verify (can be used multiple times)\", (value, previous: string[] | undefined) => {\n return previous ? [...previous, value] : [value];\n })\n .option(\"--json\", \"Output as JSON\")\n .option(\"--format <format>\", \"Output format: text, json, markdown (default: text)\")\n .option(\"--output <path>\", \"Write report to file\")\n .addHelpText(\n \"after\",\n `\nExamples:\n $ dr analyzer verify # Verify api layer (default)\n $ dr analyzer verify --layer api # Explicitly specify api layer\n $ dr analyzer verify --json # Output as JSON to stdout\n $ dr analyzer verify --format markdown # Output as Markdown to stdout\n $ dr analyzer verify --output report.json # Save report to file (format inferred as JSON)\n $ dr analyzer verify --output report.md # Save report as Markdown`\n )\n .action(async (options) => {\n // Merge global --json flag if local one isn't set\n const jsonMode = options.json ?? program.opts().json;\n try {\n // Determine output format from --json flag, --format flag, or --output file extension\n let format: \"text\" | \"json\" | \"markdown\" = \"text\";\n if (jsonMode) {\n // Warn if both --json and --format are provided\n if (options.format) {\n console.warn(ansis.yellow(`\u26A0 Both --json and --format \"${options.format}\" were provided. Using --json format (--format is ignored).`));\n }\n format = \"json\";\n } else if (options.format) {\n const validFormats = [\"text\", \"json\", \"markdown\"];\n if (!validFormats.includes(options.format)) {\n throw new CLIError(\n `Invalid format: \"${options.format}\". Valid values are: ${validFormats.join(\", \")}.`,\n ErrorCategory.USER\n );\n }\n format = options.format as \"text\" | \"json\" | \"markdown\";\n } else 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 } else if (ext) {\n // Warn if file has unrecognized extension\n console.warn(ansis.yellow(`\u26A0 Unrecognized file extension \"${ext}\" in --output. Using text format by default.`));\n }\n }\n\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n // Validate layers - only api is supported in v1\n const requestedLayers = options.layer || [\"api\"];\n const apiLayers = requestedLayers.filter((layer: string) => layer === \"api\");\n const nonApiLayers = requestedLayers.filter((layer: string) => layer !== \"api\");\n\n // Report non-api layers as not available\n for (const layer of nonApiLayers) {\n console.log(ansis.dim(`No verification available for layer '${layer}'`));\n }\n\n // If no api layers to verify, exit cleanly\n if (apiLayers.length === 0) {\n return;\n }\n\n // Resolve analyzer name\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\n \"No analyzer selected. Run `dr analyzer discover` first.\",\n ErrorCategory.USER\n );\n }\n analyzerName = session.active_analyzer;\n }\n\n // Get analyzer\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n\n if (!backend) {\n throw new CLIError(\n `Analyzer not found: ${analyzerName}`,\n ErrorCategory.NOT_FOUND\n );\n }\n\n // Load model to get codebase root\n const model = await Model.load(projectRoot);\n\n // Check if project is indexed\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\n \"Project not indexed\",\n ErrorCategory.USER,\n [\"Run `dr analyzer index` first\"]\n );\n }\n\n // Execute verification with changeset awareness enabled by default\n const report = await backend.verify(projectRoot, {\n layers: apiLayers,\n changesetAware: true,\n codebaseRoot: model.codebaseRoot,\n });\n\n const formatted = formatVerifyReport(report, { format });\n\n // Write to file if --output specified\n if (options.output) {\n const outputPath = path.resolve(options.output);\n await fs.writeFile(outputPath, formatted, \"utf-8\");\n console.log(ansis.green(`\u2713 Report written to ${outputPath}`));\n return;\n }\n\n // Print to stdout\n console.log(formatted);\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n\n /**\n * Classify subcommand - Tier-0 classification of the indexed project's symbols\n */\n analyzer\n .command(\"classify\")\n .description(\"Classify the indexed project's symbols into model layers and types (Tier 0: rules only)\")\n .option(\"--name <n>\", \"Analyzer name (defaults to active from session.json)\")\n .option(\"--tier0-only\", \"Apply only the analyzer's Tier-0 rules: no model calls, no network (required for now)\")\n .option(\"--label <labels>\", \"Comma-separated analyzer labels to classify (default: Class, Interface, Function, Method, Module, Route and every label a rule names)\")\n .option(\"--file <glob>\", \"Only symbols in files matching this glob\")\n .option(\"--exclude <regex>\", \"Also leave out files matching this regular expression (build and vendored paths always are)\")\n .option(\"--limit <n>\", \"Stop after this many symbols\")\n .option(\"--cards\", \"Include each symbol's full card (source and graph neighbourhood) in JSON output\")\n .option(\"--output <file>\", \"Write the JSON report to a file\")\n .option(\"--json\", \"Output as JSON\")\n .addHelpText(\n \"after\",\n `\nTier 0 is the first step of the classification cascade (docs/analyzers/CASCADE_DESIGN.md):\nthe analyzer's rules decide a symbol's layer and type, reject it as not a model element,\nor narrow its choices for a later tier. Symbols no rule covers are reported as undecided.\nNothing is written to the model.\n\nExamples:\n $ dr analyzer classify --tier0-only\n $ dr analyzer classify --tier0-only --json > tier0.json\n $ dr analyzer classify --tier0-only --label Class,Method --file \"src/main/**\"\n $ dr analyzer classify --tier0-only --cards --output tier0-cards.json`\n )\n .action(async (options) => {\n const jsonMode = options.json ?? program.opts().json;\n try {\n if (!options.tier0Only) {\n throw new CLIError(\n \"Only Tier-0 classification is available so far: pass --tier0-only\",\n ErrorCategory.USER,\n [\"Model-backed classification (Tier 1) needs the per-project opt-in and is not built yet\"]\n );\n }\n let exclude: RegExp | undefined;\n if (options.exclude !== undefined) {\n try {\n exclude = new RegExp(String(options.exclude));\n } catch (e) {\n throw new CLIError(`Invalid --exclude regular expression: ${e instanceof Error ? e.message : String(e)}`, ErrorCategory.USER);\n }\n }\n let limit: number | undefined;\n if (options.limit !== undefined) {\n limit = Number(options.limit);\n if (!Number.isInteger(limit) || limit < 1) {\n throw new CLIError(`--limit must be a positive integer, got '${options.limit}'`, ErrorCategory.USER);\n }\n }\n const labels = options.label\n ? String(options.label).split(\",\").map((l: string) => l.trim()).filter(Boolean)\n : undefined;\n if (options.cards && !jsonMode && !options.output) {\n console.error(ansis.yellow(\"--cards only affects JSON output: add --json or --output <file>\"));\n }\n\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n throw new ModelNotFoundError();\n }\n\n let analyzerName = options.name;\n if (!analyzerName) {\n const session = await readSession(projectRoot);\n if (!session) {\n throw new CLIError(\"No analyzer selected. Run `dr analyzer discover` first.\", ErrorCategory.USER);\n }\n analyzerName = session.active_analyzer;\n }\n\n const registry = AnalyzerRegistry.getInstance();\n await registry.initialize();\n const backend = await registry.getAnalyzer(analyzerName);\n if (!backend) {\n throw new CLIError(`Analyzer not found: ${analyzerName}`, ErrorCategory.NOT_FOUND);\n }\n if (!backend.classify) {\n throw new CLIError(`The ${analyzerName} analyzer does not support classification`, ErrorCategory.USER);\n }\n\n const indexMeta = await readIndexMeta(projectRoot, analyzerName);\n if (!indexMeta) {\n throw new CLIError(\"Project not indexed\", ErrorCategory.USER, [\"Run `dr analyzer index` first\"]);\n }\n\n const model = await Model.load(projectRoot);\n const showProgress = !jsonMode && !options.output && process.stderr.isTTY;\n const report = await backend.classify(projectRoot, {\n codebaseRoot: model.codebaseRoot,\n labels,\n filePattern: options.file,\n exclude,\n limit,\n includeCards: !!options.cards,\n onProgress: showProgress\n ? (done, total) => {\n if (done % 50 === 0 || done === total) process.stderr.write(`\\r ${done}/${total} symbols`);\n if (done === total) process.stderr.write(\"\\n\");\n }\n : undefined,\n });\n\n if (options.output) {\n const outputPath = path.resolve(options.output);\n await fs.writeFile(outputPath, JSON.stringify(report, null, 2) + \"\\n\", \"utf-8\");\n if (!jsonMode) console.log(ansis.green(`\u2713 Report written to ${outputPath}`));\n }\n if (jsonMode) {\n console.log(JSON.stringify(report, null, 2));\n return;\n }\n\n const { summary } = report;\n const pct = (n: number) => (summary.cards ? `${((100 * n) / summary.cards).toFixed(0)}%` : \"0%\");\n console.log(\"\");\n console.log(ansis.bold(`Tier-0 classification: ${summary.cards} symbols, ${report.rules} rules`));\n console.log(ansis.dim(\"\u2500\".repeat(60)));\n console.log(` ${ansis.green(\"decided\")} ${String(summary.decided).padStart(6)} ${pct(summary.decided)}`);\n console.log(` ${ansis.yellow(\"rejected\")} ${String(summary.rejected).padStart(6)} ${pct(summary.rejected)} (not model elements)`);\n console.log(` ${ansis.cyan(\"narrowed\")} ${String(summary.narrowed).padStart(6)} ${pct(summary.narrowed)} (choices restricted for Tier 1)`);\n console.log(` ${ansis.dim(\"undecided\")} ${String(summary.undecided).padStart(6)} ${pct(summary.undecided)}`);\n if (summary.no_source) {\n console.log(ansis.yellow(` ${summary.no_source} symbol(s) had no source, so rules that read the declaration could not apply`));\n }\n const targets = Object.entries(summary.by_target).sort((a, b) => b[1] - a[1]);\n if (targets.length) {\n console.log(\"\");\n console.log(ansis.bold(\"Decided, by type:\"));\n for (const [target, n] of targets) console.log(` ${target.padEnd(40)} ${String(n).padStart(6)}`);\n }\n const rules = Object.entries(summary.by_rule).sort((a, b) => b[1] - a[1]);\n if (rules.length) {\n console.log(\"\");\n console.log(ansis.bold(\"Matches, by rule:\"));\n for (const [rule, n] of rules) console.log(` ${rule.padEnd(40)} ${String(n).padStart(6)}`);\n }\n console.log(ansis.dim(\"\u2500\".repeat(60)));\n console.log(ansis.dim(\"Per-symbol outcomes: --json or --output <file>\"));\n console.log(\"\");\n } catch (error) {\n if (error instanceof CLIError || error instanceof ModelNotFoundError) throw error;\n const cliError = new CLIError(\n error instanceof Error ? error.message : String(error),\n categorizeError(error)\n );\n if (error instanceof Error) {\n cliError.cause = error;\n }\n throw cliError;\n }\n });\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["analyzerOptions", "installed", "discoveryResult", "path"]
7
7
  }
@@ -12,7 +12,7 @@ async function auditCommand(options) {
12
12
  const validAuditTypes = ["relationships", "nodes", "all"];
13
13
  if (options.type && !validAuditTypes.includes(options.type))
14
14
  throw new CLIError(`Invalid audit type: "${options.type}". Valid values are: ${validAuditTypes.join(", ")}.`);
15
- const auditType = options.type ?? "relationships";
15
+ const auditType = options.type ?? "relationships", projectRoot = options.projectRoot ?? process.cwd();
16
16
  let format = "text";
17
17
  if (options.format)
18
18
  format = options.format;
@@ -25,7 +25,7 @@ async function auditCommand(options) {
25
25
  const report = await new ModelNodeAuditOrchestrator().runAudit({
26
26
  layer: options.layer,
27
27
  verbose: options.verbose,
28
- projectRoot: process.cwd()
28
+ projectRoot
29
29
  });
30
30
  output = formatNodeAuditReport(report, { format, verbose: options.verbose });
31
31
  } else if (auditType === "all") {
@@ -34,12 +34,12 @@ async function auditCommand(options) {
34
34
  layer: options.layer,
35
35
  verbose: options.verbose,
36
36
  debug: options.debug,
37
- projectRoot: process.cwd()
37
+ projectRoot
38
38
  }),
39
39
  new ModelNodeAuditOrchestrator().runAudit({
40
40
  layer: options.layer,
41
41
  verbose: options.verbose,
42
- projectRoot: process.cwd()
42
+ projectRoot
43
43
  })
44
44
  ]);
45
45
  let relOutput, nodeOutput;
@@ -57,7 +57,7 @@ async function auditCommand(options) {
57
57
  layer: options.layer,
58
58
  verbose: options.verbose,
59
59
  debug: options.debug,
60
- projectRoot: process.cwd()
60
+ projectRoot
61
61
  });
62
62
  if (output = formatAuditReport(report, { format, verbose: options.verbose }), options.saveSnapshot) {
63
63
  options.debug && console.log(ansis.dim("Saving audit snapshot..."));
@@ -66,7 +66,7 @@ async function auditCommand(options) {
66
66
  }
67
67
  }
68
68
  if (options.output) {
69
- const outputPath = path.resolve(process.cwd(), options.output), outputDir = path.dirname(outputPath);
69
+ const outputPath = path.resolve(projectRoot, options.output), outputDir = path.dirname(outputPath);
70
70
  await ensureDir(outputDir), await writeFile(outputPath, output), console.log(ansis.green(`\u2713 Audit report written to ${options.output}`));
71
71
  } else
72
72
  console.log(output);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/audit.ts"],
4
- "sourcesContent": ["/**\n * Audit command - Analyze relationship coverage, gaps, duplicates, and balance\n */\n\nimport ansis from \"ansis\";\nimport { writeFile, ensureDir } from \"../utils/file-io.js\";\nimport { getErrorMessage, CLIError } from \"../utils/errors.js\";\nimport {\n formatAuditReport,\n formatNodeAuditReport,\n AuditReportFormat,\n} from \"../export/audit-formatters.js\";\nimport { SnapshotStorage } from \"../audit/snapshot-storage.js\";\nimport { ModelAuditOrchestrator } from \"../audit/relationships/model/orchestrator.js\";\nimport { ModelNodeAuditOrchestrator } from \"../audit/nodes/model/orchestrator.js\";\nimport { formatDate } from \"../utils/date-utils.js\";\nimport path from \"path\";\n\nexport type AuditType = \"relationships\" | \"nodes\" | \"all\";\n\nexport interface AuditOptions {\n layer?: string;\n type?: AuditType;\n format?: AuditReportFormat;\n output?: string;\n verbose?: boolean;\n debug?: boolean;\n saveSnapshot?: boolean;\n}\n\n/**\n * Run the audit command\n */\nexport async function auditCommand(options: AuditOptions): Promise<void> {\n try {\n const validAuditTypes: AuditType[] = [\"relationships\", \"nodes\", \"all\"];\n if (options.type && !validAuditTypes.includes(options.type)) {\n throw new CLIError(\n `Invalid audit type: \"${options.type}\". Valid values are: ${validAuditTypes.join(\", \")}.`\n );\n }\n const auditType: AuditType = options.type ?? \"relationships\";\n\n // Determine output format\n let format: AuditReportFormat = \"text\";\n if (options.format) {\n format = options.format;\n } else 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 let output: string;\n\n if (auditType === \"nodes\") {\n // Node type audit - analyzes element types in the model\n const orchestrator = new ModelNodeAuditOrchestrator();\n const report = await orchestrator.runAudit({\n layer: options.layer,\n verbose: options.verbose,\n projectRoot: process.cwd(),\n });\n\n output = formatNodeAuditReport(report, { format, verbose: options.verbose });\n } else if (auditType === \"all\") {\n // Combined audit - run both independently; one failing does not suppress the other\n const [relResult, nodeResult] = await Promise.allSettled([\n new ModelAuditOrchestrator().runAudit({\n layer: options.layer,\n verbose: options.verbose,\n debug: options.debug,\n projectRoot: process.cwd(),\n }),\n new ModelNodeAuditOrchestrator().runAudit({\n layer: options.layer,\n verbose: options.verbose,\n projectRoot: process.cwd(),\n }),\n ]);\n\n let relOutput: string | undefined;\n let nodeOutput: string | undefined;\n\n if (relResult.status === \"fulfilled\") {\n relOutput = formatAuditReport(relResult.value, { format, verbose: options.verbose });\n } else {\n console.error(ansis.red(`\u26A0\uFE0F Relationship audit failed: ${getErrorMessage(relResult.reason)}`));\n }\n if (nodeResult.status === \"fulfilled\") {\n nodeOutput = formatNodeAuditReport(nodeResult.value, { format, verbose: options.verbose });\n } else {\n console.error(ansis.red(`\u26A0\uFE0F Node audit failed: ${getErrorMessage(nodeResult.reason)}`));\n }\n\n if (!relOutput && !nodeOutput) {\n throw new CLIError(\"Both audit types failed. See errors above.\");\n }\n\n if (format === \"json\") {\n const merged: Record<string, unknown> = {};\n if (relOutput) merged.relationships = JSON.parse(relOutput);\n if (nodeOutput) merged.nodes = JSON.parse(nodeOutput);\n output = JSON.stringify(merged, null, 2);\n } else {\n output = [relOutput, nodeOutput].filter(Boolean).join(\"\\n\\n\");\n }\n } else {\n // Default: relationships audit - analyzes the project's actual relationship instances\n const orchestrator = new ModelAuditOrchestrator();\n const report = await orchestrator.runAudit({\n layer: options.layer,\n verbose: options.verbose,\n debug: options.debug,\n projectRoot: process.cwd(),\n });\n\n output = formatAuditReport(report, { format, verbose: options.verbose });\n\n // Save snapshot if requested (relationships audit only)\n if (options.saveSnapshot) {\n if (options.debug) {\n console.log(ansis.dim(\"Saving audit snapshot...\"));\n }\n\n const storage = new SnapshotStorage();\n const metadata = await storage.save(report);\n\n console.log(ansis.green(`\u2713 Snapshot saved: ${metadata.id}`));\n console.log(ansis.dim(` Timestamp: ${formatDate(metadata.timestamp)}`));\n }\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 await ensureDir(outputDir);\n await writeFile(outputPath, output);\n\n console.log(ansis.green(`\u2713 Audit report written to ${options.output}`));\n } else {\n console.log(output);\n }\n } catch (error) {\n const message = getErrorMessage(error);\n if (options.debug) {\n console.error(error);\n }\n throw new CLIError(`Audit failed: ${message}`);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Audit command - Analyze relationship coverage, gaps, duplicates, and balance\n */\n\nimport ansis from \"ansis\";\nimport { writeFile, ensureDir } from \"../utils/file-io.js\";\nimport { getErrorMessage, CLIError } from \"../utils/errors.js\";\nimport {\n formatAuditReport,\n formatNodeAuditReport,\n AuditReportFormat,\n} from \"../export/audit-formatters.js\";\nimport { SnapshotStorage } from \"../audit/snapshot-storage.js\";\nimport { ModelAuditOrchestrator } from \"../audit/relationships/model/orchestrator.js\";\nimport { ModelNodeAuditOrchestrator } from \"../audit/nodes/model/orchestrator.js\";\nimport { formatDate } from \"../utils/date-utils.js\";\nimport path from \"path\";\n\nexport type AuditType = \"relationships\" | \"nodes\" | \"all\";\n\nexport interface AuditOptions {\n layer?: string;\n type?: AuditType;\n format?: AuditReportFormat;\n output?: string;\n verbose?: boolean;\n debug?: boolean;\n saveSnapshot?: boolean;\n projectRoot?: string;\n}\n\n/**\n * Run the audit command\n */\nexport async function auditCommand(options: AuditOptions): Promise<void> {\n try {\n const validAuditTypes: AuditType[] = [\"relationships\", \"nodes\", \"all\"];\n if (options.type && !validAuditTypes.includes(options.type)) {\n throw new CLIError(\n `Invalid audit type: \"${options.type}\". Valid values are: ${validAuditTypes.join(\", \")}.`\n );\n }\n const auditType: AuditType = options.type ?? \"relationships\";\n const projectRoot = options.projectRoot ?? process.cwd();\n\n // Determine output format\n let format: AuditReportFormat = \"text\";\n if (options.format) {\n format = options.format;\n } else 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 let output: string;\n\n if (auditType === \"nodes\") {\n // Node type audit - analyzes element types in the model\n const orchestrator = new ModelNodeAuditOrchestrator();\n const report = await orchestrator.runAudit({\n layer: options.layer,\n verbose: options.verbose,\n projectRoot,\n });\n\n output = formatNodeAuditReport(report, { format, verbose: options.verbose });\n } else if (auditType === \"all\") {\n // Combined audit - run both independently; one failing does not suppress the other\n const [relResult, nodeResult] = await Promise.allSettled([\n new ModelAuditOrchestrator().runAudit({\n layer: options.layer,\n verbose: options.verbose,\n debug: options.debug,\n projectRoot,\n }),\n new ModelNodeAuditOrchestrator().runAudit({\n layer: options.layer,\n verbose: options.verbose,\n projectRoot,\n }),\n ]);\n\n let relOutput: string | undefined;\n let nodeOutput: string | undefined;\n\n if (relResult.status === \"fulfilled\") {\n relOutput = formatAuditReport(relResult.value, { format, verbose: options.verbose });\n } else {\n console.error(ansis.red(`\u26A0\uFE0F Relationship audit failed: ${getErrorMessage(relResult.reason)}`));\n }\n if (nodeResult.status === \"fulfilled\") {\n nodeOutput = formatNodeAuditReport(nodeResult.value, { format, verbose: options.verbose });\n } else {\n console.error(ansis.red(`\u26A0\uFE0F Node audit failed: ${getErrorMessage(nodeResult.reason)}`));\n }\n\n if (!relOutput && !nodeOutput) {\n throw new CLIError(\"Both audit types failed. See errors above.\");\n }\n\n if (format === \"json\") {\n const merged: Record<string, unknown> = {};\n if (relOutput) merged.relationships = JSON.parse(relOutput);\n if (nodeOutput) merged.nodes = JSON.parse(nodeOutput);\n output = JSON.stringify(merged, null, 2);\n } else {\n output = [relOutput, nodeOutput].filter(Boolean).join(\"\\n\\n\");\n }\n } else {\n // Default: relationships audit - analyzes the project's actual relationship instances\n const orchestrator = new ModelAuditOrchestrator();\n const report = await orchestrator.runAudit({\n layer: options.layer,\n verbose: options.verbose,\n debug: options.debug,\n projectRoot,\n });\n\n output = formatAuditReport(report, { format, verbose: options.verbose });\n\n // Save snapshot if requested (relationships audit only)\n if (options.saveSnapshot) {\n if (options.debug) {\n console.log(ansis.dim(\"Saving audit snapshot...\"));\n }\n\n const storage = new SnapshotStorage();\n const metadata = await storage.save(report);\n\n console.log(ansis.green(`\u2713 Snapshot saved: ${metadata.id}`));\n console.log(ansis.dim(` Timestamp: ${formatDate(metadata.timestamp)}`));\n }\n }\n\n // Write to file or stdout\n if (options.output) {\n const outputPath = path.resolve(projectRoot, options.output);\n const outputDir = path.dirname(outputPath);\n\n await ensureDir(outputDir);\n await writeFile(outputPath, output);\n\n console.log(ansis.green(`\u2713 Audit report written to ${options.output}`));\n } else {\n console.log(output);\n }\n } catch (error) {\n const message = getErrorMessage(error);\n if (options.debug) {\n console.error(error);\n }\n throw new CLIError(`Audit failed: ${message}`);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,55 @@
1
+ import ansis from "ansis";
2
+ import { Model } from "../core/model.js";
3
+ import { StagingAreaManager } from "../core/staging-area.js";
4
+ import { verifyChangesetInModel } from "../core/changeset-verify.js";
5
+ import { getErrorMessage } from "../utils/errors.js";
6
+ import { isJson } from "../utils/globals.js";
7
+ async function changesetVerifyCommand(planned, options = {}) {
8
+ const json = options.json === !0 || isJson(), fail = (message, hint) => {
9
+ json ? console.log(JSON.stringify({ status: "error", code: 1, message })) : (console.error(ansis.red(`Error: ${message}`)), hint && console.error(ansis.dim(hint))), process.exit(1);
10
+ };
11
+ try {
12
+ options.against && options.base && fail("Pass either --against <changeset> or --base, not both"), !options.against && !options.base && fail("Nothing to verify against", "Use --against <changeset> to compare with an as-built changeset, or --base to compare with the base model");
13
+ const model = await Model.load(options.model, { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), load = async (name, role) => {
14
+ const changeset = await manager.load(name);
15
+ return changeset || fail(`${role} changeset '${name}' not found`, "Run 'dr changeset list' to see changesets");
16
+ }, plannedName = planned ?? await manager.getActiveId();
17
+ if (!plannedName)
18
+ return fail("No changeset named and none is active", "Pass the planned changeset's name or ID");
19
+ const plannedChangeset = await load(plannedName, "Planned"), asBuilt = options.against ? await load(options.against, "As-built") : void 0, report = await verifyChangesetInModel(model, {
20
+ planned: plannedChangeset,
21
+ against: asBuilt ? { changeset: asBuilt } : { base: !0 },
22
+ matchBySource: options.matchBySource
23
+ });
24
+ console.log(json ? JSON.stringify(report, null, 2) : formatVerifyReport(report));
25
+ } catch (error) {
26
+ fail(getErrorMessage(error));
27
+ }
28
+ }
29
+ const rel = (r) => `${r.source} --${r.predicate}--> ${r.target}`, value = (v) => v === void 0 ? "(none)" : JSON.stringify(v);
30
+ function formatVerifyReport(report) {
31
+ const lines = [], verdictColor = report.verdict === "match" ? ansis.green : report.verdict === "probable-match" ? ansis.cyan : report.verdict === "diverges" ? ansis.yellow : report.verdict === "incomplete" ? ansis.red : ansis.dim;
32
+ lines.push(ansis.bold(`Verify: ${report.planned.label} vs ${report.against.label}`)), lines.push(verdictColor(`${report.verdict}: ${report.verdictText}`));
33
+ const e = report.summary.elements, r = report.summary.relationships;
34
+ lines.push(ansis.dim(`Elements: ${e.planned} planned, ${e.matched} matched (${e.divergent} with differences), ${e.missing} missing, ${e.unplanned} unplanned, ${e.deletionsNotDone} deletions not done (${e.probable} probable)`)), lines.push(ansis.dim(`Relationships: ${r.planned} planned, ${r.matched} matched (${r.divergent} with differences), ${r.missing} missing, ${r.unplanned} unplanned, ${r.deletionsNotDone} deletions not done (${r.probable} probable)`));
35
+ const section = (title, items) => {
36
+ if (items.length !== 0) {
37
+ lines.push("", ansis.bold(title));
38
+ for (const item of items)
39
+ lines.push(` ${item}`);
40
+ }
41
+ }, probable = (m) => m.match === "probable" ? ansis.cyan(` [probable: ${m.reason}]`) : "";
42
+ return section("Missing elements (planned, not built)", report.elements.missing.map((m) => `${ansis.red("-")} ${m.planned} (${m.op}): ${m.reason}` + (m.candidates ? `
43
+ candidates: ${m.candidates.join(", ")}` : "") + (m.fields ? m.fields.map((f) => `
44
+ ${f.field}: planned ${value(f.planned)}, built ${value(f.built)}`).join("") : ""))), section("Divergent elements", report.elements.divergent.map((d) => `${ansis.yellow("~")} ${d.planned}${d.built !== d.planned ? ` \u2192 ${d.built}` : ""}${probable(d)}` + d.fields.map((f) => `
45
+ ${f.field}: planned ${value(f.planned)}, built ${value(f.built)}`).join(""))), section("Planned deletions that still exist", report.elements.deletionsNotDone.map((d) => `${ansis.red("!")} ${d.built}`)), section("Unplanned elements (built, not planned)", report.elements.unplanned.map((u) => `${ansis.yellow("+")} ${u.id} (${u.change})`)), section("Matched elements", report.elements.matched.map((m) => `${ansis.green("\u2713")} ${m.planned}${m.built !== m.planned ? ` \u2192 ${m.built}` : ""} (${m.op})${probable(m)}` + (m.lifecycle ?? []).map((f) => ansis.dim(`
46
+ ${f.field}: ${value(f.planned)} \u2192 ${value(f.built)} (lifecycle)`)).join(""))), section("Missing relationships", report.relationships.missing.map((m) => `${ansis.red("-")} ${rel(m.planned)}: ${m.reason}` + (m.candidates ? `
47
+ candidates: ${m.candidates.map(rel).join(", ")}` : ""))), section("Divergent relationships", report.relationships.divergent.map((d) => `${ansis.yellow("~")} ${rel(d.planned)} built as ${rel(d.built)}${probable(d)}` + d.fields.map((f) => `
48
+ ${f.field}: planned ${value(f.planned)}, built ${value(f.built)}`).join(""))), section("Planned relationship deletions that still exist", report.relationships.deletionsNotDone.map((d) => `${ansis.red("!")} ${rel(d.built)}`)), section("Unplanned relationships", report.relationships.unplanned.map((u) => `${ansis.yellow("+")} ${rel(u)} (${u.change})`)), section("Matched relationships", report.relationships.matched.map((m) => `${ansis.green("\u2713")} ${rel(m.built)} (${m.op})${probable(m)}`)), section("Notes", report.notes.map((n) => ansis.dim(n))), lines.join(`
49
+ `);
50
+ }
51
+ export {
52
+ changesetVerifyCommand,
53
+ formatVerifyReport
54
+ };
55
+ //# sourceMappingURL=changeset-verify.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/commands/changeset-verify.ts"],
4
+ "sourcesContent": ["/**\n * dr changeset verify \u2014 compare a planned changeset with what was built (another changeset, or the\n * base model). The same comparison as the `changeset_verify` MCP tool; see\n * `cli/src/core/changeset-verify.ts`.\n */\n\nimport ansis from \"ansis\";\nimport { Model } from \"../core/model.js\";\nimport { StagingAreaManager } from \"../core/staging-area.js\";\nimport { verifyChangesetInModel, type VerifyReport } from \"../core/changeset-verify.js\";\nimport type { Changeset } from \"../core/changeset.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { isJson } from \"../utils/globals.js\";\n\nexport interface ChangesetVerifyOptions {\n model?: string;\n against?: string;\n base?: boolean;\n json?: boolean;\n matchBySource?: boolean;\n}\n\nexport async function changesetVerifyCommand(\n planned: string | undefined,\n options: ChangesetVerifyOptions = {}\n): Promise<void> {\n const json = options.json === true || isJson();\n const fail = (message: string, hint?: string): never => {\n if (json) {\n console.log(JSON.stringify({ status: \"error\", code: 1, message }));\n } else {\n console.error(ansis.red(`Error: ${message}`));\n if (hint) console.error(ansis.dim(hint));\n }\n process.exit(1);\n };\n\n try {\n if (options.against && options.base) {\n fail(\"Pass either --against <changeset> or --base, not both\");\n }\n if (!options.against && !options.base) {\n fail(\n \"Nothing to verify against\",\n \"Use --against <changeset> to compare with an as-built changeset, or --base to compare with the base model\"\n );\n }\n\n const model = await Model.load(options.model, { lazyLoad: false });\n const manager = new StagingAreaManager(model.rootPath, model);\n const load = async (name: string, role: string): Promise<Changeset> => {\n const changeset = await manager.load(name);\n if (!changeset) return fail(`${role} changeset '${name}' not found`, \"Run 'dr changeset list' to see changesets\");\n return changeset;\n };\n\n const plannedName = planned ?? (await manager.getActiveId());\n if (!plannedName) {\n return fail(\"No changeset named and none is active\", \"Pass the planned changeset's name or ID\");\n }\n const plannedChangeset = await load(plannedName, \"Planned\");\n const asBuilt = options.against ? await load(options.against, \"As-built\") : undefined;\n\n const report = await verifyChangesetInModel(model, {\n planned: plannedChangeset,\n against: asBuilt ? { changeset: asBuilt } : { base: true },\n matchBySource: options.matchBySource,\n });\n\n if (json) {\n console.log(JSON.stringify(report, null, 2));\n } else {\n console.log(formatVerifyReport(report));\n }\n } catch (error) {\n fail(getErrorMessage(error));\n }\n}\n\nconst rel = (r: { source: string; predicate: string; target: string }) => `${r.source} --${r.predicate}--> ${r.target}`;\nconst value = (v: unknown) => (v === undefined ? \"(none)\" : JSON.stringify(v));\n\n/** Human-readable rendering of a verify report. */\nexport function formatVerifyReport(report: VerifyReport): string {\n const lines: string[] = [];\n const verdictColor =\n report.verdict === \"match\"\n ? ansis.green\n : report.verdict === \"probable-match\"\n ? ansis.cyan\n : report.verdict === \"diverges\"\n ? ansis.yellow\n : report.verdict === \"incomplete\"\n ? ansis.red\n : ansis.dim;\n\n lines.push(ansis.bold(`Verify: ${report.planned.label} vs ${report.against.label}`));\n lines.push(verdictColor(`${report.verdict}: ${report.verdictText}`));\n const e = report.summary.elements;\n const r = report.summary.relationships;\n lines.push(\n ansis.dim(\n `Elements: ${e.planned} planned, ${e.matched} matched (${e.divergent} with differences), ${e.missing} missing, ` +\n `${e.unplanned} unplanned, ${e.deletionsNotDone} deletions not done (${e.probable} probable)`\n )\n );\n lines.push(\n ansis.dim(\n `Relationships: ${r.planned} planned, ${r.matched} matched (${r.divergent} with differences), ${r.missing} missing, ` +\n `${r.unplanned} unplanned, ${r.deletionsNotDone} deletions not done (${r.probable} probable)`\n )\n );\n\n const section = (title: string, items: string[]) => {\n if (items.length === 0) return;\n lines.push(\"\", ansis.bold(title));\n for (const item of items) lines.push(` ${item}`);\n };\n const probable = (m: { match: string; reason?: string }) => (m.match === \"probable\" ? ansis.cyan(` [probable: ${m.reason}]`) : \"\");\n\n section(\n \"Missing elements (planned, not built)\",\n report.elements.missing.map(\n (m) =>\n `${ansis.red(\"-\")} ${m.planned} (${m.op}): ${m.reason}` +\n (m.candidates ? `\\n candidates: ${m.candidates.join(\", \")}` : \"\") +\n (m.fields ? m.fields.map((f) => `\\n ${f.field}: planned ${value(f.planned)}, built ${value(f.built)}`).join(\"\") : \"\")\n )\n );\n section(\n \"Divergent elements\",\n report.elements.divergent.map(\n (d) =>\n `${ansis.yellow(\"~\")} ${d.planned}${d.built !== d.planned ? ` \u2192 ${d.built}` : \"\"}${probable(d)}` +\n d.fields.map((f) => `\\n ${f.field}: planned ${value(f.planned)}, built ${value(f.built)}`).join(\"\")\n )\n );\n section(\n \"Planned deletions that still exist\",\n report.elements.deletionsNotDone.map((d) => `${ansis.red(\"!\")} ${d.built}`)\n );\n section(\n \"Unplanned elements (built, not planned)\",\n report.elements.unplanned.map((u) => `${ansis.yellow(\"+\")} ${u.id} (${u.change})`)\n );\n section(\n \"Matched elements\",\n report.elements.matched.map(\n (m) =>\n `${ansis.green(\"\u2713\")} ${m.planned}${m.built !== m.planned ? ` \u2192 ${m.built}` : \"\"} (${m.op})${probable(m)}` +\n (m.lifecycle ?? []).map((f) => ansis.dim(`\\n ${f.field}: ${value(f.planned)} \u2192 ${value(f.built)} (lifecycle)`)).join(\"\")\n )\n );\n\n section(\n \"Missing relationships\",\n report.relationships.missing.map(\n (m) =>\n `${ansis.red(\"-\")} ${rel(m.planned)}: ${m.reason}` +\n (m.candidates ? `\\n candidates: ${m.candidates.map(rel).join(\", \")}` : \"\")\n )\n );\n section(\n \"Divergent relationships\",\n report.relationships.divergent.map(\n (d) =>\n `${ansis.yellow(\"~\")} ${rel(d.planned)} built as ${rel(d.built)}${probable(d)}` +\n d.fields.map((f) => `\\n ${f.field}: planned ${value(f.planned)}, built ${value(f.built)}`).join(\"\")\n )\n );\n section(\n \"Planned relationship deletions that still exist\",\n report.relationships.deletionsNotDone.map((d) => `${ansis.red(\"!\")} ${rel(d.built)}`)\n );\n section(\n \"Unplanned relationships\",\n report.relationships.unplanned.map((u) => `${ansis.yellow(\"+\")} ${rel(u)} (${u.change})`)\n );\n section(\n \"Matched relationships\",\n report.relationships.matched.map((m) => `${ansis.green(\"\u2713\")} ${rel(m.built)} (${m.op})${probable(m)}`)\n );\n\n section(\n \"Notes\",\n report.notes.map((n) => ansis.dim(n))\n );\n return lines.join(\"\\n\");\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }