@depup/nx 23.2.1-depup.8 → 23.3.0-depup.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 (350) hide show
  1. package/README.md +7 -18
  2. package/changes.json +9 -53
  3. package/dist/bin/init-local.js +7 -1
  4. package/dist/nx-cloud-internals.d.ts +1 -0
  5. package/dist/nx-cloud-internals.js +9 -0
  6. package/dist/plugins/package-json.js +1 -1
  7. package/dist/src/command-line/add/add.js +5 -1
  8. package/dist/src/command-line/affected/affected.js +70 -9
  9. package/dist/src/command-line/affected/command-object.js +1 -1
  10. package/dist/src/command-line/format/format.js +2 -18
  11. package/dist/src/command-line/graph/graph.d.ts +31 -0
  12. package/dist/src/command-line/graph/graph.js +113 -20
  13. package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +0 -3
  14. package/dist/src/command-line/init/implementation/add-nx-to-nest.js +0 -3
  15. package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +0 -3
  16. package/dist/src/command-line/init/implementation/angular/index.js +0 -3
  17. package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +0 -3
  18. package/dist/src/command-line/init/implementation/format.js +2 -3
  19. package/dist/src/command-line/init/implementation/utils.d.ts +0 -1
  20. package/dist/src/command-line/init/implementation/utils.js +6 -9
  21. package/dist/src/command-line/init/init-v2.js +0 -3
  22. package/dist/src/command-line/migrate/agentic/capture-generator-output.d.ts +25 -0
  23. package/dist/src/command-line/migrate/agentic/capture-generator-output.js +121 -5
  24. package/dist/src/command-line/migrate/agentic/close-agent-session.d.ts +21 -0
  25. package/dist/src/command-line/migrate/agentic/close-agent-session.js +126 -0
  26. package/dist/src/command-line/migrate/agentic/definitions.d.ts +24 -0
  27. package/dist/src/command-line/migrate/agentic/definitions.js +79 -20
  28. package/dist/src/command-line/migrate/agentic/format-command.d.ts +14 -0
  29. package/dist/src/command-line/migrate/agentic/format-command.js +44 -0
  30. package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +3 -3
  31. package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +3 -3
  32. package/dist/src/command-line/migrate/agentic/handoff.d.ts +50 -17
  33. package/dist/src/command-line/migrate/agentic/handoff.js +166 -24
  34. package/dist/src/command-line/migrate/agentic/instruction-files.d.ts +23 -0
  35. package/dist/src/command-line/migrate/agentic/instruction-files.js +41 -0
  36. package/dist/src/command-line/migrate/agentic/master/invocations.d.ts +12 -0
  37. package/dist/src/command-line/migrate/agentic/master/invocations.js +54 -0
  38. package/dist/src/command-line/migrate/agentic/master/run-master-session.d.ts +16 -0
  39. package/dist/src/command-line/migrate/agentic/master/run-master-session.js +175 -0
  40. package/dist/src/command-line/migrate/agentic/master/spawn-master.d.ts +31 -0
  41. package/dist/src/command-line/migrate/agentic/master/spawn-master.js +222 -0
  42. package/dist/src/command-line/migrate/agentic/prompts/final-validation.d.ts +13 -0
  43. package/dist/src/command-line/migrate/agentic/prompts/final-validation.js +41 -0
  44. package/dist/src/command-line/migrate/agentic/prompts/fragments.d.ts +17 -0
  45. package/dist/src/command-line/migrate/agentic/prompts/fragments.js +90 -0
  46. package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +4 -3
  47. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +25 -1
  48. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +57 -34
  49. package/dist/src/command-line/migrate/agentic/run-step.js +28 -4
  50. package/dist/src/command-line/migrate/agentic/runner.d.ts +3 -15
  51. package/dist/src/command-line/migrate/agentic/runner.js +57 -239
  52. package/dist/src/command-line/migrate/agentic/terminal-repair.d.ts +1 -0
  53. package/dist/src/command-line/migrate/agentic/terminal-repair.js +27 -0
  54. package/dist/src/command-line/migrate/agentic/types.d.ts +23 -8
  55. package/dist/src/command-line/migrate/agentic/types.js +10 -7
  56. package/dist/src/command-line/migrate/agentic/windows-cmd.d.ts +33 -0
  57. package/dist/src/command-line/migrate/agentic/windows-cmd.js +88 -0
  58. package/dist/src/command-line/migrate/command-object.d.ts +2 -0
  59. package/dist/src/command-line/migrate/command-object.js +11 -1
  60. package/dist/src/command-line/migrate/deferred-output.d.ts +44 -0
  61. package/dist/src/command-line/migrate/deferred-output.js +92 -0
  62. package/dist/src/command-line/migrate/execute-migration.d.ts +9 -3
  63. package/dist/src/command-line/migrate/execute-migration.js +53 -16
  64. package/dist/src/command-line/migrate/migrate-analytics.d.ts +34 -9
  65. package/dist/src/command-line/migrate/migrate-analytics.js +71 -10
  66. package/dist/src/command-line/migrate/migrate-commits.d.ts +5 -4
  67. package/dist/src/command-line/migrate/migrate-commits.js +16 -6
  68. package/dist/src/command-line/migrate/migrate-config.d.ts +5 -2
  69. package/dist/src/command-line/migrate/migrate-config.js +19 -11
  70. package/dist/src/command-line/migrate/migrate-output.d.ts +3 -7
  71. package/dist/src/command-line/migrate/migrate-output.js +3 -7
  72. package/dist/src/command-line/migrate/migrate.d.ts +3 -0
  73. package/dist/src/command-line/migrate/migrate.js +183 -46
  74. package/dist/src/command-line/migrate/resolve-package-version.js +2 -19
  75. package/dist/src/command-line/migrate/run/agent-output.d.ts +11 -0
  76. package/dist/src/command-line/migrate/run/agent-output.js +21 -2
  77. package/dist/src/command-line/migrate/run/agent-work-payload.d.ts +37 -0
  78. package/dist/src/command-line/migrate/run/agent-work-payload.js +156 -0
  79. package/dist/src/command-line/migrate/run/atomic-write.d.ts +8 -0
  80. package/dist/src/command-line/migrate/run/atomic-write.js +17 -0
  81. package/dist/src/command-line/migrate/run/broker.d.ts +150 -0
  82. package/dist/src/command-line/migrate/run/broker.js +568 -0
  83. package/dist/src/command-line/migrate/run/clean-retry.d.ts +12 -0
  84. package/dist/src/command-line/migrate/run/clean-retry.js +99 -0
  85. package/dist/src/command-line/migrate/run/existing-run-report.d.ts +55 -0
  86. package/dist/src/command-line/migrate/run/existing-run-report.js +227 -0
  87. package/dist/src/command-line/migrate/run/give-up.d.ts +41 -0
  88. package/dist/src/command-line/migrate/run/give-up.js +148 -0
  89. package/dist/src/command-line/migrate/run/index.d.ts +9 -6
  90. package/dist/src/command-line/migrate/run/index.js +21 -2
  91. package/dist/src/command-line/migrate/run/issues.d.ts +127 -0
  92. package/dist/src/command-line/migrate/run/issues.js +1121 -0
  93. package/dist/src/command-line/migrate/run/orchestrator.d.ts +59 -1
  94. package/dist/src/command-line/migrate/run/orchestrator.js +1529 -457
  95. package/dist/src/command-line/migrate/run/run-id.d.ts +0 -8
  96. package/dist/src/command-line/migrate/run/run-id.js +0 -30
  97. package/dist/src/command-line/migrate/run/run-state.d.ts +77 -17
  98. package/dist/src/command-line/migrate/run/run-state.js +263 -32
  99. package/dist/src/command-line/migrate/run/runbook.d.ts +18 -0
  100. package/dist/src/command-line/migrate/run/runbook.js +118 -0
  101. package/dist/src/command-line/migrate/run/state-lock.d.ts +33 -2
  102. package/dist/src/command-line/migrate/run/state-lock.js +128 -2
  103. package/dist/src/command-line/migrate/run/state-machine.d.ts +50 -1
  104. package/dist/src/command-line/migrate/run/state-machine.js +339 -26
  105. package/dist/src/command-line/migrate/run/util.d.ts +3 -1
  106. package/dist/src/command-line/migrate/run/util.js +24 -3
  107. package/dist/src/command-line/migrate/run/worker.js +290 -129
  108. package/dist/src/command-line/migrate/step-actions.d.ts +1 -1
  109. package/dist/src/command-line/migrate/step-actions.js +7 -1
  110. package/dist/src/command-line/migrate/text.d.ts +6 -0
  111. package/dist/src/command-line/migrate/text.js +25 -0
  112. package/dist/src/command-line/migrate/version-skew-guard.js +2 -0
  113. package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +5 -11
  114. package/dist/src/command-line/release/publish.js +11 -8
  115. package/dist/src/command-line/release/utils/get-touched-projects-for-group.js +3 -3
  116. package/dist/src/command-line/release/utils/release-graph.js +1 -1
  117. package/dist/src/command-line/release/utils/remote-release-clients/github.js +5 -8
  118. package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +3 -3
  119. package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.d.ts +4 -2
  120. package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.js +37 -3
  121. package/dist/src/command-line/release/version/version-actions.d.ts +3 -0
  122. package/dist/src/command-line/reset/reset.js +10 -4
  123. package/dist/src/command-line/run/run-one.js +5 -1
  124. package/dist/src/command-line/run-many/run-many.js +6 -12
  125. package/dist/src/command-line/show/command-object.js +1 -1
  126. package/dist/src/command-line/show/projects.js +52 -1
  127. package/dist/src/command-line/yargs-utils/shared-options.d.ts +5 -1
  128. package/dist/src/command-line/yargs-utils/shared-options.js +38 -4
  129. package/dist/src/config/task-graph.d.ts +1 -1
  130. package/dist/src/config/workspace-json-project-json.d.ts +23 -1
  131. package/dist/src/core/graph/main.js +1 -1
  132. package/dist/src/core/graph/runtime.js +1 -1
  133. package/dist/src/core/graph/styles.js +1 -1
  134. package/dist/src/daemon/client/client.d.ts +14 -8
  135. package/dist/src/daemon/client/client.js +41 -12
  136. package/dist/src/daemon/message-types/get-plugin-capabilities.d.ts +5 -0
  137. package/dist/src/daemon/message-types/get-plugin-capabilities.js +11 -0
  138. package/dist/src/daemon/message-types/run-tasks-execution-hooks.d.ts +3 -2
  139. package/dist/src/daemon/message-types/select-affected-tasks.d.ts +21 -0
  140. package/dist/src/daemon/message-types/select-affected-tasks.js +11 -0
  141. package/dist/src/daemon/message-types/ultracache-configuration-version.d.ts +8 -0
  142. package/dist/src/daemon/message-types/ultracache-configuration-version.js +2 -0
  143. package/dist/src/daemon/server/dotenv-graph-changes.d.ts +1 -1
  144. package/dist/src/daemon/server/dotenv-graph-changes.js +2 -2
  145. package/dist/src/daemon/server/handle-get-plugin-capabilities.d.ts +2 -0
  146. package/dist/src/daemon/server/handle-get-plugin-capabilities.js +13 -0
  147. package/dist/src/daemon/server/handle-hash-tasks.d.ts +10 -2
  148. package/dist/src/daemon/server/handle-hash-tasks.js +18 -3
  149. package/dist/src/daemon/server/handle-select-affected-tasks.d.ts +3 -0
  150. package/dist/src/daemon/server/handle-select-affected-tasks.js +26 -0
  151. package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +3 -2
  152. package/dist/src/daemon/server/{handle-outputs-changes.d.ts → handle-watch-events.d.ts} +4 -4
  153. package/dist/src/daemon/server/{handle-outputs-changes.js → handle-watch-events.js} +36 -37
  154. package/dist/src/daemon/server/outputs-tracking.d.ts +7 -19
  155. package/dist/src/daemon/server/outputs-tracking.js +7 -107
  156. package/dist/src/daemon/server/planning-context.d.ts +8 -0
  157. package/dist/src/daemon/server/planning-context.js +18 -0
  158. package/dist/src/daemon/server/project-graph-incremental-recomputation.d.ts +22 -7
  159. package/dist/src/daemon/server/project-graph-incremental-recomputation.js +104 -74
  160. package/dist/src/daemon/server/restart-checks.d.ts +22 -0
  161. package/dist/src/daemon/server/restart-checks.js +77 -0
  162. package/dist/src/daemon/server/server.d.ts +1 -0
  163. package/dist/src/daemon/server/server.js +54 -30
  164. package/dist/src/daemon/server/shutdown-utils.d.ts +0 -5
  165. package/dist/src/daemon/server/shutdown-utils.js +3 -26
  166. package/dist/src/daemon/server/ultracache-configuration-state.d.ts +7 -0
  167. package/dist/src/daemon/server/ultracache-configuration-state.js +36 -0
  168. package/dist/src/devkit-internals.d.ts +3 -1
  169. package/dist/src/devkit-internals.js +8 -3
  170. package/dist/src/executors/run-commands/run-commands.impl.d.ts +2 -1
  171. package/dist/src/executors/run-commands/run-commands.impl.js +19 -5
  172. package/dist/src/executors/run-commands/running-tasks.d.ts +5 -4
  173. package/dist/src/executors/run-commands/running-tasks.js +13 -13
  174. package/dist/src/hasher/create-task-hasher.d.ts +8 -1
  175. package/dist/src/hasher/create-task-hasher.js +13 -3
  176. package/dist/src/hasher/hash-plan-inspector.js +2 -2
  177. package/dist/src/hasher/hash-task.d.ts +2 -2
  178. package/dist/src/hasher/hash-task.js +28 -17
  179. package/dist/src/hasher/native-task-hasher-impl.d.ts +20 -4
  180. package/dist/src/hasher/native-task-hasher-impl.js +75 -9
  181. package/dist/src/hasher/task-hasher.d.ts +24 -7
  182. package/dist/src/hasher/task-hasher.js +27 -8
  183. package/dist/src/hasher/task-planning-context.d.ts +13 -0
  184. package/dist/src/hasher/task-planning-context.js +12 -0
  185. package/dist/src/native/index.d.ts +582 -21
  186. package/dist/src/native/index.js +3 -3
  187. package/dist/src/native/native-bindings.js +13 -1
  188. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  189. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  190. package/dist/src/native/transform-objects.d.ts +11 -2
  191. package/dist/src/native/transform-objects.js +46 -0
  192. package/dist/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.js +15 -8
  193. package/dist/src/nx-cloud/update-manager.d.ts +3 -0
  194. package/dist/src/nx-cloud/update-manager.js +19 -13
  195. package/dist/src/nx-cloud/utilities/client.d.ts +1 -1
  196. package/dist/src/nx-cloud/utilities/client.js +1 -1
  197. package/dist/src/nx-cloud/utilities/is-workspace-claimed.js +2 -1
  198. package/dist/src/nx-cloud/utilities/nx-cloud-http-client.d.ts +5 -0
  199. package/dist/src/nx-cloud/utilities/nx-cloud-http-client.js +16 -0
  200. package/dist/src/nx-cloud/utilities/url-shorten.js +17 -10
  201. package/dist/src/plugins/js/index.js +45 -64
  202. package/dist/src/plugins/js/lock-file/lock-file.d.ts +4 -4
  203. package/dist/src/plugins/js/lock-file/lock-file.js +6 -7
  204. package/dist/src/plugins/js/lock-file/pnpm-parser.js +1 -1
  205. package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.d.ts +2 -0
  206. package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +22 -0
  207. package/dist/src/plugins/js/project-graph/affected/lock-file-changes.d.ts +10 -2
  208. package/dist/src/plugins/js/project-graph/affected/lock-file-changes.js +51 -29
  209. package/dist/src/plugins/js/project-graph/affected/npm-packages.d.ts +10 -2
  210. package/dist/src/plugins/js/project-graph/affected/npm-packages.js +32 -11
  211. package/dist/src/plugins/js/project-graph/build-dependencies/target-project-locator.js +22 -18
  212. package/dist/src/plugins/js/utils/register.js +13 -4
  213. package/dist/src/plugins/package-json/create-nodes.d.ts +2 -2
  214. package/dist/src/plugins/package-json/create-nodes.js +13 -13
  215. package/dist/src/project-graph/affected/affected-project-graph-models.d.ts +14 -0
  216. package/dist/src/project-graph/affected/affected-project-graph.js +5 -18
  217. package/dist/src/project-graph/affected/affected-projects.d.ts +7 -0
  218. package/dist/src/project-graph/affected/affected-projects.js +42 -0
  219. package/dist/src/project-graph/affected/affected-reasons.d.ts +116 -0
  220. package/dist/src/project-graph/affected/affected-reasons.js +459 -0
  221. package/dist/src/project-graph/affected/affected-tasks.d.ts +103 -0
  222. package/dist/src/project-graph/affected/affected-tasks.js +386 -0
  223. package/dist/src/project-graph/affected/print-explanation.d.ts +11 -0
  224. package/dist/src/project-graph/affected/print-explanation.js +44 -0
  225. package/dist/src/project-graph/error-types.d.ts +5 -0
  226. package/dist/src/project-graph/error-types.js +44 -5
  227. package/dist/src/project-graph/file-utils.d.ts +2 -0
  228. package/dist/src/project-graph/file-utils.js +12 -3
  229. package/dist/src/project-graph/nx-deps-cache.d.ts +5 -2
  230. package/dist/src/project-graph/nx-deps-cache.js +4 -4
  231. package/dist/src/project-graph/plugins/get-plugins.d.ts +3 -1
  232. package/dist/src/project-graph/plugins/get-plugins.js +60 -82
  233. package/dist/src/project-graph/plugins/in-process-loader.d.ts +1 -1
  234. package/dist/src/project-graph/plugins/in-process-loader.js +1 -4
  235. package/dist/src/project-graph/plugins/isolation/index.d.ts +1 -1
  236. package/dist/src/project-graph/plugins/isolation/index.js +3 -1
  237. package/dist/src/project-graph/plugins/isolation/isolated-plugin.d.ts +8 -0
  238. package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +42 -6
  239. package/dist/src/project-graph/plugins/isolation/load-isolated-plugin.d.ts +10 -1
  240. package/dist/src/project-graph/plugins/isolation/load-isolated-plugin.js +67 -17
  241. package/dist/src/project-graph/plugins/isolation/messaging.d.ts +3 -2
  242. package/dist/src/project-graph/plugins/isolation/plugin-worker.js +5 -1
  243. package/dist/src/project-graph/plugins/loaded-nx-plugin.d.ts +5 -2
  244. package/dist/src/project-graph/plugins/loaded-nx-plugin.js +14 -1
  245. package/dist/src/project-graph/plugins/nx-plugin-capabilities.d.ts +6 -0
  246. package/dist/src/project-graph/plugins/nx-plugin-capabilities.js +28 -0
  247. package/dist/src/project-graph/plugins/task-results-stub.d.ts +50 -0
  248. package/dist/src/project-graph/plugins/task-results-stub.js +111 -0
  249. package/dist/src/project-graph/plugins/tasks-execution-hooks.d.ts +3 -2
  250. package/dist/src/project-graph/plugins/tasks-execution-hooks.js +14 -1
  251. package/dist/src/project-graph/project-graph.js +43 -42
  252. package/dist/src/project-graph/utils/project-configuration/target-merging.js +67 -0
  253. package/dist/src/project-graph/utils/project-configuration/target-normalization.js +83 -0
  254. package/dist/src/project-graph/utils/project-configuration/utils.d.ts +1 -0
  255. package/dist/src/project-graph/utils/project-configuration/utils.js +1 -0
  256. package/dist/src/tasks-runner/batch/run-batch.js +15 -0
  257. package/dist/src/tasks-runner/cache.d.ts +37 -2
  258. package/dist/src/tasks-runner/cache.js +42 -1
  259. package/dist/src/tasks-runner/create-task-graph.d.ts +24 -1
  260. package/dist/src/tasks-runner/create-task-graph.js +57 -2
  261. package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
  262. package/dist/src/tasks-runner/forked-process-task-runner.d.ts +1 -1
  263. package/dist/src/tasks-runner/forked-process-task-runner.js +11 -10
  264. package/dist/src/tasks-runner/init-tasks-runner.d.ts +7 -2
  265. package/dist/src/tasks-runner/init-tasks-runner.js +15 -7
  266. package/dist/src/tasks-runner/is-tui-enabled.js +4 -3
  267. package/dist/src/tasks-runner/life-cycle.d.ts +7 -0
  268. package/dist/src/tasks-runner/life-cycle.js +7 -0
  269. package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.d.ts +35 -0
  270. package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.js +146 -0
  271. package/dist/src/tasks-runner/prune-task-graph.d.ts +17 -0
  272. package/dist/src/tasks-runner/prune-task-graph.js +45 -0
  273. package/dist/src/tasks-runner/run-command.d.ts +41 -5
  274. package/dist/src/tasks-runner/run-command.js +98 -22
  275. package/dist/src/tasks-runner/running-tasks/batch-process.d.ts +93 -19
  276. package/dist/src/tasks-runner/running-tasks/batch-process.js +184 -88
  277. package/dist/src/tasks-runner/task-io-service.d.ts +11 -3
  278. package/dist/src/tasks-runner/task-io-service.js +14 -5
  279. package/dist/src/tasks-runner/task-orchestrator.d.ts +71 -4
  280. package/dist/src/tasks-runner/task-orchestrator.js +266 -66
  281. package/dist/src/tasks-runner/tasks-runner.d.ts +2 -0
  282. package/dist/src/tasks-runner/terminal-output-path.d.ts +11 -0
  283. package/dist/src/tasks-runner/terminal-output-path.js +18 -0
  284. package/dist/src/tasks-runner/utils.d.ts +5 -0
  285. package/dist/src/tasks-runner/utils.js +14 -2
  286. package/dist/src/ultracache/config.d.ts +21 -0
  287. package/dist/src/ultracache/config.js +29 -0
  288. package/dist/src/ultracache/fetch.d.ts +21 -0
  289. package/dist/src/ultracache/fetch.js +43 -0
  290. package/dist/src/ultracache/overrides.d.ts +17 -0
  291. package/dist/src/ultracache/overrides.js +61 -0
  292. package/dist/src/ultracache/report.d.ts +13 -0
  293. package/dist/src/ultracache/report.js +62 -0
  294. package/dist/src/ultracache/store.d.ts +41 -0
  295. package/dist/src/ultracache/store.js +158 -0
  296. package/dist/src/utils/ab-testing.d.ts +4 -1
  297. package/dist/src/utils/ab-testing.js +22 -19
  298. package/dist/src/utils/chunkify.d.ts +1 -7
  299. package/dist/src/utils/chunkify.js +2 -8
  300. package/dist/src/utils/command-line-utils.d.ts +20 -0
  301. package/dist/src/utils/command-line-utils.js +10 -3
  302. package/dist/src/utils/create-cli-options.d.ts +6 -0
  303. package/dist/src/utils/create-cli-options.js +29 -0
  304. package/dist/src/utils/db-connection.d.ts +2 -0
  305. package/dist/src/utils/db-connection.js +2 -0
  306. package/dist/src/utils/formatters/index.d.ts +6 -0
  307. package/dist/src/utils/formatters/index.js +5 -0
  308. package/dist/src/utils/formatters/prettier.d.ts +0 -8
  309. package/dist/src/utils/formatters/prettier.js +4 -26
  310. package/dist/src/utils/git-utils.d.ts +19 -0
  311. package/dist/src/utils/git-utils.js +97 -39
  312. package/dist/src/utils/handle-errors.js +5 -43
  313. package/dist/src/utils/http-client.d.ts +27 -0
  314. package/dist/src/utils/http-client.js +193 -0
  315. package/dist/src/utils/installed-nx-version.js +2 -48
  316. package/dist/src/utils/json-diff.d.ts +4 -2
  317. package/dist/src/utils/json-diff.js +6 -94
  318. package/dist/src/utils/min-release-age/packument.js +1 -1
  319. package/dist/src/utils/nx-cloud-utils.d.ts +2 -0
  320. package/dist/src/utils/nx-cloud-utils.js +6 -1
  321. package/dist/src/utils/output.d.ts +22 -3
  322. package/dist/src/utils/output.js +28 -5
  323. package/dist/src/utils/package-json.d.ts +25 -0
  324. package/dist/src/utils/package-json.js +49 -6
  325. package/dist/src/utils/package-manager.d.ts +6 -0
  326. package/dist/src/utils/package-manager.js +10 -0
  327. package/dist/src/utils/plugins/plugin-capabilities.js +7 -2
  328. package/dist/src/utils/project-graph-utils.d.ts +2 -0
  329. package/dist/src/utils/project-graph-utils.js +12 -0
  330. package/dist/src/utils/provenance.js +20 -4
  331. package/dist/src/utils/serialize-overrides-into-command-line.js +2 -4
  332. package/dist/src/utils/workspace-context.d.ts +51 -3
  333. package/dist/src/utils/workspace-context.js +174 -10
  334. package/package.json +36 -98
  335. package/schemas/nx-schema.json +38 -0
  336. package/schemas/project-schema.json +35 -0
  337. package/dist/src/daemon/server/file-watching/route-workspace-changes.d.ts +0 -9
  338. package/dist/src/daemon/server/file-watching/route-workspace-changes.js +0 -76
  339. package/dist/src/daemon/server/watcher.d.ts +0 -18
  340. package/dist/src/daemon/server/watcher.js +0 -126
  341. package/dist/src/nx-cloud/utilities/axios.d.ts +0 -4
  342. package/dist/src/nx-cloud/utilities/axios.js +0 -17
  343. package/dist/src/project-graph/affected/locators/project-glob-changes.d.ts +0 -2
  344. package/dist/src/project-graph/affected/locators/project-glob-changes.js +0 -47
  345. package/dist/src/project-graph/affected/locators/workspace-json-changes.d.ts +0 -4
  346. package/dist/src/project-graph/affected/locators/workspace-json-changes.js +0 -47
  347. package/dist/src/project-graph/affected/locators/workspace-projects.d.ts +0 -3
  348. package/dist/src/project-graph/affected/locators/workspace-projects.js +0 -74
  349. package/dist/src/utils/collapse-expanded-outputs.d.ts +0 -10
  350. package/dist/src/utils/collapse-expanded-outputs.js +0 -72
