nx 23.3.0-beta.0 → 23.3.0-beta.2

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 (184) hide show
  1. package/dist/src/command-line/format/format.js +2 -18
  2. package/dist/src/command-line/graph/graph.js +42 -3
  3. package/dist/src/command-line/init/implementation/add-nx-to-monorepo.js +0 -3
  4. package/dist/src/command-line/init/implementation/add-nx-to-nest.js +0 -3
  5. package/dist/src/command-line/init/implementation/add-nx-to-npm-repo.js +0 -3
  6. package/dist/src/command-line/init/implementation/angular/index.js +0 -3
  7. package/dist/src/command-line/init/implementation/angular/legacy-angular-versions.js +0 -3
  8. package/dist/src/command-line/init/implementation/format.js +2 -3
  9. package/dist/src/command-line/init/implementation/utils.d.ts +0 -1
  10. package/dist/src/command-line/init/implementation/utils.js +0 -8
  11. package/dist/src/command-line/init/init-v2.js +0 -3
  12. package/dist/src/command-line/migrate/agentic/definitions.js +75 -19
  13. package/dist/src/command-line/migrate/agentic/format-command.d.ts +14 -0
  14. package/dist/src/command-line/migrate/agentic/format-command.js +44 -0
  15. package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +3 -3
  16. package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +3 -3
  17. package/dist/src/command-line/migrate/agentic/handoff.d.ts +27 -17
  18. package/dist/src/command-line/migrate/agentic/handoff.js +107 -24
  19. package/dist/src/command-line/migrate/agentic/instruction-files.d.ts +21 -0
  20. package/dist/src/command-line/migrate/agentic/instruction-files.js +36 -0
  21. package/dist/src/command-line/migrate/agentic/prompts/fragments.d.ts +16 -0
  22. package/dist/src/command-line/migrate/agentic/prompts/fragments.js +70 -0
  23. package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +4 -3
  24. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +25 -1
  25. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +57 -34
  26. package/dist/src/command-line/migrate/agentic/run-step.js +28 -4
  27. package/dist/src/command-line/migrate/agentic/runner.d.ts +17 -8
  28. package/dist/src/command-line/migrate/agentic/runner.js +110 -55
  29. package/dist/src/command-line/migrate/agentic/types.d.ts +23 -8
  30. package/dist/src/command-line/migrate/agentic/types.js +10 -7
  31. package/dist/src/command-line/migrate/migrate-commits.d.ts +1 -0
  32. package/dist/src/command-line/migrate/migrate-commits.js +9 -0
  33. package/dist/src/command-line/migrate/migrate-output.d.ts +3 -7
  34. package/dist/src/command-line/migrate/migrate-output.js +3 -7
  35. package/dist/src/command-line/migrate/migrate.js +21 -8
  36. package/dist/src/command-line/migrate/run/agent-output.d.ts +10 -0
  37. package/dist/src/command-line/migrate/run/agent-output.js +16 -2
  38. package/dist/src/command-line/migrate/run/agent-work-payload.d.ts +37 -0
  39. package/dist/src/command-line/migrate/run/agent-work-payload.js +142 -0
  40. package/dist/src/command-line/migrate/run/atomic-write.d.ts +8 -0
  41. package/dist/src/command-line/migrate/run/atomic-write.js +17 -0
  42. package/dist/src/command-line/migrate/run/index.d.ts +1 -1
  43. package/dist/src/command-line/migrate/run/issues.d.ts +106 -0
  44. package/dist/src/command-line/migrate/run/issues.js +980 -0
  45. package/dist/src/command-line/migrate/run/orchestrator.d.ts +1 -0
  46. package/dist/src/command-line/migrate/run/orchestrator.js +662 -105
  47. package/dist/src/command-line/migrate/run/run-state.d.ts +43 -8
  48. package/dist/src/command-line/migrate/run/run-state.js +184 -20
  49. package/dist/src/command-line/migrate/run/runbook.d.ts +17 -0
  50. package/dist/src/command-line/migrate/run/runbook.js +97 -0
  51. package/dist/src/command-line/migrate/run/state-lock.d.ts +2 -2
  52. package/dist/src/command-line/migrate/run/state-lock.js +2 -2
  53. package/dist/src/command-line/migrate/run/state-machine.d.ts +5 -1
  54. package/dist/src/command-line/migrate/run/state-machine.js +27 -1
  55. package/dist/src/command-line/migrate/run/worker.js +206 -56
  56. package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +5 -11
  57. package/dist/src/command-line/release/publish.js +11 -4
  58. package/dist/src/command-line/release/utils/remote-release-clients/github.js +3 -3
  59. package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +3 -3
  60. package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.d.ts +2 -0
  61. package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.js +35 -0
  62. package/dist/src/command-line/report/report.d.ts +2 -0
  63. package/dist/src/command-line/report/report.js +28 -1
  64. package/dist/src/command-line/yargs-utils/shared-options.d.ts +1 -1
  65. package/dist/src/command-line/yargs-utils/shared-options.js +22 -4
  66. package/dist/src/config/workspace-json-project-json.d.ts +2 -0
  67. package/dist/src/core/graph/main.js +1 -1
  68. package/dist/src/daemon/client/client.d.ts +6 -2
  69. package/dist/src/daemon/client/client.js +27 -11
  70. package/dist/src/daemon/message-types/get-plugin-capabilities.d.ts +5 -0
  71. package/dist/src/daemon/message-types/get-plugin-capabilities.js +11 -0
  72. package/dist/src/daemon/message-types/run-tasks-execution-hooks.d.ts +3 -2
  73. package/dist/src/daemon/server/handle-get-plugin-capabilities.d.ts +2 -0
  74. package/dist/src/daemon/server/handle-get-plugin-capabilities.js +13 -0
  75. package/dist/src/daemon/server/handle-hash-tasks.d.ts +8 -2
  76. package/dist/src/daemon/server/handle-hash-tasks.js +16 -3
  77. package/dist/src/daemon/server/handle-outputs-changes.d.ts +2 -2
  78. package/dist/src/daemon/server/handle-outputs-changes.js +21 -6
  79. package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +3 -2
  80. package/dist/src/daemon/server/outputs-tracking.d.ts +6 -0
  81. package/dist/src/daemon/server/outputs-tracking.js +18 -0
  82. package/dist/src/daemon/server/project-graph-incremental-recomputation.d.ts +22 -7
  83. package/dist/src/daemon/server/project-graph-incremental-recomputation.js +100 -70
  84. package/dist/src/daemon/server/restart-checks.d.ts +22 -0
  85. package/dist/src/daemon/server/restart-checks.js +77 -0
  86. package/dist/src/daemon/server/server.js +33 -18
  87. package/dist/src/daemon/server/shutdown-utils.d.ts +0 -5
  88. package/dist/src/daemon/server/shutdown-utils.js +3 -26
  89. package/dist/src/hasher/hash-task.js +20 -16
  90. package/dist/src/hasher/native-task-hasher-impl.d.ts +8 -0
  91. package/dist/src/hasher/native-task-hasher-impl.js +46 -3
  92. package/dist/src/hasher/task-hasher.d.ts +9 -0
  93. package/dist/src/hasher/task-hasher.js +14 -0
  94. package/dist/src/native/index.d.ts +222 -21
  95. package/dist/src/native/index.js +3 -3
  96. package/dist/src/native/native-bindings.js +4 -1
  97. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  98. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  99. package/dist/src/plugins/js/lock-file/pnpm-parser.js +1 -1
  100. package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.d.ts +2 -0
  101. package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +22 -0
  102. package/dist/src/plugins/js/utils/register.js +2 -1
  103. package/dist/src/project-graph/affected/locators/project-glob-changes.js +19 -26
  104. package/dist/src/project-graph/error-types.d.ts +5 -0
  105. package/dist/src/project-graph/error-types.js +44 -5
  106. package/dist/src/project-graph/file-utils.d.ts +2 -0
  107. package/dist/src/project-graph/file-utils.js +6 -1
  108. package/dist/src/project-graph/nx-deps-cache.d.ts +5 -2
  109. package/dist/src/project-graph/nx-deps-cache.js +4 -4
  110. package/dist/src/project-graph/plugins/get-plugins.d.ts +3 -1
  111. package/dist/src/project-graph/plugins/get-plugins.js +60 -82
  112. package/dist/src/project-graph/plugins/in-process-loader.d.ts +1 -1
  113. package/dist/src/project-graph/plugins/in-process-loader.js +1 -4
  114. package/dist/src/project-graph/plugins/isolation/index.d.ts +1 -1
  115. package/dist/src/project-graph/plugins/isolation/index.js +3 -1
  116. package/dist/src/project-graph/plugins/isolation/isolated-plugin.d.ts +8 -0
  117. package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +42 -6
  118. package/dist/src/project-graph/plugins/isolation/load-isolated-plugin.d.ts +10 -1
  119. package/dist/src/project-graph/plugins/isolation/load-isolated-plugin.js +67 -17
  120. package/dist/src/project-graph/plugins/isolation/messaging.d.ts +3 -2
  121. package/dist/src/project-graph/plugins/isolation/plugin-worker.js +5 -1
  122. package/dist/src/project-graph/plugins/loaded-nx-plugin.d.ts +5 -2
  123. package/dist/src/project-graph/plugins/loaded-nx-plugin.js +14 -1
  124. package/dist/src/project-graph/plugins/nx-plugin-capabilities.d.ts +6 -0
  125. package/dist/src/project-graph/plugins/nx-plugin-capabilities.js +28 -0
  126. package/dist/src/project-graph/plugins/task-results-stub.d.ts +50 -0
  127. package/dist/src/project-graph/plugins/task-results-stub.js +111 -0
  128. package/dist/src/project-graph/plugins/tasks-execution-hooks.d.ts +3 -2
  129. package/dist/src/project-graph/plugins/tasks-execution-hooks.js +14 -1
  130. package/dist/src/project-graph/project-graph.js +43 -42
  131. package/dist/src/tasks-runner/batch/run-batch.js +15 -0
  132. package/dist/src/tasks-runner/cache.d.ts +35 -0
  133. package/dist/src/tasks-runner/cache.js +40 -0
  134. package/dist/src/tasks-runner/create-task-graph.js +1 -0
  135. package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
  136. package/dist/src/tasks-runner/forked-process-task-runner.d.ts +1 -1
  137. package/dist/src/tasks-runner/forked-process-task-runner.js +8 -7
  138. package/dist/src/tasks-runner/init-tasks-runner.js +5 -1
  139. package/dist/src/tasks-runner/is-tui-enabled.js +4 -3
  140. package/dist/src/tasks-runner/life-cycle.d.ts +7 -0
  141. package/dist/src/tasks-runner/life-cycle.js +7 -0
  142. package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.d.ts +35 -0
  143. package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.js +146 -0
  144. package/dist/src/tasks-runner/prune-task-graph.d.ts +17 -0
  145. package/dist/src/tasks-runner/prune-task-graph.js +45 -0
  146. package/dist/src/tasks-runner/run-command.js +14 -3
  147. package/dist/src/tasks-runner/running-tasks/batch-process.d.ts +93 -19
  148. package/dist/src/tasks-runner/running-tasks/batch-process.js +184 -88
  149. package/dist/src/tasks-runner/task-orchestrator.d.ts +64 -2
  150. package/dist/src/tasks-runner/task-orchestrator.js +232 -46
  151. package/dist/src/tasks-runner/terminal-output-path.d.ts +11 -0
  152. package/dist/src/tasks-runner/terminal-output-path.js +18 -0
  153. package/dist/src/tasks-runner/utils.js +5 -2
  154. package/dist/src/utils/ab-testing.d.ts +4 -1
  155. package/dist/src/utils/ab-testing.js +11 -7
  156. package/dist/src/utils/chunkify.d.ts +1 -7
  157. package/dist/src/utils/chunkify.js +2 -8
  158. package/dist/src/utils/command-line-utils.d.ts +19 -0
  159. package/dist/src/utils/command-line-utils.js +10 -3
  160. package/dist/src/utils/formatters/index.d.ts +6 -0
  161. package/dist/src/utils/formatters/index.js +5 -0
  162. package/dist/src/utils/formatters/prettier.d.ts +0 -8
  163. package/dist/src/utils/formatters/prettier.js +4 -26
  164. package/dist/src/utils/handle-errors.js +5 -43
  165. package/dist/src/utils/installed-nx-version.js +2 -48
  166. package/dist/src/utils/min-release-age/packument.js +1 -1
  167. package/dist/src/utils/output.d.ts +22 -3
  168. package/dist/src/utils/output.js +28 -5
  169. package/dist/src/utils/package-json.d.ts +25 -0
  170. package/dist/src/utils/package-json.js +41 -6
  171. package/dist/src/utils/package-manager.d.ts +6 -0
  172. package/dist/src/utils/package-manager.js +10 -0
  173. package/dist/src/utils/plugins/plugin-capabilities.js +7 -2
  174. package/dist/src/utils/provenance.js +20 -4
  175. package/dist/src/utils/serialize-overrides-into-command-line.js +2 -4
  176. package/dist/src/utils/workspace-context.d.ts +47 -3
  177. package/dist/src/utils/workspace-context.js +162 -10
  178. package/package.json +12 -13
  179. package/schemas/nx-schema.json +4 -0
  180. package/schemas/project-schema.json +4 -0
  181. package/dist/src/daemon/server/file-watching/route-workspace-changes.d.ts +0 -9
  182. package/dist/src/daemon/server/file-watching/route-workspace-changes.js +0 -76
  183. package/dist/src/daemon/server/watcher.d.ts +0 -18
  184. package/dist/src/daemon/server/watcher.js +0 -126
