@ohos-ports/nx 23.3.0-beta.2 → 24.0.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/README.md +3 -6
  2. package/dist/bin/nx.js +2 -2
  3. package/dist/bin/post-install.js +5 -3
  4. package/dist/nx-cloud-internals.d.ts +1 -0
  5. package/dist/nx-cloud-internals.js +7 -1
  6. package/dist/src/adapter/ngcli-adapter.js +2 -2
  7. package/dist/src/ai/clone-ai-config-repo.js +49 -12
  8. package/dist/src/command-line/add/add.d.ts +2 -0
  9. package/dist/src/command-line/add/add.js +23 -5
  10. package/dist/src/command-line/affected/affected.js +2 -2
  11. package/dist/src/command-line/configure-ai-agents/configure-ai-agents.js +0 -12
  12. package/dist/src/command-line/graph/graph.js +38 -10
  13. package/dist/src/command-line/init/command-object.js +0 -12
  14. package/dist/src/command-line/init/implementation/add-nx-to-nest.js +21 -62
  15. package/dist/src/command-line/init/init-v2.js +0 -2
  16. package/dist/src/command-line/migrate/agentic/close-agent-session.d.ts +1 -1
  17. package/dist/src/command-line/migrate/agentic/close-agent-session.js +4 -3
  18. package/dist/src/command-line/migrate/agentic/definitions.d.ts +1 -3
  19. package/dist/src/command-line/migrate/agentic/definitions.js +5 -97
  20. package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +7 -45
  21. package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +9 -51
  22. package/dist/src/command-line/migrate/agentic/handoff.d.ts +1 -43
  23. package/dist/src/command-line/migrate/agentic/handoff.js +3 -119
  24. package/dist/src/command-line/migrate/agentic/instruction-files.d.ts +0 -21
  25. package/dist/src/command-line/migrate/agentic/instruction-files.js +6 -27
  26. package/dist/src/command-line/migrate/agentic/master/run-master-session.d.ts +19 -1
  27. package/dist/src/command-line/migrate/agentic/master/run-master-session.js +88 -49
  28. package/dist/src/command-line/migrate/agentic/master/spawn-master.d.ts +1 -0
  29. package/dist/src/command-line/migrate/agentic/master/spawn-master.js +86 -24
  30. package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.d.ts +2 -2
  31. package/dist/src/command-line/migrate/agentic/print-dropped-agent-context.js +2 -2
  32. package/dist/src/command-line/migrate/agentic/prompts/fragments.d.ts +1 -12
  33. package/dist/src/command-line/migrate/agentic/prompts/fragments.js +8 -17
  34. package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.d.ts +0 -15
  35. package/dist/src/command-line/migrate/agentic/prompts/shared-rendering.js +3 -100
  36. package/dist/src/command-line/migrate/agentic/select.d.ts +12 -6
  37. package/dist/src/command-line/migrate/agentic/select.js +38 -8
  38. package/dist/src/command-line/migrate/agentic/types.d.ts +9 -68
  39. package/dist/src/command-line/migrate/agentic/types.js +6 -8
  40. package/dist/src/command-line/migrate/command-object.js +6 -10
  41. package/dist/src/command-line/migrate/execute-migration.d.ts +6 -6
  42. package/dist/src/command-line/migrate/execute-migration.js +25 -15
  43. package/dist/src/command-line/migrate/migrate-analytics.d.ts +18 -1
  44. package/dist/src/command-line/migrate/migrate-analytics.js +38 -0
  45. package/dist/src/command-line/migrate/migrate-commits.d.ts +29 -17
  46. package/dist/src/command-line/migrate/migrate-commits.js +86 -32
  47. package/dist/src/command-line/migrate/migrate-config.d.ts +6 -6
  48. package/dist/src/command-line/migrate/migrate-config.js +12 -6
  49. package/dist/src/command-line/migrate/migrate-output.d.ts +1 -6
  50. package/dist/src/command-line/migrate/migrate-output.js +1 -10
  51. package/dist/src/command-line/migrate/migrate.d.ts +6 -30
  52. package/dist/src/command-line/migrate/migrate.js +257 -255
  53. package/dist/src/command-line/migrate/resolve-package-version.d.ts +2 -4
  54. package/dist/src/command-line/migrate/resolve-package-version.js +2 -35
  55. package/dist/src/command-line/migrate/run/agent-output.d.ts +2 -0
  56. package/dist/src/command-line/migrate/run/agent-output.js +9 -0
  57. package/dist/src/command-line/migrate/run/broker.d.ts +14 -5
  58. package/dist/src/command-line/migrate/run/broker.js +69 -21
  59. package/dist/src/command-line/migrate/run/clean-retry.js +4 -2
  60. package/dist/src/command-line/migrate/run/existing-run-report.d.ts +1 -1
  61. package/dist/src/command-line/migrate/run/existing-run-report.js +7 -5
  62. package/dist/src/command-line/migrate/run/give-up.d.ts +4 -3
  63. package/dist/src/command-line/migrate/run/give-up.js +8 -5
  64. package/dist/src/command-line/migrate/run/index.d.ts +7 -5
  65. package/dist/src/command-line/migrate/run/index.js +16 -1
  66. package/dist/src/command-line/migrate/run/issues.js +7 -2
  67. package/dist/src/command-line/migrate/run/orchestrator.d.ts +61 -4
  68. package/dist/src/command-line/migrate/run/orchestrator.js +397 -133
  69. package/dist/src/command-line/migrate/run/run-state.d.ts +17 -1
  70. package/dist/src/command-line/migrate/run/run-state.js +41 -2
  71. package/dist/src/command-line/migrate/run/runbook.d.ts +1 -0
  72. package/dist/src/command-line/migrate/run/runbook.js +115 -18
  73. package/dist/src/command-line/migrate/run/state-lock.d.ts +29 -4
  74. package/dist/src/command-line/migrate/run/state-lock.js +102 -10
  75. package/dist/src/command-line/migrate/run/state-machine.js +4 -1
  76. package/dist/src/command-line/migrate/run/util.d.ts +7 -2
  77. package/dist/src/command-line/migrate/run/util.js +30 -3
  78. package/dist/src/command-line/migrate/run/worker.d.ts +1 -1
  79. package/dist/src/command-line/migrate/run/worker.js +252 -250
  80. package/dist/src/command-line/migrate/sort-migrations.d.ts +1 -7
  81. package/dist/src/command-line/migrate/sort-migrations.js +1 -12
  82. package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +17 -12
  83. package/dist/src/command-line/release/changelog.js +9 -6
  84. package/dist/src/command-line/release/config/config.d.ts +1 -0
  85. package/dist/src/command-line/release/config/config.js +48 -9
  86. package/dist/src/command-line/release/release.js +2 -2
  87. package/dist/src/command-line/release/utils/git.js +8 -7
  88. package/dist/src/command-line/release/utils/interpolate-release-config.d.ts +6 -0
  89. package/dist/src/command-line/release/utils/interpolate-release-config.js +39 -0
  90. package/dist/src/command-line/release/utils/release-graph.d.ts +5 -0
  91. package/dist/src/command-line/release/utils/release-graph.js +1 -0
  92. package/dist/src/command-line/release/utils/remote-release-clients/github.js +5 -6
  93. package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +5 -6
  94. package/dist/src/command-line/release/utils/resolve-changelog-renderer.js +2 -2
  95. package/dist/src/command-line/release/utils/shared.js +10 -10
  96. package/dist/src/command-line/release/utils/version-plan-utils.d.ts +3 -12
  97. package/dist/src/command-line/release/utils/version-plan-utils.js +33 -55
  98. package/dist/src/command-line/release/version/version-actions.js +2 -1
  99. package/dist/src/command-line/release/version.js +5 -2
  100. package/dist/src/command-line/reset/reset.js +58 -62
  101. package/dist/src/command-line/run/executor-utils.js +1 -0
  102. package/dist/src/command-line/run/run-one.d.ts +20 -1
  103. package/dist/src/command-line/run/run-one.js +153 -5
  104. package/dist/src/command-line/run/run.js +2 -1
  105. package/dist/src/command-line/show/projects.js +5 -3
  106. package/dist/src/command-line/show/show-target/info.d.ts +10 -1
  107. package/dist/src/command-line/show/show-target/info.js +100 -15
  108. package/dist/src/command-line/show/show-target/inputs.js +10 -2
  109. package/dist/src/command-line/show/show-target/utils.js +1 -0
  110. package/dist/src/command-line/watch/command-object.js +3 -22
  111. package/dist/src/command-line/watch/watch.d.ts +0 -7
  112. package/dist/src/command-line/watch/watch.js +1 -1
  113. package/dist/src/command-line/yargs-utils/shared-options.js +1 -1
  114. package/dist/src/config/misc-interfaces.d.ts +18 -0
  115. package/dist/src/config/nx-json.d.ts +22 -11
  116. package/dist/src/config/task-graph.d.ts +1 -1
  117. package/dist/src/config/workspace-json-project-json.d.ts +88 -0
  118. package/dist/src/core/graph/main.js +1 -1
  119. package/dist/src/core/graph/runtime.js +1 -1
  120. package/dist/src/core/graph/styles.css +1 -1
  121. package/dist/src/core/graph/styles.js +1 -1
  122. package/dist/src/daemon/client/client.d.ts +15 -0
  123. package/dist/src/daemon/client/client.js +181 -71
  124. package/dist/src/daemon/client/daemon-socket-messenger.d.ts +1 -1
  125. package/dist/src/daemon/client/daemon-socket-messenger.js +2 -2
  126. package/dist/src/daemon/server/client-socket-context.js +1 -1
  127. package/dist/src/daemon/server/handle-process-in-background.js +21 -9
  128. package/dist/src/daemon/server/handle-select-affected-tasks.d.ts +2 -1
  129. package/dist/src/daemon/server/handle-select-affected-tasks.js +21 -13
  130. package/dist/src/daemon/server/native-js-loader.d.ts +1 -0
  131. package/dist/src/daemon/server/native-js-loader.js +21 -0
  132. package/dist/src/daemon/server/project-graph-incremental-recomputation.js +4 -8
  133. package/dist/src/daemon/server/server.d.ts +2 -1
  134. package/dist/src/daemon/server/server.js +17 -4
  135. package/dist/src/daemon/server/shutdown-utils.js +0 -3
  136. package/dist/src/daemon/server/start.d.ts +1 -0
  137. package/dist/src/daemon/server/start.js +2 -0
  138. package/dist/src/daemon/socket-utils.d.ts +11 -9
  139. package/dist/src/daemon/socket-utils.js +31 -61
  140. package/dist/src/daemon/tmp-dir.d.ts +19 -14
  141. package/dist/src/daemon/tmp-dir.js +142 -354
  142. package/dist/src/devkit-exports.d.ts +9 -1
  143. package/dist/src/devkit-exports.js +12 -1
  144. package/dist/src/devkit-internals.d.ts +6 -5
  145. package/dist/src/devkit-internals.js +13 -4
  146. package/dist/src/executors/run-commands/run-commands.impl.d.ts +4 -2
  147. package/dist/src/executors/run-commands/run-commands.impl.js +53 -27
  148. package/dist/src/executors/run-commands/running-tasks.d.ts +13 -4
  149. package/dist/src/executors/run-commands/running-tasks.js +148 -95
  150. package/dist/src/executors/run-commands/schema.json +1 -1
  151. package/dist/src/hasher/check-task-files.js +5 -8
  152. package/dist/src/hasher/file-hasher.js +9 -7
  153. package/dist/src/hasher/hash-task.js +4 -0
  154. package/dist/src/hasher/native-task-hasher-impl.js +3 -1
  155. package/dist/src/hasher/task-hasher.d.ts +2 -0
  156. package/dist/src/hasher/task-hasher.js +4 -1
  157. package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.d.ts +1 -2
  158. package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.js +6 -11
  159. package/dist/src/migrations/update-23-2-0/set-cache-on-executor-target-defaults.md +2 -2
  160. package/dist/src/migrations/update-24-0-0/enable-legacy-affected.d.ts +4 -0
  161. package/dist/src/migrations/update-24-0-0/enable-legacy-affected.js +15 -0
  162. package/dist/src/migrations/update-24-0-0/enable-legacy-affected.md +30 -0
  163. package/dist/src/migrations/update-24-0-0/find-custom-hashers.d.ts +3 -0
  164. package/dist/src/migrations/update-24-0-0/find-custom-hashers.js +100 -0
  165. package/dist/src/migrations/update-24-0-0/find-custom-hashers.md +63 -0
  166. package/dist/src/migrations/update-24-0-0/move-custom-hashers-to-inputs.md +146 -0
  167. package/dist/src/migrations/update-24-0-0/rename-ultracache-ignore-options.d.ts +3 -0
  168. package/dist/src/migrations/update-24-0-0/rename-ultracache-ignore-options.js +130 -0
  169. package/dist/src/migrations/update-24-0-0/rename-ultracache-ignore-options.md +62 -0
  170. package/dist/src/native/assert-supported-platform.js +1 -1
  171. package/dist/src/native/index.d.ts +238 -18
  172. package/dist/src/native/index.js +6 -1
  173. package/dist/src/native/native-bindings.js +15 -6
  174. package/dist/src/native/nx.openharmony-arm64.node +0 -0
  175. package/dist/src/native/nx.wasi-browser.js +1 -0
  176. package/dist/src/native/nx.wasi.cjs +1 -0
  177. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  178. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  179. package/dist/src/nx-cloud/update-manager.d.ts +14 -0
  180. package/dist/src/nx-cloud/update-manager.js +237 -50
  181. package/dist/src/plugins/js/lock-file/pnpm-parser.js +3 -4
  182. package/dist/src/plugins/js/lock-file/pruned-output.d.ts +2 -2
  183. package/dist/src/plugins/js/lock-file/pruned-output.js +4 -4
  184. package/dist/src/plugins/js/utils/register.js +9 -4
  185. package/dist/src/project-graph/affected/affected-tasks.d.ts +9 -6
  186. package/dist/src/project-graph/affected/affected-tasks.js +31 -7
  187. package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +7 -0
  188. package/dist/src/project-graph/plugins/loaded-nx-plugin.js +49 -6
  189. package/dist/src/project-graph/utils/project-configuration/target-merging.js +1 -1
  190. package/dist/src/project-graph/utils/project-configuration/target-normalization.js +12 -133
  191. package/dist/src/project-graph/utils/project-configuration-utils.js +2 -2
  192. package/dist/src/project-graph/utils/retrieve-workspace-files.js +27 -6
  193. package/dist/src/tasks-runner/create-task-graph.d.ts +8 -7
  194. package/dist/src/tasks-runner/create-task-graph.js +50 -27
  195. package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
  196. package/dist/src/tasks-runner/init-tasks-runner.js +116 -59
  197. package/dist/src/tasks-runner/life-cycle.d.ts +4 -1
  198. package/dist/src/tasks-runner/life-cycle.js +7 -0
  199. package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +5 -2
  200. package/dist/src/tasks-runner/life-cycles/performance-analysis.js +13 -7
  201. package/dist/src/tasks-runner/life-cycles/performance-life-cycle.d.ts +4 -3
  202. package/dist/src/tasks-runner/life-cycles/performance-life-cycle.js +9 -2
  203. package/dist/src/tasks-runner/life-cycles/static-run-many-terminal-output-life-cycle.js +5 -2
  204. package/dist/src/tasks-runner/life-cycles/static-run-one-terminal-output-life-cycle.js +4 -1
  205. package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.js +5 -1
  206. package/dist/src/tasks-runner/pseudo-ipc.d.ts +1 -0
  207. package/dist/src/tasks-runner/pseudo-ipc.js +4 -0
  208. package/dist/src/tasks-runner/pseudo-terminal.d.ts +1 -1
  209. package/dist/src/tasks-runner/pseudo-terminal.js +2 -2
  210. package/dist/src/tasks-runner/readiness/executor-ready-signal.d.ts +7 -0
  211. package/dist/src/tasks-runner/readiness/executor-ready-signal.js +43 -0
  212. package/dist/src/tasks-runner/readiness/probes.d.ts +14 -0
  213. package/dist/src/tasks-runner/readiness/probes.js +101 -0
  214. package/dist/src/tasks-runner/readiness/ready-signal-server.d.ts +18 -0
  215. package/dist/src/tasks-runner/readiness/ready-signal-server.js +72 -0
  216. package/dist/src/tasks-runner/readiness/ready-signal.d.ts +33 -0
  217. package/dist/src/tasks-runner/readiness/ready-signal.js +92 -0
  218. package/dist/src/tasks-runner/readiness/ready-when.d.ts +84 -0
  219. package/dist/src/tasks-runner/readiness/ready-when.js +371 -0
  220. package/dist/src/tasks-runner/readiness/startup-host.d.ts +1 -0
  221. package/dist/src/tasks-runner/readiness/startup-host.js +32 -0
  222. package/dist/src/tasks-runner/run-command.d.ts +6 -2
  223. package/dist/src/tasks-runner/run-command.js +21 -31
  224. package/dist/src/tasks-runner/run-outcome.d.ts +16 -0
  225. package/dist/src/tasks-runner/run-outcome.js +39 -0
  226. package/dist/src/tasks-runner/running-tasks/batch-process.js +6 -0
  227. package/dist/src/tasks-runner/running-tasks/node-child-process.js +5 -4
  228. package/dist/src/tasks-runner/running-tasks/running-task.d.ts +1 -1
  229. package/dist/src/tasks-runner/task-env.d.ts +10 -0
  230. package/dist/src/tasks-runner/task-env.js +37 -5
  231. package/dist/src/tasks-runner/task-graph-utils.d.ts +9 -6
  232. package/dist/src/tasks-runner/task-graph-utils.js +17 -12
  233. package/dist/src/tasks-runner/task-orchestrator.d.ts +62 -18
  234. package/dist/src/tasks-runner/task-orchestrator.js +750 -150
  235. package/dist/src/tasks-runner/tasks-runner.d.ts +1 -1
  236. package/dist/src/tasks-runner/tasks-schedule.d.ts +18 -1
  237. package/dist/src/tasks-runner/tasks-schedule.js +63 -6
  238. package/dist/src/tasks-runner/tokens.d.ts +54 -0
  239. package/dist/src/tasks-runner/tokens.js +161 -0
  240. package/dist/src/tasks-runner/utils.d.ts +35 -6
  241. package/dist/src/tasks-runner/utils.js +149 -68
  242. package/dist/src/ultracache/ci-status.d.ts +24 -0
  243. package/dist/src/ultracache/ci-status.js +87 -0
  244. package/dist/src/ultracache/config.d.ts +3 -3
  245. package/dist/src/ultracache/config.js +4 -4
  246. package/dist/src/ultracache/fetch.d.ts +2 -0
  247. package/dist/src/ultracache/fetch.js +1 -0
  248. package/dist/src/ultracache/overrides.js +4 -0
  249. package/dist/src/utils/acknowledge-build-scripts.d.ts +34 -1
  250. package/dist/src/utils/acknowledge-build-scripts.js +171 -32
  251. package/dist/src/utils/child-process.js +2 -1
  252. package/dist/src/utils/find-matching-projects.js +9 -6
  253. package/dist/src/utils/git-utils.d.ts +12 -5
  254. package/dist/src/utils/git-utils.js +69 -11
  255. package/dist/src/utils/long-running-target.d.ts +1 -3
  256. package/dist/src/utils/long-running-target.js +1 -3
  257. package/dist/src/utils/output.d.ts +4 -3
  258. package/dist/src/utils/output.js +4 -3
  259. package/dist/src/utils/owned-private-dir.d.ts +1 -17
  260. package/dist/src/utils/owned-private-dir.js +10 -62
  261. package/dist/src/utils/package-manager.d.ts +8 -0
  262. package/dist/src/utils/package-manager.js +65 -8
  263. package/dist/src/utils/perf-hooks.d.ts +1 -0
  264. package/dist/src/utils/plugins/core-plugins.js +5 -1
  265. package/dist/src/utils/progress-topics.d.ts +1 -0
  266. package/dist/src/utils/progress-topics.js +1 -0
  267. package/dist/src/utils/safe-spawn.js +1 -5
  268. package/dist/src/utils/shell-quoting.d.ts +8 -1
  269. package/dist/src/utils/shell-quoting.js +12 -1
  270. package/dist/src/utils/spawn-without-terminal.d.ts +27 -0
  271. package/dist/src/utils/spawn-without-terminal.js +110 -0
  272. package/dist/src/utils/string-similarity.d.ts +38 -0
  273. package/dist/src/utils/string-similarity.js +108 -0
  274. package/migrations.json +20 -6
  275. package/package.json +15 -24
  276. package/schemas/migrations-schema.json +11 -0
  277. package/schemas/nx-schema.json +133 -11
  278. package/schemas/project-schema.json +114 -4
  279. package/dist/src/command-line/migrate/agentic/prompts/generic-validation.d.ts +0 -56
  280. package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +0 -67
  281. package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.d.ts +0 -49
  282. package/dist/src/command-line/migrate/agentic/prompts/hybrid-prompt-migration.js +0 -53
  283. package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.d.ts +0 -26
  284. package/dist/src/command-line/migrate/agentic/prompts/prompt-migration.js +0 -27
  285. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +0 -70
  286. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +0 -113
  287. package/dist/src/command-line/migrate/agentic/run-step.d.ts +0 -68
  288. package/dist/src/command-line/migrate/agentic/run-step.js +0 -148
  289. package/dist/src/command-line/migrate/agentic/runner.d.ts +0 -21
  290. package/dist/src/command-line/migrate/agentic/runner.js +0 -262
  291. package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.d.ts +0 -9
  292. package/dist/src/migrations/update-23-0-0/consolidate-release-tag-config.js +0 -18
  293. package/dist/src/tasks-runner/legacy-depends-on-warning.d.ts +0 -18
  294. package/dist/src/tasks-runner/legacy-depends-on-warning.js +0 -109
