@documentation-robotics/cli 0.2.0 → 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 (269) hide show
  1. package/README.md +36 -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/audit/relationships/ai/prompts.js +10 -10
  34. package/dist/audit/relationships/ai/prompts.js.map +2 -2
  35. package/dist/audit/relationships/analysis/layer-templates.js +52 -52
  36. package/dist/audit/relationships/analysis/layer-templates.js.map +1 -1
  37. package/dist/cli.js +12 -2
  38. package/dist/cli.js.map +2 -2
  39. package/dist/coding-agents/default-permissions.js +31 -1
  40. package/dist/coding-agents/default-permissions.js.map +2 -2
  41. package/dist/coding-agents/drbot-mcp.js +167 -0
  42. package/dist/coding-agents/drbot-mcp.js.map +7 -0
  43. package/dist/commands/add.js +3 -2
  44. package/dist/commands/add.js.map +2 -2
  45. package/dist/commands/analyzer.js +117 -14
  46. package/dist/commands/analyzer.js.map +2 -2
  47. package/dist/commands/changeset-verify.js +55 -0
  48. package/dist/commands/changeset-verify.js.map +7 -0
  49. package/dist/commands/changeset.js +43 -22
  50. package/dist/commands/changeset.js.map +2 -2
  51. package/dist/commands/delete.js +10 -4
  52. package/dist/commands/delete.js.map +2 -2
  53. package/dist/commands/farm.js +176 -60
  54. package/dist/commands/farm.js.map +2 -2
  55. package/dist/commands/mcp.js +19 -4
  56. package/dist/commands/mcp.js.map +2 -2
  57. package/dist/commands/relationship.js +207 -26
  58. package/dist/commands/relationship.js.map +2 -2
  59. package/dist/commands/update.js +42 -23
  60. package/dist/commands/update.js.map +2 -2
  61. package/dist/commands/upgrade.js +99 -11
  62. package/dist/commands/upgrade.js.map +3 -3
  63. package/dist/commands/version.js +1 -1
  64. package/dist/commands/visualize.js +4 -3
  65. package/dist/commands/visualize.js.map +2 -2
  66. package/dist/core/catalog-migration.js +33 -0
  67. package/dist/core/catalog-migration.js.map +7 -0
  68. package/dist/core/changeset-analysis.js +421 -0
  69. package/dist/core/changeset-analysis.js.map +7 -0
  70. package/dist/core/changeset-base-index.js +153 -0
  71. package/dist/core/changeset-base-index.js.map +7 -0
  72. package/dist/core/changeset-brief-delta.js +102 -0
  73. package/dist/core/changeset-brief-delta.js.map +7 -0
  74. package/dist/core/changeset-graph.js +281 -0
  75. package/dist/core/changeset-graph.js.map +7 -0
  76. package/dist/core/changeset-only-guard.js +32 -0
  77. package/dist/core/changeset-only-guard.js.map +7 -0
  78. package/dist/core/changeset-summary.js +68 -0
  79. package/dist/core/changeset-summary.js.map +7 -0
  80. package/dist/core/changeset-validator.js +66 -20
  81. package/dist/core/changeset-validator.js.map +2 -2
  82. package/dist/core/changeset-verify.js +518 -0
  83. package/dist/core/changeset-verify.js.map +7 -0
  84. package/dist/core/changeset.js +56 -9
  85. package/dist/core/changeset.js.map +2 -2
  86. package/dist/core/element-type-migration.js +145 -0
  87. package/dist/core/element-type-migration.js.map +7 -0
  88. package/dist/core/farm-manifest.js +12 -6
  89. package/dist/core/farm-manifest.js.map +2 -2
  90. package/dist/core/farm-sync-engine.js +1 -1
  91. package/dist/core/farm-sync-engine.js.map +2 -2
  92. package/dist/core/farm-sync-state.js +10 -2
  93. package/dist/core/farm-sync-state.js.map +2 -2
  94. package/dist/core/migration-registry.js +75 -46
  95. package/dist/core/migration-registry.js.map +2 -2
  96. package/dist/core/model-upgrade.js +102 -0
  97. package/dist/core/model-upgrade.js.map +7 -0
  98. package/dist/core/model.js +82 -30
  99. package/dist/core/model.js.map +2 -2
  100. package/dist/core/mutation-handler.js +71 -6
  101. package/dist/core/mutation-handler.js.map +2 -2
  102. package/dist/core/relationship-migration-table.js +6639 -0
  103. package/dist/core/relationship-migration-table.js.map +7 -0
  104. package/dist/core/relationship-migration.js +272 -0
  105. package/dist/core/relationship-migration.js.map +7 -0
  106. package/dist/core/relationship-prune.js +49 -0
  107. package/dist/core/relationship-prune.js.map +7 -0
  108. package/dist/core/relationship-staging.js +68 -0
  109. package/dist/core/relationship-staging.js.map +7 -0
  110. package/dist/core/relationships.js +26 -4
  111. package/dist/core/relationships.js.map +2 -2
  112. package/dist/core/report-data-model.js +7 -13
  113. package/dist/core/report-data-model.js.map +2 -2
  114. package/dist/core/staged-changeset-storage.js +64 -17
  115. package/dist/core/staged-changeset-storage.js.map +2 -2
  116. package/dist/core/staged-source-reference.js +28 -0
  117. package/dist/core/staged-source-reference.js.map +7 -0
  118. package/dist/core/staging-area.js +83 -18
  119. package/dist/core/staging-area.js.map +2 -2
  120. package/dist/core/virtual-projection.js +13 -5
  121. package/dist/core/virtual-projection.js.map +2 -2
  122. package/dist/export/archimate-exporter.js +1 -0
  123. package/dist/export/archimate-exporter.js.map +2 -2
  124. package/dist/generated/compiled-validators.js +2 -2
  125. package/dist/generated/compiled-validators.js.map +2 -2
  126. package/dist/generated/layer-registry.js +16 -16
  127. package/dist/generated/layer-registry.js.map +2 -2
  128. package/dist/generated/node-types.js +186 -168
  129. package/dist/generated/node-types.js.map +2 -2
  130. package/dist/generated/relationship-index.js +2236 -7790
  131. package/dist/generated/relationship-index.js.map +2 -2
  132. package/dist/integrations/claude_code/agents/dr-architect.md +16 -3
  133. package/dist/integrations/claude_code/agents/dr-extractor.md +1 -1
  134. package/dist/integrations/claude_code/commands/dr-analyzer.md +565 -0
  135. package/dist/integrations/claude_code/commands/dr-map.md +13 -0
  136. package/dist/integrations/claude_code/commands/dr-plan.md +40 -0
  137. package/dist/integrations/claude_code/commands/dr-relate.md +106 -96
  138. package/dist/integrations/claude_code/commands/dr-verify.md +45 -2
  139. package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +14 -0
  140. package/dist/integrations/claude_code/docs/MCP_SERVER.md +26 -2
  141. package/dist/integrations/claude_code/docs/QUICK_START.md +37 -8
  142. package/dist/integrations/claude_code/docs/README.md +48 -1
  143. package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +93 -72
  144. package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +163 -126
  145. package/dist/integrations/claude_code/skills/dr_03_product_layer/SKILL.md +161 -126
  146. package/dist/integrations/claude_code/skills/dr_04_security_layer/SKILL.md +153 -133
  147. package/dist/integrations/claude_code/skills/dr_05_application_layer/SKILL.md +129 -100
  148. package/dist/integrations/claude_code/skills/dr_06_technology_layer/SKILL.md +111 -94
  149. package/dist/integrations/claude_code/skills/dr_07_api_layer/SKILL.md +143 -157
  150. package/dist/integrations/claude_code/skills/dr_08_data_model_layer/SKILL.md +117 -33
  151. package/dist/integrations/claude_code/skills/dr_09_dataset_layer/SKILL.md +74 -25
  152. package/dist/integrations/claude_code/skills/dr_10_ux_layer/SKILL.md +88 -12
  153. package/dist/integrations/claude_code/skills/dr_11_navigation_layer/SKILL.md +83 -24
  154. package/dist/integrations/claude_code/skills/dr_12_apm_layer/SKILL.md +57 -12
  155. package/dist/integrations/claude_code/skills/dr_13_testing_layer/SKILL.md +92 -15
  156. package/dist/integrations/claude_code/skills/dr_change_planning/SKILL.md +119 -0
  157. package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +3 -0
  158. package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +1 -1
  159. package/dist/integrations/github_copilot/agents/dr-architect.md +1 -1
  160. package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +182 -102
  161. package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +266 -148
  162. package/dist/integrations/github_copilot/skills/dr_03_product_layer/SKILL.md +547 -86
  163. package/dist/integrations/github_copilot/skills/dr_04_security_layer/SKILL.md +164 -169
  164. package/dist/integrations/github_copilot/skills/dr_05_application_layer/SKILL.md +420 -150
  165. package/dist/integrations/github_copilot/skills/dr_06_technology_layer/SKILL.md +331 -138
  166. package/dist/integrations/github_copilot/skills/dr_07_api_layer/SKILL.md +265 -201
  167. package/dist/integrations/github_copilot/skills/dr_08_data_model_layer/SKILL.md +181 -58
  168. package/dist/integrations/github_copilot/skills/dr_09_dataset_layer/SKILL.md +209 -57
  169. package/dist/integrations/github_copilot/skills/dr_10_ux_layer/SKILL.md +277 -112
  170. package/dist/integrations/github_copilot/skills/dr_11_navigation_layer/SKILL.md +219 -70
  171. package/dist/integrations/github_copilot/skills/dr_12_apm_layer/SKILL.md +189 -105
  172. package/dist/integrations/github_copilot/skills/dr_13_testing_layer/SKILL.md +222 -102
  173. package/dist/integrations/github_copilot/skills/dr_change_planning/SKILL.md +119 -0
  174. package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +3 -0
  175. package/dist/integrations/hash-utils.js.map +2 -2
  176. package/dist/mcp/api-key-manager.js +14 -1
  177. package/dist/mcp/api-key-manager.js.map +2 -2
  178. package/dist/mcp/changeset-only.js +34 -0
  179. package/dist/mcp/changeset-only.js.map +7 -0
  180. package/dist/mcp/tool-registry.js +19 -3
  181. package/dist/mcp/tool-registry.js.map +2 -2
  182. package/dist/mcp/tools/changeset-analysis-tools.js +78 -0
  183. package/dist/mcp/tools/changeset-analysis-tools.js.map +7 -0
  184. package/dist/mcp/tools/changeset-editing.js +184 -0
  185. package/dist/mcp/tools/changeset-editing.js.map +7 -0
  186. package/dist/mcp/tools/changeset-lifecycle.js +83 -0
  187. package/dist/mcp/tools/changeset-lifecycle.js.map +7 -0
  188. package/dist/mcp/tools/changeset-shared.js +31 -0
  189. package/dist/mcp/tools/changeset-shared.js.map +7 -0
  190. package/dist/mcp/tools/changeset-show.js +17 -1
  191. package/dist/mcp/tools/changeset-show.js.map +2 -2
  192. package/dist/mcp/tools/changeset-verify.js +43 -0
  193. package/dist/mcp/tools/changeset-verify.js.map +7 -0
  194. package/dist/mcp/tools/index.js +19 -1
  195. package/dist/mcp/tools/index.js.map +2 -2
  196. package/dist/mcp/tools/model-add.js +6 -5
  197. package/dist/mcp/tools/model-add.js.map +2 -2
  198. package/dist/mcp/tools/model-delete.js +2 -2
  199. package/dist/mcp/tools/model-delete.js.map +2 -2
  200. package/dist/mcp/tools/model-search.js +14 -0
  201. package/dist/mcp/tools/model-search.js.map +2 -2
  202. package/dist/mcp/tools/model-show.js +29 -2
  203. package/dist/mcp/tools/model-show.js.map +2 -2
  204. package/dist/mcp/tools/model-trace.js +93 -30
  205. package/dist/mcp/tools/model-trace.js.map +2 -2
  206. package/dist/mcp/tools/model-update.js +35 -19
  207. package/dist/mcp/tools/model-update.js.map +2 -2
  208. package/dist/mcp/tools/relationship-tools.js +98 -0
  209. package/dist/mcp/tools/relationship-tools.js.map +7 -0
  210. package/dist/mcp/tools/shared.js +25 -2
  211. package/dist/mcp/tools/shared.js.map +2 -2
  212. package/dist/mcp/tools/spec-type.js +90 -0
  213. package/dist/mcp/tools/spec-type.js.map +7 -0
  214. package/dist/schemas/bundled/analyzers/cbm.json +1186 -68
  215. package/dist/schemas/bundled/analyzers/manifest.json +2 -2
  216. package/dist/schemas/bundled/api.json +1029 -1658
  217. package/dist/schemas/bundled/apm.json +499 -734
  218. package/dist/schemas/bundled/application.json +735 -371
  219. package/dist/schemas/bundled/base.json +3 -220
  220. package/dist/schemas/bundled/business.json +452 -366
  221. package/dist/schemas/bundled/data-model.json +395 -411
  222. package/dist/schemas/bundled/data-store.json +334 -558
  223. package/dist/schemas/bundled/manifest.json +18 -18
  224. package/dist/schemas/bundled/motivation.json +349 -368
  225. package/dist/schemas/bundled/navigation.json +415 -731
  226. package/dist/schemas/bundled/product.json +325 -159
  227. package/dist/schemas/bundled/security.json +864 -1232
  228. package/dist/schemas/bundled/technology.json +574 -703
  229. package/dist/schemas/bundled/testing.json +718 -1643
  230. package/dist/schemas/bundled/ux.json +739 -1352
  231. package/dist/server/schemas.js +8 -0
  232. package/dist/server/schemas.js.map +2 -2
  233. package/dist/server/server.js +218 -34
  234. package/dist/server/server.js.map +2 -2
  235. package/dist/server-entry.js +2 -1
  236. package/dist/server-entry.js.map +2 -2
  237. package/dist/telemetry/index.js +1 -1
  238. package/dist/utils/ansi-suppressor.js +6 -8
  239. package/dist/utils/ansi-suppressor.js.map +2 -2
  240. package/dist/utils/attribute-patch.js +41 -0
  241. package/dist/utils/attribute-patch.js.map +7 -0
  242. package/dist/utils/error-hints.js +29 -0
  243. package/dist/utils/error-hints.js.map +7 -0
  244. package/dist/utils/errors.js +9 -3
  245. package/dist/utils/errors.js.map +2 -2
  246. package/dist/utils/project-paths.js +26 -1
  247. package/dist/utils/project-paths.js.map +2 -2
  248. package/dist/utils/source-reference.js +14 -12
  249. package/dist/utils/source-reference.js.map +2 -2
  250. package/dist/utils/spec-version.js +2 -2
  251. package/dist/utils/spec-version.js.map +1 -1
  252. package/dist/validators/composed-reference-validator.js +5 -27
  253. package/dist/validators/composed-reference-validator.js.map +2 -2
  254. package/dist/validators/reference-validator.js +0 -7
  255. package/dist/validators/reference-validator.js.map +2 -2
  256. package/dist/validators/relationship-schema-validator.js +3 -3
  257. package/dist/validators/relationship-schema-validator.js.map +2 -2
  258. package/dist/validators/schema-validator.js +27 -9
  259. package/dist/validators/schema-validator.js.map +2 -2
  260. package/dist/validators/types.js.map +1 -1
  261. package/dist/viewer/README.md +6 -6
  262. package/dist/viewer/assets/main-CxzcuU_o.js +84 -0
  263. package/dist/viewer/assets/main-j-7ULYpm.css +1 -0
  264. package/dist/viewer/index.html +2 -2
  265. package/dist/viewer/manifest.json +10 -10
  266. package/dist/viewer/version.json +1 -1
  267. package/package.json +2 -1
  268. package/dist/viewer/assets/main-B7AOQXXX.js +0 -81
  269. package/dist/viewer/assets/main-vdrFrG7q.css +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/upgrade.ts"],
