@ohos-ports/nx 23.3.0-beta.2 → 24.0.2-beta.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 (294) hide show
  1. package/README.md +3 -6
  2. package/dist/bin/nx.js +2 -2
  3. package/dist/bin/post-install.js +5 -3
  4. package/dist/nx-cloud-internals.d.ts +1 -0
  5. package/dist/nx-cloud-internals.js +7 -1
  6. package/dist/src/adapter/ngcli-adapter.js +2 -2
  7. package/dist/src/ai/clone-ai-config-repo.js +49 -12
  8. package/dist/src/command-line/add/add.d.ts +2 -0
  9. package/dist/src/command-line/add/add.js +23 -5
  10. package/dist/src/command-line/affected/affected.js +2 -2
  11. package/dist/src/command-line/configure-ai-agents/configure-ai-agents.js +0 -12
  12. package/dist/src/command-line/graph/graph.js +38 -10
  13. package/dist/src/command-line/init/command-object.js +0 -12
  14. package/dist/src/command-line/init/implementation/add-nx-to-nest.js +21 -62
  15. package/dist/src/command-line/init/init-v2.js +0 -2
  16. package/dist/src/command-line/migrate/agentic/close-agent-session.d.ts +1 -1
  17. package/dist/src/command-line/migrate/agentic/close-agent-session.js +4 -3
  18. package/dist/src/command-line/migrate/agentic/definitions.d.ts +1 -3
  19. package/dist/src/command-line/migrate/agentic/definitions.js +5 -97
  20. package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +7 -45
  21. package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +9 -51
  22. package/dist/src/command-line/migrate/agentic/handoff.d.ts +1 -43
  23. package/dist/src/command-line/migrate/agentic/handoff.js +3 -119
  24. package/dist/src/command-line/migrate/agentic/instruction-files.d.ts +0 -21
  25. package/dist/src/command-line/migrate/agentic/instruction-files.js +6 -27
  26. package/dist/src/command-line/migrate/agentic/master/run-master-session.d.ts +19 -1
  27. package/dist/src/command-line/migrate/agentic/master/run-master-session.js +88 -49
  28. package/dist/src/command-line/migrate/agentic/master/spawn-master.d.ts +1 -0
  29. package/dist/src/command-line/migrate/agentic/master/spawn-master.js +86 -24
  30. package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.d.ts +2 -2
  31. package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.js +2 -2
  32. package/dist/src/command-line/migrate/agentic/prompts/fragments.d.ts +1 -12
  33. package/dist/src/command-line/migrate/agentic/prompts/fragments.js +8 -17
  34. package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.d.ts +0 -15
  35. package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.js +3 -100
  36. package/dist/src/command-line/migrate/agentic/select.d.ts +12 -6
  37. package/dist/src/command-line/migrate/agentic/select.js +38 -8
  38. package/dist/src/command-line/migrate/agentic/types.d.ts +9 -68
  39. package/dist/src/command-line/migrate/agentic/types.js +6 -8
  40. package/dist/src/command-line/migrate/command-object.js +6 -10
  41. package/dist/src/command-line/migrate/execute-migration.d.ts +6 -6
  42. package/dist/src/command-line/migrate/execute-migration.js +25 -15
  43. package/dist/src/command-line/migrate/migrate-analytics.d.ts +18 -1
  44. package/dist/src/command-line/migrate/migrate-analytics.js +38 -0
  45. package/dist/src/command-line/migrate/migrate-commits.d.ts +29 -17
  46. package/dist/src/command-line/migrate/migrate-commits.js +86 -32
  47. package/dist/src/command-line/migrate/migrate-config.d.ts +6 -6
  48. package/dist/src/command-line/migrate/migrate-config.js +12 -6
  49. package/dist/src/command-line/migrate/migrate-output.d.ts +1 -6
  50. package/dist/src/command-line/migrate/migrate-output.js +1 -10
  51. package/dist/src/command-line/migrate/migrate.d.ts +6 -30
  52. package/dist/src/command-line/migrate/migrate.js +257 -255
  53. package/dist/src/command-line/migrate/resolve-package-version.d.ts +2 -4
  54. package/dist/src/command-line/migrate/resolve-package-version.js +2 -35
  55. package/dist/src/command-line/migrate/run/agent-output.d.ts +2 -0
  56. package/dist/src/command-line/migrate/run/agent-output.js +9 -0
  57. package/dist/src/command-line/migrate/run/broker.d.ts +14 -5
  58. package/dist/src/command-line/migrate/run/broker.js +69 -21
  59. package/dist/src/command-line/migrate/run/clean-retry.js +4 -2
  60. package/dist/src/command-line/migrate/run/existing-run-report.d.ts +1 -1
  61. package/dist/src/command-line/migrate/run/existing-run-report.js +7 -5
  62. package/dist/src/command-line/migrate/run/give-up.d.ts +4 -3
  63. package/dist/src/command-line/migrate/run/give-up.js +8 -5
  64. package/dist/src/command-line/migrate/run/index.d.ts +7 -5
  65. package/dist/src/command-line/migrate/run/index.js +16 -1
  66. package/dist/src/command-line/migrate/run/issues.js +7 -2
  67. package/dist/src/command-line/migrate/run/orchestrator.d.ts +61 -4
  68. package/dist/src/command-line/migrate/run/orchestrator.js +397 -133
  69. package/dist/src/command-line/migrate/run/run-state.d.ts +17 -1
  70. package/dist/src/command-line/migrate/run/run-state.js +41 -2
  71. package/dist/src/command-line/migrate/run/runbook.d.ts +1 -0
  72. package/dist/src/command-line/migrate/run/runbook.js +115 -18
  73. package/dist/src/command-line/migrate/run/state-lock.d.ts +29 -4
  74. package/dist/src/command-line/migrate/run/state-lock.js +102 -10
  75. package/dist/src/command-line/migrate/run/state-machine.js +4 -1
  76. package/dist/src/command-line/migrate/run/util.d.ts +7 -2
  77. package/dist/src/command-line/migrate/run/util.js +30 -3
  78. package/dist/src/command-line/migrate/run/worker.d.ts +1 -1
  79. package/dist/src/command-line/migrate/run/worker.js +252 -250
  80. package/dist/src/command-line/migrate/sort-migrations.d.ts +1 -7
  81. package/dist/src/command-line/migrate/sort-migrations.js +1 -12
  82. package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +17 -12
  83. package/dist/src/command-line/release/changelog.js +9 -6
  84. package/dist/src/command-line/release/config/config.d.ts +1 -0
  85. package/dist/src/command-line/release/config/config.js +48 -9
  86. package/dist/src/command-line/release/release.js +2 -2
  87. package/dist/src/command-line/release/utils/git.js +8 -7
  88. package/dist/src/command-line/release/utils/interpolate-release-config.d.ts +6 -0
  89. package/dist/src/command-line/release/utils/interpolate-release-config.js +39 -0
  90. package/dist/src/command-line/release/utils/release-graph.d.ts +5 -0
  91. package/dist/src/command-line/release/utils/release-graph.js +1 -0
  92. package/dist/src/command-line/release/utils/remote-release-clients/github.js +5 -6
  93. package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +5 -6
  94. package/dist/src/command-line/release/utils/resolve-changelog-renderer.js +2 -2
  95. package/dist/src/command-line/release/utils/shared.js +10 -10
  96. package/dist/src/command-line/release/utils/version-plan-utils.d.ts +3 -12
  97. package/dist/src/command-line/release/utils/version-plan-utils.js +33 -55
  98. package/dist/src/command-line/release/version/version-actions.js +2 -1
  99. package/dist/src/command-line/release/version.js +5 -2
  100. package/dist/src/command-line/reset/reset.js +58 -62
  101. package/dist/src/command-line/run/executor-utils.js +1 -0
  102. package/dist/src/command-line/run/run-one.d.ts +20 -1
  103. package/dist/src/command-line/run/run-one.js +153 -5
  104. package/dist/src/command-line/run/run.js +2 -1
  105. package/dist/src/command-line/show/projects.js +5 -3
  106. package/dist/src/command-line/show/show-target/info.d.ts +10 -1
  107. package/dist/src/command-line/show/show-target/info.js +100 -15
  108. package/dist/src/command-line/show/show-target/inputs.js +10 -2
  109. package/dist/src/command-line/show/show-target/utils.js +1 -0
  110. package/dist/src/command-line/watch/command-object.js +3 -22
  111. package/dist/src/command-line/watch/watch.d.ts +0 -7
  112. package/dist/src/command-line/watch/watch.js +1 -1
  113. package/dist/src/command-line/yargs-utils/shared-options.js +1 -1
  114. package/dist/src/config/misc-interfaces.d.ts +18 -0
  115. package/dist/src/config/nx-json.d.ts +22 -11
  116. package/dist/src/config/task-graph.d.ts +1 -1
  117. package/dist/src/config/workspace-json-project-json.d.ts +88 -0
  118. package/dist/src/core/graph/main.js +1 -1
  119. package/dist/src/core/graph/runtime.js +1 -1
  120. package/dist/src/core/graph/styles.css +1 -1
  121. package/dist/src/core/graph/styles.js +1 -1
  122. package/dist/src/daemon/client/client.d.ts +15 -0
  123. package/dist/src/daemon/client/client.js +181 -71
  124. package/dist/src/daemon/client/daemon-socket-messenger.d.ts +1 -1
  125. package/dist/src/daemon/client/daemon-socket-messenger.js +2 -2
  126. package/dist/src/daemon/server/client-socket-context.js +1 -1
  127. package/dist/src/daemon/server/handle-process-in-background.js +21 -9
  128. package/dist/src/daemon/server/handle-select-affected-tasks.d.ts +2 -1
  129. package/dist/src/daemon/server/handle-select-affected-tasks.js +21 -13
  130. package/dist/src/daemon/server/native-js-loader.d.ts +1 -0
  131. package/dist/src/daemon/server/native-js-loader.js +21 -0
  132. package/dist/src/daemon/server/project-graph-incremental-recomputation.js +4 -8
  133. package/dist/src/daemon/server/server.d.ts +2 -1
  134. package/dist/src/daemon/server/server.js +17 -4
  135. package/dist/src/daemon/server/shutdown-utils.js +0 -3
  136. package/dist/src/daemon/server/start.d.ts +1 -0
  137. package/dist/src/daemon/server/start.js +2 -0
  138. package/dist/src/daemon/socket-utils.d.ts +11 -9
  139. package/dist/src/daemon/socket-utils.js +31 -61
  140. package/dist/src/daemon/tmp-dir.d.ts +19 -14
  141. package/dist/src/daemon/tmp-dir.js +142 -354
  142. package/dist/src/devkit-exports.d.ts +9 -1
  143. package/dist/src/devkit-exports.js +12 -1
  144. package/dist/src/devkit-internals.d.ts +6 -5
  145. package/dist/src/devkit-internals.js +13 -4
  146. package/dist/src/executors/run-commands/run-commands.impl.d.ts +4 -2
  147. package/dist/src/executors/run-commands/run-commands.impl.js +53 -27
  148. package/dist/src/executors/run-commands/running-tasks.d.ts +13 -4
  149. package/dist/src/executors/run-commands/running-tasks.js +148 -95
  150. package/dist/src/executors/run-commands/schema.json +1 -1
  151. package/dist/src/hasher/check-task-files.js +5 -8
  152. package/dist/src/hasher/file-hasher.js +9 -7
  153. package/dist/src/hasher/hash-task.js +4 -0
  154. package/dist/src/hasher/native-task-hasher-impl.js +3 -1
  155. package/dist/src/hasher/task-hasher.d.ts +2 -0
  156. package/dist/src/hasher/task-hasher.js +4 -1
  157. package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.d.ts +1 -2
  158. package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.js +6 -11
  159. package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.md +2 -2
  160. package/dist/src/migrations/update-24-0-0/enable-legacy-affected.d.ts +4 -0
  161. package/dist/src/migrations/update-24-0-0/enable-legacy-affected.js +15 -0
  162. package/dist/src/migrations/update-24-0-0/enable-legacy-affected.md +30 -0
  163. package/dist/src/migrations/update-24-0-0/find-custom-hashers.d.ts +3 -0
  164. package/dist/src/migrations/update-24-0-0/find-custom-hashers.js +100 -0
  165. package/dist/src/migrations/update-24-0-0/find-custom-hashers.md +63 -0
  166. package/dist/src/migrations/update-24-0-0/move-custom-hashers-to-inputs.md +146 -0
  167. package/dist/src/migrations/update-24-0-0/rename-ultracache-ignore-options.d.ts +3 -0
  168. package/dist/src/migrations/update-24-0-0/rename-ultracache-ignore-options.js +130 -0
  169. package/dist/src/migrations/update-24-0-0/rename-ultracache-ignore-options.md +62 -0
  170. package/dist/src/native/assert-supported-platform.js +1 -1
  171. package/dist/src/native/index.d.ts +238 -18
  172. package/dist/src/native/index.js +6 -1
  173. package/dist/src/native/native-bindings.js +15 -6
  174. package/dist/src/native/nx.openharmony-arm64.node +0 -0
  175. package/dist/src/native/nx.wasi-browser.js +1 -0
  176. package/dist/src/native/nx.wasi.cjs +1 -0
  177. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  178. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  179. package/dist/src/nx-cloud/update-manager.d.ts +14 -0
  180. package/dist/src/nx-cloud/update-manager.js +237 -50
  181. package/dist/src/plugins/js/lock-file/pnpm-parser.js +3 -4
  182. package/dist/src/plugins/js/lock-file/pruned-output.d.ts +2 -2
  183. package/dist/src/plugins/js/lock-file/pruned-output.js +4 -4
  184. package/dist/src/plugins/js/utils/register.js +9 -4
  185. package/dist/src/project-graph/affected/affected-tasks.d.ts +9 -6
  186. package/dist/src/project-graph/affected/affected-tasks.js +31 -7
  187. package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +7 -0
  188. package/dist/src/project-graph/plugins/loaded-nx-plugin.js +49 -6
  189. package/dist/src/project-graph/utils/project-configuration/target-merging.js +1 -1
  190. package/dist/src/project-graph/utils/project-configuration/target-normalization.js +12 -133
  191. package/dist/src/project-graph/utils/project-configuration-utils.js +2 -2
  192. package/dist/src/project-graph/utils/retrieve-workspace-files.js +27 -6
  193. package/dist/src/tasks-runner/create-task-graph.d.ts +8 -7
  194. package/dist/src/tasks-runner/create-task-graph.js +50 -27
  195. package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
  196. package/dist/src/tasks-runner/init-tasks-runner.js +116 -59
  197. package/dist/src/tasks-runner/life-cycle.d.ts +4 -1
  198. package/dist/src/tasks-runner/life-cycle.js +7 -0
  199. package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +5 -2
  200. package/dist/src/tasks-runner/life-cycles/performance-analysis.js +13 -7
  201. package/dist/src/tasks-runner/life-cycles/performance-life-cycle.d.ts +4 -3
  202. package/dist/src/tasks-runner/life-cycles/performance-life-cycle.js +9 -2
  203. package/dist/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.js +5 -2
  204. package/dist/src/tasks-runner/life-cycles/static-run-one-terminal-output-life-cycle.js +4 -1
  205. package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.js +5 -1
  206. package/dist/src/tasks-runner/pseudo-ipc.d.ts +1 -0
  207. package/dist/src/tasks-runner/pseudo-ipc.js +4 -0
  208. package/dist/src/tasks-runner/pseudo-terminal.d.ts +1 -1
  209. package/dist/src/tasks-runner/pseudo-terminal.js +2 -2
  210. package/dist/src/tasks-runner/readiness/executor-ready-signal.d.ts +7 -0
  211. package/dist/src/tasks-runner/readiness/executor-ready-signal.js +43 -0
  212. package/dist/src/tasks-runner/readiness/probes.d.ts +14 -0
  213. package/dist/src/tasks-runner/readiness/probes.js +101 -0
  214. package/dist/src/tasks-runner/readiness/ready-signal-server.d.ts +18 -0
  215. package/dist/src/tasks-runner/readiness/ready-signal-server.js +72 -0
  216. package/dist/src/tasks-runner/readiness/ready-signal.d.ts +33 -0
  217. package/dist/src/tasks-runner/readiness/ready-signal.js +92 -0
  218. package/dist/src/tasks-runner/readiness/ready-when.d.ts +84 -0
  219. package/dist/src/tasks-runner/readiness/ready-when.js +371 -0
  220. package/dist/src/tasks-runner/readiness/startup-host.d.ts +1 -0
  221. package/dist/src/tasks-runner/readiness/startup-host.js +32 -0
  222. package/dist/src/tasks-runner/run-command.d.ts +6 -2
  223. package/dist/src/tasks-runner/run-command.js +21 -31
  224. package/dist/src/tasks-runner/run-outcome.d.ts +16 -0
  225. package/dist/src/tasks-runner/run-outcome.js +39 -0
  226. package/dist/src/tasks-runner/running-tasks/batch-process.js +6 -0
  227. package/dist/src/tasks-runner/running-tasks/node-child-process.js +5 -4
  228. package/dist/src/tasks-runner/running-tasks/running-task.d.ts +1 -1
  229. package/dist/src/tasks-runner/task-env.d.ts +10 -0
  230. package/dist/src/tasks-runner/task-env.js +37 -5
  231. package/dist/src/tasks-runner/task-graph-utils.d.ts +9 -6
  232. package/dist/src/tasks-runner/task-graph-utils.js +17 -12
  233. package/dist/src/tasks-runner/task-orchestrator.d.ts +62 -18
  234. package/dist/src/tasks-runner/task-orchestrator.js +750 -150
  235. package/dist/src/tasks-runner/tasks-runner.d.ts +1 -1
  236. package/dist/src/tasks-runner/tasks-schedule.d.ts +18 -1
  237. package/dist/src/tasks-runner/tasks-schedule.js +63 -6
  238. package/dist/src/tasks-runner/tokens.d.ts +54 -0
  239. package/dist/src/tasks-runner/tokens.js +161 -0
  240. package/dist/src/tasks-runner/utils.d.ts +35 -6
  241. package/dist/src/tasks-runner/utils.js +149 -68
  242. package/dist/src/ultracache/ci-status.d.ts +24 -0
  243. package/dist/src/ultracache/ci-status.js +87 -0
  244. package/dist/src/ultracache/config.d.ts +3 -3
  245. package/dist/src/ultracache/config.js +4 -4
  246. package/dist/src/ultracache/fetch.d.ts +2 -0
  247. package/dist/src/ultracache/fetch.js +1 -0
  248. package/dist/src/ultracache/overrides.js +4 -0
  249. package/dist/src/utils/acknowledge-build-scripts.d.ts +34 -1
  250. package/dist/src/utils/acknowledge-build-scripts.js +171 -32
  251. package/dist/src/utils/child-process.js +2 -1
  252. package/dist/src/utils/find-matching-projects.js +9 -6
  253. package/dist/src/utils/git-utils.d.ts +12 -5
  254. package/dist/src/utils/git-utils.js +69 -11
  255. package/dist/src/utils/long-running-target.d.ts +1 -3
  256. package/dist/src/utils/long-running-target.js +1 -3
  257. package/dist/src/utils/output.d.ts +4 -3
  258. package/dist/src/utils/output.js +4 -3
  259. package/dist/src/utils/owned-private-dir.d.ts +1 -17
  260. package/dist/src/utils/owned-private-dir.js +10 -62
  261. package/dist/src/utils/package-manager.d.ts +8 -0
  262. package/dist/src/utils/package-manager.js +65 -8
  263. package/dist/src/utils/perf-hooks.d.ts +1 -0
  264. package/dist/src/utils/plugins/core-plugins.js +5 -1
  265. package/dist/src/utils/progress-topics.d.ts +1 -0
  266. package/dist/src/utils/progress-topics.js +1 -0
  267. package/dist/src/utils/safe-spawn.js +1 -5
  268. package/dist/src/utils/shell-quoting.d.ts +8 -1
  269. package/dist/src/utils/shell-quoting.js +12 -1
  270. package/dist/src/utils/spawn-without-terminal.d.ts +27 -0
  271. package/dist/src/utils/spawn-without-terminal.js +110 -0
  272. package/dist/src/utils/string-similarity.d.ts +38 -0
  273. package/dist/src/utils/string-similarity.js +108 -0
  274. package/migrations.json +20 -6
  275. package/package.json +15 -24
  276. package/schemas/migrations-schema.json +11 -0
  277. package/schemas/nx-schema.json +133 -11
  278. package/schemas/project-schema.json +114 -4
  279. package/dist/src/command-line/migrate/agentic/prompts/generic-validation.d.ts +0 -56
  280. package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +0 -67
  281. package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.d.ts +0 -49
  282. package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.js +0 -53
  283. package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.d.ts +0 -26
  284. package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.js +0 -27
  285. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +0 -70
  286. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +0 -113
  287. package/dist/src/command-line/migrate/agentic/run-step.d.ts +0 -68
  288. package/dist/src/command-line/migrate/agentic/run-step.js +0 -148
  289. package/dist/src/command-line/migrate/agentic/runner.d.ts +0 -21
  290. package/dist/src/command-line/migrate/agentic/runner.js +0 -262
  291. package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.d.ts +0 -9
  292. package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.js +0 -18
  293. package/dist/src/tasks-runner/legacy-depends-on-warning.d.ts +0 -18
  294. package/dist/src/tasks-runner/legacy-depends-on-warning.js +0 -109