@@ -1,13 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.acknowledgeBuildScripts = acknowledgeBuildScripts;
4
+ exports.acknowledgeDeclaredBuildScripts = acknowledgeDeclaredBuildScripts;
4
5
  const fs_1 = require("fs");
5
6
  const path_1 = require("path");
6
7
  const yaml_1 = require("yaml");
7
8
  const semver_1 = require("semver");
8
9
  const package_manager_1 = require("./package-manager");
9
10
  const fileutils_1 = require("./fileutils");
11
+ const is_ci_1 = require("./is-ci");
10
12
  const json_1 = require("./json");
13
+ const output_1 = require("./output");
14
+ const prompt_helpers_1 = require("./prompt-helpers");
11
15
  const PNPM_WORKSPACE_FILE = 'pnpm-workspace.yaml';
12
16
  /**
13
17
  * Records build-script decisions for dependencies that are about to be
@@ -18,67 +22,202 @@ const PNPM_WORKSPACE_FILE = 'pnpm-workspace.yaml';
18
22
  * that introduces such a dependency records the decision up front. Other
19
23
  * package managers run build scripts unconditionally, so this is a no-op for
20
24
  * them.
25
+ *
26
+ * @param treeOrRoot The workspace tree, or its root on disk.
27
+ * @param packageManager The workspace package manager.
28
+ * @param entries Package name to decision: `true` runs the package's build
29
+ * scripts, `false` skips them. Entries the user already decided are kept.
30
+ * @param directory Workspace root relative to the tree root, for generators
31
+ * that scaffold a workspace into a subdirectory.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * acknowledgeBuildScripts(tree, detectPackageManager(tree.root), {
36
+ * esbuild: false,
37
+ * cypress: true,
38
+ * });
39
+ * ```
21
40
  */