4
- "sourcesContent": ["/**\n * Upgrade Command - Manages spec reference and model upgrades\n *\n * Scans the filesystem to determine what needs upgrading:\n * 1. .dr/ (spec reference) - if CLI has newer bundled version\n * 2. Model data - if model spec version doesn't match spec reference\n *\n * Shows upgrade plan and prompts for confirmation before proceeding.\n */\n\nimport ansis from \"ansis\";\nimport { confirm } from \"@clack/prompts\";\nimport { findProjectRoot, getSpecReferencePath, getModelPath } from \"../utils/project-paths.js\";\nimport {\n getCliVersion,\n getCliBundledSpecVersion,\n getInstalledSpecVersion,\n getModelSpecVersion,\n} from \"../utils/spec-version.js\";\nimport { MigrationRegistry } from \"../core/migration-registry.js\";\nimport { installSpecReference } from \"../utils/spec-installer.js\";\nimport { Model } from \"../core/model.js\";\nimport { ClaudeIntegrationManager } from \"../integrations/claude-manager.js\";\nimport { CopilotIntegrationManager } from \"../integrations/copilot-manager.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { startSpan, endSpan } from \"../telemetry/index.js\";\nimport { hasLayerReports, regenerateLayerReports } from \"./reports.js\";\n\n// Build-time constant for telemetry feature detection\ndeclare const TELEMETRY_ENABLED: boolean | undefined;\nconst isTelemetryEnabled = typeof TELEMETRY_ENABLED !== \"undefined\" ? TELEMETRY_ENABLED : false;\n\nexport interface UpgradeOptions {\n yes?: boolean;\n dryRun?: boolean;\n force?: boolean;\n}\n\ninterface UpgradeAction {\n type: \"spec\" | \"model\" | \"integration\";\n description: string;\n fromVersion?: string;\n toVersion: string;\n details?: string[];\n integrationName?: \"claude\" | \"copilot\";\n versionBumpOnly?: boolean;\n}\n\n/**\n * Build integration upgrade actions and collect up-to-date status lines\n */\nasync function buildIntegrationActions(\n cliVersion: string,\n force: boolean\n): Promise<{ actions: UpgradeAction[]; upToDate: string[] }> {\n const actions: UpgradeAction[] = [];\n const upToDate: string[] = [];\n\n // Check Claude integration\n const claudeManager = new ClaudeIntegrationManager();\n if (await claudeManager.isInstalled()) {\n const claudeVersion = await claudeManager.loadVersionFile();\n const installedVersion = claudeVersion?.version;\n const needsUpgrade = installedVersion && installedVersion !== cliVersion;\n\n if (force || needsUpgrade) {\n actions.push({\n type: \"integration\",\n description: force\n ? \"Reinstall Claude Code integration (forced)\"\n : \"Upgrade Claude Code integration\",\n fromVersion: installedVersion,\n toVersion: cliVersion,\n integrationName: \"claude\",\n });\n } else if (installedVersion) {\n upToDate.push(\n ` ${ansis.green(\"\u2713\")} Claude Code integration up to date (v${installedVersion})`\n );\n }\n }\n\n // Check Copilot integration\n const copilotManager = new CopilotIntegrationManager();\n if (await copilotManager.isInstalled()) {\n const copilotVersion = await copilotManager.loadVersionFile();\n const installedVersion = copilotVersion?.version;\n const needsUpgrade = installedVersion && installedVersion !== cliVersion;\n\n if (force || needsUpgrade) {\n actions.push({\n type: \"integration\",\n description: force\n ? \"Reinstall GitHub Copilot integration (forced)\"\n : \"Upgrade GitHub Copilot integration\",\n fromVersion: installedVersion,\n toVersion: cliVersion,\n integrationName: \"copilot\",\n });\n } else if (installedVersion) {\n upToDate.push(\n ` ${ansis.green(\"\u2713\")} GitHub Copilot integration up to date (v${installedVersion})`\n );\n }\n }\n\n return { actions, upToDate };\n}\n\n/**\n * Check if layer reports exist; if not, offer to generate them.\n * Defaults to generating (yes) \u2014 including in non-interactive/programmatic mode.\n */\nasync function checkAndGenerateReports(\n projectRoot: string,\n options: UpgradeOptions\n): Promise<void> {\n if (await hasLayerReports(projectRoot)) {\n return;\n }\n\n console.log(ansis.yellow(\"\\n\u26A0 No layer reports found\"));\n\n if (options.dryRun) {\n console.log(ansis.yellow(\"[DRY RUN] Would generate all 13 layer reports\\n\"));\n return;\n }\n\n // Determine whether to generate: default is yes\n let shouldGenerate: boolean;\n const isInteractive = process.stdin.isTTY && process.stdout.isTTY;\n\n if (options.yes) {\n shouldGenerate = true;\n } else if (isInteractive) {\n const response = await confirm({\n message: \"Generate layer reports?\",\n initialValue: true,\n });\n shouldGenerate = response === true;\n } else {\n // Non-interactive / programmatic: auto-generate since default is yes\n shouldGenerate = true;\n }\n\n if (!shouldGenerate) {\n console.log(ansis.dim(\"Skipping report generation\\n\"));\n return;\n }\n\n try {\n console.log();\n await regenerateLayerReports(projectRoot);\n } catch (error) {\n // Warn but don't block upgrade success\n console.warn(ansis.yellow(`\\n\u26A0 Failed to generate reports: ${getErrorMessage(error)}\\n`));\n }\n}\n\nexport async function upgradeCommand(options: UpgradeOptions = {}): Promise<void> {\n const commandSpan = isTelemetryEnabled\n ? startSpan(\"upgrade.execute\", {\n \"upgrade.yes\": options.yes || false,\n \"upgrade.dry_run\": options.dryRun || false,\n \"upgrade.force\": options.force || false,\n })\n : null;\n\n try {\n console.log(ansis.bold(\"\\nScanning for available upgrades...\\n\"));\n\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n const error = new Error(\"No DR project found. Run \\\"dr init\\\" to create a new project\");\n if (commandSpan) {\n commandSpan.recordException(error);\n commandSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: error.message,\n });\n commandSpan.setAttribute(\"upgrade.result\", \"no_project\");\n }\n console.error(ansis.red(\"Error: No DR project found\"));\n console.error(ansis.dim('Run \"dr init\" to create a new project'));\n throw error;\n }\n\n const bundledSpecVersion = getCliBundledSpecVersion();\n const cliVersion = getCliVersion();\n const actions: UpgradeAction[] = [];\n\n // ============================================================================\n // STEP 1: Check spec reference (.dr/ folder)\n // ============================================================================\n\n const drPath = await getSpecReferencePath();\n let currentSpecVersion: string | null = null;\n\n if (!drPath) {\n actions.push({\n type: \"spec\",\n description: \"Install spec reference\",\n toVersion: bundledSpecVersion,\n details: [\n \"Create .dr/ folder\",\n \"Install schema files\",\n `Set spec version to ${bundledSpecVersion}`,\n ],\n });\n } else {\n let installedSpecVersion: string | null = null;\n try {\n installedSpecVersion = await getInstalledSpecVersion(drPath);\n } catch (error) {\n // Manifest file exists but is corrupted or unreadable\n const message = error instanceof Error ? error.message : String(error);\n console.error(ansis.red(`Error: ${message}`));\n throw error;\n }\n currentSpecVersion = installedSpecVersion;\n\n if (!installedSpecVersion) {\n actions.push({\n type: \"spec\",\n description: \"Reinstall spec reference (manifest missing)\",\n toVersion: bundledSpecVersion,\n details: [\n \"Recreate .dr/manifest.json\",\n \"Update schema files\",\n `Set spec version to ${bundledSpecVersion}`,\n ],\n });\n } else if (installedSpecVersion !== bundledSpecVersion || options.force) {\n actions.push({\n type: \"spec\",\n description: installedSpecVersion !== bundledSpecVersion\n ? \"Upgrade spec reference\"\n : \"Reinstall spec reference (forced)\",\n fromVersion: installedSpecVersion,\n toVersion: bundledSpecVersion,\n details: [\"Update schema files\", \"Update .dr/manifest.json\"],\n });\n }\n }\n\n // ============================================================================\n // STEP 2: Check model upgrade\n // ============================================================================\n\n const modelPath = await getModelPath();\n if (!modelPath) {\n console.log(ansis.yellow(\"\u26A0 No model found\"));\n console.log(ansis.dim(' Run \"dr init\" to create a model\\n'));\n\n // If only spec needs upgrade, handle it\n if (actions.length > 0) {\n const { actions: integrationActions, upToDate: integrationUpToDate } =\n await buildIntegrationActions(cliVersion, options.force ?? false);\n actions.push(...integrationActions);\n await handleUpgrade(projectRoot, actions, options, integrationUpToDate, commandSpan);\n }\n // No model loaded \u2014 report generation not applicable\n return;\n }\n\n let modelSpecVersion: string | null = null;\n try {\n modelSpecVersion = await getModelSpecVersion(modelPath);\n } catch (error) {\n // Manifest file exists but is corrupted or unreadable\n const message = error instanceof Error ? error.message : String(error);\n console.error(ansis.red(`Error: ${message}`));\n throw error;\n }\n\n if (!modelSpecVersion) {\n console.log(ansis.yellow(\"\u26A0 Model manifest.yaml not found or missing specVersion\"));\n console.log(ansis.dim(\" Check documentation_robotics/model/manifest.yaml\\n\"));\n\n // If only spec needs upgrade, handle it\n if (actions.length > 0) {\n const { actions: integrationActions, upToDate: integrationUpToDate } =\n await buildIntegrationActions(cliVersion, options.force ?? false);\n actions.push(...integrationActions);\n await handleUpgrade(projectRoot, actions, options, integrationUpToDate, commandSpan);\n }\n // No readable model manifest \u2014 report generation not applicable\n return;\n }\n\n // Determine target spec version for model\n const targetSpecVersion = currentSpecVersion || bundledSpecVersion;\n\n if (modelSpecVersion !== targetSpecVersion) {\n // Check if we have a migration path\n const registry = new MigrationRegistry();\n const summary = registry.getMigrationSummary(modelSpecVersion, targetSpecVersion);\n\n if (summary.migrationsNeeded === 0) {\n if (options.force) {\n // No migration path exists, but --force allows bumping the model version directly.\n // This is safe for additive spec changes (new node types / relationships) that\n // require no structural data changes.\n actions.push({\n type: \"model\",\n description: \"Force-update model spec version (no migration required)\",\n fromVersion: modelSpecVersion,\n toVersion: targetSpecVersion,\n details: [\"Update manifest.yaml specVersion (no data changes needed)\"],\n versionBumpOnly: true,\n });\n } else {\n const error = new Error(\n `No migration path found from model v${modelSpecVersion} to v${targetSpecVersion}`\n );\n if (commandSpan) {\n commandSpan.recordException(error);\n commandSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: error.message,\n });\n commandSpan.setAttribute(\"upgrade.result\", \"no_migration_path\");\n }\n console.log(\n ansis.yellow(\n `\u26A0 No migration path found from model v${modelSpecVersion} to v${targetSpecVersion}`\n )\n );\n console.log(ansis.dim(\"\\nAvailable migrations:\"));\n const allMigrations = registry.getMigrationSummary(\"0.5.0\").migrations;\n for (const migration of allMigrations) {\n console.log(\n ansis.dim(` \u2022 ${migration.from} \u2192 ${migration.to}: ${migration.description}`)\n );\n }\n console.log();\n throw error;\n }\n }\n\n const migrationDetails = summary.migrations.map(\n (m) => `${m.from} \u2192 ${m.to}: ${m.description}`\n );\n\n actions.push({\n type: \"model\",\n description: \"Migrate model data\",\n fromVersion: modelSpecVersion,\n toVersion: targetSpecVersion,\n details: migrationDetails,\n });\n }\n\n // ============================================================================\n // STEP 3: Check integration versions\n // ============================================================================\n\n const { actions: integrationActions, upToDate: integrationUpToDate } =\n await buildIntegrationActions(cliVersion, options.force ?? false);\n actions.push(...integrationActions);\n\n // ============================================================================\n // STEP 4: Display upgrade plan and execute\n // ============================================================================\n\n if (actions.length === 0) {\n if (commandSpan) {\n commandSpan.setAttribute(\"upgrade.result\", \"up_to_date\");\n commandSpan.setAttribute(\"upgrade.actions_count\", 0);\n }\n console.log(ansis.green(\"\u2713 Everything is up to date!\\n\"));\n console.log(ansis.dim(` Spec reference: v${currentSpecVersion || bundledSpecVersion}`));\n console.log(ansis.dim(` Model: v${modelSpecVersion}\\n`));\n await checkAndGenerateReports(projectRoot, options);\n return;\n }\n\n if (commandSpan) {\n commandSpan.setAttribute(\"upgrade.actions_count\", actions.length);\n commandSpan.setAttribute(\n \"upgrade.has_spec_upgrade\",\n actions.some((a) => a.type === \"spec\")\n );\n commandSpan.setAttribute(\n \"upgrade.has_model_migration\",\n actions.some((a) => a.type === \"model\")\n );\n commandSpan.setAttribute(\n \"upgrade.has_integration_upgrade\",\n actions.some((a) => a.type === \"integration\")\n );\n }\n\n await handleUpgrade(projectRoot, actions, options, integrationUpToDate, commandSpan);\n await checkAndGenerateReports(projectRoot, options);\n\n if (commandSpan) {\n commandSpan.setAttribute(\"upgrade.result\", \"success\");\n }\n } catch (error) {\n if (commandSpan) {\n commandSpan.recordException(error as Error);\n commandSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: getErrorMessage(error),\n });\n commandSpan.setAttribute(\"upgrade.result\", \"error\");\n }\n console.error(ansis.red(`Error: ${getErrorMessage(error)}`));\n throw error;\n } finally {\n endSpan(commandSpan);\n }\n}\n\n/**\n * Handle the upgrade process\n */\nasync function handleUpgrade(\n projectRoot: string,\n actions: UpgradeAction[],\n options: UpgradeOptions,\n integrationUpToDate: string[] = [],\n parentSpan: any = null\n): Promise<void> {\n // Display upgrade plan\n if (actions.length > 0) {\n console.log(ansis.bold(\"Upgrade Plan:\\n\"));\n\n for (const action of actions) {\n const versionChange = action.fromVersion\n ? `${action.fromVersion} \u2192 ${action.toVersion}`\n : `v${action.toVersion}`;\n\n const icon = action.type === \"spec\" ? \"\uD83D\uDCE6\" : action.type === \"integration\" ? \"\uD83D\uDD0C\" : \"\uD83D\uDD04\";\n console.log(ansis.yellow(`${icon} ${action.description}`));\n console.log(ansis.dim(` Version: ${versionChange}`));\n\n if (action.details && action.details.length > 0) {\n for (const detail of action.details) {\n console.log(ansis.dim(` \u2022 ${detail}`));\n }\n }\n console.log();\n }\n }\n\n // Display integration status for up-to-date integrations\n if (integrationUpToDate.length > 0) {\n console.log(ansis.bold(\"Integration Status:\"));\n integrationUpToDate.forEach((msg) => console.log(msg));\n console.log();\n }\n\n // Handle dry-run mode\n if (options.dryRun) {\n console.log(ansis.yellow(\"[DRY RUN] No changes will be made\\n\"));\n if (parentSpan) {\n parentSpan.setAttribute(\"upgrade.dry_run_completed\", true);\n }\n return;\n }\n\n // Prompt for confirmation unless --yes flag is set\n let shouldProceed = options.yes;\n if (!shouldProceed) {\n // Check if we're in an interactive terminal\n const isInteractive = process.stdin.isTTY && process.stdout.isTTY;\n\n if (isInteractive) {\n const response = await confirm({\n message: \"Proceed with upgrade?\",\n });\n shouldProceed = response === true;\n } else {\n const error = new Error(\"Non-interactive mode requires --yes flag to proceed with upgrade\");\n if (parentSpan) {\n parentSpan.recordException(error);\n parentSpan.setAttribute(\"upgrade.result\", \"non_interactive_abort\");\n }\n console.error(\n ansis.red(\"Error: Non-interactive mode requires --yes flag to proceed with upgrade\")\n );\n throw error;\n }\n }\n\n if (!shouldProceed) {\n console.log(ansis.dim(\"\\nUpgrade cancelled\\n\"));\n if (parentSpan) {\n parentSpan.setAttribute(\"upgrade.user_cancelled\", true);\n }\n return;\n }\n\n console.log(ansis.bold(\"\\nExecuting upgrades...\\n\"));\n\n // Execute actions in order: spec, model, then integrations\n for (const action of actions) {\n if (action.type === \"spec\") {\n await executeSpecUpgrade(projectRoot, action);\n } else if (action.type === \"model\") {\n await executeModelMigration(action, options);\n } else if (action.type === \"integration\") {\n await executeIntegrationUpdate(action.description, async () => {\n if (action.integrationName === \"claude\") {\n const m = new ClaudeIntegrationManager();\n await m.upgrade({ force: true }); // force=true skips internal prompts (user confirmed above)\n } else {\n const m = new CopilotIntegrationManager();\n await m.upgrade({ force: true });\n }\n });\n }\n }\n\n console.log(ansis.green(\"\\n\u2713 All upgrades completed successfully!\\n\"));\n}\n\n/**\n * Execute spec reference upgrade\n */\nasync function executeSpecUpgrade(projectRoot: string, action: UpgradeAction): Promise<void> {\n const operationSpan = isTelemetryEnabled\n ? startSpan(\"upgrade.spec\", {\n \"upgrade.spec.from_version\": action.fromVersion || \"none\",\n \"upgrade.spec.to_version\": action.toVersion,\n \"upgrade.spec.is_reinstall\": !action.fromVersion,\n })\n : null;\n\n try {\n console.log(ansis.dim(`Installing spec reference v${action.toVersion}...`));\n await installSpecReference(projectRoot, true);\n console.log(ansis.green(`\u2713 Spec reference upgraded to v${action.toVersion}`));\n\n if (operationSpan) {\n operationSpan.setAttribute(\"upgrade.spec.result\", \"success\");\n }\n } catch (error) {\n if (operationSpan) {\n operationSpan.recordException(error as Error);\n operationSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: getErrorMessage(error),\n });\n operationSpan.setAttribute(\"upgrade.spec.result\", \"error\");\n }\n console.error(\n ansis.red(\n `Error upgrading spec reference: ${getErrorMessage(error)}`\n )\n );\n throw error;\n } finally {\n endSpan(operationSpan);\n }\n}\n\n/**\n * Execute model migration\n */\nasync function executeModelMigration(\n action: UpgradeAction,\n options: UpgradeOptions\n): Promise<void> {\n const operationSpan = isTelemetryEnabled\n ? startSpan(\"upgrade.model\", {\n \"upgrade.model.from_version\": action.fromVersion || \"unknown\",\n \"upgrade.model.to_version\": action.toVersion,\n \"upgrade.model.version_bump_only\": action.versionBumpOnly || false,\n \"upgrade.model.validate\": !options.force,\n })\n : null;\n\n try {\n if (action.versionBumpOnly) {\n console.log(\n ansis.dim(`Bumping model spec version from v${action.fromVersion} to v${action.toVersion}...`)\n );\n const model = await Model.load(process.cwd(), { lazyLoad: true });\n model.manifest.specVersion = action.toVersion;\n await model.saveManifest();\n console.log(ansis.green(`\u2713 Model spec version updated to v${action.toVersion}`));\n\n if (operationSpan) {\n operationSpan.setAttribute(\"upgrade.model.result\", \"version_bumped\");\n }\n return;\n }\n\n console.log(\n ansis.dim(`Migrating model from v${action.fromVersion} to v${action.toVersion}...`)\n );\n\n // Load the model\n const model = await Model.load(process.cwd(), { lazyLoad: false });\n\n // Apply migrations\n const registry = new MigrationRegistry();\n const result = await registry.applyMigrations(model, {\n fromVersion: action.fromVersion!,\n toVersion: action.toVersion,\n dryRun: false,\n validate: !options.force,\n });\n\n // Display migration results\n for (const applied of result.applied) {\n console.log(ansis.green(` \u2713 ${applied.from} \u2192 ${applied.to}: ${applied.description}`));\n if (applied.changes?.filesModified) {\n console.log(ansis.dim(` Files modified: ${applied.changes.filesModified}`));\n }\n }\n\n // Save changes\n await model.saveManifest();\n await model.saveDirtyLayers();\n\n console.log(ansis.green(`\u2713 Model migrated to v${action.toVersion}`));\n\n if (operationSpan) {\n operationSpan.setAttribute(\"upgrade.model.result\", \"migrated\");\n operationSpan.setAttribute(\"upgrade.model.migrations_applied\", result.applied.length);\n }\n } catch (error) {\n if (operationSpan) {\n operationSpan.recordException(error as Error);\n operationSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: getErrorMessage(error),\n });\n operationSpan.setAttribute(\"upgrade.model.result\", \"error\");\n }\n console.error(\n ansis.red(`Error migrating model: ${getErrorMessage(error)}`)\n );\n throw error;\n } finally {\n endSpan(operationSpan);\n }\n}\n\n/**\n * Execute integration update\n */\nasync function executeIntegrationUpdate(\n label: string,\n updateFn: () => Promise<void>\n): Promise<void> {\n const operationSpan = isTelemetryEnabled\n ? startSpan(\"upgrade.integration\", {\n \"upgrade.integration.label\": label,\n \"upgrade.integration.type\": label.includes(\"Claude\")\n ? \"claude\"\n : label.includes(\"Copilot\")\n ? \"copilot\"\n : \"unknown\",\n })\n : null;\n\n try {\n console.log(ansis.dim(`${label}...`));\n await updateFn();\n console.log(ansis.green(`\u2713 ${label}`));\n\n if (operationSpan) {\n operationSpan.setAttribute(\"upgrade.integration.result\", \"success\");\n }\n } catch (error) {\n if (operationSpan) {\n operationSpan.recordException(error as Error);\n operationSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: getErrorMessage(error),\n });\n operationSpan.setAttribute(\"upgrade.integration.result\", \"error\");\n }\n console.error(ansis.red(`Error: ${label} failed: ${getErrorMessage(error)}`));\n throw error;\n } finally {\n endSpan(operationSpan);\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["integrationActions", "integrationUpToDate", "model"]
4
+ "sourcesContent": ["/**\n * Upgrade Command - Manages spec reference and model upgrades\n *\n * Scans the filesystem to determine what needs upgrading:\n * 1. .dr/ (spec reference) - if CLI has newer bundled version\n * 2. Model data - if model spec version doesn't match spec reference\n *\n * Shows upgrade plan and prompts for confirmation before proceeding.\n */\n\nimport ansis from \"ansis\";\nimport { confirm } from \"@clack/prompts\";\nimport { findProjectRoot, getSpecReferencePath, getModelPath } from \"../utils/project-paths.js\";\nimport {\n getCliVersion,\n getCliBundledSpecVersion,\n getInstalledSpecVersion,\n getModelSpecVersion,\n} from \"../utils/spec-version.js\";\nimport { MigrationRegistry } from \"../core/migration-registry.js\";\nimport { Model } from \"../core/model.js\";\nimport { pendingCatalogMigrations } from \"../core/catalog-migration.js\";\nimport {\n upgradeModel,\n type ChangesetRebaselineResult,\n type ChangesetRef,\n} from \"../core/model-upgrade.js\";\nimport {\n summarizeRelationshipChanges,\n type RelationshipRewriteChange,\n type StagedRelationshipRewriteChange,\n} from \"../core/relationship-migration.js\";\nimport { installSpecReference } from \"../utils/spec-installer.js\";\nimport { ClaudeIntegrationManager } from \"../integrations/claude-manager.js\";\nimport { CopilotIntegrationManager } from \"../integrations/copilot-manager.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { startSpan, endSpan } from \"../telemetry/index.js\";\nimport { hasLayerReports, regenerateLayerReports } from \"./reports.js\";\n\n// Build-time constant for telemetry feature detection\ndeclare const TELEMETRY_ENABLED: boolean | undefined;\nconst isTelemetryEnabled = typeof TELEMETRY_ENABLED !== \"undefined\" ? TELEMETRY_ENABLED : false;\n\nexport interface UpgradeOptions {\n yes?: boolean;\n dryRun?: boolean;\n force?: boolean;\n}\n\ninterface UpgradeAction {\n type: \"spec\" | \"model\" | \"integration\";\n description: string;\n fromVersion?: string;\n toVersion: string;\n details?: string[];\n integrationName?: \"claude\" | \"copilot\";\n versionBumpOnly?: boolean;\n /** Model already at the target version, but with catalog changes it has not received */\n catalogOnly?: boolean;\n}\n\n/**\n * Build integration upgrade actions and collect up-to-date status lines\n */\nasync function buildIntegrationActions(\n cliVersion: string,\n force: boolean\n): Promise<{ actions: UpgradeAction[]; upToDate: string[] }> {\n const actions: UpgradeAction[] = [];\n const upToDate: string[] = [];\n\n // Check Claude integration\n const claudeManager = new ClaudeIntegrationManager();\n if (await claudeManager.isInstalled()) {\n const claudeVersion = await claudeManager.loadVersionFile();\n const installedVersion = claudeVersion?.version;\n const needsUpgrade = installedVersion && installedVersion !== cliVersion;\n\n if (force || needsUpgrade) {\n actions.push({\n type: \"integration\",\n description: force\n ? \"Reinstall Claude Code integration (forced)\"\n : \"Upgrade Claude Code integration\",\n fromVersion: installedVersion,\n toVersion: cliVersion,\n integrationName: \"claude\",\n });\n } else if (installedVersion) {\n upToDate.push(\n ` ${ansis.green(\"\u2713\")} Claude Code integration up to date (v${installedVersion})`\n );\n }\n }\n\n // Check Copilot integration\n const copilotManager = new CopilotIntegrationManager();\n if (await copilotManager.isInstalled()) {\n const copilotVersion = await copilotManager.loadVersionFile();\n const installedVersion = copilotVersion?.version;\n const needsUpgrade = installedVersion && installedVersion !== cliVersion;\n\n if (force || needsUpgrade) {\n actions.push({\n type: \"integration\",\n description: force\n ? \"Reinstall GitHub Copilot integration (forced)\"\n : \"Upgrade GitHub Copilot integration\",\n fromVersion: installedVersion,\n toVersion: cliVersion,\n integrationName: \"copilot\",\n });\n } else if (installedVersion) {\n upToDate.push(\n ` ${ansis.green(\"\u2713\")} GitHub Copilot integration up to date (v${installedVersion})`\n );\n }\n }\n\n return { actions, upToDate };\n}\n\n/**\n * Check if layer reports exist; if not, offer to generate them.\n * Defaults to generating (yes) \u2014 including in non-interactive/programmatic mode.\n */\nasync function checkAndGenerateReports(\n projectRoot: string,\n options: UpgradeOptions\n): Promise<void> {\n if (await hasLayerReports(projectRoot)) {\n return;\n }\n\n console.log(ansis.yellow(\"\\n\u26A0 No layer reports found\"));\n\n if (options.dryRun) {\n console.log(ansis.yellow(\"[DRY RUN] Would generate all 13 layer reports\\n\"));\n return;\n }\n\n // Determine whether to generate: default is yes\n let shouldGenerate: boolean;\n const isInteractive = process.stdin.isTTY && process.stdout.isTTY;\n\n if (options.yes) {\n shouldGenerate = true;\n } else if (isInteractive) {\n const response = await confirm({\n message: \"Generate layer reports?\",\n initialValue: true,\n });\n shouldGenerate = response === true;\n } else {\n // Non-interactive / programmatic: auto-generate since default is yes\n shouldGenerate = true;\n }\n\n if (!shouldGenerate) {\n console.log(ansis.dim(\"Skipping report generation\\n\"));\n return;\n }\n\n try {\n console.log();\n await regenerateLayerReports(projectRoot);\n } catch (error) {\n // Warn but don't block upgrade success\n console.warn(ansis.yellow(`\\n\u26A0 Failed to generate reports: ${getErrorMessage(error)}\\n`));\n }\n}\n\nexport async function upgradeCommand(options: UpgradeOptions = {}): Promise<void> {\n const commandSpan = isTelemetryEnabled\n ? startSpan(\"upgrade.execute\", {\n \"upgrade.yes\": options.yes || false,\n \"upgrade.dry_run\": options.dryRun || false,\n \"upgrade.force\": options.force || false,\n })\n : null;\n\n try {\n console.log(ansis.bold(\"\\nScanning for available upgrades...\\n\"));\n\n // Find project root\n const projectRoot = await findProjectRoot();\n if (!projectRoot) {\n const error = new Error(\"No DR project found. Run \\\"dr init\\\" to create a new project\");\n if (commandSpan) {\n commandSpan.recordException(error);\n commandSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: error.message,\n });\n commandSpan.setAttribute(\"upgrade.result\", \"no_project\");\n }\n console.error(ansis.red(\"Error: No DR project found\"));\n console.error(ansis.dim('Run \"dr init\" to create a new project'));\n throw error;\n }\n\n const bundledSpecVersion = getCliBundledSpecVersion();\n const cliVersion = getCliVersion();\n const actions: UpgradeAction[] = [];\n\n // ============================================================================\n // STEP 1: Check spec reference (.dr/ folder)\n // ============================================================================\n\n const drPath = await getSpecReferencePath();\n let currentSpecVersion: string | null = null;\n\n if (!drPath) {\n actions.push({\n type: \"spec\",\n description: \"Install spec reference\",\n toVersion: bundledSpecVersion,\n details: [\n \"Create .dr/ folder\",\n \"Install schema files\",\n `Set spec version to ${bundledSpecVersion}`,\n ],\n });\n } else {\n let installedSpecVersion: string | null = null;\n try {\n installedSpecVersion = await getInstalledSpecVersion(drPath);\n } catch (error) {\n // Manifest file exists but is corrupted or unreadable\n const message = error instanceof Error ? error.message : String(error);\n console.error(ansis.red(`Error: ${message}`));\n throw error;\n }\n currentSpecVersion = installedSpecVersion;\n\n if (!installedSpecVersion) {\n actions.push({\n type: \"spec\",\n description: \"Reinstall spec reference (manifest missing)\",\n toVersion: bundledSpecVersion,\n details: [\n \"Recreate .dr/manifest.json\",\n \"Update schema files\",\n `Set spec version to ${bundledSpecVersion}`,\n ],\n });\n } else if (installedSpecVersion !== bundledSpecVersion || options.force) {\n actions.push({\n type: \"spec\",\n description: installedSpecVersion !== bundledSpecVersion\n ? \"Upgrade spec reference\"\n : \"Reinstall spec reference (forced)\",\n fromVersion: installedSpecVersion,\n toVersion: bundledSpecVersion,\n details: [\"Update schema files\", \"Update .dr/manifest.json\"],\n });\n }\n }\n\n // ============================================================================\n // STEP 2: Check model upgrade\n // ============================================================================\n\n const modelPath = await getModelPath();\n if (!modelPath) {\n console.log(ansis.yellow(\"\u26A0 No model found\"));\n console.log(ansis.dim(' Run \"dr init\" to create a model\\n'));\n\n // If only spec needs upgrade, handle it\n if (actions.length > 0) {\n const { actions: integrationActions, upToDate: integrationUpToDate } =\n await buildIntegrationActions(cliVersion, options.force ?? false);\n actions.push(...integrationActions);\n await handleUpgrade(projectRoot, actions, options, integrationUpToDate, commandSpan);\n }\n // No model loaded \u2014 report generation not applicable\n return;\n }\n\n let modelSpecVersion: string | null = null;\n try {\n modelSpecVersion = await getModelSpecVersion(modelPath);\n } catch (error) {\n // Manifest file exists but is corrupted or unreadable\n const message = error instanceof Error ? error.message : String(error);\n console.error(ansis.red(`Error: ${message}`));\n throw error;\n }\n\n if (!modelSpecVersion) {\n console.log(ansis.yellow(\"\u26A0 Model manifest.yaml not found or missing specVersion\"));\n console.log(ansis.dim(\" Check documentation_robotics/model/manifest.yaml\\n\"));\n\n // If only spec needs upgrade, handle it\n if (actions.length > 0) {\n const { actions: integrationActions, upToDate: integrationUpToDate } =\n await buildIntegrationActions(cliVersion, options.force ?? false);\n actions.push(...integrationActions);\n await handleUpgrade(projectRoot, actions, options, integrationUpToDate, commandSpan);\n }\n // No readable model manifest \u2014 report generation not applicable\n return;\n }\n\n // Determine target spec version for model\n const targetSpecVersion = currentSpecVersion || bundledSpecVersion;\n\n if (modelSpecVersion !== targetSpecVersion) {\n // Check if we have a migration path\n const registry = new MigrationRegistry();\n const summary = registry.getMigrationSummary(modelSpecVersion, targetSpecVersion);\n\n if (summary.migrationsNeeded === 0) {\n if (options.force) {\n // No migration path exists, but --force allows bumping the model version directly.\n // This is safe for additive spec changes (new node types / relationships) that\n // require no structural data changes.\n actions.push({\n type: \"model\",\n description: \"Force-update model spec version (no migration required)\",\n fromVersion: modelSpecVersion,\n toVersion: targetSpecVersion,\n details: [\"Update manifest.yaml specVersion (no data changes needed)\"],\n versionBumpOnly: true,\n });\n } else {\n const error = new Error(\n `No migration path found from model v${modelSpecVersion} to v${targetSpecVersion}`\n );\n if (commandSpan) {\n commandSpan.recordException(error);\n commandSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: error.message,\n });\n commandSpan.setAttribute(\"upgrade.result\", \"no_migration_path\");\n }\n console.log(\n ansis.yellow(\n `\u26A0 No migration path found from model v${modelSpecVersion} to v${targetSpecVersion}`\n )\n );\n console.log(ansis.dim(\"\\nAvailable migrations:\"));\n const allMigrations = registry.getMigrationSummary(\"0.5.0\").migrations;\n for (const migration of allMigrations) {\n console.log(\n ansis.dim(` \u2022 ${migration.from} \u2192 ${migration.to}: ${migration.description}`)\n );\n }\n console.log();\n throw error;\n }\n }\n\n const migrationDetails = summary.migrations.map(\n (m) => `${m.from} \u2192 ${m.to}: ${m.description}`\n );\n\n actions.push({\n type: \"model\",\n description: \"Migrate model data\",\n fromVersion: modelSpecVersion,\n toVersion: targetSpecVersion,\n details: migrationDetails,\n });\n } else {\n // Same spec version, but the relationship catalog can change between version bumps: a\n // model stamped with the current version before a catalog change still needs it\n const catalogAction = await buildCatalogAction(projectRoot, targetSpecVersion);\n if (catalogAction) {\n actions.push(catalogAction);\n }\n }\n\n // ============================================================================\n // STEP 3: Check integration versions\n // ============================================================================\n\n const { actions: integrationActions, upToDate: integrationUpToDate } =\n await buildIntegrationActions(cliVersion, options.force ?? false);\n actions.push(...integrationActions);\n\n // ============================================================================\n // STEP 4: Display upgrade plan and execute\n // ============================================================================\n\n if (actions.length === 0) {\n if (commandSpan) {\n commandSpan.setAttribute(\"upgrade.result\", \"up_to_date\");\n commandSpan.setAttribute(\"upgrade.actions_count\", 0);\n }\n console.log(ansis.green(\"\u2713 Everything is up to date!\\n\"));\n console.log(ansis.dim(` Spec reference: v${currentSpecVersion || bundledSpecVersion}`));\n console.log(ansis.dim(` Model: v${modelSpecVersion}\\n`));\n await checkAndGenerateReports(projectRoot, options);\n return;\n }\n\n if (commandSpan) {\n commandSpan.setAttribute(\"upgrade.actions_count\", actions.length);\n commandSpan.setAttribute(\n \"upgrade.has_spec_upgrade\",\n actions.some((a) => a.type === \"spec\")\n );\n commandSpan.setAttribute(\n \"upgrade.has_model_migration\",\n actions.some((a) => a.type === \"model\")\n );\n commandSpan.setAttribute(\n \"upgrade.has_integration_upgrade\",\n actions.some((a) => a.type === \"integration\")\n );\n }\n\n await handleUpgrade(projectRoot, actions, options, integrationUpToDate, commandSpan);\n await checkAndGenerateReports(projectRoot, options);\n\n if (commandSpan) {\n commandSpan.setAttribute(\"upgrade.result\", \"success\");\n }\n } catch (error) {\n if (commandSpan) {\n commandSpan.recordException(error as Error);\n commandSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: getErrorMessage(error),\n });\n commandSpan.setAttribute(\"upgrade.result\", \"error\");\n }\n console.error(ansis.red(`Error: ${getErrorMessage(error)}`));\n throw error;\n } finally {\n endSpan(commandSpan);\n }\n}\n\n/**\n * Handle the upgrade process\n */\nasync function handleUpgrade(\n projectRoot: string,\n actions: UpgradeAction[],\n options: UpgradeOptions,\n integrationUpToDate: string[] = [],\n parentSpan: any = null\n): Promise<void> {\n // Display upgrade plan\n if (actions.length > 0) {\n console.log(ansis.bold(\"Upgrade Plan:\\n\"));\n\n for (const action of actions) {\n const versionChange = action.fromVersion\n ? `${action.fromVersion} \u2192 ${action.toVersion}`\n : `v${action.toVersion}`;\n\n const icon = action.type === \"spec\" ? \"\uD83D\uDCE6\" : action.type === \"integration\" ? \"\uD83D\uDD0C\" : \"\uD83D\uDD04\";\n console.log(ansis.yellow(`${icon} ${action.description}`));\n console.log(ansis.dim(` Version: ${versionChange}`));\n\n if (action.details && action.details.length > 0) {\n for (const detail of action.details) {\n console.log(ansis.dim(` \u2022 ${detail}`));\n }\n }\n console.log();\n }\n }\n\n // Display integration status for up-to-date integrations\n if (integrationUpToDate.length > 0) {\n console.log(ansis.bold(\"Integration Status:\"));\n integrationUpToDate.forEach((msg) => console.log(msg));\n console.log();\n }\n\n // Handle dry-run mode\n if (options.dryRun) {\n console.log(ansis.yellow(\"[DRY RUN] No changes will be made\\n\"));\n if (parentSpan) {\n parentSpan.setAttribute(\"upgrade.dry_run_completed\", true);\n }\n return;\n }\n\n // Prompt for confirmation unless --yes flag is set\n let shouldProceed = options.yes;\n if (!shouldProceed) {\n // Check if we're in an interactive terminal\n const isInteractive = process.stdin.isTTY && process.stdout.isTTY;\n\n if (isInteractive) {\n const response = await confirm({\n message: \"Proceed with upgrade?\",\n });\n shouldProceed = response === true;\n } else {\n const error = new Error(\"Non-interactive mode requires --yes flag to proceed with upgrade\");\n if (parentSpan) {\n parentSpan.recordException(error);\n parentSpan.setAttribute(\"upgrade.result\", \"non_interactive_abort\");\n }\n console.error(\n ansis.red(\"Error: Non-interactive mode requires --yes flag to proceed with upgrade\")\n );\n throw error;\n }\n }\n\n if (!shouldProceed) {\n console.log(ansis.dim(\"\\nUpgrade cancelled\\n\"));\n if (parentSpan) {\n parentSpan.setAttribute(\"upgrade.user_cancelled\", true);\n }\n return;\n }\n\n console.log(ansis.bold(\"\\nExecuting upgrades...\\n\"));\n\n // Execute actions in order: spec, model, then integrations\n for (const action of actions) {\n if (action.type === \"spec\") {\n await executeSpecUpgrade(projectRoot, action);\n } else if (action.type === \"model\") {\n await executeModelMigration(action, options);\n } else if (action.type === \"integration\") {\n await executeIntegrationUpdate(action.description, async () => {\n if (action.integrationName === \"claude\") {\n const m = new ClaudeIntegrationManager();\n await m.upgrade({ force: true }); // force=true skips internal prompts (user confirmed above)\n } else {\n const m = new CopilotIntegrationManager();\n await m.upgrade({ force: true });\n }\n });\n }\n }\n\n console.log(ansis.green(\"\\n\u2713 All upgrades completed successfully!\\n\"));\n}\n\n/**\n * Execute spec reference upgrade\n */\nasync function executeSpecUpgrade(projectRoot: string, action: UpgradeAction): Promise<void> {\n const operationSpan = isTelemetryEnabled\n ? startSpan(\"upgrade.spec\", {\n \"upgrade.spec.from_version\": action.fromVersion || \"none\",\n \"upgrade.spec.to_version\": action.toVersion,\n \"upgrade.spec.is_reinstall\": !action.fromVersion,\n })\n : null;\n\n try {\n console.log(ansis.dim(`Installing spec reference v${action.toVersion}...`));\n await installSpecReference(projectRoot, true);\n console.log(ansis.green(`\u2713 Spec reference upgraded to v${action.toVersion}`));\n\n if (operationSpan) {\n operationSpan.setAttribute(\"upgrade.spec.result\", \"success\");\n }\n } catch (error) {\n if (operationSpan) {\n operationSpan.recordException(error as Error);\n operationSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: getErrorMessage(error),\n });\n operationSpan.setAttribute(\"upgrade.spec.result\", \"error\");\n }\n console.error(\n ansis.red(\n `Error upgrading spec reference: ${getErrorMessage(error)}`\n )\n );\n throw error;\n } finally {\n endSpan(operationSpan);\n }\n}\n\n/**\n * Execute model migration\n */\n/**\n * A model action when a model at the current spec version still names element types or\n * relationship types the catalog has retired; null when it is in line with the catalog\n */\nasync function buildCatalogAction(projectRoot: string, version: string): Promise<UpgradeAction | null> {\n let pending: Awaited<ReturnType<typeof pendingCatalogMigrations>>;\n try {\n pending = await pendingCatalogMigrations(await Model.load(projectRoot, { lazyLoad: false }));\n } catch (error) {\n console.log(ansis.yellow(`\u26A0 Could not check the model against the catalog: ${getErrorMessage(error)}`));\n return null;\n }\n const details = [\n ...(pending.elementTypes > 0 ? [`Rename ${pending.elementTypes} element(s) whose type was renamed`] : []),\n ...(pending.relationships > 0 ? [`Rewrite or drop ${pending.relationships} relationship(s) of retired types`] : []),\n ...(pending.stagedRelationships > 0 ? [`Rewrite ${pending.stagedRelationships} staged relationship change(s)`] : []),\n ];\n if (details.length === 0) {\n return null;\n }\n return {\n type: \"model\",\n description: `Apply catalog changes to the model (spec v${version})`,\n fromVersion: version,\n toVersion: version,\n details,\n catalogOnly: true,\n };\n}\n\nasync function executeModelMigration(\n action: UpgradeAction,\n options: UpgradeOptions\n): Promise<void> {\n const operationSpan = isTelemetryEnabled\n ? startSpan(\"upgrade.model\", {\n \"upgrade.model.from_version\": action.fromVersion || \"unknown\",\n \"upgrade.model.to_version\": action.toVersion,\n \"upgrade.model.version_bump_only\": action.versionBumpOnly || false,\n \"upgrade.model.validate\": !options.force,\n })\n : null;\n\n try {\n if (action.versionBumpOnly) {\n console.log(\n ansis.dim(`Bumping model spec version from v${action.fromVersion} to v${action.toVersion}...`)\n );\n const result = await upgradeModel(process.cwd(), {\n fromVersion: action.fromVersion!,\n toVersion: action.toVersion,\n versionBumpOnly: true,\n });\n console.log(ansis.green(`\u2713 Model spec version updated to v${action.toVersion}`));\n printChangesetRebaseline(result.changesets);\n\n if (operationSpan) {\n operationSpan.setAttribute(\"upgrade.model.result\", \"version_bumped\");\n operationSpan.setAttribute(\n \"upgrade.model.changesets_rebaselined\",\n result.changesets.rebaselined.length\n );\n }\n return;\n }\n\n console.log(\n ansis.dim(\n action.catalogOnly\n ? `Applying catalog changes to the model (v${action.toVersion})...`\n : `Migrating model from v${action.fromVersion} to v${action.toVersion}...`\n )\n );\n\n // Apply migrations, save the model and re-baseline staged changesets on it\n const result = await upgradeModel(process.cwd(), {\n fromVersion: action.fromVersion!,\n toVersion: action.toVersion,\n validate: !options.force,\n catalogOnly: action.catalogOnly,\n });\n const applied = result.migration?.applied ?? [];\n\n // Display migration results\n for (const migration of applied) {\n console.log(ansis.green(` \u2713 ${migration.from} \u2192 ${migration.to}: ${migration.description}`));\n if (migration.changes?.filesModified) {\n console.log(ansis.dim(` Files modified: ${migration.changes.filesModified}`));\n }\n printElementTypeChanges(migration.changes?.details?.elementTypeChanges);\n printRelationshipChanges(migration.changes?.details?.relationshipChanges);\n printStagedRelationshipChanges(migration.changes?.details?.stagedRelationshipChanges);\n }\n\n console.log(\n ansis.green(\n action.catalogOnly\n ? `\u2713 Model in line with the v${action.toVersion} catalog`\n : `\u2713 Model migrated to v${action.toVersion}`\n )\n );\n printChangesetRebaseline(result.changesets);\n\n if (operationSpan) {\n operationSpan.setAttribute(\"upgrade.model.result\", \"migrated\");\n operationSpan.setAttribute(\"upgrade.model.migrations_applied\", applied.length);\n operationSpan.setAttribute(\n \"upgrade.model.changesets_rebaselined\",\n result.changesets.rebaselined.length\n );\n }\n } catch (error) {\n if (operationSpan) {\n operationSpan.recordException(error as Error);\n operationSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: getErrorMessage(error),\n });\n operationSpan.setAttribute(\"upgrade.model.result\", \"error\");\n }\n console.error(\n ansis.red(`Error migrating model: ${getErrorMessage(error)}`)\n );\n throw error;\n } finally {\n endSpan(operationSpan);\n }\n}\n\n/**\n * Report elements whose type a catalog migration renamed\n */\nfunction printElementTypeChanges(changes: unknown): void {\n if (!Array.isArray(changes) || changes.length === 0) {\n return;\n }\n const byType = new Map<string, number>();\n for (const c of changes as Array<{ fromType: string; toType: string }>) {\n const key = `${c.fromType} \u2192 ${c.toType}`;\n byType.set(key, (byType.get(key) ?? 0) + 1);\n }\n for (const [key, n] of byType) {\n console.log(ansis.dim(` Renamed ${n} element(s): ${key}`));\n }\n}\n\n/**\n * Report relationships a catalog migration rewrote, listing each one it dropped\n */\nfunction printRelationshipChanges(changes: unknown): void {\n if (!Array.isArray(changes) || changes.length === 0) {\n return;\n }\n const relationshipChanges = changes as RelationshipRewriteChange[];\n\n console.log(ansis.dim(` ${summarizeRelationshipChanges(relationshipChanges)}`));\n for (const change of relationshipChanges) {\n if (change.action === \"dropped-duplicate\" && change.after) {\n console.log(\n ansis.dim(\n ` dropped ${formatRelationship(change.before)} (now the same as ${formatRelationship(change.after)})`\n )\n );\n } else if (change.action === \"dropped\") {\n console.log(\n ansis.dim(` dropped ${formatRelationship(change.before)} (no replacement in the catalog)`)\n );\n }\n }\n}\n\n/**\n * Report staged changeset changes a catalog migration rewrote, per changeset, listing each one\n * it removed from its changeset\n */\nfunction printStagedRelationshipChanges(changes: unknown): void {\n if (!Array.isArray(changes) || changes.length === 0) {\n return;\n }\n const byChangeset = new Map<string, StagedRelationshipRewriteChange[]>();\n for (const change of changes as StagedRelationshipRewriteChange[]) {\n byChangeset.set(change.changeset, [...(byChangeset.get(change.changeset) ?? []), change]);\n }\n\n for (const [changeset, staged] of byChangeset) {\n console.log(\n ansis.dim(` ${summarizeRelationshipChanges(staged, `changeset ${changeset}, staged relationships`)}`)\n );\n for (const change of staged) {\n if (change.action === \"rewritten\") {\n continue;\n }\n const kind = change.stagedAs === \"relationship-add\" ? \"add\" : \"delete\";\n console.log(\n ansis.dim(\n ` dropped staged ${kind} of ${formatRelationship(change.before)} (${stagedDropReason(change)})`\n )\n );\n }\n }\n}\n\nfunction stagedDropReason(change: StagedRelationshipRewriteChange): string {\n if (change.action === \"dropped\" || !change.after) {\n return \"no replacement in the catalog\";\n }\n const sameAs = `now the same as ${formatRelationship(change.after)}`;\n switch (change.duplicateOf) {\n case \"model\":\n return `${sameAs}, already in the model`;\n case \"kept\":\n return `${sameAs}, which also stands for a relationship the changeset keeps`;\n default:\n return change.stagedAs === \"relationship-add\"\n ? `${sameAs}, which the changeset already adds`\n : `${sameAs}, which the changeset already deletes`;\n }\n}\n\nfunction formatRelationship(rel: { source: string; predicate: string; target: string }): string {\n return `${rel.source} --[${rel.predicate}]--> ${rel.target}`;\n}\n\n/**\n * Report the staged changesets re-baselined on the upgraded model, and those left on their old\n * base snapshot because they had drifted before the upgrade\n */\nfunction printChangesetRebaseline(result: ChangesetRebaselineResult): void {\n const names = (refs: ChangesetRef[]) => refs.map((ref) => ref.name).join(\", \");\n const count = (n: number) => `${n} staged changeset${n === 1 ? \"\" : \"s\"}`;\n\n if (result.rebaselined.length > 0) {\n console.log(\n ansis.green(\n `\u2713 Re-baselined ${count(result.rebaselined.length)} on the upgraded model: ${names(result.rebaselined)}`\n )\n );\n }\n if (result.drifted.length > 0) {\n console.log(\n ansis.yellow(\n `\u26A0 ${count(result.drifted.length)} had drifted from the model before the upgrade and still ${result.drifted.length === 1 ? \"needs\" : \"need\"} --force to commit: ${names(result.drifted)}`\n )\n );\n }\n for (const error of result.errors) {\n console.log(ansis.yellow(`\u26A0 ${error}`));\n }\n}\n\n/**\n * Execute integration update\n */\nasync function executeIntegrationUpdate(\n label: string,\n updateFn: () => Promise<void>\n): Promise<void> {\n const operationSpan = isTelemetryEnabled\n ? startSpan(\"upgrade.integration\", {\n \"upgrade.integration.label\": label,\n \"upgrade.integration.type\": label.includes(\"Claude\")\n ? \"claude\"\n : label.includes(\"Copilot\")\n ? \"copilot\"\n : \"unknown\",\n })\n : null;\n\n try {\n console.log(ansis.dim(`${label}...`));\n await updateFn();\n console.log(ansis.green(`\u2713 ${label}`));\n\n if (operationSpan) {\n operationSpan.setAttribute(\"upgrade.integration.result\", \"success\");\n }\n } catch (error) {\n if (operationSpan) {\n operationSpan.recordException(error as Error);\n operationSpan.setStatus({\n code: 2, // SpanStatusCode.ERROR\n message: getErrorMessage(error),\n });\n operationSpan.setAttribute(\"upgrade.integration.result\", \"error\");\n }\n console.error(ansis.red(`Error: ${label} failed: ${getErrorMessage(error)}`));\n throw error;\n } finally {\n endSpan(operationSpan);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["integrationActions", "integrationUpToDate", "result"]
7
7
  }
@@ -2,7 +2,7 @@ import ansis from "ansis";
2
2
  import { getCliBundledSpecVersion, getCliVersion } from "../utils/spec-version.js";
3
3
  import { isTelemetryBuiltIn, isTelemetryConfigured } from "../telemetry/detect.js";
4
4
  import { getSpecReferencePath, getModelPath } from "../utils/project-paths.js";
5
- const gitHash = "749a455", cliVersion = getCliVersion();
5
+ const gitHash = "47d9e70", cliVersion = getCliVersion();
6
6
  async function versionCommand() {
7
7
  const specVersion = getCliBundledSpecVersion(), telemetryBuiltIn = isTelemetryBuiltIn(), telemetryConfigured = await isTelemetryConfigured();
8
8
  let telemetryStatus;
@@ -33,7 +33,7 @@ async function visualizeCommand(options) {
33
33
  port = portNum;
34
34
  }
35
35
  port = await findAvailablePort(port), port !== (options.port ? parseInt(String(options.port), 10) : 8080) && console.log(ansis.yellow(` Port ${options.port ?? 8080} is in use, using port ${port} instead`));
36
- const authEnabled = !options.noAuth, authToken = options.token, withDanger = options.withDanger || !1;
36
+ const authEnabled = !options.noAuth, authToken = options.token, withDanger = options.withDanger || !1, withChangesets = (options.withChangesets || !1) && !withDanger;
37
37
  logDebug(`Starting visualization server on port ${port}`), logDebug(`Authentication: ${authEnabled ? "enabled" : "disabled"}`), authEnabled && authToken ? logDebug("Using provided token for authentication") : authEnabled && logDebug("Token will be auto-generated"), withDanger && logDebug("Danger mode enabled - chat permissions will be skipped");
38
38
  const commandDir = dirname(fileURLToPath(import.meta.url)), serverEntryPath = `${dirname(commandDir)}/server-entry.js`;
39
39
  logDebug(`Server entry path: ${serverEntryPath}`);
@@ -53,7 +53,8 @@ async function visualizeCommand(options) {
53
53
  DR_VISUALIZE_PORT: String(port),
54
54
  DR_PROJECT_PATH: process.cwd(),
55
55
  DR_AUTH_ENABLED: String(authEnabled),
56
- DR_WITH_DANGER: String(withDanger)
56
+ DR_WITH_DANGER: String(withDanger),
57
+ DR_WITH_CHANGESETS: String(withChangesets)
57
58
  }, { isDebug: getDebugState, isVerbose } = await import("../utils/globals.js");
58
59
  getDebugState() && (env.DEBUG = "1", env.DR_TELEMETRY_DEBUG = "1", logDebug("Passing DEBUG=1 and DR_TELEMETRY_DEBUG=1 to subprocess")), isVerbose() && (env.VERBOSE = "1", logDebug("Passing VERBOSE=1 to subprocess")), authToken && (env.DR_AUTH_TOKEN = authToken), options.viewerPath && (env.DR_VIEWER_PATH = options.viewerPath, logDebug(`Using custom viewer from: ${options.viewerPath}`));
59
60
  const serverProcess = spawn(process.execPath, [serverEntryPath], {
@@ -91,7 +92,7 @@ async function visualizeCommand(options) {
91
92
  authTokenFromServer ? (console.log(ansis.cyan(` Access URL: http://localhost:${port}?token=${token}`)), console.log(ansis.dim(` Auth token: ${token}`))) : (console.log(ansis.dim(` Open http://localhost:${port} in your browser`)), logDebug(" (waiting for auth token...)"));
92
93
  } else
93
94
  console.log(ansis.dim(` Open http://localhost:${port} in your browser`)), console.log(ansis.yellow(" \u26A0 Authentication disabled"));
94
- withDanger && console.log(ansis.yellow(" \u26A0 Danger mode enabled - chat permissions will be skipped")), console.log(ansis.blueBright(`Model name: ${model.manifest.name}`));
95
+ withDanger ? (console.log(ansis.yellow(" \u26A0 Danger mode enabled - chat permissions will be skipped")), options.withChangesets && console.log(ansis.dim(" (--with-changesets ignored: danger mode already allows all writes)"))) : withChangesets && console.log(ansis.yellow(" \u26A0 Changeset mode enabled - chat can stage model changes in a changeset (no commit/apply/delete)")), console.log(ansis.blueBright(`Model name: ${model.manifest.name}`));
95
96
  const drFolder = await getSpecReferencePath();
96
97
  console.log(`DR folder: ${ansis.cyan(drFolder || "Not found")}`), console.log(`Model path: ${ansis.cyan(await getModelPath() || "Not found")}`);
97
98
  const shouldOpenBrowser = !options.noBrowser;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/commands/visualize.ts"],
4
- "sourcesContent": ["/**\n * Visualize command - Launch visualization server\n */\n\nimport ansis from \"ansis\"\nimport { spawn } from \"child_process\"\nimport { fileURLToPath } from \"node:url\"\nimport { dirname } from \"node:path\"\nimport { Model } from \"../core/model.js\"\nimport { logVerbose, logDebug } from \"../utils/globals.js\"\nimport { CLIError } from \"../utils/errors.js\"\nimport { getSpecReferencePath, getModelPath } from \"../utils/project-paths.js\"\nimport { getErrorMessage } from \"../utils/errors.js\"\n\n// Conditional telemetry import based on compile-time flag\ndeclare const TELEMETRY_ENABLED: boolean | undefined\nconst isTelemetryEnabled = typeof TELEMETRY_ENABLED !== \"undefined\" ? TELEMETRY_ENABLED : false\n\nexport interface VisualizeOptions {\n port?: number\n noBrowser?: boolean\n noAuth?: boolean\n token?: string\n verbose?: boolean\n debug?: boolean\n withDanger?: boolean\n viewerPath?: string\n}\n\nasync function findAvailablePort(startPort: number): Promise<number> {\n const { createServer } = await import(\"net\")\n for (let port = startPort; port <= 65535; port++) {\n const available = await new Promise<boolean>((resolve) => {\n const server = createServer()\n server.once(\"error\", () => resolve(false))\n server.once(\"listening\", () => { server.close(); resolve(true) })\n server.listen(port, \"127.0.0.1\")\n })\n if (available) return port\n }\n throw new Error(\"No available ports found\")\n}\n\nexport async function visualizeCommand(\n options: VisualizeOptions & { port?: string }\n): Promise<void> {\n try {\n logDebug(\"Loading model for validation...\")\n\n // Load model to validate it exists (without full content to be quick)\n const model = await Model.load(process.cwd(), { lazyLoad: true })\n\n logVerbose(`Model validated: ${model.manifest.name}`)\n\n // Parse and validate port\n let port = 8080\n if (options.port) {\n const portNum = parseInt(String(options.port), 10)\n if (isNaN(portNum) || portNum < 1 || portNum > 65535) {\n throw new Error(`Invalid port number: ${options.port}. Port must be between 1 and 65535.`)\n }\n port = portNum\n }\n\n // Find an available port starting from the requested port\n port = await findAvailablePort(port)\n if (port !== (options.port ? parseInt(String(options.port), 10) : 8080)) {\n console.log(ansis.yellow(` Port ${options.port ?? 8080} is in use, using port ${port} instead`))\n }\n\n // Determine auth settings\n const authEnabled = !options.noAuth // Auth enabled by default unless --no-auth flag\n const authToken = options.token // Optional token for testing\n const withDanger = options.withDanger || false // Danger mode disabled by default\n\n logDebug(`Starting visualization server on port ${port}`)\n logDebug(`Authentication: ${authEnabled ? \"enabled\" : \"disabled\"}`)\n if (authEnabled && authToken) {\n logDebug(`Using provided token for authentication`)\n } else if (authEnabled) {\n logDebug(`Token will be auto-generated`)\n }\n if (withDanger) {\n logDebug(`Danger mode enabled - chat permissions will be skipped`)\n }\n\n // Get the directory where this command file is located (dist/commands/)\n const commandDir = dirname(fileURLToPath(import.meta.url))\n const distDir = dirname(commandDir) // Go up to dist/\n const serverEntryPath = `${distDir}/server-entry.js`\n\n logDebug(`Server entry path: ${serverEntryPath}`)\n\n // Create telemetry span for server startup\n let serverStartupSpan: any = null\n if (isTelemetryEnabled) {\n logDebug(\"[Telemetry] Creating visualize.server.startup span\")\n const { startSpan } = await import(\"../telemetry/index.js\")\n serverStartupSpan = startSpan(\"visualize.server.startup\", {\n \"server.port\": port,\n \"server.auth_enabled\": authEnabled,\n \"server.with_danger\": withDanger,\n })\n logDebug(`[Telemetry] Span created: ${serverStartupSpan ? \"success\" : \"failed\"}`)\n } else {\n logDebug(\"[Telemetry] TELEMETRY_ENABLED is false - no spans will be created\")\n }\n\n // Build environment variables for the server subprocess\n const env: Record<string, string> = {\n ...process.env,\n DR_VISUALIZE_PORT: String(port),\n DR_PROJECT_PATH: process.cwd(),\n DR_AUTH_ENABLED: String(authEnabled),\n DR_WITH_DANGER: String(withDanger),\n }\n\n // Pass debug/verbose flags to subprocess\n // The CLI --debug flag sets globalOptions.debug, but subprocess checks process.env.DEBUG\n const { isDebug: getDebugState, isVerbose } = await import(\"../utils/globals.js\")\n if (getDebugState()) {\n env.DEBUG = \"1\"\n env.DR_TELEMETRY_DEBUG = \"1\" // Enable telemetry exporter debug logging\n logDebug(\"Passing DEBUG=1 and DR_TELEMETRY_DEBUG=1 to subprocess\")\n }\n if (isVerbose()) {\n env.VERBOSE = \"1\"\n logDebug(\"Passing VERBOSE=1 to subprocess\")\n }\n\n // Only set auth token if provided\n if (authToken) {\n env.DR_AUTH_TOKEN = authToken\n }\n\n // Set custom viewer path if provided\n if (options.viewerPath) {\n env.DR_VIEWER_PATH = options.viewerPath\n logDebug(`Using custom viewer from: ${options.viewerPath}`)\n }\n\n // Reuse whichever runtime is currently executing the CLI (node or bun) to launch\n // the server subprocess. server-entry.ts has no Bun-specific dependencies (see #800),\n // so this works identically under Node.js or Bun \u2014 and unlike spawning a literal\n // \"bun\" binary, process.execPath is guaranteed to exist since it's already running.\n const serverProcess = spawn(process.execPath, [serverEntryPath], {\n cwd: process.cwd(),\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env,\n })\n\n let authTokenFromServer = \"\"\n let serverOutput = \"\"\n let serverStartupShown = false\n\n // Capture output from server process\n if (serverProcess.stdout) {\n serverProcess.stdout.on(\"data\", async (data) => {\n const chunk = data.toString()\n serverOutput += chunk\n\n // Process each line individually: stdio pipe buffering can batch multiple\n // console.log calls (e.g. \"running at\" + \"TOKEN:\") into a single data event,\n // regardless of runtime.\n // Using startsWith/substring on the whole chunk would either miss the TOKEN line\n // (when \"running at\" is first) or extract a malformed token (when trailing lines\n // are appended), causing the browser to open with the wrong token and get a 403.\n const lines = chunk.split(\"\\n\")\n for (const rawLine of lines) {\n const line = rawLine.trim()\n if (!line) continue\n\n // Extract token from output\n if (line.startsWith(\"TOKEN:\")) {\n authTokenFromServer = line.substring(6)\n logDebug(`Received auth token from server: ${authTokenFromServer.substring(0, 8)}...`)\n\n // If we haven't shown startup info yet and now have the token, show it\n if (serverStartupShown && authEnabled && authTokenFromServer) {\n // Update the URL display with actual token\n console.log(\n ansis.cyan(` Access URL: http://localhost:${port}?token=${authTokenFromServer}`)\n )\n console.log(ansis.dim(` Auth token: ${authTokenFromServer}`))\n\n // Now that we have the token, open browser if needed\n if (!options.noBrowser) {\n try {\n const command = getOpenCommand()\n const url = `http://localhost:${port}?token=${authTokenFromServer}`\n logDebug(`Opening browser with command: ${command} ${url}`)\n spawn(command, [url], {\n detached: true,\n stdio: \"ignore\",\n })\n } catch (error) {\n logVerbose(\"Could not auto-open browser (not critical)\")\n }\n }\n }\n }\n\n // Server started message - defer detailed output if auth enabled\n if (line.includes(\"running at http://localhost\")) {\n serverStartupShown = true\n\n // End telemetry span for server startup\n if (isTelemetryEnabled && serverStartupSpan) {\n logDebug(\n \"[Telemetry] Ending visualize.server.startup span (server started successfully)\"\n )\n const { endSpan } = await import(\"../telemetry/index.js\")\n endSpan(serverStartupSpan)\n serverStartupSpan = null\n logDebug(\"[Telemetry] Span ended\")\n }\n\n console.log(ansis.green(`\u2713 Visualization server started`))\n\n // Display access information (but may be incomplete if auth enabled and token not yet received)\n if (authEnabled) {\n const token = authTokenFromServer || authToken || \"(pending)\"\n if (authTokenFromServer) {\n // Token already received (same chunk), show full info immediately\n console.log(ansis.cyan(` Access URL: http://localhost:${port}?token=${token}`))\n console.log(ansis.dim(` Auth token: ${token}`))\n } else {\n // Token not yet received, just show port for now\n console.log(ansis.dim(` Open http://localhost:${port} in your browser`))\n logDebug(` (waiting for auth token...)`)\n }\n } else {\n console.log(ansis.dim(` Open http://localhost:${port} in your browser`))\n console.log(ansis.yellow(` \u26A0 Authentication disabled`))\n }\n\n if (withDanger) {\n console.log(\n ansis.yellow(` \u26A0 Danger mode enabled - chat permissions will be skipped`)\n )\n }\n\n console.log(ansis.blueBright(`Model name: ${model.manifest.name}`))\n const drFolder = await getSpecReferencePath()\n console.log(\n `DR folder: ${ansis.cyan(drFolder || \"Not found\")}`\n )\n console.log(`Model path: ${ansis.cyan((await getModelPath()) || \"Not found\")}`)\n\n // Optionally open browser\n // If auth is enabled, delay opening until we have the token\n const shouldOpenBrowser = !options.noBrowser\n logDebug(\n `Browser auto-open: ${shouldOpenBrowser ? \"enabled\" : \"disabled\"} (noBrowser=${options.noBrowser})`\n )\n\n if (shouldOpenBrowser && !authEnabled) {\n // Auth disabled: open immediately\n try {\n const command = getOpenCommand()\n const url = `http://localhost:${port}`\n logDebug(`Opening browser with command: ${command} ${url}`)\n spawn(command, [url], {\n detached: true,\n stdio: \"ignore\",\n })\n } catch (error) {\n logVerbose(\"Could not auto-open browser (not critical)\")\n }\n } else if (shouldOpenBrowser && authEnabled && !authTokenFromServer) {\n // Auth enabled but token not yet in this chunk: will open when TOKEN line is processed\n logDebug(\"Browser auto-open deferred until token is received\")\n } else {\n logDebug(\"Browser auto-open disabled\")\n }\n }\n\n // Log other output\n if (!line.startsWith(\"TOKEN:\")) {\n logDebug(`[server] ${line}`)\n }\n }\n })\n }\n\n // Capture stderr\n if (serverProcess.stderr) {\n serverProcess.stderr.on(\"data\", (data) => {\n const output = data.toString().trim()\n if (output) {\n serverOutput += output + \"\\n\"\n // Log stderr at debug level so --debug flag shows telemetry exporter logs\n logDebug(`[server stderr] ${output}`)\n }\n })\n }\n\n // Handle process close (fires after all stdio streams have closed)\n let rejectKeepAlive: ((reason: Error) => void) | null = null\n\n serverProcess.on(\"close\", (code) => {\n if (code !== 0) {\n // Include server output in error message if available (avoid separate logDebug to prevent minification issues)\n const message = serverOutput\n ? `Server exited with code ${code}\\nServer output:\\n${serverOutput}`\n : `Server exited with code ${code}`\n\n // Record error in startup span if still active\n if (isTelemetryEnabled && serverStartupSpan) {\n (async () => {\n const { endSpan } = await import(\"../telemetry/index.js\")\n if (\"recordException\" in serverStartupSpan) {\n (serverStartupSpan as any).recordException(new Error(message));\n (serverStartupSpan as any).setStatus({ code: 2, message }) // ERROR\n }\n endSpan(serverStartupSpan)\n serverStartupSpan = null\n })()\n }\n\n // Print error before rejecting (CLI wrapper expects CLIError messages to be pre-printed)\n console.error(message)\n const error = new CLIError(message, code || 1)\n if (rejectKeepAlive) {\n rejectKeepAlive(error)\n }\n }\n })\n\n // Handle process errors\n serverProcess.on(\"error\", (error) => {\n const errorCode = (error as NodeJS.ErrnoException).code\n let message: string\n let suggestions: string[] | undefined\n\n // The server subprocess is launched via process.execPath (the same node/bun\n // binary already running this CLI), so it's always present - ENOENT here would\n // indicate something unusual about the runtime environment rather than a missing\n // dependency (see #800: this used to hard-depend on a separately installed `bun`).\n if (errorCode === \"EACCES\") {\n message = `dr visualize could not run the visualization server: permission denied executing ${process.execPath}.`\n suggestions = [`Check that ${process.execPath} is executable (chmod +x).`]\n } else {\n message = `Failed to start visualization server: ${error.message}`\n }\n\n // Record error in startup span if still active\n if (isTelemetryEnabled && serverStartupSpan) {\n (async () => {\n const { endSpan } = await import(\"../telemetry/index.js\")\n if (\"recordException\" in serverStartupSpan) {\n (serverStartupSpan as any).recordException(error);\n (serverStartupSpan as any).setStatus({ code: 2, message }) // ERROR\n }\n endSpan(serverStartupSpan)\n serverStartupSpan = null\n })()\n }\n\n // Don't print here: rejecting propagates this CLIError up through the catch block\n // below to the top-level CLI handler, which prints `.format()` (including\n // `suggestions`) exactly once. Printing here too would duplicate the whole block.\n const cliError = new CLIError(message, 1, suggestions)\n if (rejectKeepAlive) {\n rejectKeepAlive(cliError)\n }\n })\n\n // Setup periodic telemetry flushing for long-running command\n // Since the visualize command never completes (keep-alive pattern),\n // the cli.execute span would never end and export. We flush periodically\n // to ensure active spans are exported to the telemetry backend.\n let flushInterval: NodeJS.Timeout | null = null\n if (isTelemetryEnabled) {\n logDebug(\"[Telemetry] Setting up periodic flush (every 15 seconds)\")\n const { flushTelemetry } = await import(\"../telemetry/index.js\")\n\n flushInterval = setInterval(async () => {\n logDebug(\"[Telemetry] Periodic flush: flushing pending spans...\")\n try {\n await flushTelemetry()\n logDebug(\"[Telemetry] Periodic flush complete\")\n } catch (error) {\n // Silently ignore flush errors - telemetry should never break the app\n logDebug(`[Telemetry] Periodic flush failed: ${error}`)\n }\n }, 15000) // Flush every 15 seconds\n }\n\n // Handle graceful shutdown on SIGINT (Ctrl-C) and SIGTERM\n const handleShutdown = async (signal: string) => {\n logDebug(`\\n[${signal}] Shutting down visualization server gracefully...`)\n\n // Clear periodic flush interval\n if (flushInterval) {\n logDebug(\"[Telemetry] Stopping periodic flush\")\n clearInterval(flushInterval)\n flushInterval = null\n }\n\n // Forward signal to server process for graceful shutdown\n if (serverProcess && !serverProcess.killed) {\n logDebug(\"Sending termination signal to server process...\")\n serverProcess.kill(signal as NodeJS.Signals)\n\n // Wait for server to exit (with timeout)\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(() => {\n logDebug(\"Server shutdown timeout, forcing exit...\")\n if (!serverProcess.killed) {\n serverProcess.kill(\"SIGKILL\")\n }\n resolve()\n }, 3000) // 3 second timeout\n\n serverProcess.on(\"exit\", () => {\n clearTimeout(timeout)\n resolve()\n })\n })\n }\n\n logDebug(\"Visualization server stopped\")\n process.exit(0)\n }\n\n // Register signal handlers\n process.on(\"SIGINT\", () => handleShutdown(\"SIGINT\"))\n process.on(\"SIGTERM\", () => handleShutdown(\"SIGTERM\"))\n\n // Keep parent process alive - reject promise if server fails\n await new Promise((_, reject) => {\n rejectKeepAlive = reject\n })\n } catch (error) {\n // Throw CLIError instead of process.exit to allow telemetry shutdown\n // Note: Avoid side effects (like logDebug) before throw to prevent minification issues\n if (error instanceof CLIError) {\n // CLIError should have already printed its message\n throw error\n }\n // Non-CLIError needs to be printed and wrapped\n const message = getErrorMessage(error)\n console.error(message)\n throw new CLIError(message, 1)\n }\n}\n\n/**\n * Get the appropriate command to open a URL\n */\nfunction getOpenCommand(): string {\n const platform = process.platform\n\n if (platform === \"darwin\") {\n return \"open\"\n }\n if (platform === \"win32\") {\n return \"start\"\n }\n // Linux and others\n return \"xdg-open\"\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Visualize command - Launch visualization server\n */\n\nimport ansis from \"ansis\"\nimport { spawn } from \"child_process\"\nimport { fileURLToPath } from \"node:url\"\nimport { dirname } from \"node:path\"\nimport { Model } from \"../core/model.js\"\nimport { logVerbose, logDebug } from \"../utils/globals.js\"\nimport { CLIError } from \"../utils/errors.js\"\nimport { getSpecReferencePath, getModelPath } from \"../utils/project-paths.js\"\nimport { getErrorMessage } from \"../utils/errors.js\"\n\n// Conditional telemetry import based on compile-time flag\ndeclare const TELEMETRY_ENABLED: boolean | undefined\nconst isTelemetryEnabled = typeof TELEMETRY_ENABLED !== \"undefined\" ? TELEMETRY_ENABLED : false\n\nexport interface VisualizeOptions {\n port?: number\n noBrowser?: boolean\n noAuth?: boolean\n token?: string\n verbose?: boolean\n debug?: boolean\n withDanger?: boolean\n withChangesets?: boolean\n viewerPath?: string\n}\n\nasync function findAvailablePort(startPort: number): Promise<number> {\n const { createServer } = await import(\"net\")\n for (let port = startPort; port <= 65535; port++) {\n const available = await new Promise<boolean>((resolve) => {\n const server = createServer()\n server.once(\"error\", () => resolve(false))\n server.once(\"listening\", () => { server.close(); resolve(true) })\n server.listen(port, \"127.0.0.1\")\n })\n if (available) return port\n }\n throw new Error(\"No available ports found\")\n}\n\nexport async function visualizeCommand(\n options: VisualizeOptions & { port?: string }\n): Promise<void> {\n try {\n logDebug(\"Loading model for validation...\")\n\n // Load model to validate it exists (without full content to be quick)\n const model = await Model.load(process.cwd(), { lazyLoad: true })\n\n logVerbose(`Model validated: ${model.manifest.name}`)\n\n // Parse and validate port\n let port = 8080\n if (options.port) {\n const portNum = parseInt(String(options.port), 10)\n if (isNaN(portNum) || portNum < 1 || portNum > 65535) {\n throw new Error(`Invalid port number: ${options.port}. Port must be between 1 and 65535.`)\n }\n port = portNum\n }\n\n // Find an available port starting from the requested port\n port = await findAvailablePort(port)\n if (port !== (options.port ? parseInt(String(options.port), 10) : 8080)) {\n console.log(ansis.yellow(` Port ${options.port ?? 8080} is in use, using port ${port} instead`))\n }\n\n // Determine auth settings\n const authEnabled = !options.noAuth // Auth enabled by default unless --no-auth flag\n const authToken = options.token // Optional token for testing\n const withDanger = options.withDanger || false // Danger mode disabled by default\n // Changeset-only writes; danger mode already allows everything, so it wins\n const withChangesets = (options.withChangesets || false) && !withDanger\n\n logDebug(`Starting visualization server on port ${port}`)\n logDebug(`Authentication: ${authEnabled ? \"enabled\" : \"disabled\"}`)\n if (authEnabled && authToken) {\n logDebug(`Using provided token for authentication`)\n } else if (authEnabled) {\n logDebug(`Token will be auto-generated`)\n }\n if (withDanger) {\n logDebug(`Danger mode enabled - chat permissions will be skipped`)\n }\n\n // Get the directory where this command file is located (dist/commands/)\n const commandDir = dirname(fileURLToPath(import.meta.url))\n const distDir = dirname(commandDir) // Go up to dist/\n const serverEntryPath = `${distDir}/server-entry.js`\n\n logDebug(`Server entry path: ${serverEntryPath}`)\n\n // Create telemetry span for server startup\n let serverStartupSpan: any = null\n if (isTelemetryEnabled) {\n logDebug(\"[Telemetry] Creating visualize.server.startup span\")\n const { startSpan } = await import(\"../telemetry/index.js\")\n serverStartupSpan = startSpan(\"visualize.server.startup\", {\n \"server.port\": port,\n \"server.auth_enabled\": authEnabled,\n \"server.with_danger\": withDanger,\n })\n logDebug(`[Telemetry] Span created: ${serverStartupSpan ? \"success\" : \"failed\"}`)\n } else {\n logDebug(\"[Telemetry] TELEMETRY_ENABLED is false - no spans will be created\")\n }\n\n // Build environment variables for the server subprocess\n const env: Record<string, string> = {\n ...process.env,\n DR_VISUALIZE_PORT: String(port),\n DR_PROJECT_PATH: process.cwd(),\n DR_AUTH_ENABLED: String(authEnabled),\n DR_WITH_DANGER: String(withDanger),\n DR_WITH_CHANGESETS: String(withChangesets),\n }\n\n // Pass debug/verbose flags to subprocess\n // The CLI --debug flag sets globalOptions.debug, but subprocess checks process.env.DEBUG\n const { isDebug: getDebugState, isVerbose } = await import(\"../utils/globals.js\")\n if (getDebugState()) {\n env.DEBUG = \"1\"\n env.DR_TELEMETRY_DEBUG = \"1\" // Enable telemetry exporter debug logging\n logDebug(\"Passing DEBUG=1 and DR_TELEMETRY_DEBUG=1 to subprocess\")\n }\n if (isVerbose()) {\n env.VERBOSE = \"1\"\n logDebug(\"Passing VERBOSE=1 to subprocess\")\n }\n\n // Only set auth token if provided\n if (authToken) {\n env.DR_AUTH_TOKEN = authToken\n }\n\n // Set custom viewer path if provided\n if (options.viewerPath) {\n env.DR_VIEWER_PATH = options.viewerPath\n logDebug(`Using custom viewer from: ${options.viewerPath}`)\n }\n\n // Reuse whichever runtime is currently executing the CLI (node or bun) to launch\n // the server subprocess. server-entry.ts has no Bun-specific dependencies (see #800),\n // so this works identically under Node.js or Bun \u2014 and unlike spawning a literal\n // \"bun\" binary, process.execPath is guaranteed to exist since it's already running.\n const serverProcess = spawn(process.execPath, [serverEntryPath], {\n cwd: process.cwd(),\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env,\n })\n\n let authTokenFromServer = \"\"\n let serverOutput = \"\"\n let serverStartupShown = false\n\n // Capture output from server process\n if (serverProcess.stdout) {\n serverProcess.stdout.on(\"data\", async (data) => {\n const chunk = data.toString()\n serverOutput += chunk\n\n // Process each line individually: stdio pipe buffering can batch multiple\n // console.log calls (e.g. \"running at\" + \"TOKEN:\") into a single data event,\n // regardless of runtime.\n // Using startsWith/substring on the whole chunk would either miss the TOKEN line\n // (when \"running at\" is first) or extract a malformed token (when trailing lines\n // are appended), causing the browser to open with the wrong token and get a 403.\n const lines = chunk.split(\"\\n\")\n for (const rawLine of lines) {\n const line = rawLine.trim()\n if (!line) continue\n\n // Extract token from output\n if (line.startsWith(\"TOKEN:\")) {\n authTokenFromServer = line.substring(6)\n logDebug(`Received auth token from server: ${authTokenFromServer.substring(0, 8)}...`)\n\n // If we haven't shown startup info yet and now have the token, show it\n if (serverStartupShown && authEnabled && authTokenFromServer) {\n // Update the URL display with actual token\n console.log(\n ansis.cyan(` Access URL: http://localhost:${port}?token=${authTokenFromServer}`)\n )\n console.log(ansis.dim(` Auth token: ${authTokenFromServer}`))\n\n // Now that we have the token, open browser if needed\n if (!options.noBrowser) {\n try {\n const command = getOpenCommand()\n const url = `http://localhost:${port}?token=${authTokenFromServer}`\n logDebug(`Opening browser with command: ${command} ${url}`)\n spawn(command, [url], {\n detached: true,\n stdio: \"ignore\",\n })\n } catch (error) {\n logVerbose(\"Could not auto-open browser (not critical)\")\n }\n }\n }\n }\n\n // Server started message - defer detailed output if auth enabled\n if (line.includes(\"running at http://localhost\")) {\n serverStartupShown = true\n\n // End telemetry span for server startup\n if (isTelemetryEnabled && serverStartupSpan) {\n logDebug(\n \"[Telemetry] Ending visualize.server.startup span (server started successfully)\"\n )\n const { endSpan } = await import(\"../telemetry/index.js\")\n endSpan(serverStartupSpan)\n serverStartupSpan = null\n logDebug(\"[Telemetry] Span ended\")\n }\n\n console.log(ansis.green(`\u2713 Visualization server started`))\n\n // Display access information (but may be incomplete if auth enabled and token not yet received)\n if (authEnabled) {\n const token = authTokenFromServer || authToken || \"(pending)\"\n if (authTokenFromServer) {\n // Token already received (same chunk), show full info immediately\n console.log(ansis.cyan(` Access URL: http://localhost:${port}?token=${token}`))\n console.log(ansis.dim(` Auth token: ${token}`))\n } else {\n // Token not yet received, just show port for now\n console.log(ansis.dim(` Open http://localhost:${port} in your browser`))\n logDebug(` (waiting for auth token...)`)\n }\n } else {\n console.log(ansis.dim(` Open http://localhost:${port} in your browser`))\n console.log(ansis.yellow(` \u26A0 Authentication disabled`))\n }\n\n if (withDanger) {\n console.log(\n ansis.yellow(` \u26A0 Danger mode enabled - chat permissions will be skipped`)\n )\n if (options.withChangesets) {\n console.log(ansis.dim(` (--with-changesets ignored: danger mode already allows all writes)`))\n }\n } else if (withChangesets) {\n console.log(\n ansis.yellow(` \u26A0 Changeset mode enabled - chat can stage model changes in a changeset (no commit/apply/delete)`)\n )\n }\n\n console.log(ansis.blueBright(`Model name: ${model.manifest.name}`))\n const drFolder = await getSpecReferencePath()\n console.log(\n `DR folder: ${ansis.cyan(drFolder || \"Not found\")}`\n )\n console.log(`Model path: ${ansis.cyan((await getModelPath()) || \"Not found\")}`)\n\n // Optionally open browser\n // If auth is enabled, delay opening until we have the token\n const shouldOpenBrowser = !options.noBrowser\n logDebug(\n `Browser auto-open: ${shouldOpenBrowser ? \"enabled\" : \"disabled\"} (noBrowser=${options.noBrowser})`\n )\n\n if (shouldOpenBrowser && !authEnabled) {\n // Auth disabled: open immediately\n try {\n const command = getOpenCommand()\n const url = `http://localhost:${port}`\n logDebug(`Opening browser with command: ${command} ${url}`)\n spawn(command, [url], {\n detached: true,\n stdio: \"ignore\",\n })\n } catch (error) {\n logVerbose(\"Could not auto-open browser (not critical)\")\n }\n } else if (shouldOpenBrowser && authEnabled && !authTokenFromServer) {\n // Auth enabled but token not yet in this chunk: will open when TOKEN line is processed\n logDebug(\"Browser auto-open deferred until token is received\")\n } else {\n logDebug(\"Browser auto-open disabled\")\n }\n }\n\n // Log other output\n if (!line.startsWith(\"TOKEN:\")) {\n logDebug(`[server] ${line}`)\n }\n }\n })\n }\n\n // Capture stderr\n if (serverProcess.stderr) {\n serverProcess.stderr.on(\"data\", (data) => {\n const output = data.toString().trim()\n if (output) {\n serverOutput += output + \"\\n\"\n // Log stderr at debug level so --debug flag shows telemetry exporter logs\n logDebug(`[server stderr] ${output}`)\n }\n })\n }\n\n // Handle process close (fires after all stdio streams have closed)\n let rejectKeepAlive: ((reason: Error) => void) | null = null\n\n serverProcess.on(\"close\", (code) => {\n if (code !== 0) {\n // Include server output in error message if available (avoid separate logDebug to prevent minification issues)\n const message = serverOutput\n ? `Server exited with code ${code}\\nServer output:\\n${serverOutput}`\n : `Server exited with code ${code}`\n\n // Record error in startup span if still active\n if (isTelemetryEnabled && serverStartupSpan) {\n (async () => {\n const { endSpan } = await import(\"../telemetry/index.js\")\n if (\"recordException\" in serverStartupSpan) {\n (serverStartupSpan as any).recordException(new Error(message));\n (serverStartupSpan as any).setStatus({ code: 2, message }) // ERROR\n }\n endSpan(serverStartupSpan)\n serverStartupSpan = null\n })()\n }\n\n // Print error before rejecting (CLI wrapper expects CLIError messages to be pre-printed)\n console.error(message)\n const error = new CLIError(message, code || 1)\n if (rejectKeepAlive) {\n rejectKeepAlive(error)\n }\n }\n })\n\n // Handle process errors\n serverProcess.on(\"error\", (error) => {\n const errorCode = (error as NodeJS.ErrnoException).code\n let message: string\n let suggestions: string[] | undefined\n\n // The server subprocess is launched via process.execPath (the same node/bun\n // binary already running this CLI), so it's always present - ENOENT here would\n // indicate something unusual about the runtime environment rather than a missing\n // dependency (see #800: this used to hard-depend on a separately installed `bun`).\n if (errorCode === \"EACCES\") {\n message = `dr visualize could not run the visualization server: permission denied executing ${process.execPath}.`\n suggestions = [`Check that ${process.execPath} is executable (chmod +x).`]\n } else {\n message = `Failed to start visualization server: ${error.message}`\n }\n\n // Record error in startup span if still active\n if (isTelemetryEnabled && serverStartupSpan) {\n (async () => {\n const { endSpan } = await import(\"../telemetry/index.js\")\n if (\"recordException\" in serverStartupSpan) {\n (serverStartupSpan as any).recordException(error);\n (serverStartupSpan as any).setStatus({ code: 2, message }) // ERROR\n }\n endSpan(serverStartupSpan)\n serverStartupSpan = null\n })()\n }\n\n // Don't print here: rejecting propagates this CLIError up through the catch block\n // below to the top-level CLI handler, which prints `.format()` (including\n // `suggestions`) exactly once. Printing here too would duplicate the whole block.\n const cliError = new CLIError(message, 1, suggestions)\n if (rejectKeepAlive) {\n rejectKeepAlive(cliError)\n }\n })\n\n // Setup periodic telemetry flushing for long-running command\n // Since the visualize command never completes (keep-alive pattern),\n // the cli.execute span would never end and export. We flush periodically\n // to ensure active spans are exported to the telemetry backend.\n let flushInterval: NodeJS.Timeout | null = null\n if (isTelemetryEnabled) {\n logDebug(\"[Telemetry] Setting up periodic flush (every 15 seconds)\")\n const { flushTelemetry } = await import(\"../telemetry/index.js\")\n\n flushInterval = setInterval(async () => {\n logDebug(\"[Telemetry] Periodic flush: flushing pending spans...\")\n try {\n await flushTelemetry()\n logDebug(\"[Telemetry] Periodic flush complete\")\n } catch (error) {\n // Silently ignore flush errors - telemetry should never break the app\n logDebug(`[Telemetry] Periodic flush failed: ${error}`)\n }\n }, 15000) // Flush every 15 seconds\n }\n\n // Handle graceful shutdown on SIGINT (Ctrl-C) and SIGTERM\n const handleShutdown = async (signal: string) => {\n logDebug(`\\n[${signal}] Shutting down visualization server gracefully...`)\n\n // Clear periodic flush interval\n if (flushInterval) {\n logDebug(\"[Telemetry] Stopping periodic flush\")\n clearInterval(flushInterval)\n flushInterval = null\n }\n\n // Forward signal to server process for graceful shutdown\n if (serverProcess && !serverProcess.killed) {\n logDebug(\"Sending termination signal to server process...\")\n serverProcess.kill(signal as NodeJS.Signals)\n\n // Wait for server to exit (with timeout)\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(() => {\n logDebug(\"Server shutdown timeout, forcing exit...\")\n if (!serverProcess.killed) {\n serverProcess.kill(\"SIGKILL\")\n }\n resolve()\n }, 3000) // 3 second timeout\n\n serverProcess.on(\"exit\", () => {\n clearTimeout(timeout)\n resolve()\n })\n })\n }\n\n logDebug(\"Visualization server stopped\")\n process.exit(0)\n }\n\n // Register signal handlers\n process.on(\"SIGINT\", () => handleShutdown(\"SIGINT\"))\n process.on(\"SIGTERM\", () => handleShutdown(\"SIGTERM\"))\n\n // Keep parent process alive - reject promise if server fails\n await new Promise((_, reject) => {\n rejectKeepAlive = reject\n })\n } catch (error) {\n // Throw CLIError instead of process.exit to allow telemetry shutdown\n // Note: Avoid side effects (like logDebug) before throw to prevent minification issues\n if (error instanceof CLIError) {\n // CLIError should have already printed its message\n throw error\n }\n // Non-CLIError needs to be printed and wrapped\n const message = getErrorMessage(error)\n console.error(message)\n throw new CLIError(message, 1)\n }\n}\n\n/**\n * Get the appropriate command to open a URL\n */\nfunction getOpenCommand(): string {\n const platform = process.platform\n\n if (platform === \"darwin\") {\n return \"open\"\n }\n if (platform === \"win32\") {\n return \"start\"\n }\n // Linux and others\n return \"xdg-open\"\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,33 @@
1
+ import { migrateElementTypes, summarizeElementTypeChanges } from "./element-type-migration.js";
2
+ import { migrateRelationshipsFile, migrateStagedChangesets, summarizeRelationshipChanges } from "./relationship-migration.js";
3
+ async function applyCatalogMigrations(model, options = {}) {
4
+ const dryRun = options.dryRun ?? !1, types = await migrateElementTypes(model, void 0, { dryRun }), relationships = types.errors.length ? { filesModified: 0, changes: [], committed: { before: [], after: [] }, error: void 0 } : await migrateRelationshipsFile(model, void 0, { dryRun }), staged = relationships.error ? { changesetsModified: 0, changes: [], errors: [] } : await migrateStagedChangesets(model, relationships.committed, void 0, { dryRun }), summaries = [
5
+ ...types.changes.length > 0 ? [`element types renamed: ${summarizeElementTypeChanges(types.changes)}`] : [],
6
+ relationships.changes.length > 0 ? summarizeRelationshipChanges(relationships.changes) : "no relationships to rewrite",
7
+ ...staged.changes.length > 0 ? [summarizeRelationshipChanges(staged.changes, "staged relationship changes")] : []
8
+ ];
9
+ return {
10
+ filesModified: types.filesModified + types.changesetsModified + relationships.filesModified + staged.changesetsModified,
11
+ summaries,
12
+ errors: [...types.errors, ...relationships.error ? [relationships.error] : [], ...staged.errors],
13
+ details: {
14
+ elementTypeChanges: types.changes,
15
+ relationshipChanges: relationships.changes,
16
+ stagedRelationshipChanges: staged.changes
17
+ }
18
+ };
19
+ }
20
+ async function pendingCatalogMigrations(model) {
21
+ const r = await applyCatalogMigrations(model, { dryRun: !0 });
22
+ return {
23
+ elementTypes: r.details.elementTypeChanges.length,
24
+ relationships: r.details.relationshipChanges.length,
25
+ stagedRelationships: r.details.stagedRelationshipChanges.length,
26
+ errors: r.errors
27
+ };
28
+ }
29
+ export {
30
+ applyCatalogMigrations,
31
+ pendingCatalogMigrations
32
+ };
33
+ //# sourceMappingURL=catalog-migration.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/catalog-migration.ts"],
4
+ "sourcesContent": ["/**\n * Catalog migration: brings a model's elements and relationships in line with the current spec\n * catalog, using the generated rewrite table (relationship-migration-table.ts).\n *\n * 1. element type renames (element-type-migration.ts), so the rules below see the new types\n * 2. relationship rewrites in relationships.yaml (relationship-migration.ts)\n * 3. the same rewrites in staged changesets\n *\n * It runs inside the 0.9.0 -> 0.10.0 and 0.10.0 -> 0.11.0 migrations, and on its own when `dr upgrade` finds a model\n * already at the current spec version that still names retired types or relationships: the\n * catalog can change between spec version bumps, and a model stamped with the version before\n * a change would otherwise never receive it. Every step only rewrites what the table matches,\n * so running it again on a migrated model changes nothing.\n */\nimport type { Model } from \"./model.js\";\nimport { migrateElementTypes, summarizeElementTypeChanges, type ElementTypeRenameChange } from \"./element-type-migration.js\";\nimport {\n migrateRelationshipsFile,\n migrateStagedChangesets,\n summarizeRelationshipChanges,\n type RelationshipRewriteChange,\n type StagedRelationshipRewriteChange,\n} from \"./relationship-migration.js\";\n\nexport interface CatalogMigrationResult {\n filesModified: number;\n /** One phrase per kind of change, for the migration description */\n summaries: string[];\n errors: string[];\n details: {\n elementTypeChanges: ElementTypeRenameChange[];\n relationshipChanges: RelationshipRewriteChange[];\n stagedRelationshipChanges: StagedRelationshipRewriteChange[];\n };\n}\n\nexport async function applyCatalogMigrations(\n model: Model,\n options: { dryRun?: boolean } = {}\n): Promise<CatalogMigrationResult> {\n const dryRun = options.dryRun ?? false;\n // Renamed element types first (product.capability -> product.softwarecapability), so the\n // relationship rules, which name the new types, resolve the renamed elements.\n const types = await migrateElementTypes(model, undefined, { dryRun });\n\n const relationships = types.errors.length\n ? { filesModified: 0, changes: [], committed: { before: [], after: [] }, error: undefined }\n : await migrateRelationshipsFile(model, undefined, { dryRun });\n const staged = relationships.error\n ? { changesetsModified: 0, changes: [], errors: [] }\n : await migrateStagedChangesets(model, relationships.committed, undefined, { dryRun });\n\n const summaries = [\n ...(types.changes.length > 0 ? [`element types renamed: ${summarizeElementTypeChanges(types.changes)}`] : []),\n relationships.changes.length > 0 ? summarizeRelationshipChanges(relationships.changes) : \"no relationships to rewrite\",\n ...(staged.changes.length > 0 ? [summarizeRelationshipChanges(staged.changes, \"staged relationship changes\")] : []),\n ];\n\n return {\n filesModified: types.filesModified + types.changesetsModified + relationships.filesModified + staged.changesetsModified,\n summaries,\n errors: [...types.errors, ...(relationships.error ? [relationships.error] : []), ...staged.errors],\n details: {\n elementTypeChanges: types.changes,\n relationshipChanges: relationships.changes,\n stagedRelationshipChanges: staged.changes,\n },\n };\n}\n\n/** How many catalog changes the model still needs; all zero when it is in line with the catalog */\nexport async function pendingCatalogMigrations(\n model: Model\n): Promise<{ elementTypes: number; relationships: number; stagedRelationships: number; errors: string[] }> {\n const r = await applyCatalogMigrations(model, { dryRun: true });\n return {\n elementTypes: r.details.elementTypeChanges.length,\n relationships: r.details.relationshipChanges.length,\n stagedRelationships: r.details.stagedRelationshipChanges.length,\n errors: r.errors,\n };\n}\n"],
5
+ "mappings": "AAeA,SAAS,qBAAqB,mCAAiE;AAC/F,SACE,0BACA,yBACA,oCAGK;AAcP,eAAsB,uBACpB,OACA,UAAgC,CAAA,GAAE;AAElC,QAAM,SAAS,QAAQ,UAAU,IAG3B,QAAQ,MAAM,oBAAoB,OAAO,QAAW,EAAE,OAAM,CAAE,GAE9D,gBAAgB,MAAM,OAAO,SAC/B,EAAE,eAAe,GAAG,SAAS,CAAA,GAAI,WAAW,EAAE,QAAQ,CAAA,GAAI,OAAO,CAAA,EAAE,GAAI,OAAO,OAAS,IACvF,MAAM,yBAAyB,OAAO,QAAW,EAAE,OAAM,CAAE,GACzD,SAAS,cAAc,QACzB,EAAE,oBAAoB,GAAG,SAAS,CAAA,GAAI,QAAQ,CAAA,EAAE,IAChD,MAAM,wBAAwB,OAAO,cAAc,WAAW,QAAW,EAAE,OAAM,CAAE,GAEjF,YAAY;IAChB,GAAI,MAAM,QAAQ,SAAS,IAAI,CAAC,0BAA0B,4BAA4B,MAAM,OAAO,CAAC,EAAE,IAAI,CAAA;IAC1G,cAAc,QAAQ,SAAS,IAAI,6BAA6B,cAAc,OAAO,IAAI;IACzF,GAAI,OAAO,QAAQ,SAAS,IAAI,CAAC,6BAA6B,OAAO,SAAS,6BAA6B,CAAC,IAAI,CAAA;;AAGlH,SAAO;IACL,eAAe,MAAM,gBAAgB,MAAM,qBAAqB,cAAc,gBAAgB,OAAO;IACrG;IACA,QAAQ,CAAC,GAAG,MAAM,QAAQ,GAAI,cAAc,QAAQ,CAAC,cAAc,KAAK,IAAI,CAAA,GAAK,GAAG,OAAO,MAAM;IACjG,SAAS;MACP,oBAAoB,MAAM;MAC1B,qBAAqB,cAAc;MACnC,2BAA2B,OAAO;;;AAGxC;AAGA,eAAsB,yBACpB,OAAY;AAEZ,QAAM,IAAI,MAAM,uBAAuB,OAAO,EAAE,QAAQ,GAAI,CAAE;AAC9D,SAAO;IACL,cAAc,EAAE,QAAQ,mBAAmB;IAC3C,eAAe,EAAE,QAAQ,oBAAoB;IAC7C,qBAAqB,EAAE,QAAQ,0BAA0B;IACzD,QAAQ,EAAE;;AAEd;",
6
+ "names": []
7
+ }