@depup/nx 23.2.1-depup.7 → 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 +8 -19
  2. package/changes.json +10 -54
  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 +38 -100
  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
@@ -6,11 +6,3 @@ export declare const RUN_ID_SAFE: RegExp;
6
6
  * mid-run.
7
7
  */
8
8
  export declare function createRunId(): string;
9
- /**
10
- * Hashes a migrations.json plan so a resumed run can detect whether the plan
11
- * changed since a round was recorded. `nx-console` is stripped first since
12
- * editors write to it without changing the plan; object keys are sorted
13
- * recursively (arrays keep their order) so key reordering from a different
14
- * JSON serializer doesn't change the hash.
15
- */
16
- export declare function computePlanHash(migrationsJsonContent: string | object): string;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RUN_ID_SAFE = void 0;
4
4
  exports.createRunId = createRunId;
5
- exports.computePlanHash = computePlanHash;
6
5
  const crypto_1 = require("crypto");
7
6
  // Orchestrator-generated run ids always match; anything else could smuggle
8
7
  // shell metacharacters into dispensed commands or a path out of the runs dir
@@ -25,32 +24,3 @@ function compactUtcTimestamp(date) {
25
24
  .replace(/[-:]/g, '')
26
25
  .replace(/\.\d+Z$/, '');
27
26
  }
28
- /**
29
- * Hashes a migrations.json plan so a resumed run can detect whether the plan
30
- * changed since a round was recorded. `nx-console` is stripped first since
31
- * editors write to it without changing the plan; object keys are sorted
32
- * recursively (arrays keep their order) so key reordering from a different
33
- * JSON serializer doesn't change the hash.
34
- */
35
- function computePlanHash(migrationsJsonContent) {
36
- const parsed = (typeof migrationsJsonContent === 'string'
37
- ? JSON.parse(migrationsJsonContent)
38
- : migrationsJsonContent);
39
- const withoutNxConsole = Object.fromEntries(Object.entries(parsed).filter(([key]) => key !== 'nx-console'));
40
- return (0, crypto_1.createHash)('sha256')
41
- .update(JSON.stringify(canonicalize(withoutNxConsole)))
42
- .digest('hex');
43
- }
44
- function canonicalize(value) {
45
- if (Array.isArray(value)) {
46
- return value.map(canonicalize);
47
- }
48
- if (value !== null && typeof value === 'object') {
49
- const sorted = {};
50
- for (const key of Object.keys(value).sort()) {
51
- sorted[key] = canonicalize(value[key]);
52
- }
53
- return sorted;
54
- }
55
- return value;
56
- }
@@ -9,17 +9,20 @@ export declare const RUN_STATE_FILE_NAME = "run.json";
9
9
  * with fails closed as corrupt instead of being dispensed.
10
10
  */
11
11
  export declare const SHELL_SAFE_VALUE: RegExp;
12
+ export declare const ISSUE_ID: RegExp;
12
13
  declare const MIGRATE_RUN_STATUSES: readonly ['active', 'completed'];
13
14
  export type MigrateRunStatus = (typeof MIGRATE_RUN_STATUSES)[number];
14
15
  export interface MigrateRunRound {
15
16
  index: number;
16
- planHash: string;
17
17
  planSnapshot: string;
18
18
  }
19
- declare const MIGRATE_STEP_STATUSES: readonly ['pending', 'dispensed', 'running', 'awaiting-prompt-outcome', 'succeeded', 'failed', 'skipped', 'died'];
19
+ declare const MIGRATE_STEP_STATUSES: readonly ['pending', 'dispensed', 'running', 'awaiting-prompt-outcome', 'succeeded', 'failed', 'skipped', 'died', 'unresolved'];
20
20
  export type MigrateStepStatus = (typeof MIGRATE_STEP_STATUSES)[number];
21
+ export declare const TERMINAL_STEP_STATUSES: ReadonlySet<MigrateStepStatus>;
21
22
  declare const PROMPT_OUTCOME_STATUSES: readonly ['completed', 'skipped', 'failed'];
22
23
  export type PromptOutcomeStatus = (typeof PROMPT_OUTCOME_STATUSES)[number];