@@ -27,6 +27,7 @@ const text_1 = require("../text");
27
27
  const agent_output_1 = require("./agent-output");
28
28
  const agent_work_payload_1 = require("./agent-work-payload");
29
29
  const issues_1 = require("./issues");
30
+ const orchestrator_1 = require("./orchestrator");
30
31
  async function runSingleMigrationWorker(input) {
31
32
  const { root, runMigration, runId, commitPrefix, interactive, skipInstall, isVerbose, } = input;
32
33
  // The worker is a second CLI entry point: the run id reaches runDir() (where
@@ -35,24 +36,30 @@ async function runSingleMigrationWorker(input) {
35
36
  if (runId !== undefined && !run_id_1.RUN_ID_SAFE.test(runId)) {
36
37
  throw new Error(`Invalid run id '${runId}'.`);
37
38
  }
38
- const { migrations, source } = readMigrationsSource(root, runId);
39
+ const { migrations, source, singleMigration } = readMigrationsSource(root, runId);
39
40
  const migration = resolveMigration(migrations, runMigration, source);
40
- (0, migrate_analytics_1.reportMigrateSingleMigrationInvocation)({
41
- migrationType: (0, migration_shape_1.isPromptOnlyMigration)(migration)
42
- ? 'prompt'
43
- : (0, migration_shape_1.isHybridMigration)(migration)
44
- ? 'hybrid'
45
- : 'generator',
46
- orchestrated: !!runId,
47
- });
41
+ // A retry in the agent session of a `--run-migration` run belongs to the
42
+ // invocation that started that run, which already reported.
43
+ if (!singleMigration) {
44
+ (0, migrate_analytics_1.reportMigrateSingleMigrationInvocation)({
45
+ migrationType: (0, migration_shape_1.isPromptOnlyMigration)(migration)
46
+ ? 'prompt'
47
+ : (0, migration_shape_1.isHybridMigration)(migration)
48
+ ? 'hybrid'
49
+ : 'generator',
50
+ orchestrated: !!runId,
51
+ });
52
+ }
48
53
  if (runId) {
49
54
  // A recorded run takes its commit config from run.json and is driven by
50
55
  // the outer agent, so the standalone resolution below doesn't apply. That
51
56
  // includes the default-branch confirmation: the run decided once, at init,
52
57
  // whether to commit, and asking again would re-prompt on every step.
53
- await runRecorded(root, runId, migration, skipInstall, isVerbose);
58
+ await runRecorded(root, runId, migration, skipInstall, isVerbose, 'worker');
54
59
  return;
55
60
  }
61
+ // Before the agent selection, which may prompt.
62
+ (0, orchestrator_1.prepareSingleMigrationRun)(root);
56
63
  let agentic;
57
64
  try {
58
65
  agentic = await (0, select_1.resolveAgentic)({
@@ -65,6 +72,8 @@ async function runSingleMigrationWorker(input) {
65
72
  (0, migrate_analytics_1.reportMigrateRunError)({ code: 'agentic', error: e });
66
73
  throw e;
67
74
  }
75
+ // Resolved before the commit policy, which defaults on only for an agent.
76
+ agentic = (0, select_1.dropUnsupportedAgent)(agentic, (0, run_state_1.migrationIdProblems)([migration]));
68
77
  const resolved = (0, migrate_commits_1.resolveCreateCommits)({
69
78
  createCommits: input.createCommits,
70
79
  mode: agentic.kind,
@@ -78,19 +87,30 @@ async function runSingleMigrationWorker(input) {
78
87
  (0, agent_output_1.warnToAgent)({ title: resolved.warning });
79
88
  }
80
89
  const createCommits = resolved.effective;
81
- if (createCommits &&
82
- (0, safe_prompt_1.canPrompt)(interactive) &&
83
- !(await (0, migrate_commits_1.confirmMigrationCommitsOnDefaultBranch)(root, 'running the migration'))) {
90
+ const confirmStart = async () => !createCommits ||
91
+ !(0, safe_prompt_1.canPrompt)(interactive) ||
92
+ (await (0, migrate_commits_1.confirmMigrationCommitsOnDefaultBranch)(root, 'running the migration'));
93
+ if (agentic.kind === 'enabled') {
94
+ return runAgenticSingleMigration({
95
+ root,
96
+ migration,
97
+ agent: agentic.selectedAgent,
98
+ createCommits,
99
+ commitPrefix,
100
+ skipInstall,
101
+ isVerbose,
102
+ validate: input.validate,
103
+ confirmStart,
104
+ });
105
+ }
106
+ if (!(await confirmStart())) {
84
107
  return;
85
108
  }
86
109
  await runStandalone(root, migration, {
87
- agentic,
110
+ agenticKind: agentic.kind,
111
+ // Inside an agent, --agentic=false drops the review; prompts still go out.
112
+ validate: input.agentic === false ? false : input.validate,
88
113
  createCommits,
89
- agenticHasDiffContext: resolved.agenticHasDiffContext,
90
- shouldRunValidation: (0, select_1.resolveShouldRunValidation)({
91
- validate: input.validate,
92
- agenticKind: agentic.kind,
93
- }),
94
114
  commitPrefix,
95
115
  skipInstall,
96
116
  isVerbose,
@@ -123,6 +143,7 @@ function readMigrationsSource(root, runId) {
123
143
  return {
124
144
  migrations: readPlanMigrations(planPath),
125
145
  source: round.planSnapshot,
146
+ singleMigration: state.singleMigration === true,
126
147
  };
127
148
  }
128
149
  const migrationsPath = (0, path_1.join)(root, 'migrations.json');
@@ -155,160 +176,31 @@ function resolveMigration(migrations, id, source) {
155
176
  return matches[0];
156
177
  }
157
178
  async function runStandalone(root, migration, opts) {
158
- const { agentic, createCommits, commitPrefix, skipInstall, isVerbose } = opts;
159
- // Standalone never writes run state. Warn (don't block) when an orchestrated
160
- // run is active so the user knows this execution won't be recorded into it.
161
- // A newer-nx run dir must not hard-block this stateless path (the fail-closed
162
- // refusal in run-state.ts targets run-starting callers); tolerate it and skip
163
- // the warning. A failed scan can't block it either, but gets a warning of its
164
- // own: an active run may exist that this execution silently won't record into.
165
- let active;
166
- try {
167
- active = (0, run_state_1.findActiveRun)(root).active;
168
- }
169
- catch (e) {
170
- if (!(e instanceof run_state_1.NewerRunStateFormatError)) {
171
- (0, agent_output_1.warnToAgent)({
172
- title: `Could not check for an active migrate run: ${e instanceof Error ? e.message : e}`,
173
- });
174
- }
175
- active = null;
176
- }
177
- if (active) {
178
- (0, agent_output_1.warnToAgent)({
179
- title: `This migration won't be recorded into the active migrate run '${active.runId}'.`,
180
- bodyLines: [
181
- `Pass --run-id=${active.runId} to record it into that run instead.`,
182
- ],
183
- });
184
- }
179
+ const { agenticKind, createCommits, commitPrefix, skipInstall, isVerbose } = opts;
185
180
  if ((0, migration_shape_1.isPromptOnlyMigration)(migration)) {
186
- if (agentic.kind !== 'enabled') {
187
- // No agent to apply the prompt, so nothing runs: no checkpoint, no
188
- // commit.
189
- emitOrPrintPrompt(root, migration, agentic.kind);
190
- return;
191
- }
192
- // Checkpoint pre-existing working-tree state first, or the migration
193
- // commit's `git add -A` folds it in.
194
- if (createCommits) {
195
- (0, migrate_commits_1.commitCheckpointBeforeMigrations)(root, commitPrefix);
196
- }
197
- const agenticRun = await prepareAgenticRun(root, migration, agentic, createCommits, commitPrefix);
198
- const installer = new execute_migration_1.ChangedDepInstaller(root, skipInstall, (0, execute_migration_1.formatSingleMigrationRerunCommand)(`${migration.package}:${migration.name}`));
199
- const installDepsIfChanged = () => installer.installDepsIfChanged();
200
- const stepResult = await runAgenticStep(agenticRun, {
201
- root,
202
- migration,
203
- installDepsIfChanged,
204
- documentationPath: resolveDocumentationPath(root, migration),
205
- });
206
- await commitAndLogAgenticOutcome({
207
- root,
208
- migration,
209
- createCommits,
210
- commitPrefix,
211
- installDepsIfChanged,
212
- successLabel: 'Applied',
213
- stepResult,
214
- });
215
- if (installer.skippedInstall) {
216
- (0, execute_migration_1.logSkippedPostMigrationInstall)(root);
217
- }
181
+ // No agent to apply the prompt, so nothing runs: no checkpoint, no
182
+ // commit.
183
+ emitOrPrintPrompt(root, migration, agenticKind);
218
184
  return;
219
185
  }
186
+ // Checkpoint pre-existing working-tree state first, or the migration
187
+ // commit's `git add -A` folds it in.
220
188
  if (createCommits) {
221
189
  (0, migrate_commits_1.commitCheckpointBeforeMigrations)(root, commitPrefix);
222
190
  }
223
- const agenticRun = agentic.kind === 'enabled'
224
- ? await prepareAgenticRun(root, migration, agentic, createCommits, commitPrefix)
225
- : undefined;
226
191
  const installer = new execute_migration_1.ChangedDepInstaller(root, skipInstall, (0, execute_migration_1.formatSingleMigrationRerunCommand)(`${migration.package}:${migration.name}`));
227
- const installDepsIfChanged = () => installer.installDepsIfChanged();
228
- const validationRun = agenticRun && opts.shouldRunValidation ? agenticRun : undefined;
192
+ // The outer agent validates a generator-only migration's changes, as the
193
+ // validation pass of a recorded step would.
194
+ const shouldValidate = agenticKind === 'inside-agent' && opts.validate !== false;
229
195
  const resolvedCollection = (0, execute_migration_1.readMigrationCollection)(migration.package, root);
230
- const { changes, nextSteps, agentContext, skipAgentic, logs, madeChanges } = await (0, execute_migration_1.runNxOrAngularMigration)(root, migration, isVerbose, (0, migration_shape_1.isHybridMigration)(migration) || !!validationRun, resolvedCollection);
231
- // Whether an AI step was on the table for `skipAgentic` to waive. A hybrid
232
- // owes its prompt in every agentic mode; a generator-only migration owes
233
- // only the validation pass, and only where one would have run.
234
- const validationApplies = !!validationRun && changes.length > 0;
235
- const waivedAgenticStep = skipAgentic && ((0, migration_shape_1.isHybridMigration)(migration) || validationApplies);
236
- if ((0, migration_shape_1.isHybridMigration)(migration) && agenticRun && !skipAgentic) {
237
- // The prompt half may need the deps the generator half added, so install
238
- // before the agent runs.
239
- await installDepsIfChanged();
240
- const stepResult = await runAgenticStep(agenticRun, {
241
- root,
242
- migration,
243
- installDepsIfChanged,
244
- documentationPath: resolveDocumentationPath(root, migration, resolvedCollection),
245
- implContext: {
246
- logs,
247
- changes,
248
- agentContext,
249
- // No prior migrations run here, so unlike the classic loop there is no
250
- // pending-commit debt to suppress the git-inspect context for.
251
- hasDiffContext: opts.agenticHasDiffContext,
252
- },
253
- });
254
- await commitAndLogAgenticOutcome({
255
- root,
256
- migration,
257
- createCommits,
258
- commitPrefix,
259
- installDepsIfChanged,
260
- successLabel: 'Applied',
261
- stepResult,
262
- });
263
- if (installer.skippedInstall) {
264
- (0, execute_migration_1.logSkippedPostMigrationInstall)(root);
265
- }
266
- printNextSteps(migration, nextSteps);
267
- return;
268
- }
269
- if (validationApplies && !skipAgentic) {
270
- // Commit after validation: a failed validation throws, leaving the changes
271
- // in the working tree for review.
272
- await installDepsIfChanged();
273
- const stepResult = await runAgenticStep(validationRun, {
274
- root,
275
- migration,
276
- installDepsIfChanged,
277
- documentationPath: resolveDocumentationPath(root, migration, resolvedCollection),
278
- implContext: {
279
- logs,
280
- changes,
281
- agentContext,
282
- hasDiffContext: opts.agenticHasDiffContext,
283
- },
284
- mode: 'generic-validation',
285
- });
286
- await commitAndLogAgenticOutcome({
287
- root,
288
- migration,
289
- createCommits,
290
- commitPrefix,
291
- installDepsIfChanged,
292
- successLabel: 'Validation passed',
293
- stepResult,
294
- });
295
- if (installer.skippedInstall) {
296
- (0, execute_migration_1.logSkippedPostMigrationInstall)(root);
297
- }
298
- printNextSteps(migration, nextSteps);
299
- return;
300
- }
301
- if (waivedAgenticStep) {
302
- (0, migrate_output_1.logWaivedAgenticStep)(migration, agentContext);
303
- }
304
- else if (!(0, migration_shape_1.isHybridMigration)(migration)) {
305
- forwardDroppedAgentContext(migration, agentContext, agentic.kind);
306
- }
196
+ const { changes, nextSteps, agentContext, skipAgentic, logs, madeChanges } = await (0, execute_migration_1.runNxOrAngularMigration)(root, migration, isVerbose, (0, migration_shape_1.isHybridMigration)(migration) || shouldValidate, resolvedCollection);
197
+ const work = owedAgentWork(migration, shouldValidate, changes, skipAgentic);
198
+ logWaiverOrForwardAgentContext(migration, work, agentContext, agenticKind);
307
199
  // A no-op migration must not build a commit whose `git add -A` absorbs
308
200
  // unrelated pending diffs under its name. The commit path installs deps
309
201
  // itself, so the else branch does it here instead.
310
202
  if (createCommits && madeChanges) {
311
- await attemptStandaloneCommit(root, migration, createCommits, commitPrefix, installDepsIfChanged);
203
+ await (0, migrate_commits_1.commitMigrationIfRequested)(root, migration, createCommits, commitPrefix, () => installer.installDepsIfChanged(), [], 'manual');
312
204
  }
313
205
  else {
314
206
  await installer.installDepsIfChanged();
@@ -317,10 +209,13 @@ async function runStandalone(root, migration, opts) {
317
209
  (0, execute_migration_1.logSkippedPostMigrationInstall)(root);
318
210
  }
319
211
  printNextSteps(migration, nextSteps);
212
+ if (work.validationOwed) {
213
+ emitValidationBlock(root, migration, { logs, changes, agentContext }, { resolvedCollection });
214
+ }
320
215
  // A waived prompt is not deferred, so it gets no hand-off to an outer agent
321
216
  // and no "apply this manually" block for the user either.
322
- if ((0, migration_shape_1.isHybridMigration)(migration) && !skipAgentic) {
323
- emitOrPrintPrompt(root, migration, agentic.kind, {
217
+ if (work.promptOwed) {
218
+ emitOrPrintPrompt(root, migration, agenticKind, {
324
219
  impl: {
325
220
  logs,
326
221
  changes,
@@ -330,16 +225,160 @@ async function runStandalone(root, migration, opts) {
330
225
  });
331
226
  }
332
227
  }
333
- async function runRecorded(root, runId, migration, skipInstall, isVerbose) {
228
+ // Records the migration as a one-step run and runs its generator part here, as
229
+ // a dispensed worker would. The agent starts only for work the step hands
230
+ // back, and its first "next" gets that work.
231
+ async function runAgenticSingleMigration(input) {
232
+ const { root, migration, agent, createCommits, skipInstall } = input;
233
+ const migrationId = `${migration.package}:${migration.name}`;
234
+ const ready = await (0, orchestrator_1.runOrchestratorInit)({
235
+ root,
236
+ migrationsJson: { migrations: [migration] },
237
+ createCommits,
238
+ commitPrefix: input.commitPrefix,
239
+ skipInstall,
240
+ installedNxVersion: (0, package_json_1.readModulePackageJson)('nx', (0, installation_directory_1.getNxRequirePaths)(root))
241
+ .packageJson.version,
242
+ validate: input.validate,
243
+ finalValidation: false,
244
+ emitAgentInstructions: false,
245
+ singleMigration: true,
246
+ confirmStart: input.confirmStart,
247
+ });
248
+ switch (ready.kind) {
249
+ case 'refused':
250
+ return;
251
+ case 'existing-run':
252
+ throw new Error(`A --run-migration run never reports an active run, but init reported '${ready.runId}'.`);
253
+ case 'ready':
254
+ break;
255
+ default: {
256
+ const unhandled = ready;
257
+ throw new Error(`Unhandled init result: ${JSON.stringify(unhandled)}`);
258
+ }
259
+ }
260
+ const { runId } = ready;
261
+ try {
262
+ (0, orchestrator_1.dispenseSingleMigrationStep)(root, runId);
263
+ const parked = await runRecorded(root, runId, migration, skipInstall, input.isVerbose, 'single-run-parent');
264
+ if (!parked) {
265
+ (0, agent_output_1.logToAgent)({ title: `Migration ${migrationId} is complete.` });
266
+ warnAboutLeftovers(root, runId, (0, run_state_1.readRunState)((0, run_state_1.runDir)(root, runId)));
267
+ (0, migrate_analytics_1.reportMigrateSingleMigrationComplete)({});
268
+ return;
269
+ }
270
+ (0, agent_output_1.logToAgent)({
271
+ title: `Starting ${agent.displayName} for migration ${migrationId}.`,
272
+ });
273
+ const { driveMasterSession } = require('../agentic/master/run-master-session');
274
+ const rerunHint = `Migration ${migrationId} did not finish. Re-run the same command to run it again.`;
275
+ const state = await driveMasterSession({
276
+ agent,
277
+ ready,
278
+ policy: { createCommits, skipInstall },
279
+ migration,
280
+ notStartedHint: rerunHint,
281
+ });
282
+ if (!state)
283
+ return 1;
284
+ switch (state.status) {
285
+ case 'active':
286
+ (0, migrate_analytics_1.reportMigrateSingleMigrationAbandoned)({ agentUsed: agent.id });
287
+ (0, agent_output_1.warnToAgent)({ title: rerunHint });
288
+ return 1;
289
+ case 'completed': {
290
+ const unresolved = logSingleMigrationOutcome(state, migrationId);
291
+ warnAboutLeftovers(root, runId, state);
292
+ (0, migrate_analytics_1.reportMigrateSingleMigrationComplete)({ agentUsed: agent.id });
293
+ return unresolved ? 1 : undefined;
294
+ }
295
+ default: {
296
+ const unhandled = state.status;
297
+ throw new Error(`Unhandled migrate run status: ${unhandled}`);
298
+ }
299
+ }
300
+ }
301
+ finally {
302
+ (0, state_lock_1.withRunCreationLock)(root, () => (0, orchestrator_1.removeSingleMigrationRun)(root, runId));
303
+ }
304
+ }
305
+ function warnAboutLeftovers(root, runId, state) {
306
+ for (const lines of (0, orchestrator_1.completionWarnings)(root, runId, state)) {
307
+ (0, agent_output_1.warnToAgent)({ title: lines[0], bodyLines: lines.slice(1) });
308
+ }
309
+ }
310
+ // The record is removed next, so the closing output carries the settling
311
+ // summary and commit. Returns whether the migration was left unresolved.
312
+ function logSingleMigrationOutcome(state, migrationId) {
313
+ const [step] = state.steps;
314
+ const sha = (0, orchestrator_1.lastCoveringLandedEntry)(state, step)?.sha;
315
+ const outcomeLines = (summary) => [
316
+ ...(summary?.trim() ? [summary] : []),
317
+ ...(sha ? [`Commit: ${sha}`] : []),
318
+ ];
319
+ switch (step.status) {
320
+ case 'succeeded':
321
+ (0, agent_output_1.logToAgent)({
322
+ title: `Migration ${migrationId} is complete.`,
323
+ // Adopt writes outcome.summary; promptOutcome still holds the failed
324
+ // handoff.
325
+ bodyLines: outcomeLines(step.adopted
326
+ ? step.outcome?.summary
327
+ : (step.promptOutcome?.summary ?? step.outcome?.summary)),
328
+ });
329
+ return false;
330
+ case 'skipped':
331
+ (0, agent_output_1.logToAgent)({
332
+ title: `Migration ${migrationId} was skipped.`,
333
+ // After a --step-action skip, promptOutcome is the failed handoff's.
334
+ bodyLines: outcomeLines(step.promptOutcome?.status === 'skipped'
335
+ ? step.promptOutcome.summary
336
+ : undefined),
337
+ });
338
+ return false;
339
+ case 'unresolved':
340
+ (0, agent_output_1.errorToAgent)({
341
+ title: `Migration ${migrationId} is unresolved.`,
342
+ bodyLines: outcomeLines((0, state_machine_1.unresolvedFailureDetail)(step)),
343
+ });
344
+ return true;
345
+ case 'pending':
346
+ case 'dispensed':
347
+ case 'running':
348
+ case 'awaiting-prompt-outcome':
349
+ case 'failed':
350
+ case 'died':
351
+ throw new Error(`Migrate run completed with migration ${migrationId} in status '${step.status}'.`);
352
+ default: {
353
+ const unhandled = step.status;
354
+ throw new Error(`Unhandled step status: ${unhandled}`);
355
+ }
356
+ }
357
+ }
358
+ // 'worker': a dispensed command, whose output the agent driving the run reads.
359
+ // 'single-run-parent': the first attempt of a `--run-migration` run's step, run
360
+ // by the process that starts the agent only afterwards. Returns whether the
361
+ // step was parked for an agent.
362
+ async function runRecorded(root, runId, migration, skipInstall, isVerbose, caller) {
334
363
  const dir = (0, run_state_1.runDir)(root, runId);
335
364
  // Version refusal (NewerRunStateFormatError) propagates.
336
365
  let state = (0, run_state_1.readRunState)(dir);
337
- // A recorded run never resolves the agentic flow: the outer agent drives it,
366
+ // A worker never resolves the agentic flow: the outer agent drives the run,
338
367
  // and the dispensed command is part of the orchestrated protocol whoever
339
368
  // re-runs it. Gating the block on ambient agent detection would park the
340
- // step awaiting an outcome whose payload was never emitted.
341
- const agenticKind = 'inside-agent';
369
+ // step awaiting an outcome whose payload was never emitted. The parent of a
370
+ // `--run-migration` run stores the work it hands back without printing it:
371
+ // its agent gets that work from the first "next".
372
+ const emitsHandBack = caller === 'worker';
373
+ const agenticKind = emitsHandBack
374
+ ? 'inside-agent'
375
+ : 'enabled';
342
376
  const migrationId = `${migration.package}:${migration.name}`;
377
+ // The parent's run is removed when it ends, so its hint is the command the
378
+ // user ran.
379
+ const rerunCommand = emitsHandBack
380
+ ? `${(0, execute_migration_1.formatSingleMigrationRerunCommand)(migrationId)} --run-id=${runId}`
381
+ : (0, execute_migration_1.formatSingleMigrationRerunCommand)(migrationId);
343
382
  // The plan was read from the latest round's snapshot, so only that round's
344
383
  // step may match; a same-id step from an older round must not.
345
384
  const latest = (0, state_machine_1.latestRound)(state);
@@ -375,16 +414,17 @@ async function runRecorded(root, runId, migration, skipInstall, isVerbose) {
375
414
  const scope = {};
376
415
  // Called before a retry hands the step's work back: the prompt or validation
377
416
  // may need the dependencies the earlier attempt's generator added.
378
- const reinstallFromBaseline = () => (0, broker_1.installStepTree)(dir, startedStep, 'install', () => recordingInstallFailure(dir, step.id, () => (0, util_1.installDepsChangedSinceDispense)(root, dir, startedStep, effectiveSkipInstall, `${(0, execute_migration_1.formatSingleMigrationRerunCommand)(migrationId)} --run-id=${runId}`)), scope);
417
+ const reinstallFromBaseline = () => (0, broker_1.installStepTree)(dir, startedStep, 'install', () => recordingInstallFailure(dir, step.id, () => (0, util_1.installDepsChangedSinceDispense)(root, dir, startedStep, effectiveSkipInstall, rerunCommand)), scope);
379
418
  let outcome;
380
419
  let awaitingKind;
381
420
  const payloadPath = (0, agent_work_payload_1.agentWorkPayloadPath)(dir, step.id, startedStep.attempt);
382
421
  try {
383
422
  try {
384
423
  if ((0, migration_shape_1.isPromptOnlyMigration)(migration)) {
385
- emitOrPrintPrompt(root, migration, agenticKind, {
386
- persistPath: payloadPath,
387
- });
424
+ const payload = promptPayload(root, migration, undefined, undefined);
425
+ (0, agent_work_payload_1.persistAgentWorkPayload)(payloadPath, payload);
426
+ if (emitsHandBack)
427
+ emitPromptForOuterAgent(migrationId, payload, true);
388
428
  awaitingKind = 'migration-prompt';
389
429
  }
390
430
  else if (generatorAlreadyCompleted &&
@@ -424,39 +464,30 @@ async function runRecorded(root, runId, migration, skipInstall, isVerbose) {
424
464
  awaitingKind = 'generator-validation';
425
465
  }
426
466
  else if (generatorAlreadyCompleted) {
427
- state = await finishCompletedGenerator(dir, root, state, startedStep, migration, effectiveSkipInstall, runId, scope);
467
+ state = await finishCompletedGenerator(dir, root, state, startedStep, migration, effectiveSkipInstall, rerunCommand, scope);
428
468
  outcome = buildOutcome([], [], 'The generator ran in an earlier attempt; this attempt completed its install and commit.', root);
429
469
  }
430
470
  else {
431
- const installer = new execute_migration_1.ChangedDepInstaller(root, effectiveSkipInstall, `${(0, execute_migration_1.formatSingleMigrationRerunCommand)(migrationId)} --run-id=${runId}`);
471
+ const installer = new execute_migration_1.ChangedDepInstaller(root, effectiveSkipInstall, rerunCommand);
432
472
  // Read once; the run and the hybrid documentation resolution share it.
433
473
  const resolvedCollection = (0, execute_migration_1.readMigrationCollection)(migration.package, root);
434
474
  const { changes, nextSteps, agentContext, skipAgentic, logs, madeChanges, } = await (0, execute_migration_1.runNxOrAngularMigration)(root, migration, isVerbose,
435
475
  // Captured whenever an agent step may consume it: a hybrid's prompt
436
476
  // payload, or the validation pass over the generator's changes.
437
477
  (0, migration_shape_1.isHybridMigration)(migration) || shouldValidate, resolvedCollection);
438
- // Mirrors the classic loop's waiver semantics (migrate.ts): the two must
439
- // agree on when an AI step was owed for skipAgentic to waive.
440
- const validationApplies = shouldValidate && !(0, migration_shape_1.isHybridMigration)(migration) && changes.length > 0;
441
- const waivedAgenticStep = skipAgentic && ((0, migration_shape_1.isHybridMigration)(migration) || validationApplies);
442
- const validationOwed = validationApplies && !waivedAgenticStep;
443
- const promptOwed = (0, migration_shape_1.isHybridMigration)(migration) && !waivedAgenticStep;
478
+ const work = owedAgentWork(migration, shouldValidate, changes, skipAgentic);
479
+ const { validationOwed, promptOwed } = work;
444
480
  // Recorded before the commit is attempted: from here on the changes are
445
481
  // in the tree, so a failed install or commit must leave a retry with
446
482
  // only those left to do rather than running the generator again.
447
483
  state = transition(dir, {
448
484
  type: 'markGeneratorCompleted',
449
485
  stepId: step.id,
450
- agenticWaived: waivedAgenticStep,
486
+ agenticWaived: work.waived,
451
487
  validationOwed,
452
488
  madeChanges,
453
489
  });
454
- if (waivedAgenticStep) {
455
- (0, migrate_output_1.logWaivedAgenticStep)(migration, agentContext);
456
- }
457
- else if (!(0, migration_shape_1.isHybridMigration)(migration) && !validationApplies) {
458
- forwardDroppedAgentContext(migration, agentContext, agenticKind);
459
- }
490
+ logWaiverOrForwardAgentContext(migration, work, agentContext, agenticKind);
460
491
  // Stored before the install: a failed install fails the attempt, and
461
492
  // the retry re-hands this payload instead of a context-free one.
462
493
  const impl = { logs, changes, agentContext };
@@ -490,11 +521,13 @@ async function runRecorded(root, runId, migration, skipInstall, isVerbose) {
490
521
  }
491
522
  printNextSteps(migration, nextSteps);
492
523
  if (validationOwed) {
493
- emitValidationPayload(migrationId, owed);
524
+ if (emitsHandBack)
525
+ emitValidationPayload(migrationId, owed, true);
494
526
  awaitingKind = 'generator-validation';
495
527
  }
496
528
  else if (promptOwed) {
497
- emitPromptForOuterAgent(migrationId, owed, true);
529
+ if (emitsHandBack)
530
+ emitPromptForOuterAgent(migrationId, owed, true);
498
531
  awaitingKind = 'migration-prompt';
499
532
  }
500
533
  else {
@@ -525,7 +558,7 @@ async function runRecorded(root, runId, migration, skipInstall, isVerbose) {
525
558
  finishedAt: (0, util_1.nowIso)(),
526
559
  awaitingKind,
527
560
  });
528
- return;
561
+ return true;
529
562
  }
530
563
  transition(dir, {
531
564
  type: 'succeed',
@@ -533,6 +566,7 @@ async function runRecorded(root, runId, migration, skipInstall, isVerbose) {
533
566
  finishedAt: (0, util_1.nowIso)(),
534
567
  ...(outcome ? { outcome } : {}),
535
568
  });
569
+ return false;
536
570
  }
537
571
  finally {
538
572
  scope.lease?.release();
@@ -569,9 +603,8 @@ async function recordingInstallFailure(dir, stepId, install) {
569
603
  // on the install or the commit. The generator's changes are already in the
570
604
  // tree, so only those two are left, and the install compares against the
571
605
  // step's persisted baseline rather than against what that generator wrote.
572
- async function finishCompletedGenerator(dir, root, state, step, migration, skipInstall, runId, scope) {
573
- const migrationId = `${migration.package}:${migration.name}`;
574
- const installDeps = () => recordingInstallFailure(dir, step.id, () => (0, util_1.installDepsChangedSinceDispense)(root, dir, step, skipInstall, `${(0, execute_migration_1.formatSingleMigrationRerunCommand)(migrationId)} --run-id=${runId}`));
606
+ async function finishCompletedGenerator(dir, root, state, step, migration, skipInstall, rerunCommand, scope) {
607
+ const installDeps = () => recordingInstallFailure(dir, step.id, () => (0, util_1.installDepsChangedSinceDispense)(root, dir, step, skipInstall, rerunCommand));
575
608
  // Same no-op guard as the first attempt. Only an explicit false skips the
576
609
  // commit: absent means an older nx wrote the marker without recording the
577
610
  // answer, and the commit is kept as that version's retries did.
@@ -587,9 +620,10 @@ async function finishCompletedGenerator(dir, root, state, step, migration, skipI
587
620
  // ledger entry and the commit body name the same ones.
588
621
  async function commitStepChanges(dir, root, state, step, migration, installDeps, scope) {
589
622
  const absorbedStepIds = (0, state_machine_1.uncoveredFailedStepIds)(state).filter((id) => id !== step.id);
623
+ const recovery = (0, util_1.commitFailureRecovery)(state);
590
624
  let commit;
591
625
  try {
592
- commit = await (0, broker_1.commitStepTree)(dir, step, absorbedStepIds, () => (0, migrate_commits_1.commitMigrationIfRequested)(root, migration, true, state.commitPrefix, installDeps, (0, state_machine_1.stepsToPendingMigrations)(state, absorbedStepIds)), scope);
626
+ commit = await (0, broker_1.commitStepTree)(dir, step, absorbedStepIds, () => (0, migrate_commits_1.commitMigrationIfRequested)(root, migration, true, state.commitPrefix, installDeps, (0, state_machine_1.stepsToPendingMigrations)(state, absorbedStepIds), recovery), scope);
593
627
  }
594
628
  catch (commitError) {
595
629
  // Nothing ran for a stale or refused request, so there is no debt.
@@ -603,7 +637,7 @@ async function commitStepChanges(dir, root, state, step, migration, installDeps,
603
637
  throw commitError;
604
638
  }
605
639
  if (commit.result.status === 'failed') {
606
- (0, util_1.warnCommitFailed)(migration.name);
640
+ (0, util_1.warnCommitFailed)(migration.name, recovery);
607
641
  }
608
642
  const entry = (0, state_machine_1.commitResultToLedgerEntry)(commit.result, step.id, commit.absorbedStepIds);
609
643
  // A session's parent records what it commits itself, receipt included.
@@ -634,61 +668,27 @@ function buildOutcome(changes, nextSteps, description, root) {
634
668
  }
635
669
  return outcome;
636
670
  }
637
- // Only `run-step` is actually deferred by these requires, and it is the one
638
- // worth deferring: it pulls in the prompt builders, which nothing but an
639
- // enabled agentic flow needs. The other two are loaded either way, since the
640
- // `run/` barrel every caller comes through re-exports `orchestrator.ts`, which
641
- // imports both statically.
642
- async function prepareAgenticRun(root, migration, agentic, effectiveCreateCommits, commitPrefix) {
643
- const { applyAgenticHandoffGitignoreFallback } = require('../agentic/handoff-gitignore');
644
- const { packageJson: nxPackageJson } = (0, package_json_1.readModulePackageJson)('nx', (0, installation_directory_1.getNxRequirePaths)(root));
645
- await applyAgenticHandoffGitignoreFallback({
646
- migrations: [migration],
647
- installedNxVersion: nxPackageJson.version,
648
- effectiveCreateCommits,
649
- commitPrefix,
650
- root,
651
- });
652
- const { initRunDir, resolveAgenticRunId } = require('../agentic/handoff');
653
- const { runAgenticPromptStep } = require('../agentic/run-step');
671
+ // `skipAgentic` counts as a waiver only when an AI step was owed.
672
+ function owedAgentWork(migration, shouldValidate, changes, skipAgentic) {
673
+ const hybrid = (0, migration_shape_1.isHybridMigration)(migration);
674
+ const validationApplies = shouldValidate && !hybrid && changes.length > 0;
675
+ const waived = skipAgentic && (hybrid || validationApplies);
654
676
  return {
655
- agentic,
656
- runDir: initRunDir(root, resolveAgenticRunId([migration])),
657
- runStep: runAgenticPromptStep,
677
+ waived,
678
+ validationOwed: validationApplies && !waived,
679
+ promptOwed: hybrid && !waived,
658
680
  };
659
681
  }
660
- async function runAgenticStep(agenticRun, input) {
661
- try {
662
- return await agenticRun.runStep({
663
- ...input,
664
- agentic: agenticRun.agentic,
665
- runDir: agenticRun.runDir,
666
- });
667
- }
668
- catch (e) {
669
- (0, migrate_analytics_1.reportMigrateRunError)({
670
- code: 'agentic',
671
- migrationPackage: input.migration.package,
672
- migrationName: input.migration.name,
673
- error: e,
674
- });
675
- throw e;
682
+ // Agent work payloads already carry `agentContext`; forward it separately
683
+ // only when an outer agent has no owed work.
684
+ function logWaiverOrForwardAgentContext(migration, work, agentContext, agenticKind) {
685
+ if (work.waived) {
686
+ (0, migrate_output_1.logWaivedAgenticStep)(migration, agentContext);
676
687
  }
677
- }
678
- // A standalone run has no later commit or end-of-run recap to absorb a failed
679
- // commit's diff, so it passes its own guidance instead of the default.
680
- // `commitMigrationIfRequested` logs a failed commit itself with that guidance.
681
- function attemptStandaloneCommit(root, migration, createCommits, commitPrefix, installDepsIfChanged) {
682
- return (0, migrate_commits_1.commitMigrationIfRequested)(root, migration, createCommits, commitPrefix, installDepsIfChanged, [], 'Commit or revert any remaining uncommitted changes manually.');
683
- }
684
- async function commitAndLogAgenticOutcome(args) {
685
- const commit = await attemptStandaloneCommit(args.root, args.migration, args.createCommits, args.commitPrefix, args.installDepsIfChanged);
686
- (0, migrate_output_1.logAgenticSuccessOutcome)(args.stepResult.ambiguous ? 'Marked complete by user' : args.successLabel, commit.status === 'committed' ? commit.sha : null, args.stepResult.summary);
687
- }
688
- // Hybrids are excluded by the caller: their `agentContext` rides in the
689
- // prompt payload instead.
690
- function forwardDroppedAgentContext(migration, agentContext, agenticKind) {
691
- if (agentContext.length > 0 && agenticKind === 'inside-agent') {
688
+ else if (!work.validationOwed &&
689
+ !work.promptOwed &&
690
+ agentContext.length > 0 &&
691
+ agenticKind === 'inside-agent') {
692
692
  (0, print_dropped_agent_context_1.printDroppedAgentContextForOuterAgent)({ migration, agentContext });
693
693
  }
694
694
  }
@@ -797,13 +797,15 @@ function emitValidationBlock(root, migration, impl, opts = {}) {
797
797
  if (opts.persistPath) {
798
798
  (0, agent_work_payload_1.persistAgentWorkPayload)(opts.persistPath, payload);
799
799
  }
800
- emitValidationPayload(`${migration.package}:${migration.name}`, payload);
800
+ emitValidationPayload(`${migration.package}:${migration.name}`, payload, opts.persistPath !== undefined);
801
801
  }
802
- function emitValidationPayload(migrationId, payload) {
802
+ function emitValidationPayload(migrationId, payload, recorded) {
803
803
  (0, agent_output_1.logToAgent)({
804
- title: payload.impl !== undefined
805
- ? `The following migration's generator ran without an AI-driven part. ${RUN_NEXT_FIRST}`
806
- : `${CHANGES_AWAIT_VALIDATION} ${RUN_NEXT_FIRST} Inspect the changes with git.`,
804
+ title: payload.impl === undefined
805
+ ? `${CHANGES_AWAIT_VALIDATION} ${RUN_NEXT_FIRST} Inspect the changes with git.`
806
+ : `The following migration's generator ran without an AI-driven part. ${recorded
807
+ ? RUN_NEXT_FIRST
808
+ : "Validate its changes in this workspace, fixing only what lies within the migration's scope, then continue."}`,
807
809
  });
808
810
  (0, agent_output_1.emitPromptBlock)(migrationId, payload);
809
811
  }