nx 24.0.0-beta.1 → 24.0.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 (44) hide show
  1. package/dist/src/command-line/graph/graph.js +2 -1
  2. package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +19 -23
  3. package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +16 -19
  4. package/dist/src/command-line/migrate/agentic/master/run-master-session.js +25 -13
  5. package/dist/src/command-line/migrate/agentic/master/spawn-master.js +6 -7
  6. package/dist/src/command-line/migrate/agentic/select.js +3 -3
  7. package/dist/src/command-line/migrate/agentic/types.js +1 -3
  8. package/dist/src/command-line/migrate/command-object.js +5 -9
  9. package/dist/src/command-line/migrate/migrate-analytics.d.ts +6 -0
  10. package/dist/src/command-line/migrate/migrate-analytics.js +12 -0
  11. package/dist/src/command-line/migrate/migrate-config.d.ts +6 -6
  12. package/dist/src/command-line/migrate/migrate-config.js +12 -6
  13. package/dist/src/command-line/migrate/migrate.d.ts +3 -30
  14. package/dist/src/command-line/migrate/migrate.js +163 -231
  15. package/dist/src/command-line/migrate/run/existing-run-report.d.ts +1 -1
  16. package/dist/src/command-line/migrate/run/existing-run-report.js +7 -5
  17. package/dist/src/command-line/migrate/run/index.d.ts +3 -3
  18. package/dist/src/command-line/migrate/run/index.js +5 -1
  19. package/dist/src/command-line/migrate/run/orchestrator.d.ts +21 -0
  20. package/dist/src/command-line/migrate/run/orchestrator.js +77 -19
  21. package/dist/src/command-line/migrate/run/run-state.d.ts +13 -0
  22. package/dist/src/command-line/migrate/run/run-state.js +21 -0
  23. package/dist/src/command-line/migrate/sort-migrations.d.ts +1 -7
  24. package/dist/src/command-line/migrate/sort-migrations.js +1 -12
  25. package/dist/src/config/nx-json.d.ts +13 -4
  26. package/dist/src/config/workspace-json-project-json.d.ts +12 -0
  27. package/dist/src/core/graph/main.js +1 -1
  28. package/dist/src/hasher/task-hasher.d.ts +2 -0
  29. package/dist/src/hasher/task-hasher.js +4 -1
  30. package/dist/src/native/index.d.ts +32 -3
  31. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  32. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  33. package/dist/src/project-graph/utils/project-configuration/target-normalization.js +6 -1
  34. package/dist/src/project-graph/utils/retrieve-workspace-files.js +27 -6
  35. package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
  36. package/dist/src/tasks-runner/run-command.js +2 -2
  37. package/dist/src/tasks-runner/running-tasks/batch-process.js +6 -0
  38. package/dist/src/tasks-runner/task-orchestrator.d.ts +10 -6
  39. package/dist/src/tasks-runner/task-orchestrator.js +89 -59
  40. package/dist/src/tasks-runner/tasks-runner.d.ts +1 -1
  41. package/dist/src/utils/plugins/core-plugins.js +4 -0
  42. package/package.json +12 -11
  43. package/schemas/nx-schema.json +28 -4
  44. package/schemas/project-schema.json +22 -2
@@ -967,7 +967,8 @@ function expandInputs(inputs, project, allWorkspaceFiles, depGraphClientResponse
967
967
  }
968
968
  });
969
969
  const workspaceRootsExpanded = getExpandedWorkspaceRoots(workspaceRootInputs, allWorkspaceFiles);
