@jterrats/smart-deployment 1.0.3

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 (395) hide show
  1. package/README.md +193 -0
  2. package/lib/ai/agentforce-error-handler.d.ts +81 -0
  3. package/lib/ai/agentforce-error-handler.js +196 -0
  4. package/lib/ai/agentforce-error-handler.js.map +1 -0
  5. package/lib/ai/agentforce-priority-service.d.ts +82 -0
  6. package/lib/ai/agentforce-priority-service.js +257 -0
  7. package/lib/ai/agentforce-priority-service.js.map +1 -0
  8. package/lib/ai/agentforce-service.d.ts +99 -0
  9. package/lib/ai/agentforce-service.js +300 -0
  10. package/lib/ai/agentforce-service.js.map +1 -0
  11. package/lib/ai/circuit-breaker.d.ts +115 -0
  12. package/lib/ai/circuit-breaker.js +277 -0
  13. package/lib/ai/circuit-breaker.js.map +1 -0
  14. package/lib/ai/dependency-inference-service.d.ts +76 -0
  15. package/lib/ai/dependency-inference-service.js +220 -0
  16. package/lib/ai/dependency-inference-service.js.map +1 -0
  17. package/lib/ai/llm-provider-factory.d.ts +15 -0
  18. package/lib/ai/llm-provider-factory.js +36 -0
  19. package/lib/ai/llm-provider-factory.js.map +1 -0
  20. package/lib/ai/llm-provider.d.ts +27 -0
  21. package/lib/ai/llm-provider.js +2 -0
  22. package/lib/ai/llm-provider.js.map +1 -0
  23. package/lib/ai/openai-service.d.ts +20 -0
  24. package/lib/ai/openai-service.js +89 -0
  25. package/lib/ai/openai-service.js.map +1 -0
  26. package/lib/ai/prompt-builder.d.ts +79 -0
  27. package/lib/ai/prompt-builder.js +180 -0
  28. package/lib/ai/prompt-builder.js.map +1 -0
  29. package/lib/ai/response-parser.d.ts +67 -0
  30. package/lib/ai/response-parser.js +234 -0
  31. package/lib/ai/response-parser.js.map +1 -0
  32. package/lib/ai/wave-validation-service.d.ts +111 -0
  33. package/lib/ai/wave-validation-service.js +381 -0
  34. package/lib/ai/wave-validation-service.js.map +1 -0
  35. package/lib/analysis/analysis-reporter.d.ts +56 -0
  36. package/lib/analysis/analysis-reporter.js +170 -0
  37. package/lib/analysis/analysis-reporter.js.map +1 -0
  38. package/lib/analytics/error-analytics.d.ts +80 -0
  39. package/lib/analytics/error-analytics.js +162 -0
  40. package/lib/analytics/error-analytics.js.map +1 -0
  41. package/lib/commands/analyze.d.ts +49 -0
  42. package/lib/commands/analyze.js +232 -0
  43. package/lib/commands/analyze.js.map +1 -0
  44. package/lib/commands/config.d.ts +42 -0
  45. package/lib/commands/config.js +219 -0
  46. package/lib/commands/config.js.map +1 -0
  47. package/lib/commands/resume.d.ts +26 -0
  48. package/lib/commands/resume.js +69 -0
  49. package/lib/commands/resume.js.map +1 -0
  50. package/lib/commands/start.d.ts +70 -0
  51. package/lib/commands/start.js +659 -0
  52. package/lib/commands/start.js.map +1 -0
  53. package/lib/commands/status.d.ts +37 -0
  54. package/lib/commands/status.js +69 -0
  55. package/lib/commands/status.js.map +1 -0
  56. package/lib/commands/validate.d.ts +33 -0
  57. package/lib/commands/validate.js +66 -0
  58. package/lib/commands/validate.js.map +1 -0
  59. package/lib/config/repo-config.d.ts +22 -0
  60. package/lib/config/repo-config.js +31 -0
  61. package/lib/config/repo-config.js.map +1 -0
  62. package/lib/constants/agentforce-limits.d.ts +174 -0
  63. package/lib/constants/agentforce-limits.js +262 -0
  64. package/lib/constants/agentforce-limits.js.map +1 -0
  65. package/lib/constants/api-version.d.ts +70 -0
  66. package/lib/constants/api-version.js +122 -0
  67. package/lib/constants/api-version.js.map +1 -0
  68. package/lib/constants/deployment-order.d.ts +68 -0
  69. package/lib/constants/deployment-order.js +162 -0
  70. package/lib/constants/deployment-order.js.map +1 -0
  71. package/lib/constants/salesforce-limits.d.ts +107 -0
  72. package/lib/constants/salesforce-limits.js +104 -0
  73. package/lib/constants/salesforce-limits.js.map +1 -0
  74. package/lib/dependencies/circular-dependency-detector.d.ts +137 -0
  75. package/lib/dependencies/circular-dependency-detector.js +329 -0
  76. package/lib/dependencies/circular-dependency-detector.js.map +1 -0
  77. package/lib/dependencies/cycle-remediation-planner.d.ts +50 -0
  78. package/lib/dependencies/cycle-remediation-planner.js +192 -0
  79. package/lib/dependencies/cycle-remediation-planner.js.map +1 -0
  80. package/lib/dependencies/dependency-cache.d.ts +134 -0
  81. package/lib/dependencies/dependency-cache.js +303 -0
  82. package/lib/dependencies/dependency-cache.js.map +1 -0
  83. package/lib/dependencies/dependency-depth-calculator.d.ts +145 -0
  84. package/lib/dependencies/dependency-depth-calculator.js +368 -0
  85. package/lib/dependencies/dependency-depth-calculator.js.map +1 -0
  86. package/lib/dependencies/dependency-graph-builder.d.ts +151 -0
  87. package/lib/dependencies/dependency-graph-builder.js +411 -0
  88. package/lib/dependencies/dependency-graph-builder.js.map +1 -0
  89. package/lib/dependencies/dependency-impact-analyzer.d.ts +145 -0
  90. package/lib/dependencies/dependency-impact-analyzer.js +330 -0
  91. package/lib/dependencies/dependency-impact-analyzer.js.map +1 -0
  92. package/lib/dependencies/dependency-merger.d.ts +122 -0
  93. package/lib/dependencies/dependency-merger.js +245 -0
  94. package/lib/dependencies/dependency-merger.js.map +1 -0
  95. package/lib/dependencies/dependency-resolver.d.ts +157 -0
  96. package/lib/dependencies/dependency-resolver.js +298 -0
  97. package/lib/dependencies/dependency-resolver.js.map +1 -0
  98. package/lib/dependencies/dependency-validator.d.ts +123 -0
  99. package/lib/dependencies/dependency-validator.js +291 -0
  100. package/lib/dependencies/dependency-validator.js.map +1 -0
  101. package/lib/dependencies/graph-visualizer.d.ts +110 -0
  102. package/lib/dependencies/graph-visualizer.js +262 -0
  103. package/lib/dependencies/graph-visualizer.js.map +1 -0
  104. package/lib/dependencies/heuristic-inference.d.ts +136 -0
  105. package/lib/dependencies/heuristic-inference.js +430 -0
  106. package/lib/dependencies/heuristic-inference.js.map +1 -0
  107. package/lib/deployment/cycle-source-editor.d.ts +34 -0
  108. package/lib/deployment/cycle-source-editor.js +121 -0
  109. package/lib/deployment/cycle-source-editor.js.map +1 -0
  110. package/lib/deployment/deployment-error-handler.d.ts +38 -0
  111. package/lib/deployment/deployment-error-handler.js +79 -0
  112. package/lib/deployment/deployment-error-handler.js.map +1 -0
  113. package/lib/deployment/deployment-reporter.d.ts +63 -0
  114. package/lib/deployment/deployment-reporter.js +150 -0
  115. package/lib/deployment/deployment-reporter.js.map +1 -0
  116. package/lib/deployment/deployment-state-summary.d.ts +38 -0
  117. package/lib/deployment/deployment-state-summary.js +209 -0
  118. package/lib/deployment/deployment-state-summary.js.map +1 -0
  119. package/lib/deployment/deployment-status-service.d.ts +36 -0
  120. package/lib/deployment/deployment-status-service.js +128 -0
  121. package/lib/deployment/deployment-status-service.js.map +1 -0
  122. package/lib/deployment/deployment-tracker.d.ts +42 -0
  123. package/lib/deployment/deployment-tracker.js +79 -0
  124. package/lib/deployment/deployment-tracker.js.map +1 -0
  125. package/lib/deployment/deployment-validation-service.d.ts +28 -0
  126. package/lib/deployment/deployment-validation-service.js +161 -0
  127. package/lib/deployment/deployment-validation-service.js.map +1 -0
  128. package/lib/deployment/retry-handler.d.ts +37 -0
  129. package/lib/deployment/retry-handler.js +86 -0
  130. package/lib/deployment/retry-handler.js.map +1 -0
  131. package/lib/deployment/sf-cli-integration.d.ts +42 -0
  132. package/lib/deployment/sf-cli-integration.js +105 -0
  133. package/lib/deployment/sf-cli-integration.js.map +1 -0
  134. package/lib/deployment/state-manager.d.ts +61 -0
  135. package/lib/deployment/state-manager.js +83 -0
  136. package/lib/deployment/state-manager.js.map +1 -0
  137. package/lib/deployment/test-executor.d.ts +41 -0
  138. package/lib/deployment/test-executor.js +87 -0
  139. package/lib/deployment/test-executor.js.map +1 -0
  140. package/lib/errors/base-error.d.ts +24 -0
  141. package/lib/errors/base-error.js +66 -0
  142. package/lib/errors/base-error.js.map +1 -0
  143. package/lib/errors/dependency-error.d.ts +37 -0
  144. package/lib/errors/dependency-error.js +76 -0
  145. package/lib/errors/dependency-error.js.map +1 -0
  146. package/lib/errors/deployment-error.d.ts +55 -0
  147. package/lib/errors/deployment-error.js +132 -0
  148. package/lib/errors/deployment-error.js.map +1 -0
  149. package/lib/errors/index.d.ts +45 -0
  150. package/lib/errors/index.js +71 -0
  151. package/lib/errors/index.js.map +1 -0
  152. package/lib/errors/network-error.d.ts +53 -0
  153. package/lib/errors/network-error.js +111 -0
  154. package/lib/errors/network-error.js.map +1 -0
  155. package/lib/errors/parsing-error.d.ts +41 -0
  156. package/lib/errors/parsing-error.js +69 -0
  157. package/lib/errors/parsing-error.js.map +1 -0
  158. package/lib/errors/validation-error-reporter.d.ts +34 -0
  159. package/lib/errors/validation-error-reporter.js +99 -0
  160. package/lib/errors/validation-error-reporter.js.map +1 -0
  161. package/lib/errors/validation-error.d.ts +58 -0
  162. package/lib/errors/validation-error.js +131 -0
  163. package/lib/errors/validation-error.js.map +1 -0
  164. package/lib/index.d.ts +2 -0
  165. package/lib/index.js +2 -0
  166. package/lib/index.js.map +1 -0
  167. package/lib/monitoring/performance-monitor.d.ts +98 -0
  168. package/lib/monitoring/performance-monitor.js +260 -0
  169. package/lib/monitoring/performance-monitor.js.map +1 -0
  170. package/lib/parsers/apex-class-parser.d.ts +47 -0
  171. package/lib/parsers/apex-class-parser.js +368 -0
  172. package/lib/parsers/apex-class-parser.js.map +1 -0
  173. package/lib/parsers/apex-trigger-parser.d.ts +48 -0
  174. package/lib/parsers/apex-trigger-parser.js +229 -0
  175. package/lib/parsers/apex-trigger-parser.js.map +1 -0
  176. package/lib/parsers/aura-parser.d.ts +55 -0
  177. package/lib/parsers/aura-parser.js +229 -0
  178. package/lib/parsers/aura-parser.js.map +1 -0
  179. package/lib/parsers/bot-parser.d.ts +65 -0
  180. package/lib/parsers/bot-parser.js +225 -0
  181. package/lib/parsers/bot-parser.js.map +1 -0
  182. package/lib/parsers/custom-metadata-parser.d.ts +94 -0
  183. package/lib/parsers/custom-metadata-parser.js +199 -0
  184. package/lib/parsers/custom-metadata-parser.js.map +1 -0
  185. package/lib/parsers/custom-object-parser.d.ts +62 -0
  186. package/lib/parsers/custom-object-parser.js +297 -0
  187. package/lib/parsers/custom-object-parser.js.map +1 -0
  188. package/lib/parsers/email-template-parser.d.ts +64 -0
  189. package/lib/parsers/email-template-parser.js +238 -0
  190. package/lib/parsers/email-template-parser.js.map +1 -0
  191. package/lib/parsers/error-resilient-parser.d.ts +110 -0
  192. package/lib/parsers/error-resilient-parser.js +277 -0
  193. package/lib/parsers/error-resilient-parser.js.map +1 -0
  194. package/lib/parsers/flexipage-parser.d.ts +64 -0
  195. package/lib/parsers/flexipage-parser.js +196 -0
  196. package/lib/parsers/flexipage-parser.js.map +1 -0
  197. package/lib/parsers/flow-parser.d.ts +54 -0
  198. package/lib/parsers/flow-parser.js +287 -0
  199. package/lib/parsers/flow-parser.js.map +1 -0
  200. package/lib/parsers/genai-prompt-parser.d.ts +67 -0
  201. package/lib/parsers/genai-prompt-parser.js +160 -0
  202. package/lib/parsers/genai-prompt-parser.js.map +1 -0
  203. package/lib/parsers/layout-parser.d.ts +64 -0
  204. package/lib/parsers/layout-parser.js +267 -0
  205. package/lib/parsers/layout-parser.js.map +1 -0
  206. package/lib/parsers/lwc-parser.d.ts +60 -0
  207. package/lib/parsers/lwc-parser.js +264 -0
  208. package/lib/parsers/lwc-parser.js.map +1 -0
  209. package/lib/parsers/permission-set-parser.d.ts +86 -0
  210. package/lib/parsers/permission-set-parser.js +152 -0
  211. package/lib/parsers/permission-set-parser.js.map +1 -0
  212. package/lib/parsers/profile-parser.d.ts +81 -0
  213. package/lib/parsers/profile-parser.js +141 -0
  214. package/lib/parsers/profile-parser.js.map +1 -0
  215. package/lib/parsers/visualforce-parser.d.ts +47 -0
  216. package/lib/parsers/visualforce-parser.js +180 -0
  217. package/lib/parsers/visualforce-parser.js.map +1 -0
  218. package/lib/provisioning/data-provisioner.d.ts +88 -0
  219. package/lib/provisioning/data-provisioner.js +257 -0
  220. package/lib/provisioning/data-provisioner.js.map +1 -0
  221. package/lib/scanner/custom-structure-scanner.d.ts +66 -0
  222. package/lib/scanner/custom-structure-scanner.js +229 -0
  223. package/lib/scanner/custom-structure-scanner.js.map +1 -0
  224. package/lib/scanner/forceignore-parser.d.ts +69 -0
  225. package/lib/scanner/forceignore-parser.js +195 -0
  226. package/lib/scanner/forceignore-parser.js.map +1 -0
  227. package/lib/scanner/metadata-format-scanner.d.ts +77 -0
  228. package/lib/scanner/metadata-format-scanner.js +282 -0
  229. package/lib/scanner/metadata-format-scanner.js.map +1 -0
  230. package/lib/scanner/monorepo-scanner.d.ts +71 -0
  231. package/lib/scanner/monorepo-scanner.js +225 -0
  232. package/lib/scanner/monorepo-scanner.js.map +1 -0
  233. package/lib/scanner/project-validator.d.ts +55 -0
  234. package/lib/scanner/project-validator.js +235 -0
  235. package/lib/scanner/project-validator.js.map +1 -0
  236. package/lib/scanner/sfdx-project-detector.d.ts +86 -0
  237. package/lib/scanner/sfdx-project-detector.js +240 -0
  238. package/lib/scanner/sfdx-project-detector.js.map +1 -0
  239. package/lib/scanner/structure-validator.d.ts +64 -0
  240. package/lib/scanner/structure-validator.js +296 -0
  241. package/lib/scanner/structure-validator.js.map +1 -0
  242. package/lib/services/metadata-scanner-service.d.ts +64 -0
  243. package/lib/services/metadata-scanner-service.js +651 -0
  244. package/lib/services/metadata-scanner-service.js.map +1 -0
  245. package/lib/types/agentforce.d.ts +157 -0
  246. package/lib/types/agentforce.js +2 -0
  247. package/lib/types/agentforce.js.map +1 -0
  248. package/lib/types/dependency.d.ts +98 -0
  249. package/lib/types/dependency.js +5 -0
  250. package/lib/types/dependency.js.map +1 -0
  251. package/lib/types/deployment-plan.d.ts +81 -0
  252. package/lib/types/deployment-plan.js +6 -0
  253. package/lib/types/deployment-plan.js.map +1 -0
  254. package/lib/types/deployment.d.ts +88 -0
  255. package/lib/types/deployment.js +5 -0
  256. package/lib/types/deployment.js.map +1 -0
  257. package/lib/types/graph.d.ts +35 -0
  258. package/lib/types/graph.js +5 -0
  259. package/lib/types/graph.js.map +1 -0
  260. package/lib/types/index.d.ts +12 -0
  261. package/lib/types/index.js +17 -0
  262. package/lib/types/index.js.map +1 -0
  263. package/lib/types/metadata.d.ts +101 -0
  264. package/lib/types/metadata.js +13 -0
  265. package/lib/types/metadata.js.map +1 -0
  266. package/lib/types/project.d.ts +156 -0
  267. package/lib/types/project.js +56 -0
  268. package/lib/types/project.js.map +1 -0
  269. package/lib/types/salesforce/apex.d.ts +94 -0
  270. package/lib/types/salesforce/apex.js +6 -0
  271. package/lib/types/salesforce/apex.js.map +1 -0
  272. package/lib/types/salesforce/aura.d.ts +150 -0
  273. package/lib/types/salesforce/aura.js +6 -0
  274. package/lib/types/salesforce/aura.js.map +1 -0
  275. package/lib/types/salesforce/bot.d.ts +293 -0
  276. package/lib/types/salesforce/bot.js +6 -0
  277. package/lib/types/salesforce/bot.js.map +1 -0
  278. package/lib/types/salesforce/common.d.ts +15 -0
  279. package/lib/types/salesforce/common.js +5 -0
  280. package/lib/types/salesforce/common.js.map +1 -0
  281. package/lib/types/salesforce/custom-metadata.d.ts +92 -0
  282. package/lib/types/salesforce/custom-metadata.js +6 -0
  283. package/lib/types/salesforce/custom-metadata.js.map +1 -0
  284. package/lib/types/salesforce/email.d.ts +56 -0
  285. package/lib/types/salesforce/email.js +6 -0
  286. package/lib/types/salesforce/email.js.map +1 -0
  287. package/lib/types/salesforce/flexipage.d.ts +149 -0
  288. package/lib/types/salesforce/flexipage.js +6 -0
  289. package/lib/types/salesforce/flexipage.js.map +1 -0
  290. package/lib/types/salesforce/flow.d.ts +516 -0
  291. package/lib/types/salesforce/flow.js +6 -0
  292. package/lib/types/salesforce/flow.js.map +1 -0
  293. package/lib/types/salesforce/genai.d.ts +67 -0
  294. package/lib/types/salesforce/genai.js +6 -0
  295. package/lib/types/salesforce/genai.js.map +1 -0
  296. package/lib/types/salesforce/index.d.ts +27 -0
  297. package/lib/types/salesforce/index.js +43 -0
  298. package/lib/types/salesforce/index.js.map +1 -0
  299. package/lib/types/salesforce/layout.d.ts +236 -0
  300. package/lib/types/salesforce/layout.js +6 -0
  301. package/lib/types/salesforce/layout.js.map +1 -0
  302. package/lib/types/salesforce/lwc.d.ts +123 -0
  303. package/lib/types/salesforce/lwc.js +6 -0
  304. package/lib/types/salesforce/lwc.js.map +1 -0
  305. package/lib/types/salesforce/object.d.ts +427 -0
  306. package/lib/types/salesforce/object.js +6 -0
  307. package/lib/types/salesforce/object.js.map +1 -0
  308. package/lib/types/salesforce/parser-types.d.ts +79 -0
  309. package/lib/types/salesforce/parser-types.js +80 -0
  310. package/lib/types/salesforce/parser-types.js.map +1 -0
  311. package/lib/types/salesforce/permission.d.ts +289 -0
  312. package/lib/types/salesforce/permission.js +6 -0
  313. package/lib/types/salesforce/permission.js.map +1 -0
  314. package/lib/types/salesforce/resource.d.ts +93 -0
  315. package/lib/types/salesforce/resource.js +6 -0
  316. package/lib/types/salesforce/resource.js.map +1 -0
  317. package/lib/types/salesforce/visualforce.d.ts +70 -0
  318. package/lib/types/salesforce/visualforce.js +6 -0
  319. package/lib/types/salesforce/visualforce.js.map +1 -0
  320. package/lib/utils/cache-manager.d.ts +158 -0
  321. package/lib/utils/cache-manager.js +429 -0
  322. package/lib/utils/cache-manager.js.map +1 -0
  323. package/lib/utils/deployment-plan-manager.d.ts +40 -0
  324. package/lib/utils/deployment-plan-manager.js +183 -0
  325. package/lib/utils/deployment-plan-manager.js.map +1 -0
  326. package/lib/utils/error-aggregator.d.ts +117 -0
  327. package/lib/utils/error-aggregator.js +268 -0
  328. package/lib/utils/error-aggregator.js.map +1 -0
  329. package/lib/utils/file-system.d.ts +62 -0
  330. package/lib/utils/file-system.js +167 -0
  331. package/lib/utils/file-system.js.map +1 -0
  332. package/lib/utils/functional.d.ts +52 -0
  333. package/lib/utils/functional.js +61 -0
  334. package/lib/utils/functional.js.map +1 -0
  335. package/lib/utils/graph-algorithms.d.ts +53 -0
  336. package/lib/utils/graph-algorithms.js +177 -0
  337. package/lib/utils/graph-algorithms.js.map +1 -0
  338. package/lib/utils/logger.d.ts +154 -0
  339. package/lib/utils/logger.js +327 -0
  340. package/lib/utils/logger.js.map +1 -0
  341. package/lib/utils/network-handler.d.ts +64 -0
  342. package/lib/utils/network-handler.js +147 -0
  343. package/lib/utils/network-handler.js.map +1 -0
  344. package/lib/utils/performance.d.ts +148 -0
  345. package/lib/utils/performance.js +294 -0
  346. package/lib/utils/performance.js.map +1 -0
  347. package/lib/utils/string.d.ts +197 -0
  348. package/lib/utils/string.js +331 -0
  349. package/lib/utils/string.js.map +1 -0
  350. package/lib/utils/xml.d.ts +97 -0
  351. package/lib/utils/xml.js +227 -0
  352. package/lib/utils/xml.js.map +1 -0
  353. package/lib/validators/xml-metadata-validator.d.ts +106 -0
  354. package/lib/validators/xml-metadata-validator.js +509 -0
  355. package/lib/validators/xml-metadata-validator.js.map +1 -0
  356. package/lib/waves/priority-wave-generator-ai.d.ts +85 -0
  357. package/lib/waves/priority-wave-generator-ai.js +191 -0
  358. package/lib/waves/priority-wave-generator-ai.js.map +1 -0
  359. package/lib/waves/priority-wave-generator.d.ts +47 -0
  360. package/lib/waves/priority-wave-generator.js +88 -0
  361. package/lib/waves/priority-wave-generator.js.map +1 -0
  362. package/lib/waves/test-optimizer.d.ts +155 -0
  363. package/lib/waves/test-optimizer.js +290 -0
  364. package/lib/waves/test-optimizer.js.map +1 -0
  365. package/lib/waves/wave-builder.d.ts +147 -0
  366. package/lib/waves/wave-builder.js +286 -0
  367. package/lib/waves/wave-builder.js.map +1 -0
  368. package/lib/waves/wave-diff-generator.d.ts +17 -0
  369. package/lib/waves/wave-diff-generator.js +6 -0
  370. package/lib/waves/wave-diff-generator.js.map +1 -0
  371. package/lib/waves/wave-executor.d.ts +33 -0
  372. package/lib/waves/wave-executor.js +50 -0
  373. package/lib/waves/wave-executor.js.map +1 -0
  374. package/lib/waves/wave-merger.d.ts +96 -0
  375. package/lib/waves/wave-merger.js +181 -0
  376. package/lib/waves/wave-merger.js.map +1 -0
  377. package/lib/waves/wave-metadata-generator.d.ts +13 -0
  378. package/lib/waves/wave-metadata-generator.js +12 -0
  379. package/lib/waves/wave-metadata-generator.js.map +1 -0
  380. package/lib/waves/wave-splitter.d.ts +154 -0
  381. package/lib/waves/wave-splitter.js +307 -0
  382. package/lib/waves/wave-splitter.js.map +1 -0
  383. package/lib/waves/wave-validator.d.ts +17 -0
  384. package/lib/waves/wave-validator.js +15 -0
  385. package/lib/waves/wave-validator.js.map +1 -0
  386. package/messages/analyze.json +18 -0
  387. package/messages/config.json +29 -0
  388. package/messages/resume.json +9 -0
  389. package/messages/start.json +24 -0
  390. package/messages/status.json +8 -0
  391. package/messages/validate.json +9 -0
  392. package/npm-shrinkwrap.json +25676 -0
  393. package/oclif.lock +11988 -0
  394. package/oclif.manifest.json +589 -0
  395. package/package.json +224 -0