@@ -18,15 +18,6 @@ const ignore_1 = require("../../utils/ignore");
18
18
  const object_sort_1 = require("../../utils/object-sort");
19
19
  const output_1 = require("../../utils/output");
20
20
  const workspace_root_1 = require("../../utils/workspace-root");
21
- /**
22
- * A table, not a `switch`: this lookup sits inside a `try` whose `catch`
23
- * reports "configured but not installed", and a `never` arm would throw into
24
- * that catch and be misreported. A missing member is a compile error here.
25
- */
26
- const resolveFormatterBin = {
27
- oxfmt: oxfmt_1.getOxfmtBinPath,
28
- prettier: prettier_1.getPrettierPath,
29
- };
30
21
  async function format(command, args) {
31
22
  const formatterType = (0, formatters_1.detectFormatter)(workspace_root_1.workspaceRoot);
32
23
  if (!formatterType) {
@@ -41,7 +32,7 @@ async function format(command, args) {
41
32
  // node_modules. Resolving now turns a raw MODULE_NOT_FOUND into something
42
33
  // actionable.
43
34
  try {
44
- resolveFormatterBin[formatterType]();
35
+ formatters_1.resolveFormatterBin[formatterType]();
45
36
  }
46
37
  catch {
47
38
  output_1.output.error({
@@ -53,19 +44,12 @@ async function format(command, args) {
53
44
  process.exit(1);
54
45
  }
55
46
  const { nxArgs } = (0, command_line_utils_1.splitArgsIntoNxArgsAndOverrides)(args, 'affected', { printWarnings: false }, (0, configuration_1.readNxJson)());
56
- // Patterns are kept raw here. Prettier is invoked through a shell so it
57
- // quotes them at the call site; oxfmt is invoked with execFile and needs
58
- // the unquoted paths.
59
47
  const patterns = await getPatterns(formatterType, {
60
48
  ...args,
61
49
  ...nxArgs,
62
50
  });
63
51
  // Chunkify the patterns array to prevent crashing the windows terminal.
64
- // The prettier path quotes each pattern on its way to the shell, so size the
65
- // chunks against that; oxfmt goes through execFile and gets them raw.
66
- const chunkList = (0, chunkify_1.chunkify)(patterns, undefined, formatterType === 'prettier'
67
- ? (pattern) => (0, prettier_1.quoteForShell)(pattern).length
68
- : undefined);
52
+ const chunkList = (0, chunkify_1.chunkify)(patterns);
69
53
  switch (command) {
70
54
  case 'write':
71
55
  if (nxArgs.sortRootTsconfigPaths) {
@@ -850,17 +850,51 @@ async function getExpandedTaskInputs(depGraphClientResponse, expandedTaskInputsC
850
850
  expandedTaskInputsCache.set(taskId, result);
851
851
  return result;
852
852
  }
853
+ // A brace group ({a,b}.json) carries commas, so a glob list joined with
854
+ // commas can only be split at brace depth zero.
855
+ function splitGlobGroup(group) {
856
+ const globs = [];
857
+ let current = '';
858
+ let depth = 0;
859
+ for (const char of group) {
860
+ if (char === '{') {
861
+ depth++;
862
+ }
863
+ else if (char === '}' && depth > 0) {
864
+ depth--;
865
+ }
866
+ if (char === ',' && depth === 0) {
867
+ globs.push(current);
868
+ current = '';
869
+ }
870
+ else {
871
+ current += char;
872
+ }
873
+ }
874
+ globs.push(current);
875
+ // An unbalanced `{` would swallow the rest of the list; a plain split is
876
+ // the better guess then.
877
+ return depth === 0 ? globs : group.split(',');
878
+ }
853
879
  function expandInputs(inputs, project, allWorkspaceFiles, depGraphClientResponse) {
854
880
  const projectNames = depGraphClientResponse.projects.map((p) => p.name);
855
881
  const workspaceRootInputs = [];
856
882
  const projectRootInputs = [];
857
883
  const externalInputs = [];
858
884
  const otherInputs = [];
885
+ const filesInputs = [];
859
886
  inputs.forEach((input) => {
860
887
  // grouped workspace inputs look like workspace:[pattern,otherPattern]
861
888
  if (input.startsWith('workspace:[')) {
862
- const inputs = input.substring(11, input.length - 1).split(',');
863
- workspaceRootInputs.push(...inputs);
889
+ workspaceRootInputs.push(...splitGlobGroup(input.substring(11, input.length - 1)));
890
+ return;
891
+ }
892
+ // Disk-backed groups look like files:[glob,!otherGlob]. They expand on
893
+ // disk, so they must be matched before the `:` catch-all below classifies
894
+ // them as external dependencies.
895
+ const diskBacked = /^files:\[(.*)\]$/.exec(input);
896
+ if (diskBacked) {
897
+ filesInputs.push(splitGlobGroup(diskBacked[1]));
864
898
  return;
865
899
  }
866
900
  const maybeProjectName = input.split(':')[0];
@@ -881,6 +915,7 @@ function expandInputs(inputs, project, allWorkspaceFiles, depGraphClientResponse
881
915
  }
882
916
  });
883
917
  const workspaceRootsExpanded = getExpandedWorkspaceRoots(workspaceRootInputs, allWorkspaceFiles);
918
+ const filesExpanded = filesInputs.flatMap((globs) => (0, native_1.expandFilesInput)(workspace_root_1.workspaceRoot, globs));
884
919
  const otherInputsExpanded = otherInputs.map((input) => {
885
920
  if (input === 'TsConfig') {
886
921
  return (0, node_path_1.relative)(workspace_root_1.workspaceRoot, (0, typescript_1.getRootTsConfigPath)());
@@ -908,7 +943,11 @@ function expandInputs(inputs, project, allWorkspaceFiles, depGraphClientResponse
908
943
  return acc;
909
944
  }, {});
910
945
  return {
911
- general: [...workspaceRootsExpanded, ...otherInputsExpanded],
946
+ general: [
947
+ ...workspaceRootsExpanded,
948
+ ...filesExpanded,
949
+ ...otherInputsExpanded,
950
+ ],
912
951
  ...projectRootsExpanded,
913
952
  external: externalInputs,
914
953
  };
@@ -65,9 +65,6 @@ async function addNxToMonorepo(options, guided = true) {
65
65
  output_1.output.log({ title: '🛠️ Setting up Nx Cloud' });
66
66
  await (0, utils_1.initCloud)('nx-init-monorepo');
67
67
  }
68
- else if (nxCloudChoice === 'never') {
69
- (0, utils_1.setNeverConnectToCloud)(repoRoot);
70
- }
71
68
  }
72
69
  // scanning package.json files
73
70
  function allProjectPackageJsonFiles(repoRoot) {
@@ -92,9 +92,6 @@ async function addNxToNest(options, packageJson) {
92
92
  output_1.output.log({ title: '🛠️ Setting up Nx Cloud' });
93
93
  await (0, utils_1.initCloud)('nx-init-nest');
94
94
  }
95
- else if (nxCloudChoice === 'never') {
96
- (0, utils_1.setNeverConnectToCloud)(repoRoot);
97
- }
98
95
  }
99
96
  function addNestPluginToPackageJson(repoRoot) {
100
97
  const path = (0, path_1.join)(repoRoot, `package.json`);
@@ -64,7 +64,4 @@ async function addNxToNpmRepo(options, guided = true) {
64
64
  output_1.output.log({ title: '🛠️ Setting up Nx Cloud' });
65
65
  await (0, utils_1.initCloud)('nx-init-npm-repo');
66
66
  }
67
- else if (nxCloudChoice === 'never') {
68
- (0, utils_1.setNeverConnectToCloud)(repoRoot);
69
- }
70
67
  }
@@ -56,9 +56,6 @@ async function addNxToAngularCliRepo(options) {
56
56
  output_1.output.log({ title: '🛠️ Setting up Nx Cloud' });
57
57
  await (0, utils_1.initCloud)('nx-init-angular');
58
58
  }
59
- else if (nxCloudChoice === 'never') {
60
- (0, utils_1.setNeverConnectToCloud)(repoRoot);
61
- }
62
59
  }
63
60
  async function collectCacheableOperations(options) {
64
61
  let cacheableOperations;
@@ -119,9 +119,6 @@ async function getLegacyMigrationFunctionIfApplicable(repoRoot, options) {
119
119
  output_1.output.log({ title: '🛠️ Setting up Nx Cloud' });
120
120
  await (0, utils_1.initCloud)('nx-init-angular');
121
121
  }
122
- else if (nxCloudChoice === 'never') {
123
- (0, utils_1.setNeverConnectToCloud)(repoRoot);
124
- }
125
122
  };
126
123
  }
127
124
  async function installDependencies(repoRoot, pkgInfo, pmc) {
@@ -72,8 +72,7 @@ command = 'nx init') {
72
72
  // already finished.
73
73
  //
74
74
  // Chunked as `nx format` chunks: the Angular flow records a `project.json`
75
- // per project. The prettier path is sized against its quoted length; oxfmt
76
- // goes through execFile and gets raw paths.
75
+ // per project.
77
76
  let formatter = null;
78
77
  try {
79
78
  formatter = (0, formatters_1.detectFormatter)(repoRoot);
@@ -93,7 +92,7 @@ command = 'nx init') {
93
92
  // batch, but exits 2 on one unsupported file, which would end a
94
93
  // successful init with a spurious warning and prettier's own stderr.
95
94
  const supported = await (0, prettier_1.filterToPrettierSupportedFiles)(files);
96
- for (const chunk of (0, chunkify_1.chunkify)(supported, undefined, (pattern) => (0, prettier_1.quoteForShell)(pattern).length)) {
95
+ for (const chunk of (0, chunkify_1.chunkify)(supported)) {
97
96
  if (chunk.length) {
98
97
  (0, prettier_1.writeWithPrettier)(chunk, repoRoot);
99
98
  }
@@ -24,7 +24,6 @@ export declare function toErrorString(error: unknown): string;
24
24
  export declare function readErrorStderr(error: unknown): string;
25
25
  export declare function extractErrorName(error: unknown, stderr: string): string;
26
26
  export declare function initCloud(installationSource: 'nx-init' | 'nx-init-angular' | 'nx-init-monorepo' | 'nx-init-nest' | 'nx-init-npm-repo' | 'nx-init-turborepo'): Promise<void>;
27
- export declare function setNeverConnectToCloud(repoRoot: string): void;
28
27
  export declare function addVsCodeRecommendedExtensions(repoRoot: string, extensions: string[]): void;
29
28
  export declare function markRootPackageJsonAsNxProjectLegacy(repoRoot: string, cacheableScripts: string[], pmc: PackageManagerCommands): void;
30
29
  export declare function markPackageJsonAsNxProject(packageJsonPath: string): void;
@@ -10,7 +10,6 @@ exports.toErrorString = toErrorString;
10
10
  exports.readErrorStderr = readErrorStderr;
11
11
  exports.extractErrorName = extractErrorName;
12
12
  exports.initCloud = initCloud;
13
- exports.setNeverConnectToCloud = setNeverConnectToCloud;
14
13
  exports.addVsCodeRecommendedExtensions = addVsCodeRecommendedExtensions;
15
14
  exports.markRootPackageJsonAsNxProjectLegacy = markRootPackageJsonAsNxProjectLegacy;
16
15
  exports.markPackageJsonAsNxProject = markPackageJsonAsNxProject;
@@ -341,13 +340,6 @@ async function initCloud(installationSource) {
341
340
  });
342
341
  await (0, connect_to_nx_cloud_1.printSuccessMessage)(token, installationSource);
343
342
  }
344
- function setNeverConnectToCloud(repoRoot) {
345
- const nxJsonPath = (0, path_1.join)(repoRoot, 'nx.json');
346
- const nxJson = (0, fileutils_1.readJsonFile)(nxJsonPath);
347
- nxJson.neverConnectToCloud = true;
348
- (0, fileutils_1.writeJsonFile)(nxJsonPath, nxJson);
349
- (0, format_1.recordInitWrite)(nxJsonPath);
350
- }
351
343
  function addVsCodeRecommendedExtensions(repoRoot, extensions) {
352
344
  const vsCodeExtensionsPath = (0, path_1.join)(repoRoot, '.vscode/extensions.json');
353
345
  if ((0, fileutils_1.fileExists)(vsCodeExtensionsPath)) {
@@ -379,9 +379,6 @@ async function runInit(options, baseMeta) {
379
379
  if (nxCloudChoice === 'yes') {
380
380
  await (0, utils_1.initCloud)('nx-init');
381
381
  }
382
- else if (nxCloudChoice === 'never') {
383
- (0, utils_1.setNeverConnectToCloud)(repoRoot);
384
- }
385
382
  const analyticsPrompt = await (0, analytics_prompt_1.ensureAnalyticsPreferenceSet)(repoRoot, options.interactive);
386
383
  await (0, ab_testing_1.recordStat)({
387
384
  command: 'init',
@@ -4,6 +4,7 @@ exports.AGENT_DEFINITIONS = exports.opencodeDefinition = exports.codexDefinition
4
4
  exports.getAgentDefinition = getAgentDefinition;
5
5
  const os_1 = require("os");
6
6
  const path_1 = require("path");
7
+ const smol_toml_1 = require("smol-toml");
7
8
  const types_1 = require("./types");
8
9
  // --- Claude Code ---------------------------------------------------------
9
10
  function claudeCodeWellKnownPaths() {
@@ -49,15 +50,14 @@ function claudeCodeHandoffAllowedTools(runDirName) {
49
50
  function claudeCodeBuildInteractive(ctx) {
50
51
  const allowedTools = claudeCodeHandoffAllowedTools(ctx.runDirName);
51
52
  return {
52
- // `--allowedTools` is variadic (space/comma separated): a positional
53
- // placed right after its value gets swallowed as another rule. The rules
54
- // must stay in one comma-joined element with a non-variadic flag
55
- // (`--system-prompt`) between them and the user prompt.
53
+ // `--allowedTools` is variadic, so a positional right after it is read as
54
+ // another rule: keep the rules in one comma-joined element and a flag
55
+ // between them and the instructions pointer.
56
56
  args: [
57
57
  ...(allowedTools ? ['--allowedTools', allowedTools] : []),
58
- '--system-prompt',
59
- ctx.systemContext,
60
- ctx.userPrompt,
58
+ '--system-prompt-file',
59
+ ctx.systemPromptFilePath,
60
+ ctx.instructionsPointer,
61
61
  ],
62
62
  cwd: ctx.workspaceRoot,
63
63
  };
@@ -74,14 +74,41 @@ function codexWellKnownPaths() {
74
74
  return [];
75
75
  }
76
76
  // No handoff permission flag: codex's default sandbox already allows writes
77
- // inside the cwd tree without prompting, and a user-hardened read-only config
78
- // is a deliberate choice we don't override.
77
+ // inside the cwd tree, and a user-hardened read-only config is theirs to keep.
78
+ //
79
+ // `-c model_instructions_file` replaces codex's built-in instructions rather
80
+ // than adding this context to them, so the context stays on the command line,
81
+ // reduced rather than the full prompt.
79
82
  function codexBuildInteractive(ctx) {
80
83
  return {
81
- args: ['-c', `developer_instructions=${ctx.systemContext}`, ctx.userPrompt],
84
+ args: [
85
+ '-c',
86
+ `developer_instructions=${encodeTomlString(ctx.inlineSystemContext)}`,
87
+ ctx.instructionsPointer,
88
+ ],
82
89
  cwd: ctx.workspaceRoot,
83
90
  };
84
91
  }
92
+ /**
93
+ * Encodes a single-line TOML string for codex overrides. Codex treats a parse
94
+ * failure as literal text instead of reporting it, so the result is parsed
95
+ * back before it reaches the command line.
96
+ */
97
+ function encodeTomlString(value) {
98
+ // JSON escapes every control TOML rejects except DEL, which it leaves raw.
99
+ const encoded = JSON.stringify(value).replace(/\x7f/g, '\\u007F');
100
+ let decoded;
101
+ try {
102
+ decoded = (0, smol_toml_1.parse)(`value = ${encoded}`).value;
103
+ }
104
+ catch (err) {
105
+ throw new Error(`Could not encode the agent's system context as TOML for OpenAI Codex: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
106
+ }
107
+ if (decoded !== value) {
108
+ throw new Error(`Encoding the agent's system context as TOML for OpenAI Codex did not round-trip; refusing to run the agent on altered instructions.`);
109
+ }
110
+ return encoded;
111
+ }
85
112
  exports.codexDefinition = {
86
113
  id: 'codex',
87
114
  displayName: 'OpenAI Codex',
@@ -110,25 +137,54 @@ function opencodeWellKnownPaths() {
110
137
  return candidates;
111
138
  }
112
139
  // No handoff permission config: opencode's `edit` permission defaults to
113
- // allow, and injecting one would clobber (not merge with) a user's own
114
- // permission patterns.
140
+ // allow, and injecting one would clobber a user's own patterns rather than
141
+ // merge with them.
142
+ //
143
+ // The config travels through OPENCODE_CONFIG_CONTENT rather than
144
+ // OPENCODE_CONFIG. Both merge with the user's own config, but the runner
145
+ // spreads `env` over `process.env`, so the latter would overwrite a value the
146
+ // user had set.
115
147
  function opencodeBuildInteractive(ctx) {
116
- const config = {
117
- agent: {
118
- [OPENCODE_TRANSIENT_AGENT_NAME]: { prompt: ctx.systemContext },
119
- },
120
- };
121
148
  return {
122
149
  args: [
123
150
  '--agent',
124
151
  OPENCODE_TRANSIENT_AGENT_NAME,
125
152
  '--prompt',
126
- ctx.userPrompt,
153
+ ctx.instructionsPointer,
127
154
  ],
128
- env: { OPENCODE_CONFIG_CONTENT: JSON.stringify(config) },
155
+ env: { OPENCODE_CONFIG_CONTENT: opencodeConfigContent(ctx) },
129
156
  cwd: ctx.workspaceRoot,
130
157
  };
131
158
  }
159
+ /**
160
+ * Escapes inline prompt patterns before opencode's pre-JSON substitution pass.
161
+ * Excludes generator instructions from the config; cmd.exe drops inherited
162
+ * variables longer than 8191 characters.
163
+ */
164
+ function opencodeConfigContent(ctx) {
165
+ // Windows separators become `/`, which its APIs accept just as well.
166
+ // Elsewhere a `\` belongs to the file name.
167
+ const filePath = process.platform === 'win32'
168
+ ? ctx.systemPromptFilePath.replace(/\\/g, '/')
169
+ : ctx.systemPromptFilePath;
170
+ const prompt = isSubstitutionSafePath(filePath)
171
+ ? JSON.stringify(`{file:${filePath}}`)
172
+ : // `\u007b` starts no pattern and JSON decodes it back to `{`, so the
173
+ // prompt survives expansion whatever the workspace path put in it.
174
+ JSON.stringify(ctx.systemPrompt).replace(/\{/g, '\\u007b');
175
+ // Assembled rather than serialized whole: `JSON.stringify` over the object
176
+ // would re-escape the backslashes the `\u007b` encoding introduced.
177
+ return `{"agent":{${JSON.stringify(OPENCODE_TRANSIENT_AGENT_NAME)}:{"prompt":${prompt}}}}`;
178
+ }
179
+ /**
180
+ * Whether opencode would read back the path nx wrote. A `}` closes the
181
+ * reference early, and a character JSON escapes arrives escaped. Braces are
182
+ * rejected wholesale rather than matched against `{env:` and `{file:`, since a
183
+ * pattern opening inside the path swallows the reference's closing brace.
184
+ */
185
+ function isSubstitutionSafePath(filePath) {
186
+ return (!/[{}]/.test(filePath) && JSON.stringify(filePath).slice(1, -1) === filePath);
187
+ }
132
188
  exports.opencodeDefinition = {
133
189
  id: 'opencode',
134
190
  displayName: 'OpenCode',
@@ -0,0 +1,14 @@
1
+ import { FormatterType } from '../../../utils/formatters';
2
+ /**
3
+ * The command the agent runs over the files it changed, with a `<paths>`
4
+ * placeholder. `--` keeps a path that starts with `-` from being read as an
5
+ * option.
6
+ */
7
+ export declare function formatCommandFor(formatter: FormatterType, pmExec: string): string;
8
+ /**
9
+ * Resolved per dispense so a migration's formatter change takes effect; the
10
+ * scope rules name the replacement commands for the step that made it. `null`
11
+ * when no formatter is configured or its binary cannot be resolved: under npm
12
+ * the command would otherwise make `npx` download it.
13
+ */
14
+ export declare function resolveFormatCommand(root: string, pmExec: string): string | null;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatCommandFor = formatCommandFor;
4
+ exports.resolveFormatCommand = resolveFormatCommand;
5
+ const formatters_1 = require("../../../utils/formatters");
6
+ /**
7
+ * The command the agent runs over the files it changed, with a `<paths>`
8
+ * placeholder. `--` keeps a path that starts with `-` from being read as an
9
+ * option.
10
+ */
11
+ function formatCommandFor(formatter, pmExec) {
12
+ switch (formatter) {
13
+ case 'prettier':
14
+ // --ignore-unknown skips files prettier has no parser for.
15
+ return `${pmExec} prettier --write --ignore-unknown -- <paths>`;
16
+ case 'oxfmt':
17
+ // oxfmt exits 2 when every path was skipped; the flag makes that
18
+ // success. Unlike prettier it skips unparseable files on its own.
19
+ return `${pmExec} oxfmt --no-error-on-unmatched-pattern -- <paths>`;
20
+ default: {
21
+ const unhandled = formatter;
22
+ throw new Error(`Unhandled formatter: ${unhandled}`);
23
+ }
24
+ }
25
+ }
26
+ /**
27
+ * Resolved per dispense so a migration's formatter change takes effect; the
28
+ * scope rules name the replacement commands for the step that made it. `null`
29
+ * when no formatter is configured or its binary cannot be resolved: under npm
30
+ * the command would otherwise make `npx` download it.
31
+ */
32
+ function resolveFormatCommand(root, pmExec) {
33
+ const formatter = (0, formatters_1.detectFormatter)(root);
34
+ if (formatter === null) {
35
+ return null;
36
+ }
37
+ try {
38
+ formatters_1.resolveFormatterBin[formatter]();
39
+ }
40
+ catch {
41
+ return null;
42
+ }
43
+ return formatCommandFor(formatter, pmExec);
44
+ }
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Both the agentic runner and the orchestrator write per-run scratch under
3
- * `.nx/migrate-runs/<run-id>/`: handoff files in both cases, plus the durable
4
- * run state and its plan snapshots for the orchestrator. The v23 migration
5
- * `23-0-0-add-migrate-runs-to-git-ignore` adds `.nx/migrate-runs` to
3
+ * `.nx/migrate-runs/<run-id>/`: handoff and prompt files in both cases, plus
4
+ * the durable run state and its plan snapshots for the orchestrator. The v23
5
+ * migration `23-0-0-add-migrate-runs-to-git-ignore` adds `.nx/migrate-runs` to
6
6
  * `.gitignore`; in its declared slot (typically late) earlier per-migration
7
7
  * commits would absorb the scratch into the user-visible diff.
8
8
  *
@@ -11,9 +11,9 @@ const logger_1 = require("../../../utils/logger");
11
11
  const types_1 = require("./types");
12
12
  /**
13
13
  * Both the agentic runner and the orchestrator write per-run scratch under
14
- * `.nx/migrate-runs/<run-id>/`: handoff files in both cases, plus the durable
15
- * run state and its plan snapshots for the orchestrator. The v23 migration
16
- * `23-0-0-add-migrate-runs-to-git-ignore` adds `.nx/migrate-runs` to
14
+ * `.nx/migrate-runs/<run-id>/`: handoff and prompt files in both cases, plus
15
+ * the durable run state and its plan snapshots for the orchestrator. The v23
16
+ * migration `23-0-0-add-migrate-runs-to-git-ignore` adds `.nx/migrate-runs` to
17
17
  * `.gitignore`; in its declared slot (typically late) earlier per-migration
18
18
  * commits would absorb the scratch into the user-visible diff.
19
19
  *
@@ -1,3 +1,4 @@
1
+ import { type BigIntStats } from 'fs';
1
2
  import { HandoffFile } from './types';
2
3
  /** Returns the run directory for a given workspace + run id (target version). */
3
4
  export declare function runDirPath(workspaceRoot: string, runId: string): string;
@@ -19,19 +20,16 @@ export declare function mkdirSafely(dir: string, purpose: string): void;
19
20
  * inspection.
20
21
  */
21
22
  export declare function initRunDir(workspaceRoot: string, runId: string): string;
22
- /**
23
- * Absolute path of the handoff file for a migration step within a run, under
24
- * the run directory's `handoffs/` subtree: the pre-authorized write scope
25
- * stops there, so a handoff placed anywhere else costs an approval prompt.
26
- * The package's scope (if any) becomes a real subdirectory so the package name
27
- * stays readable; two packages can ship a migration with the same name without
28
- * colliding because they land in different package subdirectories. Each
29
- * segment is sanitized so the path is always writable on every platform.
30
- */
31
23
  export declare function stepHandoffPath(runDir: string, migration: {
32
24
  package: string;
33
25
  name: string;
34
26
  }): string;
27
+ /** Handoff path for a run step. No hash needed: step ids are unique within the run. */
28
+ export declare function runStepHandoffPath(runDir: string, stepId: string): string;
29
+ export declare function stepPromptsDir(runDir: string, migration: {
30
+ package: string;
31
+ name: string;
32
+ }): string;
35
33
  export type HandoffReadFailureReason = 'missing' | 'read-error' | 'parse-error' | 'shape-mismatch';
36
34
  export type HandoffReadResult = {
37
35
  ok: true;
@@ -42,19 +40,31 @@ export type HandoffReadResult = {
42
40
  detail?: string;
43
41
  };
44
42
  /**
45
- * Reads and validates a handoff file written by an agent. Returns a tagged
46
- * result so callers (the in-loop poller and the post-exit resolver) can
47
- * distinguish "file not yet written" from "file written but garbage" — the
48
- * latter is surfaced to the user instead of being collapsed into the same
49
- * generic ambiguous-outcome prompt.
43
+ * `lstat`, not `stat`: a symlink in the handoffs dir's place would send every
44
+ * handoff read and removal wherever it points.
45
+ */
46
+ export declare function handoffsDirState(handoffsDir: string): 'directory' | 'missing' | 'other';
47
+ /**
48
+ * Reads the file `stat` describes, refusing a symlink swapped in after the
49
+ * caller's lstat: O_NOFOLLOW fails the open with ELOOP, and O_NONBLOCK keeps a
50
+ * planted FIFO from blocking it. Windows has neither flag, so there the inode
51
+ * comparison is what catches a followed symlink. It does not guard against an
52
+ * unlink and recreate reusing the inode number. Read errors propagate: a file
53
+ * the agent cannot read must not pass.
54
+ */
55
+ export declare function readInspectedFile(filePath: string, stat: BigIntStats, replacedMessage: string): string;
56
+ /**
57
+ * Splits "not written yet" from "written but garbage" so callers can surface a
58
+ * malformed handoff instead of collapsing it into the generic
59
+ * ambiguous-outcome prompt.
50
60
  */
51
- export declare function readHandoffWithReason(filePath: string): HandoffReadResult;
61
+ export declare function readHandoffWithReason(filePath: string, handoffsDir: string): HandoffReadResult;
52
62
  /**
53
63
  * Convenience wrapper preserving the original null-on-any-failure contract.
54
64
  * Used by the polling loop (`waitForValidHandoff`) where every failure mode
55
65
  * is "keep waiting" — the file may be missing, mid-write, or being rewritten.
56
66
  */
57
- export declare function readHandoff(filePath: string): HandoffFile | null;
67
+ export declare function readHandoff(filePath: string, handoffsDir: string): HandoffFile | null;
58
68
  /**
59
69
  * Polls for a valid handoff file. Resolves once `readHandoff` accepts the
60
70
  * file's contents. Used to detect when the agent has finished its work so the
@@ -63,7 +73,7 @@ export declare function readHandoff(filePath: string): HandoffFile | null;
63
73
  *
64
74
  * Rejects with the abort reason when `options.signal` is aborted.
65
75
  */
66
- export declare function waitForValidHandoff(handoffFilePath: string, options?: {
76
+ export declare function waitForValidHandoff(handoffFilePath: string, handoffsDir: string, options?: {
67
77
  intervalMs?: number;
68
78
  signal?: AbortSignal;
69
79
  }): Promise<void>;