970
- const filesExpanded = filesInputs.flatMap((globs) => (0, native_1.expandFilesInput)(workspace_root_1.workspaceRoot, globs));
970
+ const projectRoots = depGraphClientResponse.projects.map((p) => p.data.root);
971
+ const filesExpanded = filesInputs.flatMap((globs) => (0, native_1.expandFilesInput)(workspace_root_1.workspaceRoot, globs, projectRoots));
971
972
  const otherInputsExpanded = otherInputs.map((input) => {
972
973
  if (input === 'TsConfig') {
973
974
  return (0, node_path_1.relative)(workspace_root_1.workspaceRoot, (0, typescript_1.getRootTsConfigPath)());
@@ -3,26 +3,23 @@
3
3
  * `.nx/migrate-runs/<run-id>/`: handoff and prompt files in both cases, plus
4
4
  * the durable run state and its plan snapshots for the orchestrator. The v23
5
5
  * migration `23-0-0-add-migrate-runs-to-git-ignore` adds `.nx/migrate-runs` to
6
- * `.gitignore`; in its declared slot (typically late) earlier per-migration
7
- * commits would absorb the scratch into the user-visible diff.
6
+ * `.gitignore`, but the scratch exists before that migration runs, so earlier
7
+ * commits would absorb it into the user-visible diff. Its two callers use this
8
+ * function to add the entry before that can happen:
8
9
  *
9
- * Two paths cover the leak, with no overlap:
10
+ * 1. Orchestrator init calls it with `applyWhenPlanned` and no standalone
11
+ * commit, before it creates the run dir. Its checkpoint commit carries the
12
+ * edit when commits are on and the checkpoint succeeds. A planned v23
13
+ * migration then changes nothing in its own step.
10
14
  *
11
- * 1. HOIST: `sortMigrations`, which `executeMigrations` applies, sorts the
12
- * v23 migration to position 0 when it is in the queue, so it runs first
13
- * through the normal runner with its own log line and commit. A
14
- * single-migration worker run needs no hoisting: the requested migration
15
- * is the entire queue.
15
+ * 2. A single-migration worker run with an agent defers to the requested
16
+ * migration when it is the v23 one. Otherwise, below v23, it applies the
17
+ * entry and commits it as a standalone preflight commit (or leaves it in
18
+ * the working tree under `--no-create-commits`).
16
19
  *
17
- * 2. INLINE FALLBACK, this function. When the migration is NOT in the queue
18
- * AND the highest target version is < v23 (intra-pre-v23 `--agentic`
19
- * run) it will never run, so apply its body inline against an `FsTree`
20
- * and commit it as a standalone preflight commit (or leave it in the
21
- * working tree under `--no-create-commits`).
22
- *
23
- * Not in the queue AND target >= v23 means the user is already past v23. They
24
- * had the entry historically; if it is gone, that is a conscious removal we
25
- * respect.
20
+ * When the v23 migration is not planned and nx is at v23 or later, the user is
21
+ * already past v23. They had the entry historically; if it is gone, that is a
22
+ * conscious removal we respect.
26
23
  */
27
24
  export declare function applyAgenticHandoffGitignoreFallback({ migrations, installedNxVersion, effectiveCreateCommits, commitPrefix, root, applyWhenPlanned, commitStandalone, }: {
28
25
  migrations: ReadonlyArray<{
@@ -41,12 +38,11 @@ export declare function applyAgenticHandoffGitignoreFallback({ migrations, insta
41
38
  commitPrefix: string;
42
39
  root: string;
43
40
  /**
44
- * Apply the entry even when the hoisted migration is in the plan. The
45
- * classic loop can defer to that migration because its run scratch appears
46
- * only after migration 1 has run; the orchestrator creates its run dir at
47
- * init, before any migration, so it needs the entry immediately. A planned
48
- * migration also means the missing entry is not a conscious removal, so the
49
- * v23 cutoff does not apply.
41
+ * Apply the entry even when the v23 migration is in the plan. The
42
+ * orchestrator creates its run dir at init, before any migration runs, so
43
+ * it can't defer to that migration. A planned migration also means the
44
+ * missing entry is not a conscious removal, so the v23 cutoff does not
45
+ * apply.
50
46
  */
51
47
  applyWhenPlanned?: boolean;
52
48
  /**
@@ -14,32 +14,29 @@ const types_1 = require("./types");
14
14
  * `.nx/migrate-runs/<run-id>/`: handoff and prompt files in both cases, plus
15
15
  * the durable run state and its plan snapshots for the orchestrator. The v23
16
16
  * migration `23-0-0-add-migrate-runs-to-git-ignore` adds `.nx/migrate-runs` to
17
- * `.gitignore`; in its declared slot (typically late) earlier per-migration
18
- * commits would absorb the scratch into the user-visible diff.
17
+ * `.gitignore`, but the scratch exists before that migration runs, so earlier
18
+ * commits would absorb it into the user-visible diff. Its two callers use this
19
+ * function to add the entry before that can happen:
19
20
  *
20
- * Two paths cover the leak, with no overlap:
21
+ * 1. Orchestrator init calls it with `applyWhenPlanned` and no standalone
22
+ * commit, before it creates the run dir. Its checkpoint commit carries the
23
+ * edit when commits are on and the checkpoint succeeds. A planned v23
24
+ * migration then changes nothing in its own step.
21
25
  *
22
- * 1. HOIST: `sortMigrations`, which `executeMigrations` applies, sorts the
23
- * v23 migration to position 0 when it is in the queue, so it runs first
24
- * through the normal runner with its own log line and commit. A
25
- * single-migration worker run needs no hoisting: the requested migration
26
- * is the entire queue.
26
+ * 2. A single-migration worker run with an agent defers to the requested
27
+ * migration when it is the v23 one. Otherwise, below v23, it applies the
28
+ * entry and commits it as a standalone preflight commit (or leaves it in
29
+ * the working tree under `--no-create-commits`).
27
30
  *
28
- * 2. INLINE FALLBACK, this function. When the migration is NOT in the queue
29
- * AND the highest target version is < v23 (intra-pre-v23 `--agentic`
30
- * run) it will never run, so apply its body inline against an `FsTree`
31
- * and commit it as a standalone preflight commit (or leave it in the
32
- * working tree under `--no-create-commits`).
33
- *
34
- * Not in the queue AND target >= v23 means the user is already past v23. They
35
- * had the entry historically; if it is gone, that is a conscious removal we
36
- * respect.
31
+ * When the v23 migration is not planned and nx is at v23 or later, the user is
32
+ * already past v23. They had the entry historically; if it is gone, that is a
33
+ * conscious removal we respect.
37
34
  */
38
35
  async function applyAgenticHandoffGitignoreFallback({ migrations, installedNxVersion, effectiveCreateCommits, commitPrefix, root, applyWhenPlanned = false, commitStandalone = true, }) {
39
36
  if (migrations.some(types_1.isHandoffGitignoreMigration)) {
40
37
  if (!applyWhenPlanned) {
41
- // The queue runs it itself: hoisted to the front by the sort comparator
42
- // in a full run, or as the single requested migration in a worker run.
38
+ // The single-migration worker run is that migration, and it adds the
39
+ // entry itself.
43
40
  return;
44
41
  }
45
42
  }
@@ -21,20 +21,29 @@ async function runMasterSession(input) {
21
21
  createCommits: init.createCommits,
22
22
  skipInstall: init.skipInstall,
23
23
  };
24
- const resume = (runId) => (0, run_1.runOrchestratorResume)({
25
- root: init.root,
26
- runId,
27
- policy,
28
- emitAgentInstructions: false,
29
- });
24
+ // A resume refuses when it cannot restore the run's missing runbook; a
25
+ // start refuses when the default-branch commit confirmation is declined.
26
+ let refusal = 'declined_commits';
27
+ const resume = (runId) => {
28
+ refusal = 'runbook_missing';
29
+ return (0, run_1.runOrchestratorResume)({
30
+ root: init.root,
31
+ runId,
32
+ policy,
33
+ emitAgentInstructions: false,
34
+ });
35
+ };
30
36
  // With `replaceRunId`, starts fresh over that run only; the consent covers
31
37
  // the run the user saw, and any other active run is reported instead.
32
- const start = (replaceRunId) => (0, run_1.runOrchestratorInit)({
33
- ...init,
34
- emitAgentInstructions: false,
35
- onExistingRun: replaceRunId === undefined ? 'report' : 'start-fresh',
36
- replaceRunId,
37
- });
38
+ const start = (replaceRunId) => {
39
+ refusal = 'declined_commits';
40
+ return (0, run_1.runOrchestratorInit)({
41
+ ...init,
42
+ emitAgentInstructions: false,
43
+ onExistingRun: replaceRunId === undefined ? 'report' : 'start-fresh',
44
+ replaceRunId,
45
+ });
46
+ };
38
47
  let ready = requestedRunId !== undefined && !startFresh
39
48
  ? resume(requestedRunId)
40
49
  : await start(startFresh ? requestedRunId : undefined);
@@ -44,6 +53,7 @@ async function runMasterSession(input) {
44
53
  output_1.output.log({
45
54
  title: `Leaving migrate run ${ready.runId} as it is. ${continueHint(init.root, agent.id, ready.runId, ready.facts.policy)}`,
46
55
  });
56
+ (0, migrate_analytics_1.reportMigrateRunStopped)('aborted');
47
57
  return;
48
58
  }
49
59
  if (decision === 'continue') {
@@ -56,9 +66,11 @@ async function runMasterSession(input) {
56
66
  }
57
67
  if (ready.kind === 'existing-run') {
58
68
  output_1.output.warn((0, run_1.renderExistingRunReport)(ready.facts, (0, run_1.renderExistingRunCommands)(init.root, ready.facts, init.migrationsPath, agent.id)));
69
+ (0, migrate_analytics_1.reportMigrateRunStopped)('existing_run');
59
70
  return 1;
60
71
  }
61
72
  if (ready.kind === 'refused') {
73
+ (0, migrate_analytics_1.reportMigrateRunStopped)(refusal);
62
74
  return;
63
75
  }
64
76
  const { runId, runRoot, runbookPath, reconcileCommand } = ready;
@@ -145,7 +157,7 @@ async function runMasterSession(input) {
145
157
  }
146
158
  }
147
159
  function continueHint(root, agentId, runId, policy) {
148
- return `Run ${(0, run_1.renderContinueCommand)(root, runId, policy, agentId)}, with NX_MIGRATE_ORCHESTRATOR=true set in the environment, to continue it.`;
160
+ return `Run ${(0, run_1.renderContinueCommand)(root, runId, policy, agentId)} to continue it.`;
149
161
  }
150
162
  async function decideExistingRun(found, root) {
151
163
  output_1.output.log((0, run_1.renderExistingRunReport)(found.facts));
@@ -22,16 +22,15 @@ const OPERATION_KILL_WAIT_MS = 2_000;
22
22
  // SIGINTs this close together are one Ctrl+C: `npx` and the package managers
23
23
  // pass on to nx the SIGINT the terminal already sent it.
24
24
  const SAME_PRESS_MS = 500;
25
- // The wrapper's local re-exec sets the first two for its own hop and the user
26
- // sets the third to reach this path; inherited, they would change install or
27
- // routing behavior for every `nx migrate` the agent runs. CI exports the last
28
- // two for its own `nx affected` runs; inherited, they would replace the base
29
- // the run names and drop uncommitted files from the pass's selection. The
30
- // workspace's env files can still set them: every nx command loads those.
25
+ // The wrapper's local re-exec sets the first two for its own hop; inherited,
26
+ // they would change install or routing behavior for every `nx migrate` the
27
+ // agent runs. CI exports the last two for its own `nx affected` runs;
28
+ // inherited, they would replace the base the run names and drop uncommitted
29
+ // files from the pass's selection. The workspace's env files can still set
30
+ // them: every nx command loads those.
31
31
  const STRIPPED_ENV_VARS = [
32
32
  'NX_MIGRATE_SKIP_INSTALL',
33
33
  'NX_MIGRATE_USE_LOCAL',
34
- 'NX_MIGRATE_ORCHESTRATOR',
35
34
  'NX_BASE',
36
35
  'NX_HEAD',
37
36
  ];
@@ -97,7 +97,7 @@ function requireInteractiveOrAbort(isInteractive) {
97
97
  if (isInteractive)
98
98
  return;
99
99
  output_1.output.error({
100
- title: 'The agentic flow is interactive-only in this release.',
100
+ title: 'The agentic flow needs an interactive terminal.',
101
101
  bodyLines: [
102
102
  'Re-run in an interactive terminal, or pass `--agentic=false` to skip the agentic flow.',
103
103
  ],
@@ -106,9 +106,9 @@ function requireInteractiveOrAbort(isInteractive) {
106
106
  }
107
107
  function warnAgenticInteractiveOnly() {
108
108
  output_1.output.warn({
109
- title: 'Skipping the agentic flow: it is interactive-only in this release and this run is non-interactive.',
109
+ title: 'Skipping the agentic flow: the agent session needs an interactive terminal, and this run is non-interactive.',
110
110
  bodyLines: [
111
- 'Continuing the migration without the agentic flow. Re-run in an interactive terminal to use it.',
111
+ 'Continuing without the agentic flow. Generators still run, prompt-based changes are left for you to apply, and no AI validation runs. Re-run in an interactive terminal to use the agentic flow.',
112
112
  ],
113
113
  });
114
114
  }
@@ -28,9 +28,7 @@ exports.PROMPTS_DIR_NAME = 'prompts';
28
28
  * `.gitignore`. Hard-coded because the agentic preflight is a deliberate
29
29
  * one-off coupling: this exact migration owns the entry that keeps
30
30
  * `.nx/migrate-runs/<run-id>/...` scratch out of per-migration commits. If
31
- * the migration is ever renamed, this entry must move with it. It lives here
32
- * rather than in `handoff-gitignore.ts` so `sortMigrations`' hoist check
33
- * doesn't load that module's migration-execution machinery.
31
+ * the migration is ever renamed, this entry must move with it.
34
32
  */
35
33
  const HANDOFF_GITIGNORE_MIGRATION_PACKAGE = 'nx';
36
34
  const HANDOFF_GITIGNORE_MIGRATION_NAME = '23-0-0-add-migrate-runs-to-git-ignore';
@@ -59,10 +59,8 @@ function withMigrationOptions(yargs) {
59
59
  type: 'string',
60
60
  })
61
61
  .option('runId', {
62
- // Hidden with the orchestrator itself.
63
- describe: 'The orchestrated migrate run to record a single migration into, to continue with --run-migrations, or to reconcile when given alone.',
62
+ describe: "The id of a migrate run, as nx prints it. With --run-migrations: continue that run, or replace it with --start-fresh. The AI agent driving a run also passes it with --run-migration to record a migration into the run, and alone to record a step's outcome and get the next step.",
64
63
  type: 'string',
65
- hidden: true,
66
64
  })
67
65
  .option('stepAction', {
68
66
  describe: 'How an orchestrated reconcile resolves its single failed or died step.',
@@ -71,9 +69,8 @@ function withMigrationOptions(yargs) {
71
69
  hidden: true,
72
70
  })
73
71
  .option('startFresh', {
74
- describe: 'With --run-migrations and --run-id=<id> under the orchestrator: delete the record of the active migrate run the id names and start a new run over the whole plan. Migrations the deleted run applied stay applied.',
72
+ describe: 'With --run-migrations and --run-id=<id>: delete the record of the active migrate run the id names, then run the whole plan again, as a new run when orchestrated. Migrations the deleted run applied stay applied.',
75
73
  type: 'boolean',
76
- hidden: true,
77
74
  })
78
75
  .option('ifExists', {
79
76
  describe: `Run migrations only if the migrations file exists, if not continues successfully.`,
@@ -123,17 +120,16 @@ function withMigrationOptions(yargs) {
123
120
  choices: exports.MULTI_MAJOR_MODES,
124
121
  })
125
122
  .option('agentic', {
126
- describe: 'Enable the agentic flow for prompt-based migrations and AI-driven review. Pass `--agentic=<agent>` to pin a specific agent (claude-code, codex, or opencode). Pass `--agentic=false` or `--no-agentic` to disable.',
123
+ describe: 'Use an AI agent to apply prompt-based migrations and review the results. With --run-migrations, one agent session drives the whole run. Pass `--agentic=<agent>` to pin a specific agent (claude-code, codex, or opencode). Pass `--agentic=false` or `--no-agentic` to disable it, including when nx migrate runs inside an AI agent.',
127
124
  coerce: cli_args_1.coerceAgenticArg,
128
125
  })
129
126
  .option('validate', {
130
- describe: 'When `--agentic` resolves to an enabled agent, run agent-driven validation after generator-only migrations that have no `prompt:` field. Defaults to on; pass `--no-validate` to opt out. Has no effect when `--agentic` is disabled, when running inside an outer agent, or when running non-interactively without an explicit agent.',
127
+ describe: 'Have the AI agent driving the run review the changes of generator-only migrations (those with no `prompt:` field). On by default; pass `--no-validate` to opt out. A continued run keeps the setting it started with. Has no effect when no agent drives the run, or with --run-migration inside an AI agent.',
131
128
  type: 'boolean',
132
129
  })
133
130
  .option('finalValidation', {
134
- describe: 'With --run-migrations under the orchestrator: end the run with an agent validation pass over the whole workspace once every migration has run. On by default; pass --no-final-validation to opt out.',
131
+ describe: 'With --run-migrations, when an AI agent drives the run: once every migration has run, the agent checks that the projects the run touched still lint, build, and pass their unit tests. On by default; pass --no-final-validation to opt out. A continued run keeps the setting it started with.',
135
132
  type: 'boolean',
136
- hidden: true,
137
133
  })
138
134
  .check(({ createCommits, commitPrefix, from, excludeAppliedMigrations, include, agentic, }) => {
139
135
  // Only an explicit `--no-create-commits` is decidable here, before the
@@ -18,6 +18,7 @@ export type MigratePromptChoices = {
18
18
  export type MigratePromptName = keyof MigratePromptChoices;
19
19
  export type MigrateGenerateErrorCode = 'resolve_version' | 'fetch_migrations' | 'package_updates';
20
20
  export type MigrateRunErrorCode = 'npm_install' | 'migration_exec' | 'agentic' | 'other';
21
+ export type MigrateRunStopReason = 'existing_run' | 'declined_commits' | 'aborted' | 'runbook_missing';
21
22
  export declare function setMigrateInclude(include: MigrateInclude): void;
22
23
  export declare function setMigrateIncludeSource(source: MigrateIncludeSource): void;
23
24
  export declare function classifyMigrateFetchFallback(error: unknown): MigrateFetchFallbackReason;
@@ -60,6 +61,11 @@ export declare function reportMigrateRunComplete(opts: {
60
61
  migrationCount: number;
61
62
  appliedCount: number;
62
63
  }): void;
64
+ /**
65
+ * Closes a `migrate_run_start` whose invocation stopped before running any
66
+ * migration.
67
+ */
68
+ export declare function reportMigrateRunStopped(reason: MigrateRunStopReason): void;
63
69
  export declare function reportMigrateRunError(opts: {
64
70
  code: MigrateRunErrorCode;
65
71
  migrationPackage?: string;
@@ -10,6 +10,7 @@ exports.reportMigrateGenerateError = reportMigrateGenerateError;
10
10
  exports.reportMigrateRunStart = reportMigrateRunStart;
11
11
  exports.hasMigrateRunStarted = hasMigrateRunStarted;
12
12
  exports.reportMigrateRunComplete = reportMigrateRunComplete;
13
+ exports.reportMigrateRunStopped = reportMigrateRunStopped;
13
14
  exports.reportMigrateRunError = reportMigrateRunError;
14
15
  exports.reportMigrateOrchestratorInit = reportMigrateOrchestratorInit;
15
16
  exports.reportMigrateOrchestratorDispense = reportMigrateOrchestratorDispense;
@@ -165,6 +166,17 @@ function reportMigrateRunComplete(opts) {
165
166
  });
166
167
  });
167
168
  }
169
+ /**
170
+ * Closes a `migrate_run_start` whose invocation stopped before running any
171
+ * migration.
172
+ */
173
+ function reportMigrateRunStopped(reason) {
174
+ safeReport(() => {
175
+ if (!analytics_1.customDimensions)
176
+ return;
177
+ (0, analytics_1.reportEvent)(`migrate_run_stopped_${reason}`);
178
+ });
179
+ }
168
180
  function reportMigrateRunError(opts) {
169
181
  safeReport(() => {
170
182
  if (!analytics_1.customDimensions || runErrorRecorded)
@@ -9,12 +9,12 @@ import { type MigrateArgs } from './command-object';
9
9
  * config value never trips the mutually-exclusive-flag guards in
10
10
  * `parseMigrationsOptions`: `include` and `multiMajorMode` in the generate
11
11
  * phase only; `createCommits` / `commitPrefix` and `agentic` / `validate` when
12
- * running the whole migrations file or a standalone single migration. A
13
- * `--run-id` reconcile or recorded worker takes none of them: a recorded run
14
- * takes its commit config from run.json and is driven by the outer agent. A
15
- * `--run-migrations --run-id` continue takes `agentic` only, to select the
16
- * agent of the new session. A `--start-fresh` starts a new run and takes all
17
- * four.
12
+ * running the whole migrations file or a standalone single migration, and
13
+ * `finalValidation` for the whole file only. A `--run-id` reconcile or
14
+ * recorded worker takes none of them: a recorded run takes its commit config
15
+ * from run.json and is driven by the outer agent. A `--run-migrations
16
+ * --run-id` continue takes `agentic` only, to select the agent of the new
17
+ * session. A `--start-fresh` starts a new run and takes all five.
18
18
  *
19
19
  * `include` is carried as `includeFromConfig` so it is never mistaken for an
20
20
  * explicit `--include`: `resolveInclude` applies it only when the resolved
@@ -14,12 +14,12 @@ const MULTI_MAJOR_MODE_ENV = 'NX_MULTI_MAJOR_MODE';
14
14
  * config value never trips the mutually-exclusive-flag guards in
15
15
  * `parseMigrationsOptions`: `include` and `multiMajorMode` in the generate
16
16
  * phase only; `createCommits` / `commitPrefix` and `agentic` / `validate` when
17
- * running the whole migrations file or a standalone single migration. A
18
- * `--run-id` reconcile or recorded worker takes none of them: a recorded run
19
- * takes its commit config from run.json and is driven by the outer agent. A
20
- * `--run-migrations --run-id` continue takes `agentic` only, to select the
21
- * agent of the new session. A `--start-fresh` starts a new run and takes all
22
- * four.
17
+ * running the whole migrations file or a standalone single migration, and
18
+ * `finalValidation` for the whole file only. A `--run-id` reconcile or
19
+ * recorded worker takes none of them: a recorded run takes its commit config
20
+ * from run.json and is driven by the outer agent. A `--run-migrations
21
+ * --run-id` continue takes `agentic` only, to select the agent of the new
22
+ * session. A `--start-fresh` starts a new run and takes all five.
23
23
  *
24
24
  * `include` is carried as `includeFromConfig` so it is never mistaken for an
25
25
  * explicit `--include`: `resolveInclude` applies it only when the resolved
@@ -60,6 +60,12 @@ function applyNxJsonMigrateDefaults(args, migrateConfig, env = process.env) {
60
60
  assertType(migrateConfig.validate, 'boolean', 'validate');
61
61
  merged.validate = migrateConfig.validate;
62
62
  }
63
+ if (isRunMigrations &&
64
+ merged.finalValidation === undefined &&
65
+ migrateConfig.finalValidation !== undefined) {
66
+ assertType(migrateConfig.finalValidation, 'boolean', 'finalValidation');
67
+ merged.finalValidation = migrateConfig.finalValidation;
68
+ }
63
69
  }
64
70
  // A continue takes `agentic` too; the reconcile and the worker must not:
65
71
  // there it trips the `--agentic`/`--run-id` parse conflict.
@@ -196,7 +196,9 @@ export { filterDowngradedUpdates };
196
196
  export declare function generateMigrationsJsonAndUpdatePackageJson(root: string, opts: GenerateMigrations, fetch?: MigratorOptions['fetch']): Promise<void>;
197
197
  export { isPromptOnlyMigration, isHybridMigration };
198
198
  export declare function formatSkippedPromptsNextStep(skipped: PlannedMigration[]): string;
199
- export declare function executeMigrations(root: string, migrations: PlannedMigration[], isVerbose: boolean, shouldCreateCommits: boolean, commitPrefix: string, shouldSkipInstall?: boolean, agentic?: ResolvedAgentic, agenticHasDiffContext?: boolean, shouldRunValidation?: boolean): Promise<{
199
+ export declare function executeMigrations(root: string, migrations: PlannedMigration[], isVerbose: boolean, shouldCreateCommits: boolean, commitPrefix: string, shouldSkipInstall?: boolean, agentic?: Exclude<ResolvedAgentic, {
200
+ kind: 'enabled';
201
+ }>): Promise<{
200
202
  migrationsWithNoChanges: PlannedMigration[];
201
203
  skippedPromptsCount: number;
202
204
  notRunMigrationsCount: number;
@@ -213,33 +215,4 @@ export declare function migrate(root: string, args: {
213
215
  }, rawArgs: string[]): Promise<number>;
214
216
  export declare function readLocalNxVersion(root: string): string | undefined;
215
217
  export declare function runMigration(): Promise<number>;
216
- /**
217
- * Resolves a migration's collection once and derives everything the run loop
218
- * needs from that single read: the implementation context (`collection` +
219
- * `collectionPath`, handed to `runNxOrAngularMigration`) and, for agentic runs,
220
- * the workspace-relative documentation path handed to the agent.
221
- *
222
- * Read fresh per migration (not cached across the loop) so a prior migration's
223
- * reinstall is reflected, exactly as before. Error handling matches each field's
224
- * role:
225
- * - Migrations that run an implementation REQUIRE the collection; an unreadable
226
- * collection throws and aborts that migration (caught by the run loop).
227
- * - Prompt-only migrations don't run an implementation, so the collection is
228
- * read only to resolve documentation - a failure there is non-fatal: the
229
- * prompt still runs and the supplementary doc is skipped with a warning.
230
- */
231
- export declare function resolveMigrationForRun(root: string, migration: {
232
- package: string;
233
- name: string;
234
- documentation?: string;
235
- implementation?: string;
236
- factory?: string;
237
- prompt?: string;
238
- }, resolveDocumentation: boolean): {
239
- resolvedCollection?: {
240
- collection: MigrationsJson;
241
- collectionPath: string;
242
- };
243
- documentationPath?: string;
244
- };
245
218
  export declare function nxCliPath(nxWorkspaceRoot?: string): Promise<string>;