@documentation-robotics/cli 0.2.0 → 0.4.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 (335) hide show
  1. package/README.md +46 -16
  2. package/dist/analysis/relationship-classifier.js +2 -9
  3. package/dist/analysis/relationship-classifier.js.map +2 -2
  4. package/dist/analyzers/active-analyzer.js +62 -0
  5. package/dist/analyzers/active-analyzer.js.map +7 -0
  6. package/dist/analyzers/call-graph-utils.js +2 -2
  7. package/dist/analyzers/call-graph-utils.js.map +2 -2
  8. package/dist/analyzers/cards/build.js +191 -0
  9. package/dist/analyzers/cards/build.js.map +7 -0
  10. package/dist/analyzers/cards/classify.js +42 -0
  11. package/dist/analyzers/cards/classify.js.map +7 -0
  12. package/dist/analyzers/cards/edge-index.js +44 -0
  13. package/dist/analyzers/cards/edge-index.js.map +7 -0
  14. package/dist/analyzers/cards/extract.js +138 -0
  15. package/dist/analyzers/cards/extract.js.map +7 -0
  16. package/dist/analyzers/cards/facts.js +46 -0
  17. package/dist/analyzers/cards/facts.js.map +7 -0
  18. package/dist/analyzers/cards/graph.js +42 -0
  19. package/dist/analyzers/cards/graph.js.map +7 -0
  20. package/dist/analyzers/cards/index.js +8 -0
  21. package/dist/analyzers/cards/index.js.map +7 -0
  22. package/dist/analyzers/cards/routes.js +96 -0
  23. package/dist/analyzers/cards/routes.js.map +7 -0
  24. package/dist/analyzers/cards/tier0.js +18 -0
  25. package/dist/analyzers/cards/tier0.js.map +7 -0
  26. package/dist/analyzers/cards/types.js +1 -0
  27. package/dist/analyzers/cards/types.js.map +7 -0
  28. package/dist/analyzers/cbm-analyzer.js +270 -174
  29. package/dist/analyzers/cbm-analyzer.js.map +2 -2
  30. package/dist/analyzers/cbm-responses.js +342 -0
  31. package/dist/analyzers/cbm-responses.js.map +7 -0
  32. package/dist/analyzers/code-changes.js +159 -0
  33. package/dist/analyzers/code-changes.js.map +7 -0
  34. package/dist/analyzers/edge-relationships.js +49 -0
  35. package/dist/analyzers/edge-relationships.js.map +7 -0
  36. package/dist/analyzers/extraction-plan.js +541 -0
  37. package/dist/analyzers/extraction-plan.js.map +7 -0
  38. package/dist/analyzers/index-job.js +229 -0
  39. package/dist/analyzers/index-job.js.map +7 -0
  40. package/dist/analyzers/mapping-loader.js +9 -0
  41. package/dist/analyzers/mapping-loader.js.map +2 -2
  42. package/dist/analyzers/tier0-rules.js +153 -0
  43. package/dist/analyzers/tier0-rules.js.map +7 -0
  44. package/dist/analyzers/types.js.map +1 -1
  45. package/dist/audit/relationships/ai/prompts.js +10 -10
  46. package/dist/audit/relationships/ai/prompts.js.map +2 -2
  47. package/dist/audit/relationships/analysis/layer-templates.js +52 -52
  48. package/dist/audit/relationships/analysis/layer-templates.js.map +1 -1
  49. package/dist/cli.js +23 -11
  50. package/dist/cli.js.map +2 -2
  51. package/dist/coding-agents/default-permissions.js +31 -1
  52. package/dist/coding-agents/default-permissions.js.map +2 -2
  53. package/dist/coding-agents/drbot-mcp.js +269 -0
  54. package/dist/coding-agents/drbot-mcp.js.map +7 -0
  55. package/dist/commands/add.js +7 -4
  56. package/dist/commands/add.js.map +2 -2
  57. package/dist/commands/analyzer.js +143 -40
  58. package/dist/commands/analyzer.js.map +2 -2
  59. package/dist/commands/changeset-verify.js +63 -0
  60. package/dist/commands/changeset-verify.js.map +7 -0
  61. package/dist/commands/changeset.js +80 -29
  62. package/dist/commands/changeset.js.map +2 -2
  63. package/dist/commands/delete.js +10 -4
  64. package/dist/commands/delete.js.map +2 -2
  65. package/dist/commands/farm.js +176 -60
  66. package/dist/commands/farm.js.map +2 -2
  67. package/dist/commands/init.js +9 -26
  68. package/dist/commands/init.js.map +2 -2
  69. package/dist/commands/mcp.js +40 -21
  70. package/dist/commands/mcp.js.map +3 -3
  71. package/dist/commands/relationship.js +208 -37
  72. package/dist/commands/relationship.js.map +2 -2
  73. package/dist/commands/reports.js +3 -3
  74. package/dist/commands/reports.js.map +2 -2
  75. package/dist/commands/update.js +52 -32
  76. package/dist/commands/update.js.map +2 -2
  77. package/dist/commands/upgrade.js +99 -103
  78. package/dist/commands/upgrade.js.map +3 -3
  79. package/dist/commands/validate.js +19 -3
  80. package/dist/commands/validate.js.map +2 -2
  81. package/dist/commands/version.js +1 -1
  82. package/dist/commands/visualize.js +34 -15
  83. package/dist/commands/visualize.js.map +2 -2
  84. package/dist/core/annotation-store.js +15 -5
  85. package/dist/core/annotation-store.js.map +2 -2
  86. package/dist/core/catalog-migration.js +34 -0
  87. package/dist/core/catalog-migration.js.map +7 -0
  88. package/dist/core/changeset-analysis.js +421 -0
  89. package/dist/core/changeset-analysis.js.map +7 -0
  90. package/dist/core/changeset-base-index.js +160 -0
  91. package/dist/core/changeset-base-index.js.map +7 -0
  92. package/dist/core/changeset-brief-compact.js +256 -0
  93. package/dist/core/changeset-brief-compact.js.map +7 -0
  94. package/dist/core/changeset-brief-delta.js +102 -0
  95. package/dist/core/changeset-brief-delta.js.map +7 -0
  96. package/dist/core/changeset-graph.js +281 -0
  97. package/dist/core/changeset-graph.js.map +7 -0
  98. package/dist/core/changeset-only-guard.js +32 -0
  99. package/dist/core/changeset-only-guard.js.map +7 -0
  100. package/dist/core/changeset-summary.js +68 -0
  101. package/dist/core/changeset-summary.js.map +7 -0
  102. package/dist/core/changeset-validator.js +66 -20
  103. package/dist/core/changeset-validator.js.map +2 -2
  104. package/dist/core/changeset-verify.js +848 -0
  105. package/dist/core/changeset-verify.js.map +7 -0
  106. package/dist/core/changeset.js +56 -9
  107. package/dist/core/changeset.js.map +2 -2
  108. package/dist/core/element-type-migration.js +145 -0
  109. package/dist/core/element-type-migration.js.map +7 -0
  110. package/dist/core/extraction-observability.js +161 -0
  111. package/dist/core/extraction-observability.js.map +7 -0
  112. package/dist/core/farm-manifest.js +12 -6
  113. package/dist/core/farm-manifest.js.map +2 -2
  114. package/dist/core/farm-sync-engine.js +1 -1
  115. package/dist/core/farm-sync-engine.js.map +2 -2
  116. package/dist/core/farm-sync-state.js +10 -2
  117. package/dist/core/farm-sync-state.js.map +2 -2
  118. package/dist/core/migration-registry.js +88 -47
  119. package/dist/core/migration-registry.js.map +2 -2
  120. package/dist/core/model-upgrade.js +102 -0
  121. package/dist/core/model-upgrade.js.map +7 -0
  122. package/dist/core/model.js +82 -30
  123. package/dist/core/model.js.map +2 -2
  124. package/dist/core/mutation-handler.js +71 -6
  125. package/dist/core/mutation-handler.js.map +2 -2
  126. package/dist/core/project-init.js +53 -0
  127. package/dist/core/project-init.js.map +7 -0
  128. package/dist/core/relationship-migration-table.js +6639 -0
  129. package/dist/core/relationship-migration-table.js.map +7 -0
  130. package/dist/core/relationship-migration.js +272 -0
  131. package/dist/core/relationship-migration.js.map +7 -0
  132. package/dist/core/relationship-prune.js +49 -0
  133. package/dist/core/relationship-prune.js.map +7 -0
  134. package/dist/core/relationship-staging.js +161 -0
  135. package/dist/core/relationship-staging.js.map +7 -0
  136. package/dist/core/relationships.js +26 -4
  137. package/dist/core/relationships.js.map +2 -2
  138. package/dist/core/report-data-model.js +7 -13
  139. package/dist/core/report-data-model.js.map +2 -2
  140. package/dist/core/staged-changeset-storage.js +145 -18
  141. package/dist/core/staged-changeset-storage.js.map +2 -2
  142. package/dist/core/staged-source-reference.js +28 -0
  143. package/dist/core/staged-source-reference.js.map +7 -0
  144. package/dist/core/staging-area.js +166 -24
  145. package/dist/core/staging-area.js.map +2 -2
  146. package/dist/core/upgrade-plan.js +117 -0
  147. package/dist/core/upgrade-plan.js.map +7 -0
  148. package/dist/core/virtual-projection.js +13 -5
  149. package/dist/core/virtual-projection.js.map +2 -2
  150. package/dist/export/archimate-exporter.js +1 -0
  151. package/dist/export/archimate-exporter.js.map +2 -2
  152. package/dist/generated/compiled-validators.js +2 -2
  153. package/dist/generated/compiled-validators.js.map +2 -2
  154. package/dist/generated/layer-registry.js +16 -16
  155. package/dist/generated/layer-registry.js.map +2 -2
  156. package/dist/generated/node-types.js +186 -168
  157. package/dist/generated/node-types.js.map +2 -2
  158. package/dist/generated/relationship-index.js +2468 -7913
  159. package/dist/generated/relationship-index.js.map +2 -2
  160. package/dist/integrations/claude_code/.claude-plugin/plugin.json +24 -0
  161. package/dist/integrations/claude_code/agents/dr-architect.md +30 -3
  162. package/dist/integrations/claude_code/agents/dr-extractor.md +8 -2
  163. package/dist/integrations/claude_code/commands/dr-analyzer.md +565 -0
  164. package/dist/integrations/claude_code/commands/dr-changeset.md +2 -1
  165. package/dist/integrations/claude_code/commands/dr-map.md +20 -1
  166. package/dist/integrations/claude_code/commands/dr-plan.md +66 -0
  167. package/dist/integrations/claude_code/commands/dr-relate.md +106 -96
  168. package/dist/integrations/claude_code/commands/dr-verify.md +45 -2
  169. package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +14 -0
  170. package/dist/integrations/claude_code/docs/MCP_SERVER.md +47 -26
  171. package/dist/integrations/claude_code/docs/QUICK_START.md +37 -8
  172. package/dist/integrations/claude_code/docs/README.md +68 -2
  173. package/dist/integrations/claude_code/plugin-agents/dr-advisor.md +255 -0
  174. package/dist/integrations/claude_code/plugin-agents/dr-architect.md +306 -0
  175. package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +93 -72
  176. package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +163 -126
  177. package/dist/integrations/claude_code/skills/dr_03_product_layer/SKILL.md +161 -126
  178. package/dist/integrations/claude_code/skills/dr_04_security_layer/SKILL.md +153 -133
  179. package/dist/integrations/claude_code/skills/dr_05_application_layer/SKILL.md +129 -100
  180. package/dist/integrations/claude_code/skills/dr_06_technology_layer/SKILL.md +111 -94
  181. package/dist/integrations/claude_code/skills/dr_07_api_layer/SKILL.md +143 -157
  182. package/dist/integrations/claude_code/skills/dr_08_data_model_layer/SKILL.md +117 -33
  183. package/dist/integrations/claude_code/skills/dr_09_dataset_layer/SKILL.md +74 -25
  184. package/dist/integrations/claude_code/skills/dr_10_ux_layer/SKILL.md +88 -12
  185. package/dist/integrations/claude_code/skills/dr_11_navigation_layer/SKILL.md +83 -24
  186. package/dist/integrations/claude_code/skills/dr_12_apm_layer/SKILL.md +57 -12
  187. package/dist/integrations/claude_code/skills/dr_13_testing_layer/SKILL.md +95 -15
  188. package/dist/integrations/claude_code/skills/dr_change_planning/SKILL.md +178 -0
  189. package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +8 -0
  190. package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +6 -1
  191. package/dist/integrations/github_copilot/agents/dr-architect.md +3 -1
  192. package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +182 -102
  193. package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +266 -148
  194. package/dist/integrations/github_copilot/skills/dr_03_product_layer/SKILL.md +547 -86
  195. package/dist/integrations/github_copilot/skills/dr_04_security_layer/SKILL.md +164 -169
  196. package/dist/integrations/github_copilot/skills/dr_05_application_layer/SKILL.md +420 -150
  197. package/dist/integrations/github_copilot/skills/dr_06_technology_layer/SKILL.md +331 -138
  198. package/dist/integrations/github_copilot/skills/dr_07_api_layer/SKILL.md +265 -201
  199. package/dist/integrations/github_copilot/skills/dr_08_data_model_layer/SKILL.md +181 -58
  200. package/dist/integrations/github_copilot/skills/dr_09_dataset_layer/SKILL.md +209 -57
  201. package/dist/integrations/github_copilot/skills/dr_10_ux_layer/SKILL.md +277 -112
  202. package/dist/integrations/github_copilot/skills/dr_11_navigation_layer/SKILL.md +219 -70
  203. package/dist/integrations/github_copilot/skills/dr_12_apm_layer/SKILL.md +189 -105
  204. package/dist/integrations/github_copilot/skills/dr_13_testing_layer/SKILL.md +225 -102
  205. package/dist/integrations/github_copilot/skills/dr_change_planning/SKILL.md +177 -0
  206. package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +3 -0
  207. package/dist/integrations/hash-utils.js.map +2 -2
  208. package/dist/mcp/api-key-manager.js +14 -1
  209. package/dist/mcp/api-key-manager.js.map +2 -2
  210. package/dist/mcp/changeset-only.js +45 -0
  211. package/dist/mcp/changeset-only.js.map +7 -0
  212. package/dist/mcp/project-root.js +85 -0
  213. package/dist/mcp/project-root.js.map +7 -0
  214. package/dist/mcp/server-instructions.js +27 -0
  215. package/dist/mcp/server-instructions.js.map +7 -0
  216. package/dist/mcp/strict-schema.js +52 -0
  217. package/dist/mcp/strict-schema.js.map +7 -0
  218. package/dist/mcp/tool-registry.js +55 -5
  219. package/dist/mcp/tool-registry.js.map +2 -2
  220. package/dist/mcp/tools/changeset-analysis-tools.js +98 -0
  221. package/dist/mcp/tools/changeset-analysis-tools.js.map +7 -0
  222. package/dist/mcp/tools/changeset-commit.js +224 -0
  223. package/dist/mcp/tools/changeset-commit.js.map +7 -0
  224. package/dist/mcp/tools/changeset-editing.js +260 -0
  225. package/dist/mcp/tools/changeset-editing.js.map +7 -0
  226. package/dist/mcp/tools/changeset-lifecycle.js +83 -0
  227. package/dist/mcp/tools/changeset-lifecycle.js.map +7 -0
  228. package/dist/mcp/tools/changeset-shared.js +31 -0
  229. package/dist/mcp/tools/changeset-shared.js.map +7 -0
  230. package/dist/mcp/tools/changeset-show.js +17 -1
  231. package/dist/mcp/tools/changeset-show.js.map +2 -2
  232. package/dist/mcp/tools/changeset-verify.js +49 -0
  233. package/dist/mcp/tools/changeset-verify.js.map +7 -0
  234. package/dist/mcp/tools/codebase-extract.js +836 -0
  235. package/dist/mcp/tools/codebase-extract.js.map +7 -0
  236. package/dist/mcp/tools/codebase-index.js +125 -0
  237. package/dist/mcp/tools/codebase-index.js.map +7 -0
  238. package/dist/mcp/tools/codebase-shared.js +265 -0
  239. package/dist/mcp/tools/codebase-shared.js.map +7 -0
  240. package/dist/mcp/tools/codebase-verify.js +48 -0
  241. package/dist/mcp/tools/codebase-verify.js.map +7 -0
  242. package/dist/mcp/tools/index.js +34 -1
  243. package/dist/mcp/tools/index.js.map +2 -2
  244. package/dist/mcp/tools/model-add.js +191 -74
  245. package/dist/mcp/tools/model-add.js.map +2 -2
  246. package/dist/mcp/tools/model-delete.js +2 -2
  247. package/dist/mcp/tools/model-delete.js.map +2 -2
  248. package/dist/mcp/tools/model-search.js +14 -0
  249. package/dist/mcp/tools/model-search.js.map +2 -2
  250. package/dist/mcp/tools/model-show.js +29 -2
  251. package/dist/mcp/tools/model-show.js.map +2 -2
  252. package/dist/mcp/tools/model-trace.js +93 -30
  253. package/dist/mcp/tools/model-trace.js.map +2 -2
  254. package/dist/mcp/tools/model-update.js +46 -26
  255. package/dist/mcp/tools/model-update.js.map +2 -2
  256. package/dist/mcp/tools/model-validate.js +46 -4
  257. package/dist/mcp/tools/model-validate.js.map +2 -2
  258. package/dist/mcp/tools/project-status-collectors.js +381 -0
  259. package/dist/mcp/tools/project-status-collectors.js.map +7 -0
  260. package/dist/mcp/tools/project-status.js +237 -0
  261. package/dist/mcp/tools/project-status.js.map +7 -0
  262. package/dist/mcp/tools/project-tools.js +505 -0
  263. package/dist/mcp/tools/project-tools.js.map +7 -0
  264. package/dist/mcp/tools/relationship-tools.js +167 -0
  265. package/dist/mcp/tools/relationship-tools.js.map +7 -0
  266. package/dist/mcp/tools/review-open.js +210 -0
  267. package/dist/mcp/tools/review-open.js.map +7 -0
  268. package/dist/mcp/tools/shared.js +35 -4
  269. package/dist/mcp/tools/shared.js.map +2 -2
  270. package/dist/mcp/tools/spec-type.js +90 -0
  271. package/dist/mcp/tools/spec-type.js.map +7 -0
  272. package/dist/reports/model-report-orchestrator.js +31 -2
  273. package/dist/reports/model-report-orchestrator.js.map +2 -2
  274. package/dist/schemas/bundled/analyzers/cbm.json +1200 -70
  275. package/dist/schemas/bundled/analyzers/manifest.json +2 -2
  276. package/dist/schemas/bundled/api.json +1029 -1658
  277. package/dist/schemas/bundled/apm.json +499 -734
  278. package/dist/schemas/bundled/application.json +735 -371
  279. package/dist/schemas/bundled/base.json +3 -220
  280. package/dist/schemas/bundled/business.json +452 -366
  281. package/dist/schemas/bundled/data-model.json +395 -411
  282. package/dist/schemas/bundled/data-store.json +334 -558
  283. package/dist/schemas/bundled/manifest.json +18 -18
  284. package/dist/schemas/bundled/motivation.json +349 -368
  285. package/dist/schemas/bundled/navigation.json +415 -731
  286. package/dist/schemas/bundled/product.json +325 -159
  287. package/dist/schemas/bundled/security.json +864 -1232
  288. package/dist/schemas/bundled/technology.json +574 -703
  289. package/dist/schemas/bundled/testing.json +865 -1646
  290. package/dist/schemas/bundled/ux.json +739 -1352
  291. package/dist/server/schemas.js +8 -0
  292. package/dist/server/schemas.js.map +2 -2
  293. package/dist/server/server.js +686 -231
  294. package/dist/server/server.js.map +3 -3
  295. package/dist/server/viewer-registry.js +264 -0
  296. package/dist/server/viewer-registry.js.map +7 -0
  297. package/dist/server-entry.js +2 -1
  298. package/dist/server-entry.js.map +2 -2
  299. package/dist/telemetry/index.js +1 -1
  300. package/dist/utils/ansi-suppressor.js +6 -8
  301. package/dist/utils/ansi-suppressor.js.map +2 -2
  302. package/dist/utils/attribute-patch.js +41 -0
  303. package/dist/utils/attribute-patch.js.map +7 -0
  304. package/dist/utils/error-hints.js +29 -0
  305. package/dist/utils/error-hints.js.map +7 -0
  306. package/dist/utils/errors.js +9 -3
  307. package/dist/utils/errors.js.map +2 -2
  308. package/dist/utils/id-generator.js +5 -2
  309. package/dist/utils/id-generator.js.map +2 -2
  310. package/dist/utils/project-paths.js +26 -1
  311. package/dist/utils/project-paths.js.map +2 -2
  312. package/dist/utils/source-reference.js +64 -31
  313. package/dist/utils/source-reference.js.map +2 -2
  314. package/dist/utils/spec-version.js +2 -2
  315. package/dist/utils/spec-version.js.map +1 -1
  316. package/dist/validators/composed-reference-validator.js +5 -27
  317. package/dist/validators/composed-reference-validator.js.map +2 -2
  318. package/dist/validators/model-warnings.js +28 -0
  319. package/dist/validators/model-warnings.js.map +7 -0
  320. package/dist/validators/reference-validator.js +0 -7
  321. package/dist/validators/reference-validator.js.map +2 -2
  322. package/dist/validators/relationship-schema-validator.js +3 -3
  323. package/dist/validators/relationship-schema-validator.js.map +2 -2
  324. package/dist/validators/schema-validator.js +27 -9
  325. package/dist/validators/schema-validator.js.map +2 -2
  326. package/dist/validators/types.js.map +1 -1
  327. package/dist/viewer/README.md +6 -6
  328. package/dist/viewer/assets/main-CUOQGGRA.css +1 -0
  329. package/dist/viewer/assets/main-DvH3gYrI.js +84 -0
  330. package/dist/viewer/index.html +2 -2
  331. package/dist/viewer/manifest.json +10 -10
  332. package/dist/viewer/version.json +1 -1
  333. package/package.json +2 -1
  334. package/dist/viewer/assets/main-B7AOQXXX.js +0 -81
  335. package/dist/viewer/assets/main-vdrFrG7q.css +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/core/mutation-handler.ts"],