@@ -0,0 +1,659 @@
1
+ /**
2
+ * smart-deployment:start command
3
+ * Main deployment command that orchestrates the entire workflow
4
+ *
5
+ * @ac US-046-AC-1: Analyzes metadata automatically
6
+ * @ac US-046-AC-2: Generates deployment waves
7
+ * @ac US-046-AC-3: Executes deployment sequentially
8
+ * @ac US-046-AC-4: Supports --target-org flag
9
+ * @ac US-046-AC-5: Supports --dry-run flag
10
+ * @ac US-046-AC-6: Supports --validate-only flag
11
+ * @ac US-046-AC-7: Supports --skip-tests flag
12
+ * @ac US-046-AC-8: Shows progress bar
13
+ * @ac US-046-AC-9: Generates deployment report
14
+ * @ac US-046-AC-10: Handles failures gracefully
15
+ *
16
+ * @issue #46
17
+ */
18
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
19
+ import * as path from 'node:path';
20
+ import { Messages } from '@salesforce/core';
21
+ import { Flags, SfCommand, optionalOrgFlagWithDeprecations } from '@salesforce/sf-plugins-core';
22
+ import { getLogger } from '../utils/logger.js';
23
+ import { CycleRemediationPlanner } from '../dependencies/cycle-remediation-planner.js';
24
+ import { CycleSourceEditor, } from '../deployment/cycle-source-editor.js';
25
+ import { SfCliIntegration } from '../deployment/sf-cli-integration.js';
26
+ import { MetadataScannerService } from '../services/metadata-scanner-service.js';
27
+ import { WaveBuilder } from '../waves/wave-builder.js';
28
+ import { AIEnhancedPriorityWaveGenerator } from '../waves/priority-wave-generator-ai.js';
29
+ import { getWavesInExecutionOrder } from '../waves/wave-executor.js';
30
+ import { StateManager } from '../deployment/state-manager.js';
31
+ import { DeploymentTracker } from '../deployment/deployment-tracker.js';
32
+ import { AgentforcePriorityService } from '../ai/agentforce-priority-service.js';
33
+ import { DependencyInferenceService } from '../ai/dependency-inference-service.js';
34
+ import { DependencyGraphBuilder } from '../dependencies/dependency-graph-builder.js';
35
+ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
36
+ const messages = Messages.loadMessages('@jterrats/smart-deployment', 'start');
37
+ const logger = getLogger('StartCommand');
38
+ export default class Start extends SfCommand {
39
+ static summary = messages.getMessage('summary');
40
+ static description = messages.getMessage('description');
41
+ static examples = messages.getMessages('examples');
42
+ /**
43
+ * @ac US-046-AC-4: Supports --target-org flag
44
+ * @ac US-046-AC-5: Supports --dry-run flag
45
+ * @ac US-046-AC-6: Supports --validate-only flag
46
+ * @ac US-046-AC-7: Supports --skip-tests flag
47
+ * @ac US-057-AC-1: Send component list to Agentforce
48
+ */
49
+ static flags = {
50
+ 'target-org': optionalOrgFlagWithDeprecations,
51
+ 'dry-run': Flags.boolean({
52
+ summary: messages.getMessage('flags.dry-run.summary'),
53
+ char: 'd',
54
+ default: false,
55
+ }),
56
+ 'validate-only': Flags.boolean({
57
+ summary: messages.getMessage('flags.validate-only.summary'),
58
+ char: 'v',
59
+ default: false,
60
+ }),
61
+ 'skip-tests': Flags.boolean({
62
+ summary: messages.getMessage('flags.skip-tests.summary'),
63
+ char: 's',
64
+ default: false,
65
+ }),
66
+ 'source-path': Flags.string({
67
+ summary: messages.getMessage('flags.source-path.summary'),
68
+ description: messages.getMessage('flags.source-path.description'),
69
+ }),
70
+ 'allow-cycle-remediation': Flags.boolean({
71
+ summary: messages.getMessage('flags.allow-cycle-remediation.summary'),
72
+ description: messages.getMessage('flags.allow-cycle-remediation.description'),
73
+ default: false,
74
+ }),
75
+ 'use-ai': Flags.boolean({
76
+ summary: messages.getMessage('flags.use-ai.summary'),
77
+ description: messages.getMessage('flags.use-ai.description'),
78
+ default: false,
79
+ }),
80
+ 'org-type': Flags.string({
81
+ summary: messages.getMessage('flags.org-type.summary'),
82
+ description: messages.getMessage('flags.org-type.description'),
83
+ options: ['Production', 'Sandbox', 'Developer'],
84
+ }),
85
+ industry: Flags.string({
86
+ summary: messages.getMessage('flags.industry.summary'),
87
+ description: messages.getMessage('flags.industry.description'),
88
+ }),
89
+ };
90
+ /**
91
+ * @ac US-046-AC-8: Shows progress bar
92
+ * @ac US-046-AC-9: Generates deployment report
93
+ * @ac US-046-AC-10: Handles failures gracefully
94
+ */
95
+ async run() {
96
+ const { flags } = await this.parse(Start);
97
+ const sourcePath = typeof flags['source-path'] === 'string' ? flags['source-path'] : undefined;
98
+ try {
99
+ logger.info('Starting smart deployment', { flags });
100
+ // AC-1: Analyze metadata
101
+ this.log('📊 Analyzing metadata...');
102
+ const metadataCount = await this.analyzeMetadata(sourcePath);
103
+ this.log(`✅ Found ${metadataCount} metadata components`);
104
+ // AC-2: Generate waves
105
+ this.log('🌊 Generating deployment waves...');
106
+ const deploymentContext = await this.buildDeploymentContext(flags, sourcePath);
107
+ const waves = deploymentContext.orderedWaves.length;
108
+ this.log(`✅ Generated ${waves} waves`);
109
+ // AC US-057-AC-6: Report AI decisions
110
+ if (flags['use-ai']) {
111
+ this.log('🤖 AI-enhanced prioritization enabled');
112
+ }
113
+ // AC-3: Execute deployment
114
+ if (!flags['dry-run']) {
115
+ this.log('🚀 Executing deployment...');
116
+ await this.executeDeployment(flags, sourcePath);
117
+ }
118
+ else {
119
+ this.log('🔍 Dry-run mode: skipping actual deployment');
120
+ }
121
+ // AC-9: Generate report
122
+ this.log('📄 Generating deployment report...');
123
+ this.generateReport(waves);
124
+ return { success: true, waves, ai: deploymentContext.aiContext };
125
+ }
126
+ catch (error) {
127
+ // AC-10: Handle failures gracefully
128
+ logger.error('Deployment failed', { error });
129
+ this.error(`Deployment failed: ${error instanceof Error ? error.message : String(error)}`);
130
+ }
131
+ }
132
+ async analyzeMetadata(sourcePath) {
133
+ const scanner = new MetadataScannerService();
134
+ const result = await scanner.scan({ sourcePath });
135
+ if (result.errors.length > 0) {
136
+ logger.error('Metadata scanning completed with errors', { errors: result.errors });
137
+ result.errors.forEach((err) => this.warn(err));
138
+ }
139
+ if (result.warnings.length > 0) {
140
+ logger.warn('Metadata scanning completed with warnings', { warnings: result.warnings });
141
+ result.warnings.forEach((warn) => this.warn(warn));
142
+ }
143
+ return result.components.length;
144
+ }
145
+ async executeDeployment(flags, sourcePath) {
146
+ const dryRun = flags['dry-run'];
147
+ const validateOnly = flags['validate-only'];
148
+ const allowCycleRemediation = flags['allow-cycle-remediation'];
149
+ const skipTests = flags['skip-tests'];
150
+ const targetOrg = this.getTargetOrgIdentifier(flags['target-org']);
151
+ if (dryRun || validateOnly) {
152
+ this.log('🔍 Dry-run/Validate mode: skipping actual deployment');
153
+ return;
154
+ }
155
+ const deploymentContext = await this.buildDeploymentContext(flags, sourcePath);
156
+ const { scanResult, orderedWaves } = deploymentContext;
157
+ const planner = new CycleRemediationPlanner(scanResult.dependencyResult.graph, {
158
+ components: scanResult.dependencyResult.components,
159
+ });
160
+ const remediationPlan = planner.createPlan();
161
+ if (remediationPlan.cycles.length > 0) {
162
+ this.log(`♻️ Detected ${remediationPlan.cycles.length} circular dependency cycle(s).`);
163
+ if (!allowCycleRemediation) {
164
+ this.error('Circular dependencies detected. Re-run with --allow-cycle-remediation for supported ApexClass cycles or resolve them manually.');
165
+ }
166
+ if (!remediationPlan.supported) {
167
+ this.error([
168
+ 'Cycle remediation was requested, but one or more cycles are not safely supported.',
169
+ ...remediationPlan.warnings,
170
+ ].join('\n'));
171
+ }
172
+ }
173
+ // Initialize deployment services
174
+ const sfCli = new SfCliIntegration();
175
+ const stateManager = new StateManager({ baseDir: sourcePath ?? process.cwd() });
176
+ const tracker = new DeploymentTracker();
177
+ const deploymentId = `deployment-${Date.now()}`;
178
+ if (remediationPlan.cycles.length > 0) {
179
+ if (!targetOrg) {
180
+ this.error('The --target-org flag is required for cycle remediation deployments.');
181
+ }
182
+ await this.executeCycleRemediationDeployment({
183
+ deploymentId,
184
+ targetOrg,
185
+ sourcePath,
186
+ stateManager,
187
+ tracker,
188
+ plan: remediationPlan,
189
+ sfCli,
190
+ skipTests,
191
+ componentMap: scanResult.dependencyResult.components,
192
+ });
193
+ return;
194
+ }
195
+ if (!targetOrg) {
196
+ this.error('The --target-org flag is required for real deployments.');
197
+ }
198
+ // Execute waves sequentially
199
+ await this.forEachSequentially(orderedWaves, async (wave) => {
200
+ this.log(`\n🌊 Deploying Wave ${wave.number}/${orderedWaves.length} (${wave.components.length} components)...`);
201
+ try {
202
+ // Generate manifest for this wave
203
+ const manifestPath = await this.generateWaveManifest({
204
+ baseDir: sourcePath ?? process.cwd(),
205
+ waveNumber: wave.number,
206
+ components: wave.components,
207
+ componentMap: scanResult.dependencyResult.components,
208
+ });
209
+ // Execute deployment
210
+ tracker.startTracking(deploymentId, wave.number, orderedWaves.length);
211
+ const result = await sfCli.deploy({
212
+ manifestPath,
213
+ targetOrg,
214
+ testLevel: this.resolveTestLevel(skipTests),
215
+ });
216
+ tracker.updateProgress(deploymentId, result);
217
+ if (!result.success) {
218
+ const aiMetadata = deploymentContext.aiContext === undefined
219
+ ? {}
220
+ : {
221
+ aiProvider: deploymentContext.aiContext.provider,
222
+ aiModel: deploymentContext.aiContext.model,
223
+ aiFallback: deploymentContext.aiContext.fallback,
224
+ aiAdjustments: deploymentContext.aiContext.aiAdjustments,
225
+ aiUnknownTypes: deploymentContext.aiContext.unknownTypes,
226
+ aiInferenceFallback: deploymentContext.aiContext.inferenceFallback,
227
+ aiInferredDependencies: deploymentContext.aiContext.inferredDependencies,
228
+ };
229
+ await stateManager.saveState({
230
+ deploymentId,
231
+ targetOrg,
232
+ timestamp: new Date().toISOString(),
233
+ totalWaves: orderedWaves.length,
234
+ completedWaves: Array.from({ length: Math.max(0, wave.number - 1) }, (_, i) => i + 1),
235
+ currentWave: wave.number,
236
+ failedWave: {
237
+ waveNumber: wave.number,
238
+ error: result.output,
239
+ timestamp: new Date().toISOString(),
240
+ },
241
+ metadata: {
242
+ lastKnownStatus: result.status,
243
+ testsRun: result.testsRun,
244
+ testFailures: result.testFailures,
245
+ testLevel: this.resolveTestLevel(skipTests),
246
+ ...aiMetadata,
247
+ },
248
+ });
249
+ this.error(`Wave ${wave.number} failed: ${result.output}`);
250
+ }
251
+ // Save state after each wave
252
+ const aiMetadata = deploymentContext.aiContext === undefined
253
+ ? {}
254
+ : {
255
+ aiProvider: deploymentContext.aiContext.provider,
256
+ aiModel: deploymentContext.aiContext.model,
257
+ aiFallback: deploymentContext.aiContext.fallback,
258
+ aiAdjustments: deploymentContext.aiContext.aiAdjustments,
259
+ aiUnknownTypes: deploymentContext.aiContext.unknownTypes,
260
+ aiInferenceFallback: deploymentContext.aiContext.inferenceFallback,
261
+ aiInferredDependencies: deploymentContext.aiContext.inferredDependencies,
262
+ };
263
+ await stateManager.saveState({
264
+ deploymentId,
265
+ targetOrg,
266
+ timestamp: new Date().toISOString(),
267
+ totalWaves: orderedWaves.length,
268
+ completedWaves: Array.from({ length: wave.number }, (_, i) => i + 1),
269
+ currentWave: wave.number,
270
+ metadata: {
271
+ lastKnownStatus: result.status,
272
+ testsRun: result.testsRun,
273
+ testFailures: result.testFailures,
274
+ testLevel: this.resolveTestLevel(skipTests),
275
+ ...aiMetadata,
276
+ },
277
+ });
278
+ this.log(`✅ Wave ${wave.number} deployed successfully`);
279
+ }
280
+ catch (error) {
281
+ logger.error('Wave deployment failed', { wave: wave.number, error });
282
+ this.error(`Wave ${wave.number} failed: ${error instanceof Error ? error.message : String(error)}`);
283
+ }
284
+ });
285
+ // Clear state on success
286
+ await stateManager.clearState();
287
+ this.log('\n✅ All waves deployed successfully!');
288
+ }
289
+ async buildDeploymentContext(flags, sourcePath) {
290
+ const scanner = new MetadataScannerService();
291
+ const scanResult = await scanner.scan({ sourcePath });
292
+ if (scanResult.errors.length > 0) {
293
+ logger.error('Metadata scanning completed with errors', { errors: scanResult.errors });
294
+ scanResult.errors.forEach((err) => this.warn(err));
295
+ }
296
+ if (scanResult.warnings.length > 0) {
297
+ logger.warn('Metadata scanning completed with warnings', { warnings: scanResult.warnings });
298
+ scanResult.warnings.forEach((warn) => this.warn(warn));
299
+ }
300
+ let dependencyResult = scanResult.dependencyResult;
301
+ let inferredDependencies = 0;
302
+ let inferenceFallback = false;
303
+ if (flags['use-ai']) {
304
+ const inferenceService = new DependencyInferenceService({
305
+ baseDir: sourcePath ?? process.cwd(),
306
+ });
307
+ const inferenceResult = await inferenceService.inferDependencies(scanResult.components, scanResult.dependencyResult.graph);
308
+ inferredDependencies = inferenceResult.highConfidenceCount;
309
+ inferenceFallback = inferenceResult.fallbackToStatic;
310
+ if (inferenceResult.dependencies.length > 0) {
311
+ const enrichedComponents = this.applyInferredDependencies(scanResult.components, inferenceResult.dependencies);
312
+ const graphBuilder = new DependencyGraphBuilder();
313
+ graphBuilder.addComponents(enrichedComponents);
314
+ scanResult.components = enrichedComponents;
315
+ dependencyResult = graphBuilder.build();
316
+ scanResult.dependencyResult = dependencyResult;
317
+ }
318
+ }
319
+ const waveBuilder = new WaveBuilder();
320
+ const waveResult = waveBuilder.generateWaves(dependencyResult.graph);
321
+ let orderedWaves = getWavesInExecutionOrder(waveResult);
322
+ let aiContext;
323
+ if (flags['use-ai']) {
324
+ this.log(' 🤖 Using AI priority weighting for wave ordering...');
325
+ const priorityService = new AgentforcePriorityService({
326
+ baseDir: sourcePath ?? process.cwd(),
327
+ });
328
+ const aiWaveGenerator = new AIEnhancedPriorityWaveGenerator({
329
+ agentforceService: priorityService,
330
+ orgType: typeof flags['org-type'] === 'string' ? flags['org-type'] : undefined,
331
+ industry: typeof flags.industry === 'string' ? flags.industry : undefined,
332
+ });
333
+ orderedWaves = await aiWaveGenerator.applyPriorityWavesAsync(orderedWaves, scanResult.dependencyResult.components);
334
+ const unknownTypesWarning = aiWaveGenerator.getUnknownTypesWarning();
335
+ if (unknownTypesWarning) {
336
+ this.warn(unknownTypesWarning);
337
+ }
338
+ const aiReport = aiWaveGenerator.getAIReport();
339
+ if (aiReport) {
340
+ this.log(aiReport);
341
+ }
342
+ const aiStats = aiWaveGenerator.getAIStats();
343
+ const providerConfig = priorityService.getProviderConfig();
344
+ aiContext = {
345
+ enabled: true,
346
+ provider: providerConfig.provider,
347
+ model: providerConfig.model,
348
+ aiAdjustments: aiStats?.aiAdjustments ?? 0,
349
+ unknownTypes: aiStats?.unknownTypes ?? [],
350
+ fallback: aiStats?.usedFallback ?? false,
351
+ inferredDependencies,
352
+ inferenceFallback,
353
+ };
354
+ }
355
+ return { scanResult, orderedWaves, aiContext };
356
+ }
357
+ generateReport(waves) {
358
+ this.log('\n📊 Deployment Report:');
359
+ this.log(` - Waves: ${waves}`);
360
+ this.log(' - Status: Success');
361
+ }
362
+ async forEachSequentially(items, callback) {
363
+ let chain = Promise.resolve();
364
+ items.forEach((item, index) => {
365
+ chain = chain.then(async () => callback(item, index));
366
+ });
367
+ await chain;
368
+ }
369
+ async executeCycleRemediationDeployment(params) {
370
+ const { deploymentId, targetOrg, sourcePath, stateManager, tracker, plan, sfCli, skipTests, componentMap } = params;
371
+ const editor = new CycleSourceEditor();
372
+ const startedAt = new Date().toISOString();
373
+ const editRecords = [];
374
+ const cycleId = plan.cycles.map((cycle) => cycle.id).join('||');
375
+ const phaseOneComponents = [
376
+ ...new Set(plan.cycles.flatMap((cycle) => cycle.deployPhases.find((phase) => phase.phase === 1)?.components ?? [])),
377
+ ];
378
+ const phaseTwoComponents = [
379
+ ...new Set(plan.cycles.flatMap((cycle) => cycle.deployPhases.find((phase) => phase.phase === 2)?.components ?? [])),
380
+ ];
381
+ let editsRestored = false;
382
+ let failureStateSaved = false;
383
+ try {
384
+ this.log('🩹 Applying conservative cycle remediation edits...');
385
+ await this.forEachSequentially(plan.cycles, async (cycle) => {
386
+ await this.forEachSequentially(cycle.edits, async (edit) => {
387
+ const request = await this.createCycleEditRequest(edit);
388
+ editRecords.push(await editor.applyEdit(request));
389
+ });
390
+ });
391
+ await stateManager.saveState({
392
+ deploymentId,
393
+ targetOrg,
394
+ timestamp: startedAt,
395
+ totalWaves: 2,
396
+ completedWaves: [],
397
+ currentWave: 1,
398
+ cycleRemediation: {
399
+ cycleId,
400
+ strategy: 'comment-reference',
401
+ activePhase: 1,
402
+ startedAt,
403
+ completedPhases: [],
404
+ editRecords,
405
+ },
406
+ });
407
+ tracker.startTracking(deploymentId, 1, 2);
408
+ this.log('♻️ Phase 1/2: deploying temporarily cycle-broken metadata...');
409
+ const phaseOneManifestPath = await this.generateWaveManifest({
410
+ baseDir: sourcePath ?? process.cwd(),
411
+ waveNumber: 1,
412
+ components: phaseOneComponents,
413
+ componentMap,
414
+ });
415
+ const phaseOneResult = await sfCli.deploy({
416
+ manifestPath: phaseOneManifestPath,
417
+ targetOrg,
418
+ testLevel: this.resolveTestLevel(skipTests),
419
+ });
420
+ if (!phaseOneResult.success) {
421
+ await stateManager.saveState({
422
+ deploymentId,
423
+ targetOrg,
424
+ timestamp: new Date().toISOString(),
425
+ totalWaves: 2,
426
+ completedWaves: [],
427
+ currentWave: 1,
428
+ failedWave: {
429
+ waveNumber: 1,
430
+ error: phaseOneResult.output,
431
+ timestamp: new Date().toISOString(),
432
+ },
433
+ cycleRemediation: {
434
+ cycleId,
435
+ strategy: 'comment-reference',
436
+ activePhase: 1,
437
+ startedAt,
438
+ completedPhases: [],
439
+ editRecords,
440
+ },
441
+ metadata: {
442
+ lastKnownStatus: phaseOneResult.status,
443
+ testsRun: phaseOneResult.testsRun,
444
+ testFailures: phaseOneResult.testFailures,
445
+ testLevel: this.resolveTestLevel(skipTests),
446
+ },
447
+ });
448
+ failureStateSaved = true;
449
+ throw new Error(`Cycle remediation phase 1 failed: ${phaseOneResult.output}`);
450
+ }
451
+ await stateManager.saveState({
452
+ deploymentId,
453
+ targetOrg,
454
+ timestamp: new Date().toISOString(),
455
+ totalWaves: 2,
456
+ completedWaves: [1],
457
+ currentWave: 2,
458
+ cycleRemediation: {
459
+ cycleId,
460
+ strategy: 'comment-reference',
461
+ activePhase: 2,
462
+ startedAt,
463
+ completedPhases: [1],
464
+ editRecords,
465
+ },
466
+ metadata: {
467
+ lastKnownStatus: phaseOneResult.status,
468
+ testsRun: phaseOneResult.testsRun,
469
+ testFailures: phaseOneResult.testFailures,
470
+ testLevel: this.resolveTestLevel(skipTests),
471
+ },
472
+ });
473
+ this.log('♻️ Restoring original references before phase 2...');
474
+ await this.restoreCycleEdits(editor, editRecords);
475
+ editsRestored = true;
476
+ tracker.startTracking(deploymentId, 2, 2);
477
+ this.log('♻️ Phase 2/2: redeploying restored metadata...');
478
+ const phaseTwoManifestPath = await this.generateWaveManifest({
479
+ baseDir: sourcePath ?? process.cwd(),
480
+ waveNumber: 2,
481
+ components: phaseTwoComponents,
482
+ componentMap,
483
+ });
484
+ const phaseTwoResult = await sfCli.deploy({
485
+ manifestPath: phaseTwoManifestPath,
486
+ targetOrg,
487
+ testLevel: this.resolveTestLevel(skipTests),
488
+ });
489
+ if (!phaseTwoResult.success) {
490
+ await stateManager.saveState({
491
+ deploymentId,
492
+ targetOrg,
493
+ timestamp: new Date().toISOString(),
494
+ totalWaves: 2,
495
+ completedWaves: [1],
496
+ currentWave: 2,
497
+ failedWave: {
498
+ waveNumber: 2,
499
+ error: phaseTwoResult.output,
500
+ timestamp: new Date().toISOString(),
501
+ },
502
+ cycleRemediation: {
503
+ cycleId,
504
+ strategy: 'comment-reference',
505
+ activePhase: 2,
506
+ startedAt,
507
+ completedPhases: [1],
508
+ editRecords,
509
+ },
510
+ metadata: {
511
+ lastKnownStatus: phaseTwoResult.status,
512
+ testsRun: phaseTwoResult.testsRun,
513
+ testFailures: phaseTwoResult.testFailures,
514
+ testLevel: this.resolveTestLevel(skipTests),
515
+ },
516
+ });
517
+ failureStateSaved = true;
518
+ throw new Error(`Cycle remediation phase 2 failed: ${phaseTwoResult.output}`);
519
+ }
520
+ await stateManager.clearState();
521
+ this.log('\n✅ Cycle remediation deployment completed successfully!');
522
+ }
523
+ catch (error) {
524
+ if (!editsRestored) {
525
+ await this.restoreCycleEdits(editor, editRecords, true);
526
+ }
527
+ if (!failureStateSaved) {
528
+ await stateManager.saveState({
529
+ deploymentId,
530
+ targetOrg,
531
+ timestamp: new Date().toISOString(),
532
+ totalWaves: 2,
533
+ completedWaves: [],
534
+ currentWave: 1,
535
+ failedWave: {
536
+ waveNumber: 1,
537
+ error: error instanceof Error ? error.message : String(error),
538
+ timestamp: new Date().toISOString(),
539
+ },
540
+ cycleRemediation: {
541
+ cycleId,
542
+ strategy: 'comment-reference',
543
+ activePhase: 1,
544
+ startedAt,
545
+ completedPhases: [],
546
+ editRecords,
547
+ },
548
+ });
549
+ }
550
+ throw error;
551
+ }
552
+ }
553
+ async createCycleEditRequest(edit) {
554
+ if (edit.filePath === undefined) {
555
+ throw new Error(`Cycle remediation edit for ${edit.nodeId} is missing a file path.`);
556
+ }
557
+ const content = await readFile(edit.filePath, 'utf8');
558
+ const dependencyName = edit.targetDependency.includes(':')
559
+ ? edit.targetDependency.split(':').pop() ?? edit.targetDependency
560
+ : edit.targetDependency;
561
+ const candidateLines = content.split('\n').filter((line) => {
562
+ const trimmed = line.trim();
563
+ return trimmed.length > 0 && !trimmed.startsWith('//') && line.includes(dependencyName);
564
+ });
565
+ if (candidateLines.length !== 1) {
566
+ throw new Error(`Cycle remediation for ${edit.nodeId} requires exactly one candidate source line containing ${dependencyName}; found ${candidateLines.length}.`);
567
+ }
568
+ return {
569
+ filePath: edit.filePath,
570
+ targetDescription: edit.targetDescription,
571
+ targetDependency: edit.targetDependency,
572
+ sourceSnippet: candidateLines[0],
573
+ };
574
+ }
575
+ applyInferredDependencies(components, inferredDependencies) {
576
+ const clonedComponents = components.map((component) => ({
577
+ ...component,
578
+ dependencies: new Set(component.dependencies),
579
+ dependents: new Set(component.dependents),
580
+ }));
581
+ const nodeIdsByName = new Map();
582
+ for (const component of clonedComponents) {
583
+ nodeIdsByName.set(component.name, `${component.type}:${component.name}`);
584
+ }
585
+ const componentsByNodeId = new Map();
586
+ for (const component of clonedComponents) {
587
+ const nodeId = `${component.type}:${component.name}`;
588
+ componentsByNodeId.set(nodeId, component);
589
+ }
590
+ for (const inferred of inferredDependencies) {
591
+ const fromNodeId = nodeIdsByName.get(inferred.from);
592
+ const toNodeId = nodeIdsByName.get(inferred.to);
593
+ if (!fromNodeId || !toNodeId) {
594
+ continue;
595
+ }
596
+ componentsByNodeId.get(fromNodeId)?.dependencies.add(toNodeId);
597
+ componentsByNodeId.get(toNodeId)?.dependents.add(fromNodeId);
598
+ }
599
+ return clonedComponents;
600
+ }
601
+ async restoreCycleEdits(editor, editRecords, bestEffort = false) {
602
+ await this.forEachSequentially([...editRecords].reverse(), async (record) => {
603
+ const result = await editor.restoreEdit(record);
604
+ if (!result.restored && result.reason !== 'backup-missing' && !bestEffort) {
605
+ throw new Error(`Failed to restore cycle remediation edit for ${record.filePath}: ${result.reason ?? 'unknown'}.`);
606
+ }
607
+ });
608
+ }
609
+ resolveTestLevel(skipTests) {
610
+ return skipTests ? 'NoTestRun' : 'RunLocalTests';
611
+ }
612
+ getTargetOrgIdentifier(value) {
613
+ if (typeof value === 'string' && value.length > 0) {
614
+ return value;
615
+ }
616
+ if (typeof value === 'object' && value !== null && 'getUsername' in value) {
617
+ const getUsername = value.getUsername;
618
+ return typeof getUsername === 'function' ? getUsername.call(value) : undefined;
619
+ }
620
+ return undefined;
621
+ }
622
+ async generateWaveManifest(params) {
623
+ const manifestDir = path.join(params.baseDir, '.smart-deployment', 'manifests');
624
+ await mkdir(manifestDir, { recursive: true });
625
+ const grouped = new Map();
626
+ for (const nodeId of params.components) {
627
+ const component = params.componentMap.get(nodeId);
628
+ if (!component) {
629
+ continue;
630
+ }
631
+ if (!grouped.has(component.type)) {
632
+ grouped.set(component.type, new Set());
633
+ }
634
+ grouped.get(component.type).add(component.name);
635
+ }
636
+ const typeBlocks = [...grouped.entries()]
637
+ .sort((a, b) => a[0].localeCompare(b[0]))
638
+ .map(([type, members]) => {
639
+ const memberLines = [...members]
640
+ .sort((left, right) => left.localeCompare(right))
641
+ .map((member) => ` <members>${member}</members>`)
642
+ .join('\n');
643
+ return [' <types>', memberLines, ` <name>${type}</name>`, ' </types>'].join('\n');
644
+ })
645
+ .join('\n');
646
+ const content = [
647
+ '<?xml version="1.0" encoding="UTF-8"?>',
648
+ '<Package xmlns="http://soap.sforce.com/2006/04/metadata">',
649
+ typeBlocks,
650
+ ' <version>61.0</version>',
651
+ '</Package>',
652
+ '',
653
+ ].join('\n');
654
+ const manifestPath = path.join(manifestDir, `wave-${String(params.waveNumber).padStart(3, '0')}.xml`);
655
+ await writeFile(manifestPath, content, 'utf8');
656
+ return manifestPath;
657
+ }
658
+ }
659
+ //# sourceMappingURL=start.js.map