24
+ declare const MIGRATE_STEP_AWAITING_KINDS: readonly ['migration-prompt', 'generator-validation', 'final-validation'];
25
+ export type MigrateStepAwaitingKind = (typeof MIGRATE_STEP_AWAITING_KINDS)[number];
23
26
  export interface MigrateStepOutcome {
24
27
  fileChanges?: string[];
25
28
  gitRefAfter?: string;
@@ -30,10 +33,16 @@ export interface MigrateStepPromptOutcome {
30
33
  status: PromptOutcomeStatus;
31
34
  summary?: string;
32
35
  }
33
- export interface MigrateStep {
36
+ export type MigrateStepKindFields = {
37
+ kind: 'migration';
38
+ migrationId: string;
39
+ } | {
40
+ kind: 'final-validation';
41
+ };
42
+ export type MigrateStep = MigrateStepBase & MigrateStepKindFields;
43
+ export interface MigrateStepBase {
34
44
  id: string;
35
45
  roundIndex: number;
36
- migrationId: string;
37
46
  status: MigrateStepStatus;
38
47
  attempt: number;
39
48
  dispenseCount: number;
@@ -46,7 +55,16 @@ export interface MigrateStep {
46
55
  depsHashAtDispense?: string;
47
56
  outcome?: MigrateStepOutcome;
48
57
  promptOutcome?: MigrateStepPromptOutcome;
58
+ adopted?: boolean;
59
+ unresolvedIssueId?: string;
60
+ awaitingKind?: MigrateStepAwaitingKind;
61
+ commitLedgerIndex?: number;
62
+ commitStarted?: boolean;
49
63
  generatorCompleted?: boolean;
64
+ generatorCompletedAtAttempt?: number;
65
+ agenticWaived?: boolean;
66
+ validationOwed?: boolean;
67
+ generatorMadeChanges?: boolean;
50
68
  installFailed?: boolean;
51
69
  }
52
70
  declare const MIGRATE_COMMIT_KINDS: readonly ['checkpoint', 'landed', 'failed'];
@@ -55,11 +73,41 @@ export interface MigrateCommitLedgerEntry {
55
73
  sha?: string;
56
74
  kind: MigrateCommitKind;
57
75
  stepIds: string[];
76
+ issueIds?: string[];
77
+ }
78
+ /**
79
+ * Dedup key: the same underlying problem reported twice folds into one ledger
80
+ * entry. Derived from the normalized summary, so agent text never becomes a
81
+ * path or command fragment; the state reader re-checks the derivation on
82
+ * every persisted entry.
83
+ */
84
+ export declare function issueFingerprint(summary: string): string;
85
+ export declare const MIGRATE_ISSUE_DISPOSITIONS: readonly ['recorded', 'resolved', 'deferred-final'];
86
+ export type MigrateIssueDisposition = (typeof MIGRATE_ISSUE_DISPOSITIONS)[number];
87
+ export interface MigrateRunIssue {
88
+ id: string;
89
+ fingerprint: string;
90
+ summary: string;
91
+ reportedByStepId: string;
92
+ applicableStepIds: string[] | 'unknown';
93
+ disposition: MigrateIssueDisposition;
94
+ claimedByStepId?: string;
95
+ resolvedByStepId?: string;
96
+ resolvedAtCommitCount?: number;
58
97
  }
59
98
  export interface MigrateRunAnalytics {
60
99
  startEmitted: boolean;
61
100
  completeEmitted: boolean;
62
101
  }
102
+ export interface MigrateRunNoProgress {
103
+ fingerprint: string;
104
+ consecutiveCount: number;
105
+ firstSeenAt: string;
106
+ }
107
+ export interface MigrateRunPolicy {
108
+ createCommits: boolean;
109
+ skipInstall: boolean;
110
+ }
63
111
  export interface MigrateRunState {
64
112
  formatVersion: number;
65
113
  runId: string;
@@ -69,38 +117,49 @@ export interface MigrateRunState {
69
117
  createCommits: boolean;
70
118
  commitPrefix: string;
71
119
  skipInstall?: boolean;
120
+ validate?: boolean;
121
+ gitRefAtInit?: string;
122
+ runbookPath?: string;
123
+ branch?: string;
72
124
  rounds: MigrateRunRound[];
73
125
  steps: MigrateStep[];
74
126
  commits: MigrateCommitLedgerEntry[];
127
+ issues?: MigrateRunIssue[];
128
+ noProgress?: MigrateRunNoProgress;
75
129
  checkpointFailed?: boolean;
130
+ treeOperation?: MigrateTreeOperation;
76
131
  analytics: MigrateRunAnalytics;
77
132
  }
133
+ export declare const TREE_OPERATION_KINDS: readonly ['commit', 'install', 'fold-install', 'action-install', 'reset', 'give-up', 'checkpoint'];
134
+ export type MigrateTreeOperationKind = (typeof TREE_OPERATION_KINDS)[number];
135
+ export interface MigrateTreeOperation {
136
+ kind: MigrateTreeOperationKind;
137
+ stepId?: string;
138
+ attempt?: number;
139
+ owner: string;
140
+ pid: number;
141
+ }
78
142
  export declare function migrateRunsDir(root: string): string;
79
143
  export declare function runDir(root: string, runId: string): string;
80
144
  /** See `HANDOFFS_DIR_NAME` for why the subtree exists. */
81
145
  export declare function runHandoffsDir(runDirPath: string): string;
82
146
  /**
83
- * Thrown when a run.json declares a `formatVersion` newer than this Nx
147
+ * Thrown for a run.json whose `formatVersion` is newer than this Nx
84
148
  * understands. Callers must not treat such a run as absent: an older Nx
85
149
  * ignoring a newer active run would start a competing run on top of it.
86
150
  *
87
- * Adding a member to any persisted closed set (run status, step status,
88
- * prompt-outcome status, commit kind) needs a
89
- * `CURRENT_RUN_STATE_FORMAT_VERSION` bump: without it, an older Nx reading
90
- * the new value would reject the run as corrupt (the closed-set validation
91
- * fails) instead of refusing with this error's ask for a newer Nx.
151
+ * Adding a member to a persisted closed set needs a
152
+ * `CURRENT_RUN_STATE_FORMAT_VERSION` bump only once a released Nx can read the
153
+ * run, or that Nx rejects the new value as corruption instead of asking for a
154
+ * newer Nx.
92
155
  */
93
156
  export declare class NewerRunStateFormatError extends Error {
94
157
  constructor(message: string);
95
158
  }
96
159
  /**
97
- * Reads and validates `run.json` from a run directory.
98
- *
99
- * A `formatVersion` newer than {@link CURRENT_RUN_STATE_FORMAT_VERSION} means
100
- * the run was created by a newer Nx than the one currently running, so the
101
- * shape may not be interpretable here; this throws rather than attempting a
102
- * best-effort read. An older `formatVersion` is returned as-is: only v1
103
- * exists today, so there is nothing to migrate yet.
160
+ * Reads and validates `run.json` from a run directory. A `formatVersion`
161
+ * newer than {@link CURRENT_RUN_STATE_FORMAT_VERSION} throws instead of being
162
+ * read best-effort; an older one is returned as-is.
104
163
  */
105
164
  export declare function readRunState(runDirPath: string): MigrateRunState;
106
165
  /**
@@ -140,6 +199,7 @@ export declare function findActiveRun(root: string): {
140
199
  runId: string;
141
200
  state: MigrateRunState;
142
201
  } | null;
202
+ activeRunIds: string[];
143
203
  uninterpretable: UninterpretableRunDir[];
144
204
  };
145
205
  /**
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NewerRunStateFormatError = exports.SHELL_SAFE_VALUE = exports.RUN_STATE_FILE_NAME = exports.CURRENT_RUN_STATE_FORMAT_VERSION = void 0;
3
+ exports.NewerRunStateFormatError = exports.TREE_OPERATION_KINDS = exports.MIGRATE_ISSUE_DISPOSITIONS = exports.TERMINAL_STEP_STATUSES = exports.ISSUE_ID = exports.SHELL_SAFE_VALUE = exports.RUN_STATE_FILE_NAME = exports.CURRENT_RUN_STATE_FORMAT_VERSION = void 0;
4
+ exports.issueFingerprint = issueFingerprint;
4
5
  exports.migrateRunsDir = migrateRunsDir;
5
6
  exports.runDir = runDir;
6
7
  exports.runHandoffsDir = runHandoffsDir;
@@ -13,9 +14,11 @@ const fs_1 = require("fs");
13
14
  const crypto_1 = require("crypto");
14
15
  const path_1 = require("path");
15
16
  const fileutils_1 = require("../../../utils/fileutils");
17
+ const atomic_write_1 = require("./atomic-write");
16
18
  const git_utils_1 = require("../../../utils/git-utils");
17
19
  const versions_1 = require("../../../utils/versions");
18
20
  const types_1 = require("../agentic/types");
21
+ const handoff_1 = require("../agentic/handoff");
19
22
  const run_id_1 = require("./run-id");
20
23
  const text_1 = require("../text");
21
24
  exports.CURRENT_RUN_STATE_FORMAT_VERSION = 1;
@@ -48,7 +51,21 @@ const PLAN_SNAPSHOT_NAME = /^plan-\d+\.json$/;
48
51
  * transition with, and the worker throws that reason, which puts it in front
49
52
  * of the agent without passing the block-safe writer.
50
53
  */
51
- const STEP_ID = /^step-\d+$/;
54
+ const STEP_ID = /^step-\d{1,18}$/;
55
+ // The id names the archived detail file in the run's issues directory, so a
56
+ // tampered value must not resolve outside it. The suffix is bounded so the
57
+ // allocator, which mints against this same pattern, can never produce an id
58
+ // past the filesystem's component limit and then fail forever.
59
+ exports.ISSUE_ID = /^issue-\d{1,18}$/;
60
+ /**
61
+ * A resume joins this to the run directory and re-emits the file's bytes
62
+ * verbatim, so a tampered value naming a sibling (`run.json`, a plan
63
+ * snapshot) would leak that file's bytes past every line-safety check.
64
+ */
65
+ const RUNBOOK_NAME = /^RUNBOOK\.md$/;
66
+ // The terminators `singleLine` collapses. An embedded one could open a forged
67
+ // block at a line start in the stdout the agent scans.
68
+ const LINE_TERMINATORS = /[\r\n\u000b\u000c\u0085\u2028\u2029]/;
52
69
  // Keeps `.nx/migrate-runs` from growing unbounded across many `nx migrate`
53
70
  // invocations over the life of a workspace.
54
71
  const MAX_RETAINED_COMPLETED_RUNS = 5;
@@ -65,9 +82,50 @@ const MIGRATE_STEP_STATUSES = [
65
82
  'failed',
66
83
  'skipped',
67
84
  'died',
85
+ 'unresolved',
68
86
  ];
87
+ // 'failed' and 'died' can be re-armed; 'unresolved' cannot.
88
+ exports.TERMINAL_STEP_STATUSES = new Set([
89
+ 'succeeded',
90
+ 'skipped',
91
+ 'unresolved',
92
+ ]);
69
93
  const PROMPT_OUTCOME_STATUSES = ['completed', 'skipped', 'failed'];
94
+ const MIGRATE_STEP_AWAITING_KINDS = [
95
+ 'migration-prompt',
96
+ 'generator-validation',
97
+ 'final-validation',
98
+ ];
99
+ // What a step does when dispensed: 'migration' runs one planned migration,
100
+ // 'final-validation' checks the whole workspace once every migration has run.
101
+ const MIGRATE_STEP_KINDS = ['migration', 'final-validation'];
70
102
  const MIGRATE_COMMIT_KINDS = ['checkpoint', 'landed', 'failed'];
103
+ /**
104
+ * Dedup key: the same underlying problem reported twice folds into one ledger
105
+ * entry. Derived from the normalized summary, so agent text never becomes a
106
+ * path or command fragment; the state reader re-checks the derivation on
107
+ * every persisted entry.
108
+ */
109
+ function issueFingerprint(summary) {
110
+ return (0, crypto_1.createHash)('sha256')
111
+ .update(summary.toLowerCase().replace(/\s+/g, ' ').trim())
112
+ .digest('hex')
113
+ .slice(0, 16);
114
+ }
115
+ exports.MIGRATE_ISSUE_DISPOSITIONS = [
116
+ 'recorded',
117
+ 'resolved',
118
+ 'deferred-final',
119
+ ];
120
+ exports.TREE_OPERATION_KINDS = [
121
+ 'commit',
122
+ 'install',
123
+ 'fold-install',
124
+ 'action-install',
125
+ 'reset',
126
+ 'give-up',
127
+ 'checkpoint',
128
+ ];
71
129
  const REQUIRED_TOP_LEVEL_FIELDS = [
72
130
  'formatVersion',
73
131
  'runId',
@@ -127,10 +185,19 @@ function isOptionalStringArray(value) {
127
185
  return (value === undefined ||
128
186
  (Array.isArray(value) && value.every((item) => typeof item === 'string')));
129
187
  }
188
+ function isOptionalMatching(pattern, value) {
189
+ return (value === undefined || (typeof value === 'string' && pattern.test(value)));
190
+ }
191
+ function isLineSafeString(value) {
192
+ return typeof value === 'string' && !LINE_TERMINATORS.test(value);
193
+ }
194
+ function isStepIdArray(value) {
195
+ return (Array.isArray(value) &&
196
+ value.every((id) => typeof id === 'string' && STEP_ID.test(id)));
197
+ }
130
198
  function isRoundShape(value) {
131
199
  return (isPlainObject(value) &&
132
200
  typeof value.index === 'number' &&
133
- typeof value.planHash === 'string' &&
134
201
  typeof value.planSnapshot === 'string' &&
135
202
  PLAN_SNAPSHOT_NAME.test(value.planSnapshot));
136
203
  }
@@ -148,15 +215,34 @@ function isPromptOutcomeShape(value) {
148
215
  isOneOf(PROMPT_OUTCOME_STATUSES, value.status) &&
149
216
  isOptionalString(value.summary)));
150
217
  }
218
+ function isStepKindShape(value) {
219
+ const kind = value.kind === undefined ? 'migration' : value.kind;
220
+ if (!isOneOf(MIGRATE_STEP_KINDS, kind))
221
+ return false;
222
+ switch (kind) {
223
+ case 'migration':
224
+ return (typeof value.migrationId === 'string' &&
225
+ exports.SHELL_SAFE_VALUE.test(value.migrationId));
226
+ case 'final-validation':
227
+ return value.migrationId === undefined;
228
+ default: {
229
+ const exhaustive = kind;
230
+ throw new Error(`Unhandled step kind '${exhaustive}'.`);
231
+ }
232
+ }
233
+ }
151
234
  function isStepShape(value) {
152
235
  return (isPlainObject(value) &&
153
236
  typeof value.id === 'string' &&
154
237
  STEP_ID.test(value.id) &&
155
238
  typeof value.roundIndex === 'number' &&
156
- typeof value.migrationId === 'string' &&
157
- exports.SHELL_SAFE_VALUE.test(value.migrationId) &&
239
+ isStepKindShape(value) &&
158
240
  isOneOf(MIGRATE_STEP_STATUSES, value.status) &&
159
- typeof value.attempt === 'number' &&
241
+ // The attempt is interpolated into the stored-payload file name and
242
+ // range-compared against it (agent-work-payload.ts), so a fractional or
243
+ // non-finite value (JSON's 1e400 parses to Infinity) must be refused here.
244
+ Number.isSafeInteger(value.attempt) &&
245
+ value.attempt >= 1 &&
160
246
  typeof value.dispenseCount === 'number' &&
161
247
  isOptionalBoolean(value.hasGenerator) &&
162
248
  isOptionalNumber(value.pid) &&
@@ -167,8 +253,29 @@ function isStepShape(value) {
167
253
  isOptionalString(value.depsHashAtDispense) &&
168
254
  isStepOutcomeShape(value.outcome) &&
169
255
  isPromptOutcomeShape(value.promptOutcome) &&
256
+ (value.awaitingKind === undefined ||
257
+ isOneOf(MIGRATE_STEP_AWAITING_KINDS, value.awaitingKind)) &&
258
+ isOptionalBoolean(value.commitStarted) &&
170
259
  isOptionalBoolean(value.generatorCompleted) &&
260
+ // Bounded by the step's attempt: a higher value could not name one that
261
+ // exists.
262
+ (value.generatorCompletedAtAttempt === undefined ||
263
+ (Number.isSafeInteger(value.generatorCompletedAtAttempt) &&
264
+ value.generatorCompletedAtAttempt >= 1 &&
265
+ value.generatorCompletedAtAttempt <=
266
+ value.attempt)) &&
267
+ (value.commitLedgerIndex === undefined ||
268
+ (Number.isSafeInteger(value.commitLedgerIndex) &&
269
+ value.commitLedgerIndex >= 0)) &&
270
+ isOptionalBoolean(value.agenticWaived) &&
271
+ isOptionalBoolean(value.validationOwed) &&
272
+ isOptionalBoolean(value.generatorMadeChanges) &&
171
273
  isOptionalBoolean(value.installFailed) &&
274
+ isOptionalBoolean(value.adopted) &&
275
+ isOptionalMatching(exports.ISSUE_ID, value.unresolvedIssueId) &&
276
+ // Minted by the same write that gives the step up, so it never names a
277
+ // step in any other status.
278
+ (value.unresolvedIssueId === undefined || value.status === 'unresolved') &&
172
279
  // A cross-field invariant the rest of the loop relies on: a running step
173
280
  // without a pid is never reclassified as died and no step action targets
174
281
  // it, so it stalls the run forever.
@@ -177,9 +284,110 @@ function isStepShape(value) {
177
284
  function isCommitLedgerEntryShape(value) {
178
285
  return (isPlainObject(value) &&
179
286
  isOneOf(MIGRATE_COMMIT_KINDS, value.kind) &&
180
- Array.isArray(value.stepIds) &&
181
- value.stepIds.every((id) => typeof id === 'string' && STEP_ID.test(id)) &&
182
- isOptionalSha(value.sha));
287
+ isStepIdArray(value.stepIds) &&
288
+ isOptionalSha(value.sha) &&
289
+ (value.issueIds === undefined ||
290
+ (Array.isArray(value.issueIds) &&
291
+ value.issueIds.every((id) => typeof id === 'string' && exports.ISSUE_ID.test(id)))));
292
+ }
293
+ // The id names the archived `issues/<id>.json`, so a duplicate would alias two
294
+ // entries onto one file. Runs after isIssueShape, so the ids are known strings.
295
+ function hasUniqueIssueIds(issues) {
296
+ return (new Set(issues.map((issue) => issue.id)).size ===
297
+ issues.length);
298
+ }
299
+ // A duplicate would make every step lookup ambiguous, and a bare-package
300
+ // report against it would write applicability this same reader rejects.
301
+ function hasUniqueStepIds(steps) {
302
+ return (new Set(steps.map((step) => step.id)).size ===
303
+ steps.length);
304
+ }
305
+ // The fingerprint is the duplicate-report fold key; two entries sharing one
306
+ // would make ledger order decide which entry a report folds into.
307
+ function hasUniqueIssueFingerprints(issues) {
308
+ return (new Set(issues.map((issue) => issue.fingerprint)).size === issues.length);
309
+ }
310
+ // Cross-entry references, checked after the per-entry shapes so the casts
311
+ // hold. nx never writes these violations, and the helpers that trust the
312
+ // fields (routing, resolver credit, carried checks) cannot repair them.
313
+ function hasSoundIssueRefs(parsed) {
314
+ const issues = parsed.issues;
315
+ const steps = parsed.steps;
316
+ const stepIds = new Set(steps.map((s) => s.id));
317
+ const stepOrder = new Map(steps.map((s, index) => [s.id, index]));
318
+ const commitCount = parsed.commits.length;
319
+ return issues.every((issue) => stepIds.has(issue.reportedByStepId) &&
320
+ (issue.applicableStepIds === 'unknown' ||
321
+ (issue.applicableStepIds.every((id) => stepIds.has(id)) &&
322
+ // Applicability is a plan-ordered set (mints and merges both emit it that
323
+ // way): a duplicate would read as newly supplied routing in the normalizing
324
+ // merge, and an unordered scope is a shape no transition writes.
325
+ issue.applicableStepIds.every((id, index) => index === 0 ||
326
+ stepOrder.get(issue.applicableStepIds[index - 1]) <
327
+ stepOrder.get(id)))) &&
328
+ (issue.claimedByStepId === undefined ||
329
+ (Array.isArray(issue.applicableStepIds) &&
330
+ issue.applicableStepIds.includes(issue.claimedByStepId))) &&
331
+ (issue.resolvedByStepId === undefined ||
332
+ stepIds.has(issue.resolvedByStepId)) &&
333
+ (issue.resolvedAtCommitCount === undefined ||
334
+ issue.resolvedAtCommitCount <= commitCount));
335
+ }
336
+ function isIssueShape(value) {
337
+ return (isPlainObject(value) &&
338
+ typeof value.id === 'string' &&
339
+ exports.ISSUE_ID.test(value.id) &&
340
+ isLineSafeString(value.summary) &&
341
+ // The derivation is enforced, not just the shape: a fingerprint detached from
342
+ // its summary would split one problem into independent histories.
343
+ value.fingerprint === issueFingerprint(value.summary) &&
344
+ typeof value.reportedByStepId === 'string' &&
345
+ STEP_ID.test(value.reportedByStepId) &&
346
+ // Reports carry 1+ identifiers and merges only widen, so [] is unproducible.
347
+ (value.applicableStepIds === 'unknown' ||
348
+ (isStepIdArray(value.applicableStepIds) &&
349
+ value.applicableStepIds.length > 0)) &&
350
+ isOneOf(exports.MIGRATE_ISSUE_DISPOSITIONS, value.disposition) &&
351
+ isOptionalMatching(STEP_ID, value.claimedByStepId) &&
352
+ isOptionalMatching(STEP_ID, value.resolvedByStepId) &&
353
+ // The helpers built on these (commit association, retry-clean reverts, update
354
+ // ownership) break on a state outside them.
355
+ (value.claimedByStepId === undefined || value.disposition === 'recorded') &&
356
+ (value.disposition === 'resolved') ===
357
+ (value.resolvedByStepId !== undefined) &&
358
+ // A resolution without a stamp has no carried-commit window; a stamp without
359
+ // a resolution fences nothing that exists.
360
+ (value.disposition === 'resolved') ===
361
+ (value.resolvedAtCommitCount !== undefined) &&
362
+ (value.resolvedAtCommitCount === undefined ||
363
+ (Number.isSafeInteger(value.resolvedAtCommitCount) &&
364
+ value.resolvedAtCommitCount >= 0)));
365
+ }
366
+ // The record drives the no-progress cutoff: a count outside the positive
367
+ // integers (JSON's 1e400 parses to Infinity) could delay it forever, and an
368
+ // empty fingerprint would collapse unrelated responses into one streak.
369
+ function isNoProgressShape(value) {
370
+ return (value === undefined ||
371
+ (isPlainObject(value) &&
372
+ isLineSafeString(value.fingerprint) &&
373
+ value.fingerprint.length > 0 &&
374
+ Number.isSafeInteger(value.consecutiveCount) &&
375
+ value.consecutiveCount > 0 &&
376
+ typeof value.firstSeenAt === 'string' &&
377
+ ISO_TIMESTAMP.test(value.firstSeenAt)));
378
+ }
379
+ function isTreeOperationShape(value) {
380
+ return (value === undefined ||
381
+ (isPlainObject(value) &&
382
+ isOneOf(exports.TREE_OPERATION_KINDS, value.kind) &&
383
+ (value.stepId === undefined || typeof value.stepId === 'string') &&
384
+ (value.attempt === undefined ||
385
+ (Number.isSafeInteger(value.attempt) &&
386
+ value.attempt >= 1)) &&
387
+ typeof value.owner === 'string' &&
388
+ value.owner.length > 0 &&
389
+ Number.isSafeInteger(value.pid) &&
390
+ value.pid > 0));
183
391
  }
184
392
  function isAnalyticsShape(value) {
185
393
  return (isPlainObject(value) &&
@@ -200,24 +408,45 @@ function hasValidRunStateShape(parsed) {
200
408
  isOneOf(MIGRATE_RUN_STATUSES, parsed.status) &&
201
409
  isOptionalBoolean(parsed.checkpointFailed) &&
202
410
  isOptionalBoolean(parsed.skipInstall) &&
411
+ isOptionalBoolean(parsed.validate) &&
412
+ isOptionalSha(parsed.gitRefAtInit) &&
413
+ isOptionalMatching(RUNBOOK_NAME, parsed.runbookPath) &&
414
+ isOptionalString(parsed.branch) &&
203
415
  parsed.rounds.every(isRoundShape) &&
204
416
  parsed.steps.every(isStepShape) &&
417
+ hasUniqueStepIds(parsed.steps) &&
205
418
  parsed.commits.every(isCommitLedgerEntryShape) &&
419
+ (parsed.issues === undefined ||
420
+ (Array.isArray(parsed.issues) &&
421
+ parsed.issues.every(isIssueShape) &&
422
+ hasUniqueIssueIds(parsed.issues) &&
423
+ hasUniqueIssueFingerprints(parsed.issues) &&
424
+ hasSoundIssueRefs(parsed))) &&
425
+ // Written only for issues that already existed: a dangling id could make a
426
+ // future issue's resolution look carried by a commit that predates it.
427
+ parsed.commits.every((c) => c.issueIds === undefined ||
428
+ c.issueIds.every((id) => hasIssueWithId(parsed, id))) &&
429
+ parsed.steps.every((s) => s.unresolvedIssueId === undefined ||
430
+ hasIssueWithId(parsed, s.unresolvedIssueId)) &&
431
+ isNoProgressShape(parsed.noProgress) &&
432
+ isTreeOperationShape(parsed.treeOperation) &&
206
433
  isAnalyticsShape(parsed.analytics));
207
434
  }
435
+ function hasIssueWithId(parsed, id) {
436
+ return (parsed.issues ?? []).some((i) => i.id === id);
437
+ }
208
438
  function corruptRunStateError(filePath, reason) {
209
439
  return new Error(`Corrupt run state at ${filePath}: ${reason}`);
210
440
  }
211
441
  /**
212
- * Thrown when a run.json declares a `formatVersion` newer than this Nx
442
+ * Thrown for a run.json whose `formatVersion` is newer than this Nx
213
443
  * understands. Callers must not treat such a run as absent: an older Nx
214
444
  * ignoring a newer active run would start a competing run on top of it.
215
445
  *
216
- * Adding a member to any persisted closed set (run status, step status,
217
- * prompt-outcome status, commit kind) needs a
218
- * `CURRENT_RUN_STATE_FORMAT_VERSION` bump: without it, an older Nx reading
219
- * the new value would reject the run as corrupt (the closed-set validation
220
- * fails) instead of refusing with this error's ask for a newer Nx.
446
+ * Adding a member to a persisted closed set needs a
447
+ * `CURRENT_RUN_STATE_FORMAT_VERSION` bump only once a released Nx can read the
448
+ * run, or that Nx rejects the new value as corruption instead of asking for a
449
+ * newer Nx.
221
450
  */
222
451
  class NewerRunStateFormatError extends Error {
223
452
  constructor(message) {
@@ -227,17 +456,17 @@ class NewerRunStateFormatError extends Error {
227
456
  }
228
457
  exports.NewerRunStateFormatError = NewerRunStateFormatError;
229
458
  /**
230
- * Reads and validates `run.json` from a run directory.
231
- *
232
- * A `formatVersion` newer than {@link CURRENT_RUN_STATE_FORMAT_VERSION} means
233
- * the run was created by a newer Nx than the one currently running, so the
234
- * shape may not be interpretable here; this throws rather than attempting a
235
- * best-effort read. An older `formatVersion` is returned as-is: only v1
236
- * exists today, so there is nothing to migrate yet.
459
+ * Reads and validates `run.json` from a run directory. A `formatVersion`
460
+ * newer than {@link CURRENT_RUN_STATE_FORMAT_VERSION} throws instead of being
461
+ * read best-effort; an older one is returned as-is.
237
462
  */
238
463
  function readRunState(runDirPath) {
239
464
  const filePath = (0, path_1.join)(runDirPath, exports.RUN_STATE_FILE_NAME);
240
- const content = (0, fs_1.readFileSync)(filePath, 'utf-8');
465
+ // run.json lives in the agent-writable run directory, so it could be a
466
+ // planted symlink or FIFO; read it without reading a symlink's target or
467
+ // blocking on a FIFO, while still tolerating a concurrent tmp + rename
468
+ // publish. A non-regular file reads as corruption; ENOENT stays "no run".
469
+ const content = (0, handoff_1.readAtomicallyPublishedFile)(filePath, corruptRunStateError(filePath, 'is not a regular file.').message);
241
470
  let parsed;
242
471
  try {
243
472
  parsed = JSON.parse(content);
@@ -260,7 +489,7 @@ function readRunState(runDirPath) {
260
489
  const createdBy = typeof parsed.nxVersion === 'string'
261
490
  ? `Nx ${(0, text_1.singleLine)(parsed.nxVersion)}`
262
491
  : 'a newer version of Nx';
263
- throw new NewerRunStateFormatError(`This migrate run was created with ${createdBy} (run state format v${parsed.formatVersion}), which is newer than the Nx version currently running, ${versions_1.nxVersion} (run state format v${exports.CURRENT_RUN_STATE_FORMAT_VERSION}). Re-run your migrate command with ${createdBy} or later to resume this run.`);
492
+ throw new NewerRunStateFormatError(`This migrate run was created with ${createdBy} (run state format v${parsed.formatVersion}), which is newer than the Nx version currently running, ${versions_1.nxVersion} (run state format v${exports.CURRENT_RUN_STATE_FORMAT_VERSION}). Re-run your migrate command with ${createdBy} or later.`);
264
493
  }
265
494
  if (REQUIRED_TOP_LEVEL_FIELDS.some((field) => !(field in parsed)) ||
266
495
  !hasValidRunStateShape(parsed)) {
@@ -276,7 +505,10 @@ function readRunState(runDirPath) {
276
505
  // literal.
277
506
  throw corruptRunStateError(filePath, `declares run id ${JSON.stringify((0, text_1.singleLine)(parsed.runId))} but sits in a directory named ${JSON.stringify((0, text_1.singleLine)((0, path_1.basename)(runDirPath)))}.`);
278
507
  }
279
- return parsed;
508
+ // Steps written before they had a kind each ran a migration; naming it here
509
+ // keeps every reader on one shape.
510
+ const steps = parsed.steps.map((s) => s.kind === undefined ? { ...s, kind: 'migration' } : s);
511
+ return { ...parsed, steps };
280
512
  }
281
513
  /**
282
514
  * Writes `run.json` atomically: serializes to a temp file in the same
@@ -288,9 +520,7 @@ function readRunState(runDirPath) {
288
520
  */
289
521
  function writeRunState(runDirPath, state) {
290
522
  const filePath = (0, path_1.join)(runDirPath, exports.RUN_STATE_FILE_NAME);
291
- const tmpPath = `${filePath}~${(0, crypto_1.randomBytes)(4).toString('hex')}`;
292
- (0, fileutils_1.writeJsonFile)(tmpPath, state);
293
- (0, fs_1.renameSync)(tmpPath, filePath);
523
+ (0, atomic_write_1.publishFileAtomically)(filePath, (tmpPath) => (0, fileutils_1.writeJsonFile)(tmpPath, state));
294
524
  }
295
525
  // ENOENT is the ordinary "no runs yet" answer. Any other failure (EACCES,
296
526
  // ENOTDIR) hides runs that may exist, so it propagates rather than reading
@@ -345,6 +575,7 @@ function readRunDirState(candidateDir) {
345
575
  */
346
576
  function findActiveRun(root) {
347
577
  let newest = null;
578
+ const activeRunIds = [];
348
579
  const uninterpretable = [];
349
580
  for (const entry of readDirEntries(migrateRunsDir(root))) {
350
581
  if (!entry.isDirectory())
@@ -378,11 +609,12 @@ function findActiveRun(root) {
378
609
  });
379
610
  continue;
380
611
  }
612
+ activeRunIds.push(entry.name);
381
613
  if (!newest || state.createdAt > newest.state.createdAt) {
382
614
  newest = { runId: entry.name, state };
383
615
  }
384
616
  }
385
- return { active: newest, uninterpretable };
617
+ return { active: newest, activeRunIds, uninterpretable };
386
618
  }
387
619
  /**
388
620
  * Creates a new run directory and writes its initial state, then prunes old
@@ -397,9 +629,8 @@ function findActiveRun(root) {
397
629
  */
398
630
  function createRun(root, state) {
399
631
  const dir = runDir(root, state.runId);
400
- // Created up front, and each step's package directory at dispense, so the
401
- // agent never has to `mkdir -p`: that costs a workspace-permission prompt in
402
- // agents like Claude Code, on every step.
632
+ // Created up front so the agent never has to `mkdir -p`: that costs a
633
+ // workspace-permission prompt in agents like Claude Code, on every step.
403
634
  (0, fs_1.mkdirSync)(runHandoffsDir(dir), { recursive: true });
404
635
  writeRunState(dir, state);
405
636
  pruneCompletedRuns(root, state.runId);