4
- "sourcesContent": ["/**\n * MutationHandler - Unified mutation execution strategy\n *\n * Eliminates duplicate code paths by centralizing all element mutations.\n * Ensures consistency between staging and base model operations through\n * a single execution path that supports both.\n *\n * This fixes data corruption risk from divergent code paths in add/update/delete commands.\n */\n\nimport { Model } from \"./model.js\";\nimport { Element } from \"./element.js\";\nimport { StagingAreaManager } from \"./staging-area.js\";\nimport { isValidLayerName } from \"./layers.js\";\nimport { CLIError } from \"../utils/errors.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { ModelReportOrchestrator } from \"../reports/model-report-orchestrator.js\";\nimport { emitLog, SeverityNumber } from \"../telemetry/index.js\";\n\nexport type MutationType = \"add\" | \"update\" | \"delete\";\n\nexport interface MutationContext {\n model: Model;\n elementId: string;\n layerName: string;\n element?: Element;\n before?: Record<string, unknown>;\n after?: Record<string, unknown>;\n}\n\nexport interface MutationStep {\n execute: (context: MutationContext) => void | Promise<void>;\n stageable: boolean; // Can this step be executed in staging?\n description: string;\n}\n\n/**\n * Unified mutation executor\n *\n * Single point of mutation execution that:\n * 1. Builds complete before/after states\n * 2. Validates mutations\n * 3. Executes consistently for both staging and base model\n * 4. Handles all persistence atomically\n * 5. Tracks changes in legacy changeset context\n */\nexport class MutationHandler {\n private context: MutationContext;\n private steps: MutationStep[] = [];\n private stagingManager: StagingAreaManager;\n\n constructor(model: Model, elementId: string, layerName: string) {\n this.context = { model, elementId, layerName };\n this.stagingManager = new StagingAreaManager(model.rootPath, model);\n }\n\n /**\n * Set the element being mutated\n */\n setElement(element: Element): this {\n this.context.element = element;\n return this;\n }\n\n /**\n * Add a mutation step\n */\n addStep(step: MutationStep): this {\n this.steps.push(step);\n return this;\n }\n\n /**\n * Get before state (snapshot before mutations)\n */\n getBeforeState(): Record<string, unknown> | undefined {\n return this.context.before;\n }\n\n /**\n * Get after state (result of mutations)\n */\n getAfterState(): Record<string, unknown> | undefined {\n return this.context.after;\n }\n\n /**\n * Get staging manager for accessing changeset information\n */\n getStagingManager(): StagingAreaManager {\n return this.stagingManager;\n }\n\n /**\n * Compute before and after states\n *\n * For add: before is undefined, after is the new element state\n * For update: before is original state, after is modified state\n * For delete: before is original state, after is undefined\n */\n async computeStates(element: Element): Promise<void> {\n this.context.element = element;\n this.context.before = element.toJSON() as unknown as Record<string, unknown>;\n this.context.after = { ...this.context.before };\n }\n\n /**\n * Execute mutation for add operation\n */\n async executeAdd(\n element: Element,\n mutator: (elem: Element) => void | Promise<void>\n ): Promise<void> {\n // For add, before is undefined, after is the new element\n this.context.element = element;\n this.context.before = undefined;\n\n // Check if we're in staging mode\n const activeChangeset = await this.stagingManager.getActive();\n if (activeChangeset && activeChangeset.status === \"staged\") {\n // Staging path: capture after state and stage\n this.context.after = element.toJSON() as unknown as Record<string, unknown>;\n\n await this.stagingManager.stage(activeChangeset.id, {\n type: \"add\",\n elementId: this.context.elementId,\n layerName: this.context.layerName,\n after: this.context.after,\n timestamp: new Date().toISOString(),\n });\n return;\n }\n\n // Base model path: add element and persist\n await mutator(element);\n this.context.after = element.toJSON() as unknown as Record<string, unknown>;\n\n // Persist to base model\n await this._persistChanges(\"add\");\n }\n\n /**\n * Execute mutation for update operation\n */\n async executeUpdate(\n element: Element,\n mutator: (elem: Element, after: Record<string, unknown>) => Promise<void>\n ): Promise<void> {\n // Compute before and after states\n this.context.element = element;\n this.context.before = element.toJSON() as unknown as Record<string, unknown>;\n this.context.after = { ...this.context.before };\n\n // Check if we're in staging mode\n const activeChangeset = await this.stagingManager.getActive();\n if (activeChangeset && activeChangeset.status === \"staged\") {\n // Staging path: apply mutations to after state, then stage\n await mutator(element, this.context.after);\n\n await this.stagingManager.stage(activeChangeset.id, {\n type: \"update\",\n elementId: this.context.elementId,\n layerName: this.context.layerName,\n before: this.context.before,\n after: this.context.after,\n timestamp: new Date().toISOString(),\n });\n return;\n }\n\n // Base model path: apply mutations atomically\n await this._executeBasePath(mutator);\n }\n\n /**\n * Execute mutation for delete operation\n */\n async executeDelete(element: Element): Promise<void> {\n // For delete, before is the current state, after is undefined\n this.context.element = element;\n this.context.before = element.toJSON() as unknown as Record<string, unknown>;\n this.context.after = undefined;\n\n // Check if we're in staging mode\n const activeChangeset = await this.stagingManager.getActive();\n if (activeChangeset && activeChangeset.status === \"staged\") {\n // Staging path: stage the deletion only\n await this.stagingManager.stage(activeChangeset.id, {\n type: \"delete\",\n elementId: this.context.elementId,\n layerName: this.context.layerName,\n before: this.context.before,\n timestamp: new Date().toISOString(),\n });\n return;\n }\n\n // Base model path: delete from model\n const layer = (await this.context.model.getLayer(this.context.layerName))!;\n const deleted = layer.deleteElement(element.path || element.id);\n\n if (!deleted) {\n throw new CLIError(`Failed to delete element ${this.context.elementId}`, 1, [\n \"Element may have already been deleted\",\n ]);\n }\n\n // Delete relationships\n this.context.model.relationships.deleteForElement(this.context.elementId);\n\n // Track and save atomically\n await this._persistChanges(\"delete\");\n }\n\n /**\n * Execute all registered steps and persist\n */\n async execute(\n mutator: (elem: Element, after: Record<string, unknown>) => Promise<void>,\n type: \"add\" | \"update\" | \"delete\"\n ): Promise<void> {\n if (!this.context.element) {\n throw new CLIError(\"Element not set on MutationHandler\", 1);\n }\n\n // Check if we're in staging mode\n const activeChangeset = await this.stagingManager.getActive();\n if (activeChangeset && activeChangeset.status === \"staged\") {\n // Staging path: build after state and stage\n if (this.context.before === undefined && type !== \"add\") {\n this.context.before = this.context.element.toJSON() as unknown as Record<string, unknown>;\n }\n\n this.context.after =\n type === \"delete\"\n ? undefined\n : {\n ...(this.context.before ||\n (this.context.element.toJSON() as unknown as Record<string, unknown>)),\n };\n\n if (type !== \"delete\" && this.context.after) {\n await mutator(this.context.element, this.context.after);\n }\n\n await this.stagingManager.stage(activeChangeset.id, {\n type,\n elementId: this.context.elementId,\n layerName: this.context.layerName,\n ...(this.context.before !== undefined && { before: this.context.before }),\n ...(this.context.after !== undefined && { after: this.context.after }),\n timestamp: new Date().toISOString(),\n });\n return;\n }\n\n // Base model path: execute and persist atomically\n await this._executeBasePath(mutator, type);\n }\n\n /**\n * Base model path: execute mutations and persist atomically\n */\n private async _executeBasePath(\n mutator: (elem: Element, after: Record<string, unknown>) => Promise<void>,\n type?: string\n ): Promise<void> {\n if (!this.context.element) {\n throw new CLIError(\"Element not set\", 1);\n }\n\n // Initialize before state if not already set\n if (this.context.before === undefined) {\n this.context.before = this.context.element.toJSON() as unknown as Record<string, unknown>;\n }\n\n // Initialize after state if not already set\n if (this.context.after === undefined) {\n this.context.after = { ...this.context.before };\n }\n\n // Apply mutations to element AND after state together\n // This ensures they stay in sync\n await mutator(this.context.element, this.context.after);\n\n // Persist changes to disk\n await this._persistChanges(type);\n }\n\n /**\n * Persist changes to disk\n *\n * Performs sequential writes to layer, relationships, and manifest files.\n * If any write fails, subsequent writes are skipped via error propagation.\n * Note: Not truly atomic\u2014if a write succeeds then a later write fails,\n * earlier writes remain on disk. Use within transaction-like contexts only.\n */\n private async _persistChanges(type?: string): Promise<void> {\n try {\n // Save layer\n await this.context.model.saveLayer(this.context.layerName);\n\n // Save relationships if modified (for deletes)\n if (type === \"delete\" && this.context.model.relationships.isDirty()) {\n await this.context.model.saveRelationships();\n }\n\n // Save manifest\n await this.context.model.saveManifest();\n } catch (error) {\n throw new CLIError(\n `Failed to persist changes: ${getErrorMessage(error)}`,\n 1,\n [\"Check that the model directory is writable\", \"Verify the model is not corrupted\"]\n );\n }\n\n // Post-persist: regenerate affected layer reports (non-blocking, FR-4)\n // This is a separate try/catch from the above to ensure report failures never cause mutations to fail\n try {\n const orchestrator = new ModelReportOrchestrator(\n this.context.model,\n this.context.model.rootPath\n );\n if (isValidLayerName(this.context.layerName)) {\n const affected = orchestrator.computeAffectedLayers(this.context.layerName);\n await orchestrator.regenerate(affected);\n } else {\n emitLog(SeverityNumber.WARN, \"Report regeneration skipped: invalid layer name\", {\n \"layer.name\": this.context.layerName,\n \"elementId\": this.context.elementId,\n });\n }\n } catch (error) {\n emitLog(SeverityNumber.WARN, \"Failed to update layer reports after mutation\", {\n \"error\": getErrorMessage(error),\n \"layer.name\": this.context.layerName,\n \"elementId\": this.context.elementId,\n });\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * MutationHandler - Unified mutation execution strategy\n *\n * Eliminates duplicate code paths by centralizing all element mutations.\n * Ensures consistency between staging and base model operations through\n * a single execution path that supports both.\n *\n * This fixes data corruption risk from divergent code paths in add/update/delete commands.\n */\n\nimport { Model } from \"./model.js\";\nimport { Element } from \"./element.js\";\nimport { elementIdentifiers } from \"./relationships.js\";\nimport { StagingAreaManager } from \"./staging-area.js\";\nimport { isValidLayerName } from \"./layers.js\";\nimport { CLIError } from \"../utils/errors.js\";\nimport { ChangesetOnlyError } from \"./changeset-only-guard.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { ModelReportOrchestrator } from \"../reports/model-report-orchestrator.js\";\nimport { emitLog, SeverityNumber } from \"../telemetry/index.js\";\nimport type { Changeset, StagedChange } from \"./changeset.js\";\nimport { changedFields } from \"./changeset-summary.js\";\n\n/**\n * An element snapshot staged by an add, with an update applied: the top-level keys the update\n * changed (before vs after) take their new value, and a key the update cleared is removed. Keys the\n * update did not touch keep the add's own value, so the add's shape is preserved.\n */\nexport function foldIntoSnapshot(\n addAfter: Record<string, unknown>,\n before: Record<string, unknown> | undefined,\n after: Record<string, unknown> | undefined\n): Record<string, unknown> {\n const folded = { ...addAfter };\n const b = before ?? {};\n const a = after ?? {};\n for (const key of new Set([...Object.keys(b), ...Object.keys(a)])) {\n if (JSON.stringify(b[key]) === JSON.stringify(a[key])) continue;\n if (a[key] === undefined) {\n delete folded[key];\n } else {\n folded[key] = a[key];\n }\n }\n // A cleared source reference is written as `source_reference: null`; drop the legacy camelCase key\n // so it cannot shadow it.\n if (\"source_reference\" in a && JSON.stringify(b.source_reference) !== JSON.stringify(a.source_reference)) {\n delete folded.sourceReference;\n }\n return folded;\n}\n\nexport type MutationType = \"add\" | \"update\" | \"delete\";\n\nexport interface MutationContext {\n model: Model;\n elementId: string;\n layerName: string;\n element?: Element;\n before?: Record<string, unknown>;\n after?: Record<string, unknown>;\n}\n\nexport interface MutationStep {\n execute: (context: MutationContext) => void | Promise<void>;\n stageable: boolean; // Can this step be executed in staging?\n description: string;\n}\n\n/**\n * Unified mutation executor\n *\n * Single point of mutation execution that:\n * 1. Builds complete before/after states\n * 2. Validates mutations\n * 3. Executes consistently for both staging and base model\n * 4. Handles all persistence atomically\n * 5. Tracks changes in legacy changeset context\n */\nexport class MutationHandler {\n private context: MutationContext;\n private steps: MutationStep[] = [];\n private stagingManager: StagingAreaManager;\n private changedFields: string[] = [];\n private foldedIntoAdd = false;\n\n constructor(model: Model, elementId: string, layerName: string) {\n this.context = { model, elementId, layerName };\n this.stagingManager = new StagingAreaManager(model.rootPath, model);\n }\n\n /**\n * Set the element being mutated\n */\n setElement(element: Element): this {\n this.context.element = element;\n return this;\n }\n\n /**\n * Add a mutation step\n */\n addStep(step: MutationStep): this {\n this.steps.push(step);\n return this;\n }\n\n /**\n * Get before state (snapshot before mutations)\n */\n getBeforeState(): Record<string, unknown> | undefined {\n return this.context.before;\n }\n\n /**\n * Get after state (result of mutations)\n */\n getAfterState(): Record<string, unknown> | undefined {\n return this.context.after;\n }\n\n /**\n * Get staging manager for accessing changeset information\n */\n getStagingManager(): StagingAreaManager {\n return this.stagingManager;\n }\n\n /**\n * The fields the last executeUpdate changed (`attributes.x` for attribute keys), sorted.\n * Empty before an update runs or when it changed nothing.\n */\n getChangedFields(): string[] {\n return this.changedFields;\n }\n\n /** Whether the last executeUpdate rewrote the changeset's staged add of the element in place. */\n wasFoldedIntoAdd(): boolean {\n return this.foldedIntoAdd;\n }\n\n /**\n * The active changeset's add of this element, when an update should be folded into it: the\n * add is the element's only staged element change (an update staged after it by an earlier\n * build keeps the old append behaviour, so it is not overridden), and the base model does not\n * already hold the element (commit skips such an add; a staged update still applies).\n */\n private async stagedAddToFoldInto(changeset: Changeset, element: Element): Promise<StagedChange | null> {\n const ids = new Set(elementIdentifiers(element, this.context.elementId));\n const own = (changeset.changes as StagedChange[]).filter(\n (c) => !c.type.startsWith(\"relationship-\") && ids.has(c.elementId)\n );\n if (own.length !== 1 || own[0].type !== \"add\" || !own[0].after) return null;\n const baseLayer = await this.context.model.getBaseLayer(this.context.layerName);\n if ([...ids].some((id) => baseLayer?.getElement(id))) return null;\n return own[0];\n }\n\n /**\n * Compute before and after states\n *\n * For add: before is undefined, after is the new element state\n * For update: before is original state, after is modified state\n * For delete: before is original state, after is undefined\n */\n async computeStates(element: Element): Promise<void> {\n this.context.element = element;\n this.context.before = element.toJSON() as unknown as Record<string, unknown>;\n this.context.after = { ...this.context.before };\n }\n\n /**\n * Execute mutation for add operation\n */\n async executeAdd(\n element: Element,\n mutator: (elem: Element) => void | Promise<void>\n ): Promise<void> {\n // For add, before is undefined, after is the new element\n this.context.element = element;\n this.context.before = undefined;\n\n // Check if we're in staging mode\n const activeChangeset = await this.stagingManager.getActive();\n if (activeChangeset && activeChangeset.status === \"staged\") {\n // Staging path: capture after state and stage\n this.context.after = element.toJSON() as unknown as Record<string, unknown>;\n\n await this.stagingManager.stage(activeChangeset.id, {\n type: \"add\",\n elementId: this.context.elementId,\n layerName: this.context.layerName,\n after: this.context.after,\n timestamp: new Date().toISOString(),\n });\n return;\n }\n\n // Base model path: add element and persist\n await mutator(element);\n this.context.after = element.toJSON() as unknown as Record<string, unknown>;\n\n // Persist to base model\n await this._persistChanges(\"add\");\n }\n\n /**\n * Execute mutation for update operation\n */\n async executeUpdate(\n element: Element,\n mutator: (elem: Element, after: Record<string, unknown>) => Promise<void>\n ): Promise<void> {\n // Compute before and after states\n this.context.element = element;\n this.context.before = element.toJSON() as unknown as Record<string, unknown>;\n this.context.after = { ...this.context.before };\n\n // Check if we're in staging mode\n const activeChangeset = await this.stagingManager.getActive();\n if (activeChangeset && activeChangeset.status === \"staged\") {\n // Staging path: apply mutations to after state, then stage\n await mutator(element, this.context.after);\n this.changedFields = changedFields(this.context.before, this.context.after);\n\n // An element this changeset adds: rewrite the add's snapshot rather than stacking an update.\n const add = await this.stagedAddToFoldInto(activeChangeset, element);\n if (add) {\n await this.stagingManager.restage(activeChangeset.id, add.elementId, {\n type: \"add\",\n elementId: add.elementId,\n layerName: add.layerName,\n ...(add.before !== undefined ? { before: add.before } : {}),\n after: foldIntoSnapshot(add.after!, this.context.before, this.context.after),\n timestamp: new Date().toISOString(),\n });\n this.foldedIntoAdd = true;\n return;\n }\n\n await this.stagingManager.stage(activeChangeset.id, {\n type: \"update\",\n elementId: this.context.elementId,\n layerName: this.context.layerName,\n before: this.context.before,\n after: this.context.after,\n timestamp: new Date().toISOString(),\n });\n return;\n }\n\n // Base model path: apply mutations atomically\n await this._executeBasePath(mutator);\n }\n\n /**\n * Execute mutation for delete operation\n */\n async executeDelete(element: Element): Promise<void> {\n // For delete, before is the current state, after is undefined\n this.context.element = element;\n this.context.before = element.toJSON() as unknown as Record<string, unknown>;\n this.context.after = undefined;\n\n // Every identifier relationships.yaml may use for this element: UUID id, dotted\n // path, and whatever the caller addressed it by.\n const identifiers = elementIdentifiers(element, this.context.elementId);\n\n // Check if we're in staging mode\n const activeChangeset = await this.stagingManager.getActive();\n if (activeChangeset && activeChangeset.status === \"staged\") {\n // Staging path: stage the deletion, then stage the removal of every\n // relationship that names the element so the commit leaves no dangling rows\n // (and so commit validation does not reject the changeset for them).\n await this.stagingManager.stage(activeChangeset.id, {\n type: \"delete\",\n elementId: this.context.elementId,\n layerName: this.context.layerName,\n before: this.context.before,\n timestamp: new Date().toISOString(),\n });\n\n const ids = new Set(identifiers);\n // A cascade delete stages one handler per element; a row between two deleted\n // elements must not be staged for removal twice.\n const alreadyStaged = new Set(\n activeChangeset.changes\n .filter((change) => change.type === \"relationship-delete\")\n .map((change) => change.elementId)\n );\n const dangling = this.context.model.relationships\n .getAll()\n .filter((rel) => ids.has(rel.source) || ids.has(rel.target))\n .filter((rel) => !alreadyStaged.has(`${rel.source}::${rel.predicate}::${rel.target}`));\n for (const rel of dangling) {\n alreadyStaged.add(`${rel.source}::${rel.predicate}::${rel.target}`);\n await this.stagingManager.stage(activeChangeset.id, {\n type: \"relationship-delete\",\n elementId: `${rel.source}::${rel.predicate}::${rel.target}`,\n layerName: rel.layer,\n before: {\n source: rel.source,\n target: rel.target,\n predicate: rel.predicate,\n layer: rel.layer,\n ...(rel.targetLayer ? { targetLayer: rel.targetLayer } : {}),\n ...(rel.properties ? { properties: rel.properties } : {}),\n },\n timestamp: new Date().toISOString(),\n });\n }\n return;\n }\n\n // Base model path: delete from model\n const layer = (await this.context.model.getLayer(this.context.layerName))!;\n const deleted = layer.deleteElement(element.path || element.id);\n\n if (!deleted) {\n throw new CLIError(`Failed to delete element ${this.context.elementId}`, 1, [\n \"Element may have already been deleted\",\n ]);\n }\n\n // Delete relationships that name the element by UUID or by path\n this.context.model.relationships.deleteForElement(identifiers);\n\n // Track and save atomically\n await this._persistChanges(\"delete\");\n }\n\n /**\n * Execute all registered steps and persist\n */\n async execute(\n mutator: (elem: Element, after: Record<string, unknown>) => Promise<void>,\n type: \"add\" | \"update\" | \"delete\"\n ): Promise<void> {\n if (!this.context.element) {\n throw new CLIError(\"Element not set on MutationHandler\", 1);\n }\n\n // Check if we're in staging mode\n const activeChangeset = await this.stagingManager.getActive();\n if (activeChangeset && activeChangeset.status === \"staged\") {\n // Staging path: build after state and stage\n if (this.context.before === undefined && type !== \"add\") {\n this.context.before = this.context.element.toJSON() as unknown as Record<string, unknown>;\n }\n\n this.context.after =\n type === \"delete\"\n ? undefined\n : {\n ...(this.context.before ||\n (this.context.element.toJSON() as unknown as Record<string, unknown>)),\n };\n\n if (type !== \"delete\" && this.context.after) {\n await mutator(this.context.element, this.context.after);\n }\n\n await this.stagingManager.stage(activeChangeset.id, {\n type,\n elementId: this.context.elementId,\n layerName: this.context.layerName,\n ...(this.context.before !== undefined && { before: this.context.before }),\n ...(this.context.after !== undefined && { after: this.context.after }),\n timestamp: new Date().toISOString(),\n });\n return;\n }\n\n // Base model path: execute and persist atomically\n await this._executeBasePath(mutator, type);\n }\n\n /**\n * Base model path: execute mutations and persist atomically\n */\n private async _executeBasePath(\n mutator: (elem: Element, after: Record<string, unknown>) => Promise<void>,\n type?: string\n ): Promise<void> {\n if (!this.context.element) {\n throw new CLIError(\"Element not set\", 1);\n }\n\n // Initialize before state if not already set\n if (this.context.before === undefined) {\n this.context.before = this.context.element.toJSON() as unknown as Record<string, unknown>;\n }\n\n // Initialize after state if not already set\n if (this.context.after === undefined) {\n this.context.after = { ...this.context.before };\n }\n\n // Apply mutations to element AND after state together\n // This ensures they stay in sync\n await mutator(this.context.element, this.context.after);\n this.changedFields = changedFields(this.context.before, this.context.after);\n\n // Persist changes to disk\n await this._persistChanges(type);\n }\n\n /**\n * Persist changes to disk\n *\n * Performs sequential writes to layer, relationships, and manifest files.\n * If any write fails, subsequent writes are skipped via error propagation.\n * Note: Not truly atomic\u2014if a write succeeds then a later write fails,\n * earlier writes remain on disk. Use within transaction-like contexts only.\n */\n private async _persistChanges(type?: string): Promise<void> {\n try {\n // Save layer\n await this.context.model.saveLayer(this.context.layerName);\n\n // Save relationships if modified (for deletes)\n if (type === \"delete\" && this.context.model.relationships.isDirty()) {\n await this.context.model.saveRelationships();\n }\n\n // Save manifest\n await this.context.model.saveManifest();\n } catch (error) {\n // A changeset-only refusal is not a disk failure: keep it recognisable for callers.\n if (error instanceof ChangesetOnlyError) throw error;\n throw new CLIError(\n `Failed to persist changes: ${getErrorMessage(error)}`,\n 1,\n [\"Check that the model directory is writable\", \"Verify the model is not corrupted\"]\n );\n }\n\n // Post-persist: regenerate affected layer reports (non-blocking, FR-4)\n // This is a separate try/catch from the above to ensure report failures never cause mutations to fail\n try {\n const orchestrator = new ModelReportOrchestrator(\n this.context.model,\n this.context.model.rootPath\n );\n if (isValidLayerName(this.context.layerName)) {\n const affected = orchestrator.computeAffectedLayers(this.context.layerName);\n await orchestrator.regenerate(affected);\n } else {\n emitLog(SeverityNumber.WARN, \"Report regeneration skipped: invalid layer name\", {\n \"layer.name\": this.context.layerName,\n \"elementId\": this.context.elementId,\n });\n }\n } catch (error) {\n emitLog(SeverityNumber.WARN, \"Failed to update layer reports after mutation\", {\n \"error\": getErrorMessage(error),\n \"layer.name\": this.context.layerName,\n \"elementId\": this.context.elementId,\n });\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,53 @@
1
+ import { join } from "path";
2
+ import { Model } from "./model.js";
3
+ import { fileExists } from "../utils/file-io.js";
4
+ import { logVerbose as globalLogVerbose, logDebug as globalLogDebug } from "../utils/globals.js";
5
+ import { installSpecReference } from "../utils/spec-installer.js";
6
+ import { getCliBundledSpecVersion } from "../utils/spec-version.js";
7
+ import { getErrorMessage } from "../utils/errors.js";
8
+ import { regenerateLayerReports } from "../commands/reports.js";
9
+ function modelManifestPath(rootPath) {
10
+ return join(rootPath, "documentation-robotics", "model", "manifest.yaml");
11
+ }
12
+ async function hasModel(rootPath) {
13
+ return fileExists(modelManifestPath(rootPath));
14
+ }
15
+ async function initProject(rootPath, options) {
16
+ if (await hasModel(rootPath))
17
+ throw new Error(`A model already exists in ${rootPath}`);
18
+ const logVerbose = options.logVerbose ?? globalLogVerbose, logDebug = options.logDebug ?? globalLogDebug, specVersion = getCliBundledSpecVersion(), modelPath = join(rootPath, "documentation-robotics", "model");
19
+ logDebug(`Creating model directory at ${rootPath}/documentation-robotics/model`);
20
+ const model = await Model.init(rootPath, {
21
+ name: options.name,
22
+ version: "0.1.0",
23
+ description: options.description || void 0,
24
+ author: options.author || void 0,
25
+ specVersion,
26
+ created: (/* @__PURE__ */ new Date()).toISOString()
27
+ }, { lazyLoad: !1 });
28
+ logVerbose(`Model saved with:
29
+ - Version: 0.1.0
30
+ - Spec Version: ${specVersion}
31
+ - Location: ${rootPath}/documentation-robotics/model`), logDebug("Installing spec reference (.dr/ folder)..."), await installSpecReference(rootPath, !1), logVerbose("Spec reference installed");
32
+ let reportError;
33
+ logDebug("Generating reports and README...");
34
+ try {
35
+ await regenerateLayerReports(rootPath, options.log), logVerbose("Reports and README generated");
36
+ } catch (error) {
37
+ reportError = getErrorMessage(error), logDebug(`Report generation failed (non-fatal): ${reportError}`);
38
+ }
39
+ return {
40
+ rootPath,
41
+ modelPath,
42
+ name: model.manifest.name,
43
+ version: "0.1.0",
44
+ specVersion,
45
+ ...reportError !== void 0 ? { reportError } : {}
46
+ };
47
+ }
48
+ export {
49
+ hasModel,
50
+ initProject,
51
+ modelManifestPath
52
+ };
53
+ //# sourceMappingURL=project-init.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/project-init.ts"],
4
+ "sourcesContent": ["/**\n * Project init - creates an empty model at the CLI's spec version in a folder.\n *\n * Shared by `dr init` (which gathers the name and the rest by prompting) and the\n * `project_init` MCP tool (which takes them as arguments). Neither installs per-project\n * integration files: `dr claude install` and the Claude Code plugin do that.\n */\n\nimport { join } from \"path\";\nimport { Model } from \"./model.js\";\nimport { fileExists } from \"../utils/file-io.js\";\nimport { logVerbose as globalLogVerbose, logDebug as globalLogDebug } from \"../utils/globals.js\";\nimport { installSpecReference } from \"../utils/spec-installer.js\";\nimport { getCliBundledSpecVersion } from \"../utils/spec-version.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { regenerateLayerReports } from \"../commands/reports.js\";\n\nexport interface ProjectInitOptions {\n name: string;\n description?: string;\n author?: string;\n /** Where progress lines go; `dr init` prints them, the MCP server must not write stdout. */\n log?: (message: string) => void;\n /** Where --verbose lines go (default: stdout when verbose is on). */\n logVerbose?: (message: string) => void;\n /** Where --debug lines go (default: console.debug when debug is on). */\n logDebug?: (message: string) => void;\n}\n\nexport interface ProjectInitResult {\n rootPath: string;\n modelPath: string;\n name: string;\n version: string;\n specVersion: string;\n /** Set when the model was created but its layer reports and README could not be generated. */\n reportError?: string;\n}\n\n/** The manifest path of the model in a folder (not searching parent folders). */\nexport function modelManifestPath(rootPath: string): string {\n return join(rootPath, \"documentation-robotics\", \"model\", \"manifest.yaml\");\n}\n\n/** Whether the folder already holds a model. */\nexport async function hasModel(rootPath: string): Promise<boolean> {\n return fileExists(modelManifestPath(rootPath));\n}\n\n/**\n * Create the model in rootPath, install the spec reference (.dr/) and generate the layer\n * reports and README. Throws when the folder already has a model. A report failure doesn't\n * fail the init: it comes back as reportError.\n */\nexport async function initProject(rootPath: string, options: ProjectInitOptions): Promise<ProjectInitResult> {\n if (await hasModel(rootPath)) {\n throw new Error(`A model already exists in ${rootPath}`);\n }\n\n const logVerbose = options.logVerbose ?? globalLogVerbose;\n const logDebug = options.logDebug ?? globalLogDebug;\n const specVersion = getCliBundledSpecVersion();\n const modelPath = join(rootPath, \"documentation-robotics\", \"model\");\n\n logDebug(`Creating model directory at ${rootPath}/documentation-robotics/model`);\n const model = await Model.init(\n rootPath,\n {\n name: options.name,\n version: \"0.1.0\",\n description: options.description || undefined,\n author: options.author || undefined,\n specVersion,\n created: new Date().toISOString(),\n },\n { lazyLoad: false }\n );\n\n logVerbose(`Model saved with:\n - Version: 0.1.0\n - Spec Version: ${specVersion}\n - Location: ${rootPath}/documentation-robotics/model`);\n\n logDebug(\"Installing spec reference (.dr/ folder)...\");\n await installSpecReference(rootPath, false);\n logVerbose(\"Spec reference installed\");\n\n let reportError: string | undefined;\n logDebug(\"Generating reports and README...\");\n try {\n await regenerateLayerReports(rootPath, options.log);\n logVerbose(\"Reports and README generated\");\n } catch (error) {\n reportError = getErrorMessage(error);\n logDebug(`Report generation failed (non-fatal): ${reportError}`);\n }\n\n return {\n rootPath,\n modelPath,\n name: model.manifest.name,\n version: \"0.1.0\",\n specVersion,\n ...(reportError !== undefined ? { reportError } : {}),\n };\n}\n"],
5
+ "mappings": "AAQA,SAAS,YAAY;AACrB,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAC3B,SAAS,cAAc,kBAAkB,YAAY,sBAAsB;AAC3E,SAAS,4BAA4B;AACrC,SAAS,gCAAgC;AACzC,SAAS,uBAAuB;AAChC,SAAS,8BAA8B;AAyBjC,SAAU,kBAAkB,UAAgB;AAChD,SAAO,KAAK,UAAU,0BAA0B,SAAS,eAAe;AAC1E;AAGA,eAAsB,SAAS,UAAgB;AAC7C,SAAO,WAAW,kBAAkB,QAAQ,CAAC;AAC/C;AAOA,eAAsB,YAAY,UAAkB,SAA2B;AAC7E,MAAI,MAAM,SAAS,QAAQ;AACzB,UAAM,IAAI,MAAM,6BAA6B,QAAQ,EAAE;AAGzD,QAAM,aAAa,QAAQ,cAAc,kBACnC,WAAW,QAAQ,YAAY,gBAC/B,cAAc,yBAAwB,GACtC,YAAY,KAAK,UAAU,0BAA0B,OAAO;AAElE,WAAS,+BAA+B,QAAQ,+BAA+B;AAC/E,QAAM,QAAQ,MAAM,MAAM,KACxB,UACA;IACE,MAAM,QAAQ;IACd,SAAS;IACT,aAAa,QAAQ,eAAe;IACpC,QAAQ,QAAQ,UAAU;IAC1B;IACA,UAAS,oBAAI,KAAI,GAAG,YAAW;KAEjC,EAAE,UAAU,GAAK,CAAE;AAGrB,aAAW;;oBAEO,WAAW;gBACf,QAAQ,+BAA+B,GAErD,SAAS,4CAA4C,GACrD,MAAM,qBAAqB,UAAU,EAAK,GAC1C,WAAW,0BAA0B;AAErC,MAAI;AACJ,WAAS,kCAAkC;AAC3C,MAAI;AACF,UAAM,uBAAuB,UAAU,QAAQ,GAAG,GAClD,WAAW,8BAA8B;EAC3C,SAAS,OAAO;AACd,kBAAc,gBAAgB,KAAK,GACnC,SAAS,yCAAyC,WAAW,EAAE;EACjE;AAEA,SAAO;IACL;IACA;IACA,MAAM,MAAM,SAAS;IACrB,SAAS;IACT;IACA,GAAI,gBAAgB,SAAY,EAAE,YAAW,IAAK,CAAA;;AAEtD;",
6
+ "names": []
7
+ }