@@ -0,0 +1,568 @@
1
+ "use strict";
2
+ // A master session's agent runs the dispensed `nx migrate` commands inside
3
+ // its own sandbox, where a dependency install has no network and a commit
4
+ // cannot write `.git`. The parent nx that spawned the session advertises
5
+ // itself through NX_MIGRATE_BROKER, and a step then hands its install, and
6
+ // its commit when one is due, over a request/result file pair under
7
+ // <runDir>/broker/ instead of running them itself. Nothing here authorizes:
8
+ // every file the parent could consult is writable from the sandbox, so the
9
+ // parent's own invocation decides what it installs and commits.
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.MigrateCommitBroker = exports.TreeBusyError = exports.BrokerUnavailableError = exports.BrokerStaleRequestError = exports.BROKER_ENV_VAR = void 0;
12
+ exports.acquireTreeOperation = acquireTreeOperation;
13
+ exports.releaseTreeOperation = releaseTreeOperation;
14
+ exports.liveTreeOperation = liveTreeOperation;
15
+ exports.treeBusyMessage = treeBusyMessage;
16
+ exports.treeOperationLabel = treeOperationLabel;
17
+ exports.brokerDir = brokerDir;
18
+ exports.commitStepTree = commitStepTree;
19
+ exports.installStepTree = installStepTree;
20
+ exports.resetStepTree = resetStepTree;
21
+ exports.giveUpStepTree = giveUpStepTree;
22
+ const crypto_1 = require("crypto");
23
+ const fs_1 = require("fs");
24
+ const path_1 = require("path");
25
+ const native_1 = require("../../../native");
26
+ const fileutils_1 = require("../../../utils/fileutils");
27
+ const json_1 = require("../../../utils/json");
28
+ const handoff_1 = require("../agentic/handoff");
29
+ const deferred_output_1 = require("../deferred-output");
30
+ const execute_migration_1 = require("../execute-migration");
31
+ const migrate_commits_1 = require("../migrate-commits");
32
+ const atomic_write_1 = require("./atomic-write");
33
+ const give_up_1 = require("./give-up");
34
+ const run_state_1 = require("./run-state");
35
+ const state_lock_1 = require("./state-lock");
36
+ const state_machine_1 = require("./state-machine");
37
+ const issues_1 = require("./issues");
38
+ const clean_retry_1 = require("./clean-retry");
39
+ const util_1 = require("./util");
40
+ exports.BROKER_ENV_VAR = 'NX_MIGRATE_BROKER';
41
+ const BROKER_DIR_NAME = 'broker';
42
+ const CHILD_POLL_INTERVAL_MS = 250;
43
+ /** The request no longer matches the step: another attempt owns it. */
44
+ class BrokerStaleRequestError extends Error {
45
+ }
46
+ exports.BrokerStaleRequestError = BrokerStaleRequestError;
47
+ /**
48
+ * The advertised parent could not accept the request, or went away before
49
+ * answering it. It may have landed the install or the commit; the tree and
50
+ * the run state say.
51
+ */
52
+ class BrokerUnavailableError extends Error {
53
+ }
54
+ exports.BrokerUnavailableError = BrokerUnavailableError;
55
+ /** Another live process holds the working tree for an operation of its own. */
56
+ class TreeBusyError extends Error {
57
+ }
58
+ exports.TreeBusyError = TreeBusyError;
59
+ /**
60
+ * Reserves the working tree for one operation in a single fresh-state write:
61
+ * the request must still be at its seam (else the attempt moved on and the
62
+ * request is stale), and no other live process may hold a reservation.
63
+ * A reservation whose owner process is gone holds nothing.
64
+ */
65
+ function acquireTreeOperation(dir, request, owner = (0, crypto_1.randomBytes)(4).toString('hex')) {
66
+ // A commit marks its step as started; a mark already there belongs to an
67
+ // operation whose outcome is still unknown, and this one leaves it.
68
+ let marks = false;
69
+ (0, state_lock_1.updateRunState)(dir, (fresh) => {
70
+ if (!atSeam(fresh, request)) {
71
+ throw new BrokerStaleRequestError(`The request for this step no longer matches its attempt; nothing was installed or committed.`);
72
+ }
73
+ const held = liveTreeOperation(fresh, owner);
74
+ if (held)
75
+ throw new TreeBusyError(treeBusyMessage(held));
76
+ marks =
77
+ (request.kind === 'commit' || request.kind === 'give-up') &&
78
+ fresh.steps.find((s) => s.id === request.stepId)?.commitStarted !== true;
79
+ return {
80
+ ...(marks ? (0, state_machine_1.markCommitStarted)(fresh, request.stepId) : fresh),
81
+ treeOperation: {
82
+ kind: request.kind,
83
+ ...(request.stepId !== undefined ? { stepId: request.stepId } : {}),
84
+ ...(request.attempt !== undefined ? { attempt: request.attempt } : {}),
85
+ owner,
86
+ pid: process.pid,
87
+ },
88
+ };
89
+ });
90
+ const lease = {
91
+ owner,
92
+ ...(marks ? { markedStepId: request.stepId } : {}),
93
+ release: () => releaseTreeOperation(dir, owner, lease.markedStepId),
94
+ };
95
+ return lease;
96
+ }
97
+ /**
98
+ * Owner-checked: a lease released late never drops a newer reservation, nor
99
+ * the mark it set.
100
+ */
101
+ function releaseTreeOperation(dir, owner, markedStepId) {
102
+ (0, state_lock_1.updateRunState)(dir, (fresh) => {
103
+ if (fresh.treeOperation?.owner !== owner)
104
+ return null;
105
+ const released = { ...fresh, treeOperation: undefined };
106
+ return markedStepId ? (0, state_machine_1.clearCommitStarted)(released, markedStepId) : released;
107
+ });
108
+ }
109
+ /** The reservation a live process other than `owner` holds, if any. */
110
+ function liveTreeOperation(state, owner) {
111
+ const held = state.treeOperation;
112
+ if (!held || held.owner === owner || !(0, util_1.isPidAlive)(held.pid))
113
+ return undefined;
114
+ return held;
115
+ }
116
+ function treeBusyMessage(held) {
117
+ return `The working tree is held by process ${held.pid} for ${treeOperationLabel(held)}; run the reconcile again once it finishes.`;
118
+ }
119
+ function treeOperationLabel(held) {
120
+ switch (held.kind) {
121
+ case 'checkpoint':
122
+ return 'the checkpoint commit';
123
+ case 'commit':
124
+ case 'give-up':
125
+ return `the commit of step '${held.stepId}'`;
126
+ case 'reset':
127
+ return `the reset of step '${held.stepId}'`;
128
+ case 'install':
129
+ case 'fold-install':
130
+ case 'action-install':
131
+ return `the install of step '${held.stepId}'`;
132
+ default: {
133
+ const exhaustive = held.kind;
134
+ throw new Error(`Unhandled tree operation '${exhaustive}'.`);
135
+ }
136
+ }
137
+ }
138
+ function atSeam(state, request) {
139
+ if (request.kind === 'checkpoint') {
140
+ return (state.createCommits &&
141
+ state.checkpointFailed === true &&
142
+ state.steps.every((s) => s.status === 'pending'));
143
+ }
144
+ return (Object.hasOwn(SEAM_STATUSES, request.kind) &&
145
+ request.stepId !== undefined &&
146
+ request.attempt !== undefined &&
147
+ isAtSeam(state.steps.find((s) => s.id === request.stepId), request));
148
+ }
149
+ const SEAM_STATUSES = {
150
+ commit: new Set(['running', 'awaiting-prompt-outcome', 'failed', 'died']),
151
+ install: new Set(['running']),
152
+ 'fold-install': new Set(['awaiting-prompt-outcome']),
153
+ 'action-install': new Set(['failed', 'died']),
154
+ reset: new Set(['failed', 'died']),
155
+ 'give-up': new Set(['failed', 'died']),
156
+ };
157
+ function isAtSeam(step, request) {
158
+ if (step === undefined || step.attempt !== request.attempt)
159
+ return false;
160
+ // A failed step commits only through its adopt.
161
+ if (request.kind === 'commit' && step.status === 'failed') {
162
+ return request.commitAs === 'adopt';
163
+ }
164
+ return SEAM_STATUSES[request.kind].has(step.status);
165
+ }
166
+ function brokerDir(runDirPath) {
167
+ return (0, path_1.join)(runDirPath, BROKER_DIR_NAME);
168
+ }
169
+ function lockPath(runDirPath, nonce) {
170
+ return (0, path_1.join)(brokerDir(runDirPath), `${nonce}.lock`);
171
+ }
172
+ function requestPath(runDirPath, id) {
173
+ return (0, path_1.join)(brokerDir(runDirPath), `${id}.request.json`);
174
+ }
175
+ function resultPath(runDirPath, id) {
176
+ return (0, path_1.join)(brokerDir(runDirPath), `${id}.result.json`);
177
+ }
178
+ // A request file lives in the agent-writable broker directory, so it could be
179
+ // a planted symlink or FIFO; read it without reading a symlink's target or
180
+ // blocking on a FIFO.
181
+ function readRequestFile(filePath) {
182
+ return (0, json_1.parseJson)((0, handoff_1.readAtomicallyPublishedFile)(filePath, `${filePath} is not a regular file.`));
183
+ }
184
+ /**
185
+ * Runs the step's install and commit where they can land: in this process
186
+ * unless a parent session advertised its broker, in which case the request
187
+ * goes to the parent and the answer comes back with the output the parent
188
+ * collected, printed here. The absorbed step ids come from whichever side
189
+ * ran the commit, so the ledger entry names what its `git add -A` took.
190
+ */
191
+ async function commitStepTree(dir, step, absorbedStepIds, commitInProcess, scope, commitAs) {
192
+ const request = {
193
+ kind: 'commit',
194
+ stepId: step.id,
195
+ attempt: step.attempt,
196
+ ...(commitAs !== undefined ? { commitAs } : {}),
197
+ };
198
+ const nonce = process.env[exports.BROKER_ENV_VAR];
199
+ if (!nonce) {
200
+ const lease = acquireTreeOperation(dir, request);
201
+ scope.lease = lease;
202
+ const result = await commitInProcess();
203
+ if ((0, state_machine_1.gitRan)(result))
204
+ lease.markedStepId = undefined;
205
+ return { result, absorbedStepIds, recorded: false };
206
+ }
207
+ const answer = await ask(dir, nonce, request);
208
+ if (answer.kind !== 'commit') {
209
+ throw new Error(`Unexpected '${answer.kind}' answer to a commit request.`);
210
+ }
211
+ return {
212
+ result: answer.result,
213
+ absorbedStepIds: answer.absorbedStepIds,
214
+ recorded: true,
215
+ };
216
+ }
217
+ /**
218
+ * The same for a step that owes only its install: no commit is due, or the
219
+ * commit waits for a fold.
220
+ */
221
+ async function installStepTree(dir, step, seam, installInProcess, scope) {
222
+ const request = {
223
+ kind: seam,
224
+ stepId: step.id,
225
+ attempt: step.attempt,
226
+ };
227
+ const nonce = process.env[exports.BROKER_ENV_VAR];
228
+ if (!nonce) {
229
+ scope.lease = acquireTreeOperation(dir, request);
230
+ return installInProcess();
231
+ }
232
+ const answer = await ask(dir, nonce, request);
233
+ if (answer.kind !== 'installed') {
234
+ throw new Error(`Unexpected '${answer.kind}' answer to an install request.`);
235
+ }
236
+ }
237
+ /**
238
+ * The same for the reset a clean retry of a failed or died step needs. Runs
239
+ * `resetInProcess` under the reservation, or asks the parent, which resets
240
+ * against the state it reads then; a reset that could not run throws.
241
+ */
242
+ async function resetStepTree(dir, step, resetInProcess, scope) {
243
+ const request = {
244
+ kind: 'reset',
245
+ stepId: step.id,
246
+ attempt: step.attempt,
247
+ invocation: (0, crypto_1.randomBytes)(4).toString('hex'),
248
+ };
249
+ const nonce = process.env[exports.BROKER_ENV_VAR];
250
+ if (!nonce) {
251
+ scope.lease = acquireTreeOperation(dir, request);
252
+ return resetInProcess();
253
+ }
254
+ const answer = await ask(dir, nonce, request);
255
+ if (answer.kind !== 'reset') {
256
+ throw new Error(`Unexpected '${answer.kind}' answer to a reset request.`);
257
+ }
258
+ }
259
+ /**
260
+ * The same for giving a failed or died step up while the run commits. Unlike
261
+ * the seams above, the operation settles the step itself, under the
262
+ * reservation it runs with, so the caller writes no transition of its own.
263
+ */
264
+ async function giveUpStepTree(root, dir, step, skipInstall, reconcileCommand, scope) {
265
+ const request = {
266
+ kind: 'give-up',
267
+ stepId: step.id,
268
+ attempt: step.attempt,
269
+ };
270
+ const nonce = process.env[exports.BROKER_ENV_VAR];
271
+ if (!nonce) {
272
+ const lease = acquireTreeOperation(dir, request);
273
+ scope.lease = lease;
274
+ return (0, give_up_1.giveUpWithCommit)({
275
+ root,
276
+ dir,
277
+ step,
278
+ lease,
279
+ skipInstall,
280
+ reconcileCommand,
281
+ });
282
+ }
283
+ const answer = await ask(dir, nonce, request);
284
+ if (answer.kind !== 'give-up') {
285
+ throw new Error(`Unexpected '${answer.kind}' answer to a give-up request.`);
286
+ }
287
+ return answer.outcome;
288
+ }
289
+ async function ask(dir, nonce, request) {
290
+ const id = `${nonce}-${request.stepId}-${request.attempt}-${request.kind}${request.invocation ? `-${request.invocation}` : ''}${request.commitAs !== undefined ? `-${request.commitAs}` : ''}`;
291
+ const path = resultPath(dir, id);
292
+ // A repeat reads the first answer, whatever became of the session since.
293
+ if ((0, fs_1.existsSync)(path)) {
294
+ return settle((0, fileutils_1.readJsonFile)(path));
295
+ }
296
+ // No deadline: an install or a commit over a large tree takes as long as it
297
+ // takes; the poll ends with an answer or a released lock. The probe is built
298
+ // first so a request is never left unwatched, and once: each instance holds
299
+ // a descriptor, and `wait()` would pin this process until the session ends.
300
+ let lock = null;
301
+ try {
302
+ lock = native_1.IS_WASM ? null : new native_1.FileLock(lockPath(dir, nonce));
303
+ }
304
+ catch (e) {
305
+ if ((0, fs_1.existsSync)(path)) {
306
+ return settle((0, fileutils_1.readJsonFile)(path));
307
+ }
308
+ throw notAccepting(e);
309
+ }
310
+ try {
311
+ (0, atomic_write_1.publishFileAtomically)(requestPath(dir, id), (tmpPath) => (0, fileutils_1.writeJsonFile)(tmpPath, request));
312
+ }
313
+ catch (e) {
314
+ throw notAccepting(e);
315
+ }
316
+ for (;;) {
317
+ if ((0, fs_1.existsSync)(path)) {
318
+ return settle((0, fileutils_1.readJsonFile)(path));
319
+ }
320
+ if (lock && lockIsFree(lock)) {
321
+ // Answered and closed between the two checks: the answer stays on disk.
322
+ if ((0, fs_1.existsSync)(path))
323
+ continue;
324
+ throw new BrokerUnavailableError(`The nx migrate session that started this step ended before its request was answered. The install or the commit may still have landed; check the working tree and git log.`);
325
+ }
326
+ await new Promise((resolve) => setTimeout(resolve, CHILD_POLL_INTERVAL_MS));
327
+ }
328
+ }
329
+ function notAccepting(e) {
330
+ return new BrokerUnavailableError(`The nx migrate session that started this step is not accepting its request (${e instanceof Error ? e.message : String(e)}).`);
331
+ }
332
+ // A probe that fails says nothing about the parent; keep waiting.
333
+ function lockIsFree(lock) {
334
+ try {
335
+ return !lock.check();
336
+ }
337
+ catch {
338
+ return false;
339
+ }
340
+ }
341
+ function settle(result) {
342
+ switch (result.kind) {
343
+ case 'commit':
344
+ case 'installed':
345
+ (0, deferred_output_1.replayDeferredOutput)(result.output);
346
+ return result;
347
+ case 'install-failed':
348
+ (0, deferred_output_1.replayDeferredOutput)(result.output);
349
+ // The CLI catch returns 1 on the typed error instead of logging again.
350
+ throw result.peerDeps
351
+ ? new execute_migration_1.NpmPeerDepsInstallError()
352
+ : new Error(result.message);
353
+ case 'reset':
354
+ if (result.error !== undefined)
355
+ throw new Error(result.error);
356
+ return result;
357
+ case 'give-up':
358
+ (0, deferred_output_1.replayDeferredOutput)(result.output);
359
+ return result;
360
+ case 'stale':
361
+ throw new BrokerStaleRequestError(`The request for this step no longer matches its attempt; nothing was installed or committed.`);
362
+ default: {
363
+ const exhaustive = result;
364
+ throw new Error(`Unhandled broker result: ${JSON.stringify(exhaustive)}`);
365
+ }
366
+ }
367
+ }
368
+ /**
369
+ * The parent side. Holds one exclusive lock for the session's lifetime so a
370
+ * waiting step can tell a slow parent from a dead one, answers each request
371
+ * once, and removes its own requests on close; its answers stay for the steps
372
+ * still reading them. Requests carrying another session's nonce belong to
373
+ * that session and are never touched. Whether to install or commit comes from
374
+ * the policy the session started with, never from run state, which the
375
+ * agent's sandbox can write.
376
+ */
377
+ class MigrateCommitBroker {
378
+ constructor(root, dir, reconcileCommand, policy) {
379
+ this.root = root;
380
+ this.dir = dir;
381
+ this.reconcileCommand = reconcileCommand;
382
+ this.policy = policy;
383
+ this.nonce = (0, crypto_1.randomBytes)(4).toString('hex');
384
+ this.handled = new Set();
385
+ this.inFlight = null;
386
+ (0, handoff_1.ensureRunSubdir)(brokerDir(dir), () => this.notADirectory());
387
+ this.lock = native_1.IS_WASM ? null : new native_1.FileLock(lockPath(dir, this.nonce));
388
+ this.lock?.lock();
389
+ }
390
+ /** The request whose operation this process is running right now. */
391
+ get requestInFlight() {
392
+ return this.inFlight;
393
+ }
394
+ /** Answers this session's unanswered requests, one at a time. */
395
+ async service() {
396
+ // Refused rather than followed: a symlink swapped in would send the reads
397
+ // and the answers wherever it points, or leave requests unanswered.
398
+ if ((0, handoff_1.handoffsDirState)(brokerDir(this.dir)) !== 'directory') {
399
+ throw this.notADirectory();
400
+ }
401
+ const prefix = `${this.nonce}-`;
402
+ const suffix = '.request.json';
403
+ for (const name of (0, fs_1.readdirSync)(brokerDir(this.dir))) {
404
+ if (!name.startsWith(prefix) || !name.endsWith(suffix))
405
+ continue;
406
+ const id = name.slice(0, -suffix.length);
407
+ if (this.handled.has(id))
408
+ continue;
409
+ const request = readRequestFile(requestPath(this.dir, id));
410
+ // Reserved before anything runs, released after the record is written.
411
+ // A tree held by another live process is left for a later pass, not
412
+ // marked handled; a request no longer at its seam is answered stale.
413
+ let lease = null;
414
+ try {
415
+ lease = acquireTreeOperation(this.dir, request, this.nonce);
416
+ }
417
+ catch (e) {
418
+ if (e instanceof TreeBusyError)
419
+ continue;
420
+ if (!(e instanceof BrokerStaleRequestError))
421
+ throw e;
422
+ }
423
+ this.handled.add(id);
424
+ let result;
425
+ try {
426
+ if (lease)
427
+ this.inFlight = request;
428
+ result = lease ? await this.answer(request, lease) : { kind: 'stale' };
429
+ // Recorded by the process that ran the commit, before the answer: the
430
+ // step reading it can die with the commit already in history. A failed
431
+ // record throws and ends the session rather than losing the entry.
432
+ if (result.kind === 'commit') {
433
+ if ((0, state_machine_1.gitRan)(result.result))
434
+ lease.markedStepId = undefined;
435
+ this.record(request, result);
436
+ }
437
+ }
438
+ finally {
439
+ this.inFlight = null;
440
+ lease?.release();
441
+ }
442
+ // Published after the release, so the step reading the answer never
443
+ // finds this request's reservation still standing over its own write.
444
+ (0, atomic_write_1.publishFileAtomically)(resultPath(this.dir, id), (tmpPath) => (0, fileutils_1.writeJsonFile)(tmpPath, result));
445
+ }
446
+ }
447
+ // Appends the entry and leaves the step a receipt for it, on the attempt the
448
+ // request named: a rearmed step owes nothing to the old attempt's commit.
449
+ record(request, result) {
450
+ const entry = (0, state_machine_1.commitResultToLedgerEntry)(result.result, request.stepId, result.absorbedStepIds);
451
+ if (!entry)
452
+ return;
453
+ (0, state_lock_1.updateRunState)(this.dir, (fresh) => {
454
+ const index = fresh.commits.length;
455
+ const next = (0, state_machine_1.appendCommit)(fresh, (0, issues_1.attachIssueIdsToCommitEntry)(fresh, entry));
456
+ return {
457
+ ...next,
458
+ steps: next.steps.map((s) => s.id === request.stepId && s.attempt === request.attempt
459
+ ? { ...s, commitLedgerIndex: index }
460
+ : s),
461
+ };
462
+ });
463
+ }
464
+ async answer(request, lease) {
465
+ const state = (0, run_state_1.readRunState)(this.dir);
466
+ const step = state.steps.find((s) => s.id === request.stepId);
467
+ if (!Object.hasOwn(SEAM_STATUSES, request.kind) ||
468
+ !isAtSeam(step, request) ||
469
+ ((request.kind === 'commit' ||
470
+ request.kind === 'reset' ||
471
+ request.kind === 'give-up') &&
472
+ !this.policy.createCommits) ||
473
+ (request.commitAs !== undefined && request.commitAs !== 'adopt')) {
474
+ return { kind: 'stale' };
475
+ }
476
+ if (request.kind === 'give-up') {
477
+ const output = new deferred_output_1.DeferredOutputCollector();
478
+ const outcome = await (0, give_up_1.giveUpWithCommit)({
479
+ root: this.root,
480
+ dir: this.dir,
481
+ step,
482
+ lease,
483
+ skipInstall: this.policy.skipInstall,
484
+ reconcileCommand: this.reconcileCommand,
485
+ output,
486
+ });
487
+ // Raw package-manager output only for a failed install, as for a commit.
488
+ return {
489
+ kind: 'give-up',
490
+ outcome,
491
+ output: output.render(outcome.kind === 'given-up' &&
492
+ outcome.commit.status === 'install-failed'
493
+ ? 'keep'
494
+ : 'drop'),
495
+ };
496
+ }
497
+ if (request.kind === 'reset') {
498
+ try {
499
+ (0, clean_retry_1.resetForCleanRetry)(this.root, this.dir, step.id);
500
+ return { kind: 'reset' };
501
+ }
502
+ catch (e) {
503
+ return {
504
+ kind: 'reset',
505
+ error: e instanceof Error ? e.message : String(e),
506
+ };
507
+ }
508
+ }
509
+ const output = new deferred_output_1.DeferredOutputCollector();
510
+ const install = () => (0, util_1.installDepsChangedSinceDispense)(this.root, this.dir, step, this.policy.skipInstall, this.reconcileCommand, output);
511
+ try {
512
+ if (request.kind !== 'commit') {
513
+ await install();
514
+ return { kind: 'installed', output: output.render('drop') };
515
+ }
516
+ const absorbedStepIds = (0, state_machine_1.uncoveredFailedStepIds)(state).filter((id) => id !== step.id);
517
+ const result = await (0, migrate_commits_1.commitMigrationIfRequested)(this.root, { name: (0, state_machine_1.commitNameForStep)(step) }, true, state.commitPrefix, install, (0, state_machine_1.stepsToPendingMigrations)(state, absorbedStepIds), undefined, output);
518
+ return {
519
+ kind: 'commit',
520
+ result,
521
+ absorbedStepIds,
522
+ output: output.render('drop'),
523
+ };
524
+ }
525
+ catch (e) {
526
+ // The install is the only thing that throws: the commit reports through
527
+ // its result, and the install's own bookkeeping never throws. Marked
528
+ // here, where the install ran, on the attempt it ran for: a reconcile
529
+ // may have rearmed the step meanwhile, and that attempt owes nothing.
530
+ (0, state_lock_1.updateRunState)(this.dir, (fresh) => isAtSeam(fresh.steps.find((s) => s.id === step.id), request)
531
+ ? (0, state_machine_1.markInstallFailed)(fresh, step.id)
532
+ : null);
533
+ return {
534
+ kind: 'install-failed',
535
+ message: e instanceof Error ? e.message : String(e),
536
+ peerDeps: e instanceof execute_migration_1.NpmPeerDepsInstallError,
537
+ // The package manager's own output: for pnpm, Yarn and Bun the error
538
+ // says only that the command failed.
539
+ output: output.render('keep'),
540
+ };
541
+ }
542
+ }
543
+ /** Releases the lock; call after the last `service` settled. */
544
+ close() {
545
+ this.lock?.unlock();
546
+ // A reservation this session still holds would only expire with its pid.
547
+ try {
548
+ releaseTreeOperation(this.dir, this.nonce);
549
+ }
550
+ catch { }
551
+ // Hygiene only; a file left behind is never read by another session.
552
+ try {
553
+ if ((0, handoff_1.handoffsDirState)(brokerDir(this.dir)) !== 'directory')
554
+ return;
555
+ for (const name of (0, fs_1.readdirSync)(brokerDir(this.dir))) {
556
+ if (name === `${this.nonce}.lock` ||
557
+ (name.startsWith(`${this.nonce}-`) && name.endsWith('.request.json'))) {
558
+ (0, fs_1.rmSync)((0, path_1.join)(brokerDir(this.dir), name), { force: true });
559
+ }
560
+ }
561
+ }
562
+ catch { }
563
+ }
564
+ notADirectory() {
565
+ return new Error(`The migrate run has something other than a directory at ${brokerDir(this.dir)}; remove it and try again.`);
566
+ }
567
+ }
568
+ exports.MigrateCommitBroker = MigrateCommitBroker;
@@ -0,0 +1,12 @@
1
+ import type { MigrateRunState, MigrateStep } from './run-state';
2
+ export declare function canOfferCleanRetry(root: string, state: MigrateRunState, step: MigrateStep, head: string | null): boolean;
3
+ export declare function cleanRetryUnavailableReason(root: string, state: MigrateRunState, step: MigrateStep, head: string | null): string;
4
+ /**
5
+ * The reset a clean retry of `stepId` needs, run with the tree reserved. The
6
+ * retry is re-checked against the state read then, and the attempt's
7
+ * generator run and the fixes its resolutions claimed are forgotten in a
8
+ * write of their own before git runs, so a reset that fails midway leaves
9
+ * the plain retry gated. Throws the reason when the retry is no longer
10
+ * available, or what git said when the reset fails.
11
+ */
12
+ export declare function resetForCleanRetry(root: string, dir: string, stepId: string): void;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.canOfferCleanRetry = canOfferCleanRetry;
4
+ exports.cleanRetryUnavailableReason = cleanRetryUnavailableReason;
5
+ exports.resetForCleanRetry = resetForCleanRetry;
6
+ const git_utils_1 = require("../../../utils/git-utils");
7
+ const types_1 = require("../agentic/types");
8
+ const agent_output_1 = require("./agent-output");
9
+ const issues_1 = require("./issues");
10
+ const state_lock_1 = require("./state-lock");
11
+ const state_machine_1 = require("./state-machine");
12
+ const util_1 = require("./util");
13
+ // A clean retry resets the tree to the step's `gitRefBefore`, discarding
14
+ // everything the ref does not account for. It is offered only when it does
15
+ // account for the whole tree: every prior diff committed, the tree clean when
16
+ // the step was dispensed, and HEAD still at the ref. An absent or unreadable
17
+ // value is no restore point, never a clean one. The debt check is run-wide:
18
+ // the reset discards every step's uncommitted work, not only this one's.
19
+ function canOfferCleanRetry(root, state, step, head) {
20
+ return (state.createCommits &&
21
+ !state.checkpointFailed &&
22
+ !(0, state_machine_1.hasPendingCommitDebt)(state) &&
23
+ !!step.gitRefBefore &&
24
+ head === step.gitRefBefore &&
25
+ step.treeCleanAtDispense === true &&
26
+ !endangeredLandedEntry(root, state, step));
27
+ }
28
+ // The last landed entry covering the step whose commit a reset to the step's
29
+ // `gitRefBefore` would discard: one that is not a verified ancestor of it.
30
+ function endangeredLandedEntry(root, state, step) {
31
+ let endangered = null;
32
+ for (const entry of (0, state_machine_1.coveringLandedEntries)(state, step.id)) {
33
+ if (!entry.sha ||
34
+ !step.gitRefBefore ||
35
+ !(0, git_utils_1.isAncestorCommit)(entry.sha, step.gitRefBefore, root)) {
36
+ endangered = entry;
37
+ }
38
+ }
39
+ return endangered;
40
+ }
41
+ function cleanRetryUnavailableReason(root, state, step, head) {
42
+ const endangered = endangeredLandedEntry(root, state, step);
43
+ const noun = (0, state_machine_1.stepNoun)(step);
44
+ if (endangered) {
45
+ return endangered.sha
46
+ ? `this ${noun}'s changes already landed in commit ${endangered.sha}, which a reset would discard.`
47
+ : `this ${noun}'s changes already landed in a commit, which a reset would discard.`;
48
+ }
49
+ if (step.gitRefBefore && head !== step.gitRefBefore) {
50
+ return `HEAD is at ${head ?? '(unreadable)'} rather than the ${step.gitRefBefore} this ${noun} started from, so a reset would discard what was committed in between.`;
51
+ }
52
+ return `resetting the tree could discard uncommitted work that no restore point accounts for.`;
53
+ }
54
+ // Best-effort: run.json records the reverted dispositions and stays
55
+ // authoritative, so a failed append loses only the archive's trail record of
56
+ // the revert.
57
+ function archiveReopenedResolutions(dir, state, updates, label) {
58
+ if (updates.length === 0)
59
+ return;
60
+ const reconstructedIds = [];
61
+ try {
62
+ (0, issues_1.archiveIssues)(dir, { state, newIssues: [], updates }, reconstructedIds);
63
+ }
64
+ catch (e) {
65
+ (0, agent_output_1.warnToAgent)({
66
+ title: `The reverted issue resolutions for ${label} could not be archived (${(0, util_1.summarizeError)(e)}).`,
67
+ bodyLines: [
68
+ `run.json stays authoritative for the dispositions; the archived files under the run's issues directory miss the revert records, so their last entries may still read resolved.`,
69
+ ],
70
+ });
71
+ }
72
+ (0, issues_1.warnReconstructedArchives)(reconstructedIds);
73
+ }
74
+ /**
75
+ * The reset a clean retry of `stepId` needs, run with the tree reserved. The
76
+ * retry is re-checked against the state read then, and the attempt's
77
+ * generator run and the fixes its resolutions claimed are forgotten in a
78
+ * write of their own before git runs, so a reset that fails midway leaves
79
+ * the plain retry gated. Throws the reason when the retry is no longer
80
+ * available, or what git said when the reset fails.
81
+ */
82
+ function resetForCleanRetry(root, dir, stepId) {
83
+ const head = (0, git_utils_1.getLatestCommitSha)(root);
84
+ let step;
85
+ let updates = [];
86
+ const prepared = (0, state_lock_1.updateRunState)(dir, (fresh) => {
87
+ step = fresh.steps.find((s) => s.id === stepId);
88
+ if (!step)
89
+ throw new Error(`step '${stepId}' is not in the run.`);
90
+ if (!canOfferCleanRetry(root, fresh, step, head)) {
91
+ throw new Error(cleanRetryUnavailableReason(root, fresh, step, head));
92
+ }
93
+ const reopened = (0, issues_1.reopenResolutionsForStep)((0, state_machine_1.discardGeneratorRun)(fresh, stepId), stepId);
94
+ updates = reopened.updates;
95
+ return reopened.state;
96
+ });
97
+ archiveReopenedResolutions(dir, prepared, updates, (0, state_machine_1.stepLabel)(step));
98
+ (0, git_utils_1.resetWorkingTree)(step.gitRefBefore, [types_1.MIGRATE_RUNS_RELATIVE_DIR], root);
99
+ }