@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
@@ -4,12 +4,14 @@ import { StagingAreaManager } from "../core/staging-area.js";
4
4
  import { ChangesetExporter } from "../core/changeset-exporter.js";
5
5
  import { StagedChangesetStorage } from "../core/staged-changeset-storage.js";
6
6
  import { ValidationFormatter } from "../validators/validation-formatter.js";
7
+ import { Option } from "commander";
7
8
  import * as prompts from "@clack/prompts";
8
9
  import path from "path";
9
10
  import { isTelemetryEnabled, startSpan, endSpan, startActiveSpan } from "../telemetry/index.js";
10
11
  import { getErrorMessage, handleSuccess, handleInfo, handleWarning } from "../utils/errors.js";
11
12
  import { isJson } from "../utils/globals.js";
12
13
  import { findElementLayer } from "../utils/element-utils.js";
14
+ import { changesetVerifyCommand } from "./changeset-verify.js";
13
15
  function generateImportedChangesetId() {
14
16
  return `imported-${Date.now()}`;
15
17
  }
@@ -19,7 +21,7 @@ async function changesetCreateCommand(name, options) {
19
21
  "changeset.hasDescription": !!options.description
20
22
  }) : null;
21
23
  try {
22
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model);
24
+ const model = await Model.load(options.model, { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model);
23
25
  await manager.load(name) && (isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: `Changeset '${name}' already exists` })) : console.error(ansis.red(`Error: Changeset '${name}' already exists`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset already exists" }), endSpan(span), process.exit(1));
24
26
  let description = options.description;
25
27
  if (!description) {
@@ -55,7 +57,7 @@ async function changesetCreateCommand(name, options) {
55
57
  async function changesetListCommand(options = {}) {
56
58
  const span = isTelemetryEnabled ? startSpan("changeset.list") : null;
57
59
  try {
58
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), changesets = await new StagingAreaManager(model.rootPath, model).list();
60
+ const model = await Model.load(options.model, { lazyLoad: !0 }), changesets = await new StagingAreaManager(model.rootPath, model).list();
59
61
  if (isTelemetryEnabled && span && span.setAttribute("changeset.count", changesets.length), changesets.length === 0) {
60
62
  console.log(ansis.yellow("No changesets found")), console.log(), isTelemetryEnabled && span && span.setStatus({ code: 0 }), endSpan(span);
61
63
  return;
@@ -83,6 +85,14 @@ Changesets (${changesets.length}):
83
85
  endSpan(span);
84
86
  }
85
87
  }
88
+ function reportCommitValidation(result, details) {
89
+ if (result.validation.ran === !1) {
90
+ delete details.validationPassed, details.validationSkipped = !0, isJson() || console.log(ansis.yellow("\u26A0 Validation skipped (--no-validate); run 'dr validate' to check the result"));
91
+ return;
92
+ }
93
+ const preExisting = result.validation.preExistingErrors ?? 0;
94
+ details.preExistingErrors = preExisting, preExisting > 0 && (details.preExistingSample = result.validation.preExistingSample ?? [], isJson() || console.log(ansis.yellow(`\u26A0 ${preExisting} validation error(s) already in the base model were ignored; the changeset introduced none. Run 'dr validate' to see them.`)));
95
+ }
86
96
  async function changesetApplyCommand(name, options) {
87
97
  const span = isTelemetryEnabled ? startSpan("changeset.apply", {
88
98
  "changeset.name": name,
@@ -90,7 +100,7 @@ async function changesetApplyCommand(name, options) {
90
100
  "apply.force": options?.force === !0
91
101
  }) : null;
92
102
  try {
93
- const model = await Model.load(options?.model || process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
103
+ const model = await Model.load(options?.model, { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
94
104
  if (changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${name}' not found` })) : console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), isTelemetryEnabled && span && (span.setAttribute("changeset.id", changeset.id), span.setAttribute("changeset.changeCount", changeset.changes.length)), !isJson()) {
95
105
  console.log(ansis.bold(`
96
106
  Applying changeset: ${ansis.cyan(name)}
@@ -120,7 +130,7 @@ Applying changeset: ${ansis.cyan(name)}
120
130
  failed: result.failed,
121
131
  validationPassed: result.validation.passed
122
132
  };
123
- if (result.failed > 0 && (applyDetails.errors = result.validation.errors, !isJson())) {
133
+ if (reportCommitValidation(result, applyDetails), result.failed > 0 && (applyDetails.errors = result.validation.errors, !isJson())) {
124
134
  handleInfo(ansis.red(`\u2717 Failed to apply ${result.failed} change(s):`));
125
135
  for (const error of result.validation.errors)
126
136
  handleInfo(ansis.dim(` - ${error}`));
@@ -144,7 +154,7 @@ async function changesetRevertCommand(name, options = {}) {
144
154
  "changeset.name": name
145
155
  }) : null;
146
156
  try {
147
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
157
+ const model = await Model.load(options.model, { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
148
158
  changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${name}' not found` })) : console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), isTelemetryEnabled && span && (span.setAttribute("changeset.id", changeset.id), span.setAttribute("changeset.changeCount", changeset.changes.length)), isJson() || (console.log(ansis.bold(`
149
159
  Reverting changeset: ${ansis.cyan(name)}
150
160
  `)), console.log(ansis.dim(`Changes to discard: ${changeset.changes.length}`)));
@@ -173,7 +183,7 @@ async function changesetActivateCommand(name, options = {}) {
173
183
  "changeset.name": name
174
184
  }) : null;
175
185
  try {
176
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
186
+ const model = await Model.load(options.model, { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
177
187
  changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${name}' not found` })) : console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), await manager.setActive(name), handleSuccess(`Activated changeset: ${ansis.bold(name)}`, {
178
188
  changesetName: name,
179
189
  changesetId: changeset.id
@@ -190,7 +200,7 @@ async function changesetActivateCommand(name, options = {}) {
190
200
  async function changesetDeactivateCommand(options = {}) {
191
201
  const span = isTelemetryEnabled ? startSpan("changeset.deactivate") : null;
192
202
  try {
193
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), active = await manager.getActiveId();
203
+ const model = await Model.load(options.model, { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), active = await manager.getActiveId();
194
204
  if (!active) {
195
205
  handleInfo(ansis.yellow("No active changeset")), isTelemetryEnabled && span && (span.setAttribute("changeset.wasActive", !1), span.setStatus({ code: 0 })), endSpan(span);
196
206
  return;
@@ -216,7 +226,7 @@ async function changesetDeleteCommand(name, options) {
216
226
  "delete.force": options.force === !0
217
227
  }) : null;
218
228
  try {
219
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
229
+ const model = await Model.load(options.model, { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), changeset = await manager.load(name);
220
230
  if (changeset || (isJson() ? console.log(JSON.stringify({ status: "error", code: 2, message: `Changeset '${name}' not found` })) : console.error(ansis.red(`Error: Changeset '${name}' not found`)), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Changeset not found" }), endSpan(span), process.exit(1)), await manager.getActiveId() === changeset.id && (isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: `Cannot delete active changeset '${name}'` })) : (console.error(ansis.red(`Error: Cannot delete active changeset '${name}'`)), console.log(ansis.dim(" Run `dr changeset deactivate` first"))), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "Cannot delete active changeset" }), endSpan(span), process.exit(1)), !options.force) {
221
231
  const isInteractive = process.stdin.isTTY && process.stdout.isTTY;
222
232
  if (isTelemetryEnabled && span && span.setAttribute("cli.interactive", isInteractive), isInteractive) {
@@ -248,7 +258,7 @@ async function changesetDeleteCommand(name, options) {
248
258
  async function changesetStatusCommand(options = {}) {
249
259
  const span = isTelemetryEnabled ? startSpan("changeset.status") : null;
250
260
  try {
251
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), active = await manager.getActiveId();
261
+ const model = await Model.load(options.model, { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), active = await manager.getActiveId();
252
262
  if (!active) {
253
263
  console.log(ansis.dim("No active changeset")), isTelemetryEnabled && span && (span.setAttribute("changeset.hasActive", !1), span.setStatus({ code: 0 })), endSpan(span);
254
264
  return;
@@ -277,7 +287,7 @@ async function changesetStagedCommand(options) {
277
287
  "staged.layer": options.layer
278
288
  }) : null;
279
289
  try {
280
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangeset = await manager.getActiveId();
290
+ const model = await Model.load(options.model, { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangeset = await manager.getActiveId();
281
291
  if (!activeChangeset) {
282
292
  isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "No active changeset" })) : console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
283
293
  return;
@@ -327,7 +337,7 @@ Staged Changes (${changes.length}):
327
337
  async function changesetExplicitStageCommand(elementId, options = {}) {
328
338
  const span = isTelemetryEnabled ? startSpan("changeset.stage-explicit", { "stage.elementId": elementId }) : null;
329
339
  try {
330
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
340
+ const model = await Model.load(options.model, { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
331
341
  if (!activeChangesetId) {
332
342
  isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "No active changeset" })) : console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
333
343
  return;
@@ -361,7 +371,7 @@ async function changesetUnstageCommand(elementId, options = {}) {
361
371
  "unstage.elementId": elementId
362
372
  }) : null;
363
373
  try {
364
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
374
+ const model = await Model.load(options.model, { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
365
375
  if (!activeChangesetId) {
366
376
  isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "No active changeset" })) : console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
367
377
  return;
@@ -395,7 +405,7 @@ async function changesetDiscardCommand(elementId, options = {}) {
395
405
  "discard.all": !elementId
396
406
  }) : null;
397
407
  try {
398
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
408
+ const model = await Model.load(options.model, { lazyLoad: !0 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
399
409
  if (!activeChangesetId) {
400
410
  isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "No active changeset" })) : console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
401
411
  return;
@@ -445,7 +455,7 @@ async function changesetPreviewCommand(options) {
445
455
  "preview.layer": options.layer
446
456
  }) : null;
447
457
  try {
448
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
458
+ const model = await Model.load(options.model, { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
449
459
  if (!activeChangesetId) {
450
460
  console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
451
461
  return;
@@ -498,7 +508,7 @@ async function changesetDiffCommand(options) {
498
508
  "diff.layer": options.layer
499
509
  }) : null;
500
510
  try {
501
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
511
+ const model = await Model.load(options.model, { lazyLoad: !1 }), manager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await manager.getActiveId();
502
512
  if (!activeChangesetId) {
503
513
  console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span && span.setStatus({ code: 2, message: "No active changeset" }), endSpan(span);
504
514
  return;
@@ -536,7 +546,7 @@ Diff: Base Model vs Staged Changes
536
546
  async function changesetCommitCommand(options) {
537
547
  await startActiveSpan("changeset.commit", async (span) => {
538
548
  try {
539
- const model = await Model.load(options?.model || process.cwd(), { lazyLoad: !1 }), stagingManager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await stagingManager.getActiveId();
549
+ const model = await Model.load(options?.model, { lazyLoad: !1 }), stagingManager = new StagingAreaManager(model.rootPath, model), activeChangesetId = await stagingManager.getActiveId();
540
550
  if (!activeChangesetId) {
541
551
  isJson() ? console.log(JSON.stringify({ status: "error", code: 1, message: "No active changeset" })) : console.error(ansis.red("Error: No active changeset")), isTelemetryEnabled && span.setStatus({ code: 2, message: "No active changeset" });
542
552
  return;
@@ -567,7 +577,7 @@ Committing changeset: ${ansis.cyan(changeset.name)}`)), console.log(ansis.dim(`S
567
577
  stagedChanges: changeCount,
568
578
  validationPassed: result.validation.passed
569
579
  };
570
- (result.skipped ?? 0) > 0 && (commitDetails.skipped = result.skipped, commitDetails.skippedDetails = (result.skippedDetails ?? []).slice(0, 10)), result.failed > 0 && (commitDetails.failed = result.failed);
580
+ reportCommitValidation(result, commitDetails), (result.skipped ?? 0) > 0 && (commitDetails.skipped = result.skipped, commitDetails.skippedDetails = (result.skippedDetails ?? []).slice(0, 10)), result.failed > 0 && (commitDetails.failed = result.failed);
571
581
  const accountedFor = result.committed + (result.skipped ?? 0) + result.failed;
572
582
  if (accountedFor < changeCount) {
573
583
  const unaccounted = changeCount - accountedFor;
@@ -594,7 +604,7 @@ async function changesetExportCommand(changesetId, options) {
594
604
  "export.format": format
595
605
  }) : null;
596
606
  try {
597
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !0 }), exporter = new ChangesetExporter(model.rootPath), ext = format === "patch" ? "patch" : format, outputPath = options.output || `${changesetId}.${ext}`, absolutePath = path.isAbsolute(outputPath) ? outputPath : path.join(process.cwd(), outputPath);
607
+ const model = await Model.load(options.model, { lazyLoad: !0 }), exporter = new ChangesetExporter(model.rootPath), ext = format === "patch" ? "patch" : format, outputPath = options.output || `${changesetId}.${ext}`, absolutePath = path.isAbsolute(outputPath) ? outputPath : path.join(process.cwd(), outputPath);
598
608
  isTelemetryEnabled && span && span.setAttribute("export.outputPath", outputPath), await exporter.exportToFile(changesetId, absolutePath, format), handleSuccess(`Exported changeset to ${outputPath}`, {
599
609
  changesetId,
600
610
  outputPath,
@@ -615,7 +625,7 @@ async function changesetImportCommand(file, options = {}) {
615
625
  "import.force": options.force === !0
616
626
  }) : null;
617
627
  try {
618
- const model = await Model.load(options.model || process.cwd(), { lazyLoad: !1 }), exporter = new ChangesetExporter(model.rootPath), absolutePath = path.isAbsolute(file) ? file : path.join(process.cwd(), file), imported = await exporter.importFromFile(absolutePath);
628
+ const model = await Model.load(options.model, { lazyLoad: !1 }), exporter = new ChangesetExporter(model.rootPath), absolutePath = path.isAbsolute(file) ? file : path.join(process.cwd(), file), imported = await exporter.importFromFile(absolutePath);
619
629
  isTelemetryEnabled && span && (span.setAttribute("changeset.name", imported.name), span.setAttribute("changeset.changeCount", imported.changes.length));
620
630
  const compatibility = await exporter.validateCompatibility(imported, model);
621
631
  if (isTelemetryEnabled && span && (span.setAttribute("import.compatible", compatibility.compatible), span.setAttribute("import.baseSnapshotMatch", compatibility.baseSnapshotMatch)), !compatibility.compatible) {
@@ -734,11 +744,15 @@ Examples:
734
744
  $ dr changeset diff
735
745
  $ dr changeset diff --layer api`).action(async (options) => {
736
746
  await changesetDiffCommand(options);
737
- }), changesetGroup.command("commit").description("Apply staged changes to the base model").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("--validate", "Run validation before commit (default: true)", !0).option("--force", "Commit despite drift warnings", !1).addHelpText("after", `
747
+ }), changesetGroup.command("commit").description("Apply the active changeset's staged changes to the base model").allowExcessArguments(!1).option("--model <path>", "Path to model root (contains model/manifest.yaml)").addOption(new Option("--validate", "Run validation before commit (default)").hideHelp()).option("--no-validate", "Skip validation before commit (validation runs by default; only errors the changeset introduces block, errors already in the base model are reported as a count)").option("--force", "Commit despite drift warnings (does not skip validation)", !1).addHelpText("after", `
748
+ Validation compares the model with and without the changeset. Errors the
749
+ changeset introduces block the commit; errors the base model already had are
750
+ not counted against it, and the output says how many there were.
751
+
738
752
  Examples:
739
753
  $ dr changeset commit
740
- $ dr changeset commit --validate
741
- $ dr changeset commit --force`).action(async (options) => {
754
+ $ dr changeset commit --force # commit despite drift
755
+ $ dr changeset commit --no-validate # skip validation entirely`).action(async (options) => {
742
756
  await changesetCommitCommand(options);
743
757
  }), changesetGroup.command("export <changeset-id>").description("Export changeset to portable file").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("-o, --output <file>", "Output file path").option("-f, --format <format>", "Export format (yaml|json|patch)", "yaml").addHelpText("after", `
744
758
  Examples:
@@ -753,6 +767,13 @@ Examples:
753
767
  $ dr changeset import ../team-changes.json
754
768
  $ dr changeset import changes.yaml --force`).action(async (file, options) => {
755
769
  await changesetImportCommand(file, options);
770
+ }), changesetGroup.command("verify [planned]").description("Compare a planned changeset with what was built (an as-built changeset, or the base model)").option("--model <path>", "Path to model root (contains model/manifest.yaml)").option("--against <changeset>", "As-built changeset (ID or name) to compare with").option("--base", "Compare with the base model").option("--no-match-by-source", "Do not match elements by shared source file").option("--json", "Output as JSON").addHelpText("after", `
771
+ The planned changeset defaults to the active one.
772
+
773
+ Examples:
774
+ $ dr changeset verify export-orders --against export-orders-as-built
775
+ $ dr changeset verify export-orders --base --json`).action(async (planned, options) => {
776
+ await changesetVerifyCommand(planned, options);
756
777
  }), changesetGroup.showSuggestionAfterError();
757
778
  }
758
779
  export {