22
- function acknowledgeBuildScripts(treeOrRoot, packageManager, entries) {
41
+ function acknowledgeBuildScripts(treeOrRoot, packageManager, entries, directory = '') {
23
42
  if (packageManager !== 'pnpm') {
24
43
  return;
25
44
  }
26
- acknowledgePnpmBuildScripts(treeOrRoot, entries);
45
+ const host = createHost(treeOrRoot, directory);
46
+ const pnpmVersion = getPnpmVersion(host);
47
+ if (!pnpmVersion || !(0, semver_1.gte)(pnpmVersion, '11.0.0')) {
48
+ return;
49
+ }
50
+ acknowledgePnpmBuildScripts(host, entries);
27
51
  }
28
52
  /**
29
- * Records `allowBuilds` decisions in pnpm-workspace.yaml, creating the file
30
- * when missing (mirroring `pnpm approve-builds` in single-package repos).
53
+ * Records the build-script decisions a package declares for its own
54
+ * dependency tree, so the install that first pulls the package in can stay
55
+ * strict. A package declares them in the `pnpm.allowBuilds` field of its
56
+ * package.json, the same shape pnpm reads from a workspace root; pnpm ignores
57
+ * the field on dependencies, so it is read from the registry here.
31
58
  *
32
- * Comment-preserving. Existing entries are never overwritten, so user
33
- * decisions always win. No-op for pnpm < 11, which warns instead of erroring
34
- * and does not read `allowBuilds`.
59
+ * A declared `false` is recorded as is: it only skips a script. A declared
60
+ * `true` would let a publisher authorize code execution in the workspace, so
61
+ * it is a request: in a terminal the owner picks which to allow, elsewhere
62
+ * every request is recorded as `false`. Decisions the owner already recorded
63
+ * are kept either way, and everything recorded is printed.
64
+ *
65
+ * Resolves to whether the package declared any decision. Nothing is recorded
66
+ * for package managers other than pnpm, pnpm < 11, packages that declare
67
+ * nothing, and specs the registry cannot answer, such as a tarball path.
35
68
  */
36
- function acknowledgePnpmBuildScripts(treeOrRoot, entries) {
37
- const host = createHost(treeOrRoot);
69
+ async function acknowledgeDeclaredBuildScripts(treeOrRoot, packageManager, packageName, version, directory = '') {
70
+ if (packageManager !== 'pnpm') {
71
+ return false;
72
+ }
73
+ const host = createHost(treeOrRoot, directory);
38
74
  const pnpmVersion = getPnpmVersion(host);
39
75
  if (!pnpmVersion || !(0, semver_1.gte)(pnpmVersion, '11.0.0')) {
40
- return;
76
+ return false;
41
77
  }
42
- const parsed = (0, yaml_1.parseDocument)(host.exists(PNPM_WORKSPACE_FILE) ? host.read(PNPM_WORKSPACE_FILE) : '');
43
- // A file that doesn't parse cleanly or whose root isn't a mapping is
44
- // malformed for pnpm; leave it alone rather than crashing or replacing the
45
- // user's content. pnpm's own error on the file is the actionable signal.
46
- // Empty and comment-only files have no contents at all; setIn creates the
47
- // mapping for them while keeping whatever comments they carry.
48
- if (parsed.errors.length > 0 ||
49
- (parsed.contents != null && !(parsed.contents instanceof yaml_1.YAMLMap))) {
50
- return;
78
+ const declared = await readDeclaredBuildScripts(packageName, version);
79
+ if (Object.keys(declared).length === 0) {
80
+ return false;
81
+ }
82
+ const decided = readRecordedDecisions(host);
83
+ const requests = Object.keys(declared).filter((pkg) => declared[pkg] && !(pkg in decided));
84
+ const prompted = requests.length > 0 && canPrompt();
85
+ const allowed = prompted
86
+ ? await (0, prompt_helpers_1.multiselectPrompt)({
87
+ message: `${packageName}@${version} asks to run the install scripts of these packages. Which ones do you allow?`,
88
+ choices: requests,
89
+ required: false,
90
+ })
91
+ : [];
92
+ const entries = { ...declared };
93
+ for (const pkg of requests) {
94
+ entries[pkg] = allowed.includes(pkg);
51
95
  }
52
- let changed = false;
96
+ const recorded = acknowledgePnpmBuildScripts(host, entries);
97
+ if (Object.keys(recorded).length > 0) {
98
+ const blocked = requests.filter((pkg) => !entries[pkg] && pkg in recorded);
99
+ output_1.output.note({
100
+ title: `Recorded the build-script decisions ${packageName}@${version} declares in ${PNPM_WORKSPACE_FILE}`,
101
+ bodyLines: [
102
+ ...Object.entries(recorded).map(([pkg, value]) => blocked.includes(pkg)
103
+ ? `${pkg}: false (the package asked to run it)`
104
+ : `${pkg}: ${value}`),
105
+ ...(blocked.length > 0
106
+ ? [
107
+ `To run a blocked script, set its entry to true in ${PNPM_WORKSPACE_FILE} and run "pnpm rebuild <package>".`,
108
+ ]
109
+ : []),
110
+ ],
111
+ });
112
+ }
113
+ return true;
114
+ }
115
+ function canPrompt() {
116
+ return (process.env.NX_INTERACTIVE !== 'false' &&
117
+ !(0, is_ci_1.isCI)() &&
118
+ !!process.stdout.isTTY &&
119
+ !!process.stdin.isTTY);
120
+ }
121
+ async function readDeclaredBuildScripts(packageName, version) {
122
+ let declared;
123
+ try {
124
+ const output = await (0, package_manager_1.packageRegistryView)(packageName, version, [
125
+ 'pnpm.allowBuilds',
126
+ '--json',
127
+ ]);
128
+ declared = output ? JSON.parse(output) : undefined;
129
+ }
130
+ catch {
131
+ return {};
132
+ }
133
+ // A range matches several versions; the view lists them lowest first.
134
+ if (Array.isArray(declared)) {
135
+ declared = declared[declared.length - 1];
136
+ }
137
+ if (declared == null || typeof declared !== 'object') {
138
+ return {};
139
+ }
140
+ return Object.fromEntries(Object.entries(declared).filter((entry) => typeof entry[1] === 'boolean'));
141
+ }
142
+ /**
143
+ * Records `allowBuilds` decisions in pnpm-workspace.yaml, creating the file
144
+ * when missing (mirroring `pnpm approve-builds` in single-package repos).
145
+ * Returns the entries it wrote.
146
+ *
147
+ * Comment-preserving. Existing entries are never overwritten, so user
148
+ * decisions always win. pnpm < 11 warns instead of erroring and does not read
149
+ * `allowBuilds`, so callers gate on the version first.
150
+ */
151
+ function acknowledgePnpmBuildScripts(host, entries) {
152
+ const parsed = parseWorkspaceFile(host);
153
+ if (!parsed) {
154
+ return {};
155
+ }
156
+ const recorded = {};
53
157
  for (const [pkg, allowed] of Object.entries(entries)) {
54
158
  // Only a real boolean is a user decision. pnpm's non-strict installs stub
55
159
  // undecided packages with a placeholder string ("set this to true or
56
160
  // false"), which would fail the next strict install if left in place.
57
161
  if (typeof parsed.getIn(['allowBuilds', pkg]) !== 'boolean') {
58
162
  parsed.setIn(['allowBuilds', pkg], allowed);
59
- changed = true;
163
+ recorded[pkg] = allowed;
60
164
  }
61
165
  }
62
- if (changed) {
166
+ if (Object.keys(recorded).length > 0) {
63
167
  host.write(PNPM_WORKSPACE_FILE, parsed.toString());
64
168
  }
169
+ return recorded;
170
+ }
171
+ /**
172
+ * Parses pnpm-workspace.yaml, or null when pnpm itself would reject it. A file
173
+ * that doesn't parse cleanly or whose root isn't a mapping is left alone
174
+ * rather than crashed on or replaced; pnpm's own error on the file is the
175
+ * actionable signal. Empty and comment-only files have no contents at all;
176
+ * setIn creates the mapping for them while keeping whatever comments they
177
+ * carry.
178
+ */
179
+ function parseWorkspaceFile(host) {
180
+ const parsed = (0, yaml_1.parseDocument)(host.exists(PNPM_WORKSPACE_FILE) ? host.read(PNPM_WORKSPACE_FILE) : '');
181
+ if (parsed.errors.length > 0 ||
182
+ (parsed.contents != null && !(parsed.contents instanceof yaml_1.YAMLMap))) {
183
+ return null;
184
+ }
185
+ return parsed;
186
+ }
187
+ /** The `allowBuilds` entries that carry a real decision, not a placeholder. */
188
+ function readRecordedDecisions(host) {
189
+ const allowBuilds = parseWorkspaceFile(host)?.get('allowBuilds');
190
+ if (!(allowBuilds instanceof yaml_1.YAMLMap)) {
191
+ return {};
192
+ }
193
+ const decisions = {};
194
+ for (const pair of allowBuilds.items) {
195
+ const value = (0, yaml_1.isScalar)(pair.value) ? pair.value.value : pair.value;
196
+ if (typeof value === 'boolean') {
197
+ decisions[String((0, yaml_1.isScalar)(pair.key) ? pair.key.value : pair.key)] = value;
198
+ }
199
+ }
200
+ return decisions;
65
201
  }
66
- function createHost(treeOrRoot) {
202
+ function createHost(treeOrRoot, directory) {
67
203
  if (typeof treeOrRoot === 'string') {
204
+ const root = (0, path_1.join)(treeOrRoot, directory);
68
205
  return {
69
- root: treeOrRoot,
70
- exists: (p) => (0, fs_1.existsSync)((0, path_1.join)(treeOrRoot, p)),
71
- read: (p) => (0, fs_1.readFileSync)((0, path_1.join)(treeOrRoot, p), 'utf-8'),
72
- write: (p, c) => (0, fs_1.writeFileSync)((0, path_1.join)(treeOrRoot, p), c),
73
- readJson: (p) => (0, fileutils_1.readJsonFile)((0, path_1.join)(treeOrRoot, p)),
206
+ root,
207
+ exists: (p) => (0, fs_1.existsSync)((0, path_1.join)(root, p)),
208
+ read: (p) => (0, fs_1.readFileSync)((0, path_1.join)(root, p), 'utf-8'),
209
+ write: (p, c) => (0, fs_1.writeFileSync)((0, path_1.join)(root, p), c),
210
+ readJson: (p) => (0, fileutils_1.readJsonFile)((0, path_1.join)(root, p)),
74
211
  };
75
212
  }
213
+ // The directory may not exist on disk yet (a workspace being scaffolded
214
+ // into it), so the package manager is probed from the tree root.
76
215
  return {
77
216
  root: treeOrRoot.root,
78
- exists: (p) => treeOrRoot.exists(p),
79
- read: (p) => treeOrRoot.read(p, 'utf-8'),
80
- write: (p, c) => treeOrRoot.write(p, c),
81
- readJson: (p) => (0, json_1.parseJson)(treeOrRoot.read(p, 'utf-8')),
217
+ exists: (p) => treeOrRoot.exists((0, path_1.join)(directory, p)),
218
+ read: (p) => treeOrRoot.read((0, path_1.join)(directory, p), 'utf-8'),
219
+ write: (p, c) => treeOrRoot.write((0, path_1.join)(directory, p), c),
220
+ readJson: (p) => (0, json_1.parseJson)(treeOrRoot.read((0, path_1.join)(directory, p), 'utf-8')),
82
221
  };
83
222
  }
84
223
  function getPnpmVersion(host) {
@@ -128,6 +128,7 @@ function runNxArgvSync(argv, options) {
128
128
  if (result.status !== 0) {
129
129
  const error = new Error(`Command failed: nx ${argv.join(' ')} (exit code ${result.status})`);
130
130
  error.status = result.status ?? 1;
131
+ error.signal = result.signal;
131
132
  throw error;
132
133
  }
133
134
  }
@@ -174,7 +175,7 @@ class PseudoTtyProcess {
174
175
  this.exitCallbacks.push(callback);
175
176
  }
176
177
  onOutput(callback) {
177
- this.childProcess.onOutput(callback);
178
+ this.childProcess.onOutput((message) => callback(message));
178
179
  }
179
180
  kill() {
180
181
  try {
@@ -112,8 +112,9 @@ function addMatchingProjectsByName(projectNames, projects, pattern, matchedProje
112
112
  return;
113
113
  }
114
114
  if (!(0, globs_1.isGlobPattern)(pattern.value)) {
115
+ const escapedValue = pattern.value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
115
116
  // Custom regex that is basically \b but includes hyphens (-) and excludes underscores (_), so "foo" pattern matches "foo_bar" but not "foo-e2e".
116
- const regex = new RegExp(`(?<![@a-zA-Z0-9-])${pattern.value}(?![@a-zA-Z0-9-])`, 'i');
117
+ const regex = new RegExp(`(?<![@a-zA-Z0-9-])${escapedValue}(?![@a-zA-Z0-9-])`, 'i');
117
118
  const matchingProjects = Object.keys(projects).filter((name) => regex.test(name));
118
119
  for (const projectName of matchingProjects) {
119
120
  if (pattern.exclude) {
@@ -181,11 +182,13 @@ function parseStringPattern(pattern, projects) {
181
182
  }
182
183
  else {
183
184
  const potentialType = pattern.substring(0, indexOfFirstPotentialSeparator);
184
- return {
185
- type: isValidPatternType(potentialType) ? potentialType : 'unlabeled',
186
- value: pattern.substring(indexOfFirstPotentialSeparator + 1),
187
- exclude: isExclude,
188
- };
185
+ return isValidPatternType(potentialType)
186
+ ? {
187
+ type: potentialType,
188
+ value: pattern.substring(indexOfFirstPotentialSeparator + 1),
189
+ exclude: isExclude,
190
+ }
191
+ : { type: 'unlabeled', value: pattern, exclude: isExclude };
189
192
  }
190
193
  }
191
194
  function isValidPatternType(type) {
@@ -71,6 +71,8 @@ export declare function getWorkingTreeStatus(directory?: string, excludePaths?:
71
71
  export declare function hasUncommittedChanges(directory?: string, excludePaths?: string[]): boolean;
72
72
  export type PathCommitExposure = 'ignored' | 'tracked' | 'unignored' | 'unknown';
73
73
  export declare function getPathCommitExposure(dirPath: string, directory?: string): PathCommitExposure;
74
+ export type PathHeadStatus = 'committed' | 'absent' | 'unknown';
75
+ export declare function getPathHeadStatus(path: string, directory: string): PathHeadStatus;
74
76
  export declare function getUncommittedChangesSnapshot(directory?: string): string;
75
77
  export declare function commitChanges(commitMessage: string, directory?: string): string | null;
76
78
  /**
@@ -93,13 +95,18 @@ export declare function tryCommitChanges(commitMessage: string, directory: strin
93
95
  /**
94
96
  * `tryCommitChanges` for a process that has to stay responsive while git
95
97
  * runs: a signing prompt or a hook can hold the commit for minutes.
98
+ * `withoutTerminal` is for a caller sharing the terminal with another program:
99
+ * git runs without it (see `spawnWithoutTerminal`), so such a prompt fails the
100
+ * commit instead.
96
101
  */
97
- export declare function tryCommitChangesAsync(commitMessage: string, directory: string, excludePaths?: string[]): Promise<string | null>;
102
+ export declare function tryCommitChangesAsync(commitMessage: string, directory: string, excludePaths?: string[], { withoutTerminal }?: {
103
+ withoutTerminal?: boolean;
104
+ }): Promise<string | null>;
98
105
  /**
99
- * `git reset --hard <ref>` then `git clean -fd`, keeping `keepPaths` (git
100
- * exclusion patterns, repo-relative) out of the clean. Throws with git's
101
- * stderr when either fails. `ref` is a sha a caller validated with `GIT_SHA`,
102
- * never user input.
106
+ * `git reset --hard <ref>` then `git clean -fd`, sparing the
107
+ * `directory`-relative `keepPaths`, staged or not. A kept path `ref` tracks
108
+ * comes back at `ref`'s version. Throws with git's stderr when git fails.
109
+ * `ref` is a sha a caller validated with `GIT_SHA`, never user input.
103
110
  */
104
111
  export declare function resetWorkingTree(ref: string, keepPaths: string[], directory: string): void;
105
112
  export declare function getLatestCommitSha(directory?: string): string | null;
@@ -16,6 +16,7 @@ exports.getGitRemoteNames = getGitRemoteNames;
16
16
  exports.getWorkingTreeStatus = getWorkingTreeStatus;
17
17
  exports.hasUncommittedChanges = hasUncommittedChanges;
18
18
  exports.getPathCommitExposure = getPathCommitExposure;
19
+ exports.getPathHeadStatus = getPathHeadStatus;
19
20
  exports.getUncommittedChangesSnapshot = getUncommittedChangesSnapshot;
20
21
  exports.commitChanges = commitChanges;
21
22
  exports.tryCommitChanges = tryCommitChanges;
@@ -30,6 +31,7 @@ const crypto = tslib_1.__importStar(require("crypto"));
30
31
  const fs = tslib_1.__importStar(require("fs"));
31
32
  const path_1 = require("path");
32
33
  const owned_private_dir_1 = require("./owned-private-dir");
34
+ const spawn_without_terminal_1 = require("./spawn-without-terminal");
33
35
  function execFileAsync(file, args, execOptions) {
34
36
  return new Promise((res, rej) => {
35
37
  (0, child_process_1.execFile)(file, args, { ...execOptions, windowsHide: true }, (err, stdout) => {
@@ -673,12 +675,14 @@ function getGitRemoteNames(directory) {
673
675
  // `excludePaths` are left out of the probe the way `tryCommitChanges` leaves
674
676
  // them out of the commit, so a tree dirty only under them reads as clean. An
675
677
  // exclude-only pathspec still covers the whole tree, matching `git add -A`.
678
+ // The untracked mode is explicit because `status.showUntrackedFiles=no` would
679
+ // hide new files that `git add -A` still stages.
676
680
  function getWorkingTreeStatus(directory, excludePaths = []) {
677
681
  const pathspecs = excludePaths
678
682
  .map((excludePath) => ` ":(exclude)${excludePath}"`)
679
683
  .join('');
680
684
  try {
681
- const out = (0, child_process_1.execSync)(`git status --porcelain${pathspecs ? ` --${pathspecs}` : ''}`, {
685
+ const out = (0, child_process_1.execSync)(`git status --porcelain --untracked-files=normal${pathspecs ? ` --${pathspecs}` : ''}`, {
682
686
  encoding: 'utf8',
683
687
  cwd: directory,
684
688
  stdio: ['ignore', 'pipe', 'pipe'],
@@ -738,6 +742,30 @@ function getPathCommitExposure(dirPath, directory) {
738
742
  return e?.status === 1 ? 'unignored' : 'unknown';
739
743
  }
740
744
  }
745
+ // Whether HEAD's tree, not the index, has an entry at the `directory`-relative
746
+ // `path`. An unborn HEAD has none; 'unknown' means git failed.
747
+ function getPathHeadStatus(path, directory) {
748
+ const options = {
749
+ encoding: 'utf8',
750
+ cwd: directory,
751
+ stdio: ['ignore', 'pipe', 'pipe'],
752
+ windowsHide: true,
753
+ };
754
+ try {
755
+ (0, child_process_1.execFileSync)('git', ['rev-parse', '--verify', '-q', 'HEAD'], options);
756
+ }
757
+ catch (e) {
758
+ // --verify -q exits 1 for a ref that does not resolve: an unborn HEAD.
759
+ return e?.status === 1 ? 'absent' : 'unknown';
760
+ }
761
+ try {
762
+ const entries = (0, child_process_1.execFileSync)('git', ['ls-tree', '--name-only', 'HEAD', '--', path], options);
763
+ return entries.trim() === '' ? 'absent' : 'committed';
764
+ }
765
+ catch {
766
+ return 'unknown';
767
+ }
768
+ }
741
769
  // Returns a content-sensitive sha1 snapshot of the working tree state for
742
770
  // before/after comparison. Hashes three probes:
743
771
  // 1. `git diff HEAD` with defensive flags — every byte of tracked-file
@@ -870,11 +898,14 @@ function tryCommitChanges(commitMessage, directory, excludePaths = []) {
870
898
  /**
871
899
  * `tryCommitChanges` for a process that has to stay responsive while git
872
900
  * runs: a signing prompt or a hook can hold the commit for minutes.
901
+ * `withoutTerminal` is for a caller sharing the terminal with another program:
902
+ * git runs without it (see `spawnWithoutTerminal`), so such a prompt fails the
903
+ * commit instead.
873
904
  */
874
- async function tryCommitChangesAsync(commitMessage, directory, excludePaths = []) {
905
+ async function tryCommitChangesAsync(commitMessage, directory, excludePaths = [], { withoutTerminal = false } = {}) {
875
906
  try {
876
907
  for (const { command, input } of commitCommands(commitMessage, excludePaths)) {
877
- await execAsync(command, directory, input);
908
+ await execAsync(command, directory, input, withoutTerminal);
878
909
  }
879
910
  }
880
911
  catch (err) {
@@ -908,12 +939,14 @@ function commitFailure(err) {
908
939
  // for callers to inspect; otherwise only stderr/stdout text survives.
909
940
  return new Error(detail || (err instanceof Error ? err.message : String(err)), { cause: err });
910
941
  }
911
- function execAsync(command, cwd, input) {
942
+ function execAsync(command, cwd, input, withoutTerminal) {
912
943
  return new Promise((res, rej) => {
913
- const child = (0, child_process_1.exec)(command, { encoding: 'utf8', cwd, windowsHide: true },
914
944
  // The streams ride on the error as `execSync` reports them, so
915
945
  // `commitFailure` shapes both the same way.
916
- (err, stdout, stderr) => err ? rej(Object.assign(err, { stdout, stderr })) : res());
946
+ const settle = (err, stdout, stderr) => err ? rej(Object.assign(err, { stdout, stderr })) : res();
947
+ const child = withoutTerminal
948
+ ? collectOutput((0, spawn_without_terminal_1.spawnWithoutTerminal)(command, { cwd }), command, settle)
949
+ : (0, child_process_1.exec)(command, { encoding: 'utf8', cwd, windowsHide: true }, settle);
917
950
  // Closed for every command, since `git commit -F -` reads to end of
918
951
  // input. A child that exits before reading raises EPIPE here, which the
919
952
  // exit callback already reports.
@@ -921,21 +954,46 @@ function execAsync(command, cwd, input) {
921
954
  child.stdin?.end(input ?? '');
922
955
  });
923
956
  }
957
+ // What `exec` reports through its callback; `exec` itself ignores `detached`.
958
+ function collectOutput(child, command, done) {
959
+ let stdout = '';
960
+ let stderr = '';
961
+ child.stdout?.setEncoding('utf8').on('data', (chunk) => (stdout += chunk));
962
+ child.stderr?.setEncoding('utf8').on('data', (chunk) => (stderr += chunk));
963
+ child.once('error', (err) => done(err, stdout, stderr));
964
+ child.once('close', (code, signal) => done(code === 0
965
+ ? null
966
+ : Object.assign(new Error(`Command failed: ${command}`), {
967
+ code,
968
+ signal,
969
+ }), stdout, stderr));
970
+ return child;
971
+ }
924
972
  /**
925
- * `git reset --hard <ref>` then `git clean -fd`, keeping `keepPaths` (git
926
- * exclusion patterns, repo-relative) out of the clean. Throws with git's
927
- * stderr when either fails. `ref` is a sha a caller validated with `GIT_SHA`,
928
- * never user input.
973
+ * `git reset --hard <ref>` then `git clean -fd`, sparing the
974
+ * `directory`-relative `keepPaths`, staged or not. A kept path `ref` tracks
975
+ * comes back at `ref`'s version. Throws with git's stderr when git fails.
976
+ * `ref` is a sha a caller validated with `GIT_SHA`, never user input.
929
977
  */
930
978
  function resetWorkingTree(ref, keepPaths, directory) {
979
+ // `git clean -e` takes ignore patterns, which resolve from the repository
980
+ // root whatever the cwd, and match at any depth when they hold no slash.
981
+ const prefix = getGitRootRelativePath(directory);
982
+ if (prefix === null) {
983
+ throw new Error(`${directory} is not inside a git repository.`);
984
+ }
985
+ const keepPatterns = keepPaths.map((keepPath) => `/${path_1.posix.join(prefix, keepPath).replace(/[\\*?[]/g, '\\$&')}`);
931
986
  const options = {
932
987
  encoding: 'utf8',
933
988
  stdio: 'pipe',
934
989
  cwd: directory,
935
990
  windowsHide: true,
936
991
  };
992
+ // `reset --hard` deletes a kept path staged since `ref`, so its index entry
993
+ // goes back to `ref` first, leaving it untracked for the clean to skip.
994
+ (0, child_process_1.execFileSync)('git', ['reset', '-q', ref, '--', ...keepPaths], options);
937
995
  (0, child_process_1.execFileSync)('git', ['reset', '--hard', ref], options);
938
- (0, child_process_1.execFileSync)('git', ['clean', '-fd', ...keepPaths.flatMap((keepPath) => ['-e', keepPath])], options);
996
+ (0, child_process_1.execFileSync)('git', ['clean', '-fd', ...keepPatterns.flatMap((pattern) => ['-e', pattern])], options);
939
997
  }
940
998
  function getLatestCommitSha(directory) {
941
999
  try {
@@ -1,7 +1,5 @@
1
1
  /**
2
- * Target names the pre-23 `longRunningTask` guard excluded from caching. Shared
3
- * between that guard and the deprecated target-name cache fallback so the two
4
- * cannot drift apart.
2
+ * Target names the pre-23 `longRunningTask` guard excluded from caching.
5
3
  *
6
4
  * The copy in `migrations/update-23-2-0/set-cache-on-executor-target-defaults.ts`
7
5
  * deliberately does not use this: a migration's decision has to freeze at the
@@ -2,9 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isLongRunningTargetName = isLongRunningTargetName;
4
4
  /**
5
- * Target names the pre-23 `longRunningTask` guard excluded from caching. Shared
6
- * between that guard and the deprecated target-name cache fallback so the two
7
- * cannot drift apart.
5
+ * Target names the pre-23 `longRunningTask` guard excluded from caching.
8
6
  *
9
7
  * The copy in `migrations/update-23-2-0/set-cache-on-executor-target-defaults.ts`
10
8
  * deliberately does not use this: a migration's decision has to freeze at the
@@ -224,9 +224,10 @@ declare class CLIOutput {
224
224
  * The batch's own output is copied straight from the file it was captured
225
225
  * into, so an arbitrarily long log costs a fixed amount of memory here.
226
226
  * Nothing is withheld: this rendering is chosen because the whole log was
227
- * asked for, because no task claimed any of it, or because a task failed or
228
- * was stopped — in which case repeating claimed bytes beside the per-task
229
- * blocks is deliberate (see TaskOrchestrator.printGroupedBatchOutput).
227
+ * asked for, because no task claimed any of it, or because a task failed,
228
+ * was stopped or was never reached — in which case repeating claimed bytes
229
+ * beside the per-task blocks is deliberate (see
230
+ * TaskOrchestrator.printGroupedBatchOutput).
230
231
  */
231
232
  logBatchGroup(label: string, body: {
232
233
  capturedOutputPath?: string;
@@ -422,9 +422,10 @@ class CLIOutput {
422
422
  * The batch's own output is copied straight from the file it was captured
423
423
  * into, so an arbitrarily long log costs a fixed amount of memory here.
424
424
  * Nothing is withheld: this rendering is chosen because the whole log was
425
- * asked for, because no task claimed any of it, or because a task failed or
426
- * was stopped — in which case repeating claimed bytes beside the per-task
427
- * blocks is deliberate (see TaskOrchestrator.printGroupedBatchOutput).
425
+ * asked for, because no task claimed any of it, or because a task failed,
426
+ * was stopped or was never reached — in which case repeating claimed bytes
427
+ * beside the per-task blocks is deliberate (see
428
+ * TaskOrchestrator.printGroupedBatchOutput).
428
429
  */
429
430
  logBatchGroup(label, body, taskStatus) {
430
431
  const grouped = isLogGroupingEnabled();
@@ -25,7 +25,7 @@ export type OwnedRealDir = string & {
25
25
  export type OwnedPrivateDir = string & {
26
26
  readonly [ownedPrivateDirBrand]: true;
27
27
  };
28
- /** Why a guard refused a directory. Data, not a sentence: `remedyFor` decides on it. */
28
+ /** Why a guard refused a directory. Data, not a sentence. */
29
29
  export type DirRefusal = {
30
30
  kind: 'not-created';
31
31
  dir: string;
@@ -65,8 +65,6 @@ export type GuardResult<T> = {
65
65
  };
66
66
  /** The user-facing sentence for a refusal. The only place wording is decided. */
67
67
  export declare function describeRefusal(r: DirRefusal): string;
68
- /** What the user can do about a refusal, or `undefined` when there is nothing. */
69
- export declare function remedyFor(r: DirRefusal): string | undefined;
70
68
  /** One refusal as an `Error`, so several can travel in an `AggregateError`. */
71
69
  export declare class DirectoryRefusedError extends Error {
72
70
  readonly refusal: DirRefusal;
@@ -98,20 +96,6 @@ export declare function canonicalDir(dir: string): string;
98
96
  * verified private directory beneath it.
99
97
  */
100
98
  export declare function isSafeSharedRoot(dir: string): GuardResult<SafeSharedRoot>;
101
- /**
102
- * Whether other users on this machine can write into `dir`. Gates whether a
103
- * refusal message may cite other users, so it must not over-report: `false` on
104
- * Windows, where libuv synthesizes `st_mode` from the READONLY attribute and
105
- * reports an ordinary per-account directory as `0666`, and `false` on a path
106
- * that cannot be inspected.
107
- *
108
- * `statSync`, not `lstatSync`: the question is about the directory that will be
109
- * used, not the link pointing at it. Link modes mislead in both directions —
110
- * Linux creates symlinks `0777`, macOS applies the umask. Nothing here decides
111
- * whether a path is accepted, so following the link costs nothing the guards
112
- * do not already re-check.
113
- */
114
- export declare function isPeerWritable(dir: string): boolean;
115
99
  /**
116
100
  * Create a shared container as sticky + world-writable if it does not exist,
117
101
  * and report whether the resulting path is safe for the current user.