@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
@@ -0,0 +1,107 @@
1
+ import { z } from "zod";
2
+ import { Element } from "../../core/element.js";
3
+ import { Layer } from "../../core/layer.js";
4
+ import { MutationHandler } from "../../core/mutation-handler.js";
5
+ import { getAllLayerIds, isValidLayer } from "../../generated/layer-registry.js";
6
+ import { getNodeTypesForLayer, isValidNodeType, normalizeNodeType } from "../../generated/node-types.js";
7
+ import { generateElementId, generateUUID } from "../../utils/id-generator.js";
8
+ import { buildSourceReference, validateSourceReferenceOptions } from "../../utils/source-reference.js";
9
+ import { schemaLookupHint } from "../../utils/error-hints.js";
10
+ import { SchemaValidator } from "../../validators/schema-validator.js";
11
+ import { CLIError, ErrorCategory, findSimilar, formatValidOptions } from "../../utils/errors.js";
12
+ import { jsonResult, loadModel, reloadModel, rootPathSchema, runTool } from "./shared.js";
13
+ const inputSchema = {
14
+ layer: z.string().describe("Canonical layer name (e.g. 'api', 'data-model')."),
15
+ type: z.string().describe("Element type within the layer (e.g. 'operation', 'entity')."),
16
+ name: z.string().describe("Human-readable element name; used to derive the element ID."),
17
+ description: z.string().optional(),
18
+ attributes: z.record(z.string(), z.unknown()).optional().describe("Type-specific attributes, validated against the element's spec schema."),
19
+ sourceFile: z.string().optional().describe("Source file path relative to the repository root."),
20
+ sourceSymbol: z.string().optional(),
21
+ sourceProvenance: z.enum(["extracted", "manual", "inferred", "generated"]).optional(),
22
+ sourceRepoRemote: z.string().optional(),
23
+ sourceRepoCommit: z.string().optional().describe("Full 40-character Git commit SHA."),
24
+ rootPath: rootPathSchema
25
+ };
26
+ async function modelAddHandler(args) {
27
+ return runTool(async () => {
28
+ if (!isValidLayer(args.layer)) {
29
+ const validLayers = getAllLayerIds(), similar = findSimilar(args.layer, validLayers, 3), suggestions = [`Use a valid layer name: ${formatValidOptions(validLayers)}`];
30
+ throw similar.length > 0 && suggestions.unshift(`Did you mean: ${similar.join(" or ")}?`), new CLIError(`Unknown layer "${args.layer}"`, ErrorCategory.USER, suggestions);
31
+ }
32
+ if (!isValidNodeType(args.layer, args.type)) {
33
+ const typeNames = getNodeTypesForLayer(args.layer).map((t) => t.type).sort(), similar = findSimilar(args.type, typeNames, 3), suggestions = [`Valid types for ${args.layer}: ${formatValidOptions(typeNames)}`];
34
+ throw similar.length > 0 && suggestions.unshift(`Did you mean: ${similar.join(" or ")}?`), new CLIError(`Invalid element type "${args.type}" for layer "${args.layer}"`, ErrorCategory.USER, suggestions);
35
+ }
36
+ const resolvedType = normalizeNodeType(args.layer, args.type), elementPath = generateElementId(args.layer, resolvedType, args.name), elementUUID = generateUUID();
37
+ if (!elementPath.split(".")[2])
38
+ throw new CLIError(`Cannot generate a valid element ID from name "${args.name}"`, ErrorCategory.USER, [
39
+ "Element names must contain at least one letter or digit"
40
+ ]);
41
+ validateSourceReferenceOptions(args, "mcp");
42
+ const model = await loadModel(args.rootPath), layerKnown = model.getLayerNames().includes(args.layer);
43
+ let layerObj = await model.getLayer(args.layer), isNewLayer = !1;
44
+ layerObj || (layerObj = new Layer(args.layer), isNewLayer = !0);
45
+ const now = (/* @__PURE__ */ new Date()).toISOString(), element = new Element({
46
+ id: elementUUID,
47
+ path: elementPath,
48
+ spec_node_id: `${args.layer}.${resolvedType}`,
49
+ layer_id: args.layer,
50
+ type: resolvedType,
51
+ name: args.name,
52
+ description: args.description,
53
+ attributes: args.attributes ?? {},
54
+ metadata: {
55
+ created_at: now,
56
+ updated_at: now,
57
+ version: 1
58
+ },
59
+ layer: args.layer
60
+ }), sourceRef = buildSourceReference(args);
61
+ sourceRef && element.setSourceReference(sourceRef);
62
+ {
63
+ const schemaValidator = new SchemaValidator(), tempLayer = new Layer(args.layer);
64
+ tempLayer.addElement(element);
65
+ const attrValidation = await schemaValidator.validateLayer(tempLayer);
66
+ if (!attrValidation.isValid()) {
67
+ const errorMessages = attrValidation.errors.map((e) => ` ${e.message}`).join(`
68
+ `);
69
+ throw new CLIError(`Element ${elementPath} has invalid attributes:
70
+ ${errorMessages}`, ErrorCategory.USER, [
71
+ schemaLookupHint("mcp", args.layer, resolvedType)
72
+ ]);
73
+ }
74
+ }
75
+ if (layerObj.getElement(elementPath))
76
+ throw new CLIError(`Element ${elementPath} already exists in ${args.layer} layer`, ErrorCategory.USER, [
77
+ 'Use "model_show" to view the existing element',
78
+ 'Use "model_update" to modify it',
79
+ 'Use "model_delete" to remove it first if you want to recreate it'
80
+ ]);
81
+ isNewLayer && model.addLayer(layerObj);
82
+ const mutationHandler = new MutationHandler(model, elementPath, args.layer);
83
+ await mutationHandler.executeAdd(element, (elem) => {
84
+ layerObj.addElement(elem);
85
+ });
86
+ const activeChangeset = await mutationHandler.getStagingManager().getActive(), staged = !!(activeChangeset && activeChangeset.status === "staged");
87
+ return staged && !layerKnown && await reloadModel(args.rootPath), jsonResult({
88
+ status: staged ? "staged" : "added",
89
+ changeset: staged ? activeChangeset.name : void 0,
90
+ id: elementPath,
91
+ layer: args.layer,
92
+ type: resolvedType,
93
+ name: args.name
94
+ });
95
+ });
96
+ }
97
+ const modelAddTool = {
98
+ name: "model_add",
99
+ description: "Add a new element to a layer, validated against its spec schema.",
100
+ inputSchema,
101
+ handler: modelAddHandler
102
+ };
103
+ export {
104
+ modelAddHandler,
105
+ modelAddTool
106
+ };
107
+ //# sourceMappingURL=model-add.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/tools/model-add.ts"],
4
+ "sourcesContent": ["/**\n * model_add \u2014 add an element to a layer. Mirrors `dr add`, operating through\n * the shared MutationHandler so staging and base-model persistence stay\n * consistent with the CLI.\n */\n\nimport { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { Element } from \"../../core/element.js\";\nimport { Layer } from \"../../core/layer.js\";\nimport { MutationHandler } from \"../../core/mutation-handler.js\";\nimport { getAllLayerIds, isValidLayer } from \"../../generated/layer-registry.js\";\nimport { getNodeTypesForLayer, isValidNodeType, normalizeNodeType } from \"../../generated/node-types.js\";\nimport { generateElementId, generateUUID } from \"../../utils/id-generator.js\";\nimport { buildSourceReference, validateSourceReferenceOptions } from \"../../utils/source-reference.js\";\nimport { schemaLookupHint } from \"../../utils/error-hints.js\";\nimport { SchemaValidator } from \"../../validators/schema-validator.js\";\nimport { CLIError, ErrorCategory, findSimilar, formatValidOptions } from \"../../utils/errors.js\";\nimport { jsonResult, loadModel, reloadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n layer: z.string().describe(\"Canonical layer name (e.g. 'api', 'data-model').\"),\n type: z.string().describe(\"Element type within the layer (e.g. 'operation', 'entity').\"),\n name: z.string().describe(\"Human-readable element name; used to derive the element ID.\"),\n description: z.string().optional(),\n attributes: z.record(z.string(), z.unknown()).optional().describe(\"Type-specific attributes, validated against the element's spec schema.\"),\n sourceFile: z.string().optional().describe(\"Source file path relative to the repository root.\"),\n sourceSymbol: z.string().optional(),\n sourceProvenance: z.enum([\"extracted\", \"manual\", \"inferred\", \"generated\"]).optional(),\n sourceRepoRemote: z.string().optional(),\n sourceRepoCommit: z.string().optional().describe(\"Full 40-character Git commit SHA.\"),\n rootPath: rootPathSchema,\n};\n\nexport type ModelAddArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function modelAddHandler(args: ModelAddArgs): Promise<CallToolResult> {\n return runTool(async () => {\n if (!isValidLayer(args.layer)) {\n const validLayers = getAllLayerIds();\n const similar = findSimilar(args.layer, validLayers, 3);\n const suggestions: string[] = [`Use a valid layer name: ${formatValidOptions(validLayers)}`];\n if (similar.length > 0) suggestions.unshift(`Did you mean: ${similar.join(\" or \")}?`);\n throw new CLIError(`Unknown layer \"${args.layer}\"`, ErrorCategory.USER, suggestions);\n }\n\n if (!isValidNodeType(args.layer, args.type)) {\n const validNodeTypes = getNodeTypesForLayer(args.layer);\n const typeNames = validNodeTypes.map((t) => t.type).sort();\n const similar = findSimilar(args.type, typeNames, 3);\n const suggestions: string[] = [`Valid types for ${args.layer}: ${formatValidOptions(typeNames)}`];\n if (similar.length > 0) suggestions.unshift(`Did you mean: ${similar.join(\" or \")}?`);\n throw new CLIError(`Invalid element type \"${args.type}\" for layer \"${args.layer}\"`, ErrorCategory.USER, suggestions);\n }\n\n const resolvedType = normalizeNodeType(args.layer, args.type);\n const elementPath = generateElementId(args.layer, resolvedType, args.name);\n const elementUUID = generateUUID();\n\n const slugPart = elementPath.split(\".\")[2];\n if (!slugPart) {\n throw new CLIError(`Cannot generate a valid element ID from name \"${args.name}\"`, ErrorCategory.USER, [\n \"Element names must contain at least one letter or digit\",\n ]);\n }\n\n validateSourceReferenceOptions(args, \"mcp\");\n\n const model = await loadModel(args.rootPath);\n\n // Inside a changeset getLayer() projects even a layer the model has no elements in, so ask the\n // model's layer list whether this layer is new to it.\n const layerKnown = model.getLayerNames().includes(args.layer);\n let layerObj = await model.getLayer(args.layer);\n let isNewLayer = false;\n if (!layerObj) {\n layerObj = new Layer(args.layer);\n isNewLayer = true;\n }\n\n const now = new Date().toISOString();\n const element = new Element({\n id: elementUUID,\n path: elementPath,\n spec_node_id: `${args.layer}.${resolvedType}`,\n layer_id: args.layer,\n type: resolvedType,\n name: args.name,\n description: args.description,\n attributes: args.attributes ?? {},\n metadata: {\n created_at: now,\n updated_at: now,\n version: 1,\n },\n layer: args.layer,\n });\n\n const sourceRef = buildSourceReference(args);\n if (sourceRef) {\n element.setSourceReference(sourceRef);\n }\n\n {\n const schemaValidator = new SchemaValidator();\n const tempLayer = new Layer(args.layer);\n tempLayer.addElement(element);\n const attrValidation = await schemaValidator.validateLayer(tempLayer);\n if (!attrValidation.isValid()) {\n const errorMessages = attrValidation.errors.map((e) => ` ${e.message}`).join(\"\\n\");\n throw new CLIError(`Element ${elementPath} has invalid attributes:\\n${errorMessages}`, ErrorCategory.USER, [\n schemaLookupHint(\"mcp\", args.layer, resolvedType),\n ]);\n }\n }\n\n if (layerObj.getElement(elementPath)) {\n throw new CLIError(`Element ${elementPath} already exists in ${args.layer} layer`, ErrorCategory.USER, [\n `Use \"model_show\" to view the existing element`,\n `Use \"model_update\" to modify it`,\n `Use \"model_delete\" to remove it first if you want to recreate it`,\n ]);\n }\n\n if (isNewLayer) {\n model.addLayer(layerObj);\n }\n\n const mutationHandler = new MutationHandler(model, elementPath, args.layer);\n await mutationHandler.executeAdd(element, (elem) => {\n layerObj!.addElement(elem);\n });\n\n const stagingManager = mutationHandler.getStagingManager();\n const activeChangeset = await stagingManager.getActive();\n const staged = !!(activeChangeset && activeChangeset.status === \"staged\");\n if (staged && !layerKnown) {\n // The cached model did not list this layer: reread it so every later tool call\n // (relationship_add, model_show, model_update, ...) sees the layer and the element.\n await reloadModel(args.rootPath);\n }\n\n return jsonResult({\n status: staged ? \"staged\" : \"added\",\n changeset: staged ? activeChangeset!.name : undefined,\n id: elementPath,\n layer: args.layer,\n type: resolvedType,\n name: args.name,\n });\n });\n}\n\nexport const modelAddTool: McpToolDefinition<typeof inputSchema> = {\n name: \"model_add\",\n description: \"Add a new element to a layer, validated against its spec schema.\",\n inputSchema,\n handler: modelAddHandler,\n};\n"],
5
+ "mappings": "AAMA,SAAS,SAAS;AAElB,SAAS,eAAe;AACxB,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAChC,SAAS,gBAAgB,oBAAoB;AAC7C,SAAS,sBAAsB,iBAAiB,yBAAyB;AACzE,SAAS,mBAAmB,oBAAoB;AAChD,SAAS,sBAAsB,sCAAsC;AACrE,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,UAAU,eAAe,aAAa,0BAA0B;AACzE,SAAS,YAAY,WAAW,aAAa,gBAAgB,eAAuC;AAEpG,MAAM,cAAc;EAClB,OAAO,EAAE,OAAM,EAAG,SAAS,kDAAkD;EAC7E,MAAM,EAAE,OAAM,EAAG,SAAS,6DAA6D;EACvF,MAAM,EAAE,OAAM,EAAG,SAAS,6DAA6D;EACvF,aAAa,EAAE,OAAM,EAAG,SAAQ;EAChC,YAAY,EAAE,OAAO,EAAE,OAAM,GAAI,EAAE,QAAO,CAAE,EAAE,SAAQ,EAAG,SAAS,wEAAwE;EAC1I,YAAY,EAAE,OAAM,EAAG,SAAQ,EAAG,SAAS,mDAAmD;EAC9F,cAAc,EAAE,OAAM,EAAG,SAAQ;EACjC,kBAAkB,EAAE,KAAK,CAAC,aAAa,UAAU,YAAY,WAAW,CAAC,EAAE,SAAQ;EACnF,kBAAkB,EAAE,OAAM,EAAG,SAAQ;EACrC,kBAAkB,EAAE,OAAM,EAAG,SAAQ,EAAG,SAAS,mCAAmC;EACpF,UAAU;;AAKZ,eAAsB,gBAAgB,MAAkB;AACtD,SAAO,QAAQ,YAAW;AACxB,QAAI,CAAC,aAAa,KAAK,KAAK,GAAG;AAC7B,YAAM,cAAc,eAAc,GAC5B,UAAU,YAAY,KAAK,OAAO,aAAa,CAAC,GAChD,cAAwB,CAAC,2BAA2B,mBAAmB,WAAW,CAAC,EAAE;AAC3F,YAAI,QAAQ,SAAS,KAAG,YAAY,QAAQ,iBAAiB,QAAQ,KAAK,MAAM,CAAC,GAAG,GAC9E,IAAI,SAAS,kBAAkB,KAAK,KAAK,KAAK,cAAc,MAAM,WAAW;IACrF;AAEA,QAAI,CAAC,gBAAgB,KAAK,OAAO,KAAK,IAAI,GAAG;AAE3C,YAAM,YADiB,qBAAqB,KAAK,KAAK,EACrB,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAI,GAClD,UAAU,YAAY,KAAK,MAAM,WAAW,CAAC,GAC7C,cAAwB,CAAC,mBAAmB,KAAK,KAAK,KAAK,mBAAmB,SAAS,CAAC,EAAE;AAChG,YAAI,QAAQ,SAAS,KAAG,YAAY,QAAQ,iBAAiB,QAAQ,KAAK,MAAM,CAAC,GAAG,GAC9E,IAAI,SAAS,yBAAyB,KAAK,IAAI,gBAAgB,KAAK,KAAK,KAAK,cAAc,MAAM,WAAW;IACrH;AAEA,UAAM,eAAe,kBAAkB,KAAK,OAAO,KAAK,IAAI,GACtD,cAAc,kBAAkB,KAAK,OAAO,cAAc,KAAK,IAAI,GACnE,cAAc,aAAY;AAGhC,QAAI,CADa,YAAY,MAAM,GAAG,EAAE,CAAC;AAEvC,YAAM,IAAI,SAAS,iDAAiD,KAAK,IAAI,KAAK,cAAc,MAAM;QACpG;OACD;AAGH,mCAA+B,MAAM,KAAK;AAE1C,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GAIrC,aAAa,MAAM,cAAa,EAAG,SAAS,KAAK,KAAK;AAC5D,QAAI,WAAW,MAAM,MAAM,SAAS,KAAK,KAAK,GAC1C,aAAa;AACjB,IAAK,aACH,WAAW,IAAI,MAAM,KAAK,KAAK,GAC/B,aAAa;AAGf,UAAM,OAAM,oBAAI,KAAI,GAAG,YAAW,GAC5B,UAAU,IAAI,QAAQ;MAC1B,IAAI;MACJ,MAAM;MACN,cAAc,GAAG,KAAK,KAAK,IAAI,YAAY;MAC3C,UAAU,KAAK;MACf,MAAM;MACN,MAAM,KAAK;MACX,aAAa,KAAK;MAClB,YAAY,KAAK,cAAc,CAAA;MAC/B,UAAU;QACR,YAAY;QACZ,YAAY;QACZ,SAAS;;MAEX,OAAO,KAAK;KACb,GAEK,YAAY,qBAAqB,IAAI;AAC3C,IAAI,aACF,QAAQ,mBAAmB,SAAS;AAGtC;AACE,YAAM,kBAAkB,IAAI,gBAAe,GACrC,YAAY,IAAI,MAAM,KAAK,KAAK;AACtC,gBAAU,WAAW,OAAO;AAC5B,YAAM,iBAAiB,MAAM,gBAAgB,cAAc,SAAS;AACpE,UAAI,CAAC,eAAe,QAAO,GAAI;AAC7B,cAAM,gBAAgB,eAAe,OAAO,IAAI,CAAC,MAAM,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK;CAAI;AAClF,cAAM,IAAI,SAAS,WAAW,WAAW;EAA6B,aAAa,IAAI,cAAc,MAAM;UACzG,iBAAiB,OAAO,KAAK,OAAO,YAAY;SACjD;MACH;IACF;AAEA,QAAI,SAAS,WAAW,WAAW;AACjC,YAAM,IAAI,SAAS,WAAW,WAAW,sBAAsB,KAAK,KAAK,UAAU,cAAc,MAAM;QACrG;QACA;QACA;OACD;AAGH,IAAI,cACF,MAAM,SAAS,QAAQ;AAGzB,UAAM,kBAAkB,IAAI,gBAAgB,OAAO,aAAa,KAAK,KAAK;AAC1E,UAAM,gBAAgB,WAAW,SAAS,CAAC,SAAQ;AACjD,eAAU,WAAW,IAAI;IAC3B,CAAC;AAGD,UAAM,kBAAkB,MADD,gBAAgB,kBAAiB,EACX,UAAS,GAChD,SAAS,CAAC,EAAE,mBAAmB,gBAAgB,WAAW;AAChE,WAAI,UAAU,CAAC,cAGb,MAAM,YAAY,KAAK,QAAQ,GAG1B,WAAW;MAChB,QAAQ,SAAS,WAAW;MAC5B,WAAW,SAAS,gBAAiB,OAAO;MAC5C,IAAI;MACJ,OAAO,KAAK;MACZ,MAAM;MACN,MAAM,KAAK;KACZ;EACH,CAAC;AACH;AAEO,MAAM,eAAsD;EACjE,MAAM;EACN,aAAa;EACb;EACA,SAAS;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,99 @@
1
+ import { z } from "zod";
2
+ import { DependencyTracker, TraceDirection } from "../../core/dependency-tracker.js";
3
+ import { MutationHandler } from "../../core/mutation-handler.js";
4
+ import { ReferenceRegistry } from "../../core/reference-registry.js";
5
+ import { findElementLayer } from "../../utils/element-utils.js";
6
+ import { CLIError, ErrorCategory, getErrorMessage } from "../../utils/errors.js";
7
+ import { jsonResult, loadModel, reloadModel, rootPathSchema, runTool } from "./shared.js";
8
+ const inputSchema = {
9
+ id: z.string().describe("Element ID or path to delete."),
10
+ cascade: z.boolean().optional().describe("Also delete elements that depend on this one."),
11
+ force: z.boolean().optional().describe("Skip the dependency check and delete only this element, even if others depend on it."),
12
+ dryRun: z.boolean().optional().describe("Preview what would be deleted without making changes."),
13
+ rootPath: rootPathSchema
14
+ };
15
+ async function modelDeleteHandler(args) {
16
+ return runTool(async () => {
17
+ const model = await loadModel(args.rootPath), layerName = await findElementLayer(model, args.id);
18
+ if (!layerName)
19
+ throw new CLIError(`Element ${args.id} not found`, ErrorCategory.NOT_FOUND, [
20
+ 'Use "model_search" to find similar elements'
21
+ ]);
22
+ const element = (await model.getLayer(layerName)).getElement(args.id);
23
+ if (!element)
24
+ throw new CLIError(`Element ${args.id} not found`, ErrorCategory.NOT_FOUND, [
25
+ 'Use "model_search" to find similar elements'
26
+ ]);
27
+ const registry = new ReferenceRegistry();
28
+ for (const l of model.layers.values())
29
+ for (const el of l.listElements())
30
+ registry.registerElement(el);
31
+ const dependents = new DependencyTracker(registry, model).traceDependencies(args.id, TraceDirection.DOWN, null);
32
+ if (dependents.length > 0 && !args.cascade && !args.force)
33
+ throw new CLIError("Element has dependencies", ErrorCategory.USER, [
34
+ "Use cascade=true to remove all dependent elements",
35
+ "Use dryRun=true with cascade=true to preview what would be deleted",
36
+ "Or use force=true to remove only this element (dependencies will reference a non-existent element)"
37
+ ]);
38
+ const elementsToRemove = args.cascade ? [args.id, ...dependents] : [args.id];
39
+ if (args.dryRun)
40
+ return jsonResult({
41
+ status: "dry-run",
42
+ id: args.id,
43
+ layer: layerName,
44
+ elementsToRemove
45
+ });
46
+ let deletedCount = 0;
47
+ const skippedDependents = [], cascadeDeleted = [];
48
+ if (args.cascade && dependents.length > 0)
49
+ for (const depId of [...dependents].reverse()) {
50
+ const depLayerName = await findElementLayer(model, depId);
51
+ if (!depLayerName) {
52
+ console.error(`[mcp] model_delete: cascade dependent "${depId}" not found, skipping`), skippedDependents.push(depId);
53
+ continue;
54
+ }
55
+ const depElement = (await model.getLayer(depLayerName)).getElement(depId);
56
+ if (!depElement) {
57
+ console.error(`[mcp] model_delete: cascade dependent "${depId}" not found, skipping`), skippedDependents.push(depId);
58
+ continue;
59
+ }
60
+ const depHandler = new MutationHandler(model, depId, depLayerName);
61
+ try {
62
+ await depHandler.executeDelete(depElement);
63
+ } catch (error) {
64
+ throw new CLIError(`Failed to delete dependent element "${depId}": ${getErrorMessage(error)}`, ErrorCategory.SYSTEM, [
65
+ `${cascadeDeleted.length} dependent element(s) were deleted before the error`,
66
+ 'Use "model_validate" to check the model for broken references',
67
+ `"${args.id}" was not deleted \u2014 you can retry the operation once dependents are resolved`
68
+ ], {
69
+ operation: "model_delete (cascade)",
70
+ relatedElements: cascadeDeleted,
71
+ partialProgress: { completed: cascadeDeleted.length, total: dependents.length }
72
+ });
73
+ }
74
+ cascadeDeleted.push(depId), deletedCount++;
75
+ }
76
+ const mutationHandler = new MutationHandler(model, args.id, layerName);
77
+ await mutationHandler.executeDelete(element);
78
+ const activeChangeset = await mutationHandler.getStagingManager().getActive(), staged = !!(activeChangeset && activeChangeset.status === "staged");
79
+ return staged && await reloadModel(args.rootPath), jsonResult({
80
+ status: staged ? "staged" : "deleted",
81
+ changeset: staged ? activeChangeset.name : void 0,
82
+ id: args.id,
83
+ layer: layerName,
84
+ cascadedDeletes: deletedCount,
85
+ ...skippedDependents.length > 0 ? { skippedDependents } : {}
86
+ });
87
+ });
88
+ }
89
+ const modelDeleteTool = {
90
+ name: "model_delete",
91
+ description: "Delete an element, optionally cascading to elements that depend on it.",
92
+ inputSchema,
93
+ handler: modelDeleteHandler
94
+ };
95
+ export {
96
+ modelDeleteHandler,
97
+ modelDeleteTool
98
+ };
99
+ //# sourceMappingURL=model-delete.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/tools/model-delete.ts"],
4
+ "sourcesContent": ["/**\n * model_delete \u2014 delete an element (optionally cascading to dependents).\n * Mirrors `dr delete`, but since an MCP session has no interactive confirmation\n * channel, the caller must pass `force` or `cascade` explicitly when dependents\n * exist rather than being prompted; operates through the shared MutationHandler.\n */\n\nimport { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { DependencyTracker, TraceDirection } from \"../../core/dependency-tracker.js\";\nimport { MutationHandler } from \"../../core/mutation-handler.js\";\nimport { ReferenceRegistry } from \"../../core/reference-registry.js\";\nimport { findElementLayer } from \"../../utils/element-utils.js\";\nimport { CLIError, ErrorCategory, getErrorMessage } from \"../../utils/errors.js\";\nimport { jsonResult, loadModel, reloadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n id: z.string().describe(\"Element ID or path to delete.\"),\n cascade: z.boolean().optional().describe(\"Also delete elements that depend on this one.\"),\n force: z.boolean().optional().describe(\"Skip the dependency check and delete only this element, even if others depend on it.\"),\n dryRun: z.boolean().optional().describe(\"Preview what would be deleted without making changes.\"),\n rootPath: rootPathSchema,\n};\n\nexport type ModelDeleteArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function modelDeleteHandler(args: ModelDeleteArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n\n const layerName = await findElementLayer(model, args.id);\n if (!layerName) {\n throw new CLIError(`Element ${args.id} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"model_search\" to find similar elements',\n ]);\n }\n\n const layer = (await model.getLayer(layerName))!;\n const element = layer.getElement(args.id);\n if (!element) {\n throw new CLIError(`Element ${args.id} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"model_search\" to find similar elements',\n ]);\n }\n\n // Cascade is scoped to cross-layer references only, matching `dr delete`. This is\n // narrower than \"model_trace\", which also follows intra-layer relationships.yaml\n // edges \u2014 a dependent found by model_trace may not be included in a cascade delete.\n const registry = new ReferenceRegistry();\n for (const l of model.layers.values()) {\n for (const el of l.listElements()) {\n registry.registerElement(el);\n }\n }\n const tracker = new DependencyTracker(registry, model);\n const dependents = tracker.traceDependencies(args.id, TraceDirection.DOWN, null);\n\n if (dependents.length > 0 && !args.cascade && !args.force) {\n throw new CLIError(\"Element has dependencies\", ErrorCategory.USER, [\n \"Use cascade=true to remove all dependent elements\",\n \"Use dryRun=true with cascade=true to preview what would be deleted\",\n \"Or use force=true to remove only this element (dependencies will reference a non-existent element)\",\n ]);\n }\n\n const elementsToRemove = args.cascade ? [args.id, ...dependents] : [args.id];\n\n if (args.dryRun) {\n return jsonResult({\n status: \"dry-run\",\n id: args.id,\n layer: layerName,\n elementsToRemove,\n });\n }\n\n let deletedCount = 0;\n const skippedDependents: string[] = [];\n const cascadeDeleted: string[] = [];\n if (args.cascade && dependents.length > 0) {\n for (const depId of [...dependents].reverse()) {\n const depLayerName = await findElementLayer(model, depId);\n if (!depLayerName) {\n console.error(`[mcp] model_delete: cascade dependent \"${depId}\" not found, skipping`);\n skippedDependents.push(depId);\n continue;\n }\n\n const depLayer = (await model.getLayer(depLayerName))!;\n const depElement = depLayer.getElement(depId);\n if (!depElement) {\n console.error(`[mcp] model_delete: cascade dependent \"${depId}\" not found, skipping`);\n skippedDependents.push(depId);\n continue;\n }\n\n const depHandler = new MutationHandler(model, depId, depLayerName);\n try {\n await depHandler.executeDelete(depElement);\n } catch (error) {\n throw new CLIError(\n `Failed to delete dependent element \"${depId}\": ${getErrorMessage(error)}`,\n ErrorCategory.SYSTEM,\n [\n `${cascadeDeleted.length} dependent element(s) were deleted before the error`,\n 'Use \"model_validate\" to check the model for broken references',\n `\"${args.id}\" was not deleted \u2014 you can retry the operation once dependents are resolved`,\n ],\n {\n operation: \"model_delete (cascade)\",\n relatedElements: cascadeDeleted,\n partialProgress: { completed: cascadeDeleted.length, total: dependents.length },\n }\n );\n }\n cascadeDeleted.push(depId);\n deletedCount++;\n }\n }\n\n const mutationHandler = new MutationHandler(model, args.id, layerName);\n await mutationHandler.executeDelete(element);\n\n const stagingManager = mutationHandler.getStagingManager();\n const activeChangeset = await stagingManager.getActive();\n const staged = !!(activeChangeset && activeChangeset.status === \"staged\");\n // The cached model's merged relationships still hold the rows the delete just staged for\n // removal; reload so later reads (model_validate, model_export) see the plan.\n if (staged) await reloadModel(args.rootPath);\n\n return jsonResult({\n status: staged ? \"staged\" : \"deleted\",\n changeset: staged ? activeChangeset!.name : undefined,\n id: args.id,\n layer: layerName,\n cascadedDeletes: deletedCount,\n ...(skippedDependents.length > 0 ? { skippedDependents } : {}),\n });\n });\n}\n\nexport const modelDeleteTool: McpToolDefinition<typeof inputSchema> = {\n name: \"model_delete\",\n description: \"Delete an element, optionally cascading to elements that depend on it.\",\n inputSchema,\n handler: modelDeleteHandler,\n};\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,72 @@
1
+ import { z } from "zod";
2
+ import { ArchiMateExporter, ExportManager, GraphMLExporter, JsonSchemaExporter, MarkdownExporter, MermaidMarkdownExporter, OpenAPIExporter, PlantUMLExporter } from "../../export/index.js";
3
+ import { Validator } from "../../validators/validator.js";
4
+ import { CLIError, ErrorCategory } from "../../utils/errors.js";
5
+ import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
6
+ const inputSchema = {
7
+ format: z.string().describe("Export format: archimate, openapi, json-schema, plantuml, graphml, markdown, or mermaid-markdown."),
8
+ layers: z.array(z.string()).optional().describe("Restrict export to these layers (must be supported by the chosen format)."),
9
+ includeSources: z.boolean().optional().describe("Include source_reference provenance in the export, where supported."),
10
+ rootPath: rootPathSchema
11
+ };
12
+ function buildExportManager() {
13
+ const manager = new ExportManager();
14
+ return manager.register("archimate", new ArchiMateExporter(), {
15
+ description: "ArchiMate 3.2 XML format",
16
+ mimeType: "application/xml"
17
+ }), manager.register("openapi", new OpenAPIExporter(), {
18
+ description: "OpenAPI 3.0 specification",
19
+ mimeType: "application/json"
20
+ }), manager.register("json-schema", new JsonSchemaExporter(), {
21
+ description: "JSON Schema Draft 7",
22
+ mimeType: "application/json"
23
+ }), manager.register("jsonschema", new JsonSchemaExporter(), {
24
+ description: "JSON Schema Draft 7",
25
+ mimeType: "application/json"
26
+ }), manager.register("plantuml", new PlantUMLExporter(), {
27
+ description: "PlantUML diagram format",
28
+ mimeType: "text/plain"
29
+ }), manager.register("graphml", new GraphMLExporter(), {
30
+ description: "GraphML graph format",
31
+ mimeType: "application/xml"
32
+ }), manager.register("markdown", new MarkdownExporter(), {
33
+ description: "Markdown documentation",
34
+ mimeType: "text/markdown"
35
+ }), manager.register("mermaid-markdown", new MermaidMarkdownExporter(), {
36
+ description: "Markdown with Mermaid diagrams and formatted tables",
37
+ mimeType: "text/markdown"
38
+ }), manager;
39
+ }
40
+ const SEMANTIC_FORMATS = /* @__PURE__ */ new Set(["openapi", "archimate", "jsonschema", "json-schema"]);
41
+ async function modelExportHandler(args) {
42
+ return runTool(async () => {
43
+ const model = await loadModel(args.rootPath), manager = buildExportManager(), format = args.format.toLowerCase();
44
+ if (!manager.hasFormat(format)) {
45
+ const available = manager.getAllFormats().map((f) => f.format);
46
+ throw new CLIError(`Unknown export format: ${args.format}`, ErrorCategory.USER, [
47
+ `Available formats: ${available.join(", ")}`
48
+ ]);
49
+ }
50
+ const warnings = [];
51
+ if (SEMANTIC_FORMATS.has(format)) {
52
+ const validationResult = await new Validator().validateModel(model);
53
+ validationResult.isValid() || warnings.push(`Model has ${validationResult.errors.length} validation error(s). Export output may be incomplete or incorrect.`);
54
+ }
55
+ const content = await manager.export(model, format, {
56
+ layers: args.layers,
57
+ includeSources: args.includeSources
58
+ });
59
+ return jsonResult({ format, warnings, content });
60
+ });
61
+ }
62
+ const modelExportTool = {
63
+ name: "model_export",
64
+ description: "Export the architecture model to ArchiMate, OpenAPI, JSON Schema, PlantUML, GraphML, Markdown, or Markdown with Mermaid diagrams.",
65
+ inputSchema,
66
+ handler: modelExportHandler
67
+ };
68
+ export {
69
+ modelExportHandler,
70
+ modelExportTool
71
+ };
72
+ //# sourceMappingURL=model-export.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/tools/model-export.ts"],
4
+ "sourcesContent": ["/**\n * model_export \u2014 export the model to a documentation/interchange format.\n * Mirrors `dr export`, reusing the shared ExportManager and exporters.\n */\n\nimport { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n ArchiMateExporter,\n ExportManager,\n GraphMLExporter,\n JsonSchemaExporter,\n MarkdownExporter,\n MermaidMarkdownExporter,\n OpenAPIExporter,\n PlantUMLExporter,\n} from \"../../export/index.js\";\nimport { Validator } from \"../../validators/validator.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n format: z\n .string()\n .describe(\"Export format: archimate, openapi, json-schema, plantuml, graphml, markdown, or mermaid-markdown.\"),\n layers: z.array(z.string()).optional().describe(\"Restrict export to these layers (must be supported by the chosen format).\"),\n includeSources: z.boolean().optional().describe(\"Include source_reference provenance in the export, where supported.\"),\n rootPath: rootPathSchema,\n};\n\nexport type ModelExportArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nfunction buildExportManager(): ExportManager {\n const manager = new ExportManager();\n manager.register(\"archimate\", new ArchiMateExporter(), {\n description: \"ArchiMate 3.2 XML format\",\n mimeType: \"application/xml\",\n });\n manager.register(\"openapi\", new OpenAPIExporter(), {\n description: \"OpenAPI 3.0 specification\",\n mimeType: \"application/json\",\n });\n manager.register(\"json-schema\", new JsonSchemaExporter(), {\n description: \"JSON Schema Draft 7\",\n mimeType: \"application/json\",\n });\n manager.register(\"jsonschema\", new JsonSchemaExporter(), {\n description: \"JSON Schema Draft 7\",\n mimeType: \"application/json\",\n });\n manager.register(\"plantuml\", new PlantUMLExporter(), {\n description: \"PlantUML diagram format\",\n mimeType: \"text/plain\",\n });\n manager.register(\"graphml\", new GraphMLExporter(), {\n description: \"GraphML graph format\",\n mimeType: \"application/xml\",\n });\n manager.register(\"markdown\", new MarkdownExporter(), {\n description: \"Markdown documentation\",\n mimeType: \"text/markdown\",\n });\n manager.register(\"mermaid-markdown\", new MermaidMarkdownExporter(), {\n description: \"Markdown with Mermaid diagrams and formatted tables\",\n mimeType: \"text/markdown\",\n });\n return manager;\n}\n\nconst SEMANTIC_FORMATS = new Set([\"openapi\", \"archimate\", \"jsonschema\", \"json-schema\"]);\n\nexport async function modelExportHandler(args: ModelExportArgs): Promise<CallToolResult> {\n return runTool(async () => {\n // Unlike \"model_validate\", this exports the base model as-is and does not project\n // the active changeset onto it \u2014 matching `dr export`. A staged-but-uncommitted\n // change will not appear in the export output.\n const model = await loadModel(args.rootPath);\n const manager = buildExportManager();\n const format = args.format.toLowerCase();\n\n if (!manager.hasFormat(format)) {\n const available = manager.getAllFormats().map((f) => f.format);\n throw new CLIError(`Unknown export format: ${args.format}`, ErrorCategory.USER, [\n `Available formats: ${available.join(\", \")}`,\n ]);\n }\n\n const warnings: string[] = [];\n if (SEMANTIC_FORMATS.has(format)) {\n const validator = new Validator();\n const validationResult = await validator.validateModel(model);\n if (!validationResult.isValid()) {\n warnings.push(\n `Model has ${validationResult.errors.length} validation error(s). Export output may be incomplete or incorrect.`\n );\n }\n }\n\n const content = await manager.export(model, format, {\n layers: args.layers,\n includeSources: args.includeSources,\n });\n\n return jsonResult({ format, warnings, content });\n });\n}\n\nexport const modelExportTool: McpToolDefinition<typeof inputSchema> = {\n name: \"model_export\",\n description:\n \"Export the architecture model to ArchiMate, OpenAPI, JSON Schema, PlantUML, GraphML, Markdown, or Markdown with Mermaid diagrams.\",\n inputSchema,\n handler: modelExportHandler,\n};\n"],
5
+ "mappings": "AAKA,SAAS,SAAS;AAElB,SACE,mBACA,eACA,iBACA,oBACA,kBACA,yBACA,iBACA,wBACK;AACP,SAAS,iBAAiB;AAC1B,SAAS,UAAU,qBAAqB;AACxC,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,QAAQ,EACL,OAAM,EACN,SAAS,mGAAmG;EAC/G,QAAQ,EAAE,MAAM,EAAE,OAAM,CAAE,EAAE,SAAQ,EAAG,SAAS,2EAA2E;EAC3H,gBAAgB,EAAE,QAAO,EAAG,SAAQ,EAAG,SAAS,qEAAqE;EACrH,UAAU;;AAKZ,SAAS,qBAAkB;AACzB,QAAM,UAAU,IAAI,cAAa;AACjC,iBAAQ,SAAS,aAAa,IAAI,kBAAiB,GAAI;IACrD,aAAa;IACb,UAAU;GACX,GACD,QAAQ,SAAS,WAAW,IAAI,gBAAe,GAAI;IACjD,aAAa;IACb,UAAU;GACX,GACD,QAAQ,SAAS,eAAe,IAAI,mBAAkB,GAAI;IACxD,aAAa;IACb,UAAU;GACX,GACD,QAAQ,SAAS,cAAc,IAAI,mBAAkB,GAAI;IACvD,aAAa;IACb,UAAU;GACX,GACD,QAAQ,SAAS,YAAY,IAAI,iBAAgB,GAAI;IACnD,aAAa;IACb,UAAU;GACX,GACD,QAAQ,SAAS,WAAW,IAAI,gBAAe,GAAI;IACjD,aAAa;IACb,UAAU;GACX,GACD,QAAQ,SAAS,YAAY,IAAI,iBAAgB,GAAI;IACnD,aAAa;IACb,UAAU;GACX,GACD,QAAQ,SAAS,oBAAoB,IAAI,wBAAuB,GAAI;IAClE,aAAa;IACb,UAAU;GACX,GACM;AACT;AAEA,MAAM,mBAAmB,oBAAI,IAAI,CAAC,WAAW,aAAa,cAAc,aAAa,CAAC;AAEtF,eAAsB,mBAAmB,MAAqB;AAC5D,SAAO,QAAQ,YAAW;AAIxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GACrC,UAAU,mBAAkB,GAC5B,SAAS,KAAK,OAAO,YAAW;AAEtC,QAAI,CAAC,QAAQ,UAAU,MAAM,GAAG;AAC9B,YAAM,YAAY,QAAQ,cAAa,EAAG,IAAI,CAAC,MAAM,EAAE,MAAM;AAC7D,YAAM,IAAI,SAAS,0BAA0B,KAAK,MAAM,IAAI,cAAc,MAAM;QAC9E,sBAAsB,UAAU,KAAK,IAAI,CAAC;OAC3C;IACH;AAEA,UAAM,WAAqB,CAAA;AAC3B,QAAI,iBAAiB,IAAI,MAAM,GAAG;AAEhC,YAAM,mBAAmB,MADP,IAAI,UAAS,EACU,cAAc,KAAK;AAC5D,MAAK,iBAAiB,QAAO,KAC3B,SAAS,KACP,aAAa,iBAAiB,OAAO,MAAM,qEAAqE;IAGtH;AAEA,UAAM,UAAU,MAAM,QAAQ,OAAO,OAAO,QAAQ;MAClD,QAAQ,KAAK;MACb,gBAAgB,KAAK;KACtB;AAED,WAAO,WAAW,EAAE,QAAQ,UAAU,QAAO,CAAE;EACjD,CAAC;AACH;AAEO,MAAM,kBAAyD;EACpE,MAAM;EACN,aACE;EACF;EACA,SAAS;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,51 @@
1
+ import { z } from "zod";
2
+ import { CLIError, ErrorCategory } from "../../utils/errors.js";
3
+ import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
4
+ const inputSchema = {
5
+ layer: z.string().optional().describe("Show details for a single layer instead of the whole-model summary."),
6
+ rootPath: rootPathSchema
7
+ };
8
+ async function modelInfoHandler(args) {
9
+ return runTool(async () => {
10
+ const model = await loadModel(args.rootPath), manifest = model.manifest, modelSummary = {
11
+ name: manifest.name,
12
+ version: manifest.version,
13
+ specVersion: manifest.specVersion,
14
+ description: manifest.description,
15
+ author: manifest.author,
16
+ created: manifest.created,
17
+ modified: manifest.modified
18
+ };
19
+ if (args.layer) {
20
+ const layer = await model.getLayer(args.layer);
21
+ if (!layer)
22
+ throw new CLIError(`Layer ${args.layer} not found`, ErrorCategory.NOT_FOUND, [
23
+ 'Use "model_info" (without a layer) to see all available layers'
24
+ ]);
25
+ const elements = layer.listElements(), elementsByType = {};
26
+ for (const element of elements)
27
+ elementsByType[element.type] = (elementsByType[element.type] || 0) + 1;
28
+ return jsonResult({
29
+ model: modelSummary,
30
+ layer: { name: args.layer, elementCount: elements.length, elementsByType }
31
+ });
32
+ }
33
+ const layerNames = model.getLayerNames(), layers = [];
34
+ for (const layerName of layerNames) {
35
+ const layer = await model.getLayer(layerName);
36
+ layer && layers.push({ name: layerName, elementCount: layer.listElements().length });
37
+ }
38
+ return jsonResult({ model: modelSummary, layers });
39
+ });
40
+ }
41
+ const modelInfoTool = {
42
+ name: "model_info",
43
+ description: "Get model metadata and a summary of layers (or a single layer's element type breakdown).",
44
+ inputSchema,
45
+ handler: modelInfoHandler
46
+ };
47
+ export {
48
+ modelInfoHandler,
49
+ modelInfoTool
50
+ };
51
+ //# sourceMappingURL=model-info.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/tools/model-info.ts"],
4
+ "sourcesContent": ["/**\n * model_info \u2014 model or single-layer summary information. Mirrors `dr info`.\n */\n\nimport { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n layer: z.string().optional().describe(\"Show details for a single layer instead of the whole-model summary.\"),\n rootPath: rootPathSchema,\n};\n\nexport type ModelInfoArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function modelInfoHandler(args: ModelInfoArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await loadModel(args.rootPath);\n const manifest = model.manifest;\n\n const modelSummary = {\n name: manifest.name,\n version: manifest.version,\n specVersion: manifest.specVersion,\n description: manifest.description,\n author: manifest.author,\n created: manifest.created,\n modified: manifest.modified,\n };\n\n if (args.layer) {\n const layer = await model.getLayer(args.layer);\n if (!layer) {\n throw new CLIError(`Layer ${args.layer} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"model_info\" (without a layer) to see all available layers',\n ]);\n }\n\n const elements = layer.listElements();\n const elementsByType: Record<string, number> = {};\n for (const element of elements) {\n elementsByType[element.type] = (elementsByType[element.type] || 0) + 1;\n }\n\n return jsonResult({\n model: modelSummary,\n layer: { name: args.layer, elementCount: elements.length, elementsByType },\n });\n }\n\n const layerNames = model.getLayerNames();\n const layers: Array<{ name: string; elementCount: number }> = [];\n for (const layerName of layerNames) {\n const layer = await model.getLayer(layerName);\n if (!layer) continue;\n layers.push({ name: layerName, elementCount: layer.listElements().length });\n }\n\n return jsonResult({ model: modelSummary, layers });\n });\n}\n\nexport const modelInfoTool: McpToolDefinition<typeof inputSchema> = {\n name: \"model_info\",\n description: \"Get model metadata and a summary of layers (or a single layer's element type breakdown).\",\n inputSchema,\n handler: modelInfoHandler,\n};\n"],
5
+ "mappings": "AAIA,SAAS,SAAS;AAElB,SAAS,UAAU,qBAAqB;AACxC,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,OAAO,EAAE,OAAM,EAAG,SAAQ,EAAG,SAAS,qEAAqE;EAC3G,UAAU;;AAKZ,eAAsB,iBAAiB,MAAmB;AACxD,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GACrC,WAAW,MAAM,UAEjB,eAAe;MACnB,MAAM,SAAS;MACf,SAAS,SAAS;MAClB,aAAa,SAAS;MACtB,aAAa,SAAS;MACtB,QAAQ,SAAS;MACjB,SAAS,SAAS;MAClB,UAAU,SAAS;;AAGrB,QAAI,KAAK,OAAO;AACd,YAAM,QAAQ,MAAM,MAAM,SAAS,KAAK,KAAK;AAC7C,UAAI,CAAC;AACH,cAAM,IAAI,SAAS,SAAS,KAAK,KAAK,cAAc,cAAc,WAAW;UAC3E;SACD;AAGH,YAAM,WAAW,MAAM,aAAY,GAC7B,iBAAyC,CAAA;AAC/C,iBAAW,WAAW;AACpB,uBAAe,QAAQ,IAAI,KAAK,eAAe,QAAQ,IAAI,KAAK,KAAK;AAGvE,aAAO,WAAW;QAChB,OAAO;QACP,OAAO,EAAE,MAAM,KAAK,OAAO,cAAc,SAAS,QAAQ,eAAc;OACzE;IACH;AAEA,UAAM,aAAa,MAAM,cAAa,GAChC,SAAwD,CAAA;AAC9D,eAAW,aAAa,YAAY;AAClC,YAAM,QAAQ,MAAM,MAAM,SAAS,SAAS;AAC5C,MAAK,SACL,OAAO,KAAK,EAAE,MAAM,WAAW,cAAc,MAAM,aAAY,EAAG,OAAM,CAAE;IAC5E;AAEA,WAAO,WAAW,EAAE,OAAO,cAAc,OAAM,CAAE;EACnD,CAAC;AACH;AAEO,MAAM,gBAAuD;EAClE,MAAM;EACN,aAAa;EACb;EACA,SAAS;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,53 @@
1
+ import { z } from "zod";
2
+ import { CANONICAL_LAYER_NAMES } from "../../core/layers.js";
3
+ import { CLIError, ErrorCategory } from "../../utils/errors.js";
4
+ import { jsonResult, loadModel, rootPathSchema, runTool } from "./shared.js";
5
+ const inputSchema = {
6
+ layer: z.string().optional().describe("Canonical layer name to list (e.g. 'api', 'data-model'). Omit to list across all layers."),
7
+ type: z.string().optional().describe("Restrict results to a single element type."),
8
+ rootPath: rootPathSchema
9
+ };
10
+ async function modelListHandler(args) {
11
+ return runTool(async () => {
12
+ if (args.layer) {
13
+ const layer = await (await loadModel(args.rootPath)).getLayer(args.layer);
14
+ if (!layer)
15
+ throw new CLIError(`Layer ${args.layer} not found`, ErrorCategory.NOT_FOUND, [
16
+ 'Use "model_info" to see all available layers'
17
+ ]);
18
+ let elements = layer.listElements();
19
+ return args.type && (elements = elements.filter((e) => e.type === args.type)), jsonResult({
20
+ layer: args.layer,
21
+ count: elements.length,
22
+ elements: elements.map((e) => e.toJSON())
23
+ });
24
+ }
25
+ const model = await loadModel(args.rootPath), layers = [];
26
+ for (const layerName of CANONICAL_LAYER_NAMES) {
27
+ const layer = await model.getLayer(layerName);
28
+ if (!layer)
29
+ continue;
30
+ let elements = layer.listElements();
31
+ args.type && (elements = elements.filter((e) => e.type === args.type)), elements.length > 0 && layers.push({
32
+ layer: layerName,
33
+ count: elements.length,
34
+ elements: elements.map((e) => e.toJSON())
35
+ });
36
+ }
37
+ return jsonResult({
38
+ layers,
39
+ totalElements: layers.reduce((sum, l) => sum + l.count, 0)
40
+ });
41
+ });
42
+ }
43
+ const modelListTool = {
44
+ name: "model_list",
45
+ description: "List elements in the architecture model, optionally scoped to a layer and/or element type.",
46
+ inputSchema,
47
+ handler: modelListHandler
48
+ };
49
+ export {
50
+ modelListHandler,
51
+ modelListTool
52
+ };
53
+ //# sourceMappingURL=model-list.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/tools/model-list.ts"],
4
+ "sourcesContent": ["/**\n * model_list \u2014 list elements in the architecture model, optionally scoped to\n * a single layer and/or element type. Mirrors `dr list`.\n */\n\nimport { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { CANONICAL_LAYER_NAMES } from \"../../core/layers.js\";\nimport { CLIError, ErrorCategory } from \"../../utils/errors.js\";\nimport { jsonResult, loadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n layer: z\n .string()\n .optional()\n .describe(\"Canonical layer name to list (e.g. 'api', 'data-model'). Omit to list across all layers.\"),\n type: z.string().optional().describe(\"Restrict results to a single element type.\"),\n rootPath: rootPathSchema,\n};\n\nexport type ModelListArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function modelListHandler(args: ModelListArgs): Promise<CallToolResult> {\n return runTool(async () => {\n if (args.layer) {\n const model = await loadModel(args.rootPath);\n const layer = await model.getLayer(args.layer);\n if (!layer) {\n throw new CLIError(`Layer ${args.layer} not found`, ErrorCategory.NOT_FOUND, [\n 'Use \"model_info\" to see all available layers',\n ]);\n }\n\n let elements = layer.listElements();\n if (args.type) {\n elements = elements.filter((e) => e.type === args.type);\n }\n\n return jsonResult({\n layer: args.layer,\n count: elements.length,\n elements: elements.map((e) => e.toJSON()),\n });\n }\n\n const model = await loadModel(args.rootPath);\n const layers: Array<{ layer: string; count: number; elements: unknown[] }> = [];\n\n for (const layerName of CANONICAL_LAYER_NAMES) {\n const layer = await model.getLayer(layerName);\n if (!layer) continue;\n\n let elements = layer.listElements();\n if (args.type) {\n elements = elements.filter((e) => e.type === args.type);\n }\n\n if (elements.length > 0) {\n layers.push({\n layer: layerName,\n count: elements.length,\n elements: elements.map((e) => e.toJSON()),\n });\n }\n }\n\n return jsonResult({\n layers,\n totalElements: layers.reduce((sum, l) => sum + l.count, 0),\n });\n });\n}\n\nexport const modelListTool: McpToolDefinition<typeof inputSchema> = {\n name: \"model_list\",\n description:\n \"List elements in the architecture model, optionally scoped to a layer and/or element type.\",\n inputSchema,\n handler: modelListHandler,\n};\n"],
5
+ "mappings": "AAKA,SAAS,SAAS;AAElB,SAAS,6BAA6B;AACtC,SAAS,UAAU,qBAAqB;AACxC,SAAS,YAAY,WAAW,gBAAgB,eAAuC;AAEvF,MAAM,cAAc;EAClB,OAAO,EACJ,OAAM,EACN,SAAQ,EACR,SAAS,0FAA0F;EACtG,MAAM,EAAE,OAAM,EAAG,SAAQ,EAAG,SAAS,4CAA4C;EACjF,UAAU;;AAKZ,eAAsB,iBAAiB,MAAmB;AACxD,SAAO,QAAQ,YAAW;AACxB,QAAI,KAAK,OAAO;AAEd,YAAM,QAAQ,OADA,MAAM,UAAU,KAAK,QAAQ,GACjB,SAAS,KAAK,KAAK;AAC7C,UAAI,CAAC;AACH,cAAM,IAAI,SAAS,SAAS,KAAK,KAAK,cAAc,cAAc,WAAW;UAC3E;SACD;AAGH,UAAI,WAAW,MAAM,aAAY;AACjC,aAAI,KAAK,SACP,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,IAGjD,WAAW;QAChB,OAAO,KAAK;QACZ,OAAO,SAAS;QAChB,UAAU,SAAS,IAAI,CAAC,MAAM,EAAE,OAAM,CAAE;OACzC;IACH;AAEA,UAAM,QAAQ,MAAM,UAAU,KAAK,QAAQ,GACrC,SAAuE,CAAA;AAE7E,eAAW,aAAa,uBAAuB;AAC7C,YAAM,QAAQ,MAAM,MAAM,SAAS,SAAS;AAC5C,UAAI,CAAC;AAAO;AAEZ,UAAI,WAAW,MAAM,aAAY;AACjC,MAAI,KAAK,SACP,WAAW,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,IAGpD,SAAS,SAAS,KACpB,OAAO,KAAK;QACV,OAAO;QACP,OAAO,SAAS;QAChB,UAAU,SAAS,IAAI,CAAC,MAAM,EAAE,OAAM,CAAE;OACzC;IAEL;AAEA,WAAO,WAAW;MAChB;MACA,eAAe,OAAO,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;KAC1D;EACH,CAAC;AACH;AAEO,MAAM,gBAAuD;EAClE,MAAM;EACN,aACE;EACF;EACA,SAAS;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,34 @@
1
+ import { jsonResult, reloadModel, rootPathSchema, runTool } from "./shared.js";
2
+ const inputSchema = {
3
+ rootPath: rootPathSchema
4
+ };
5
+ async function modelReloadHandler(args) {
6
+ return runTool(async () => {
7
+ const model = await reloadModel(args.rootPath), layers = [];
8
+ for (const layerName of model.getLayerNames()) {
9
+ const layer = await model.getLayer(layerName);
10
+ layer && layers.push({ name: layerName, elementCount: layer.listElements().length });
11
+ }
12
+ return jsonResult({
13
+ status: "reloaded",
14
+ model: {
15
+ name: model.manifest.name,
16
+ version: model.manifest.version,
17
+ modified: model.manifest.modified
18
+ },
19
+ layers,
20
+ totalElements: layers.reduce((sum, layer) => sum + layer.elementCount, 0)
21
+ });
22
+ });
23
+ }
24
+ const modelReloadTool = {
25
+ name: "model_reload",
26
+ description: "Force a full reload of the architecture model from disk and report a summary of its current state.",
27
+ inputSchema,
28
+ handler: modelReloadHandler
29
+ };
30
+ export {
31
+ modelReloadHandler,
32
+ modelReloadTool
33
+ };
34
+ //# sourceMappingURL=model-reload.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/tools/model-reload.ts"],
4
+ "sourcesContent": ["/**\n * model_reload \u2014 force a full, non-lazy reload of the architecture model from\n * disk and report a summary of what was read.\n *\n * `loadModel()` (shared.ts) loads the model once per rootPath and holds it in\n * memory for reuse across tool calls, the same way the REST/visualization server\n * holds a long-lived `this.model` field (see `setupFileWatcher()` in\n * `cli/src/server/server.ts`). That cache can go stale after edits made outside\n * this MCP session (e.g. the CLI or another process editing files on disk), so\n * this tool exists to force a fresh read and refresh the cache \u2014 the MCP\n * equivalent of that server's file-watcher-triggered reload.\n */\n\nimport type { z } from \"zod\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { jsonResult, reloadModel, rootPathSchema, runTool, type McpToolDefinition } from \"./shared.js\";\n\nconst inputSchema = {\n rootPath: rootPathSchema,\n};\n\nexport type ModelReloadArgs = z.infer<z.ZodObject<typeof inputSchema>>;\n\nexport async function modelReloadHandler(args: ModelReloadArgs): Promise<CallToolResult> {\n return runTool(async () => {\n const model = await reloadModel(args.rootPath);\n\n const layers: Array<{ name: string; elementCount: number }> = [];\n for (const layerName of model.getLayerNames()) {\n const layer = await model.getLayer(layerName);\n if (!layer) continue;\n layers.push({ name: layerName, elementCount: layer.listElements().length });\n }\n\n return jsonResult({\n status: \"reloaded\",\n model: {\n name: model.manifest.name,\n version: model.manifest.version,\n modified: model.manifest.modified,\n },\n layers,\n totalElements: layers.reduce((sum, layer) => sum + layer.elementCount, 0),\n });\n });\n}\n\nexport const modelReloadTool: McpToolDefinition<typeof inputSchema> = {\n name: \"model_reload\",\n description: \"Force a full reload of the architecture model from disk and report a summary of its current state.\",\n inputSchema,\n handler: modelReloadHandler,\n};\n"],
5
+ "mappings": "AAeA,SAAS,YAAY,aAAa,gBAAgB,eAAuC;AAEzF,MAAM,cAAc;EAClB,UAAU;;AAKZ,eAAsB,mBAAmB,MAAqB;AAC5D,SAAO,QAAQ,YAAW;AACxB,UAAM,QAAQ,MAAM,YAAY,KAAK,QAAQ,GAEvC,SAAwD,CAAA;AAC9D,eAAW,aAAa,MAAM,cAAa,GAAI;AAC7C,YAAM,QAAQ,MAAM,MAAM,SAAS,SAAS;AAC5C,MAAK,SACL,OAAO,KAAK,EAAE,MAAM,WAAW,cAAc,MAAM,aAAY,EAAG,OAAM,CAAE;IAC5E;AAEA,WAAO,WAAW;MAChB,QAAQ;MACR,OAAO;QACL,MAAM,MAAM,SAAS;QACrB,SAAS,MAAM,SAAS;QACxB,UAAU,MAAM,SAAS;;MAE3B;MACA,eAAe,OAAO,OAAO,CAAC,KAAK,UAAU,MAAM,MAAM,cAAc,CAAC;KACzE;EACH,CAAC;AACH;AAEO,MAAM,kBAAyD;EACpE,MAAM;EACN,aAAa;EACb;EACA,SAAS;;",
6
+ "names": []
7
+ }