nx 24.0.0-beta.0 → 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 (90) hide show
  1. package/dist/nx-cloud-internals.d.ts +1 -0
  2. package/dist/nx-cloud-internals.js +7 -1
  3. package/dist/src/command-line/graph/graph.js +2 -1
  4. package/dist/src/command-line/migrate/agentic/close-agent-session.d.ts +1 -1
  5. package/dist/src/command-line/migrate/agentic/close-agent-session.js +4 -3
  6. package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +19 -23
  7. package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +16 -19
  8. package/dist/src/command-line/migrate/agentic/master/run-master-session.js +25 -13
  9. package/dist/src/command-line/migrate/agentic/master/spawn-master.js +82 -22
  10. package/dist/src/command-line/migrate/agentic/select.js +3 -3
  11. package/dist/src/command-line/migrate/agentic/types.js +1 -3
  12. package/dist/src/command-line/migrate/command-object.js +5 -9
  13. package/dist/src/command-line/migrate/execute-migration.d.ts +2 -2
  14. package/dist/src/command-line/migrate/execute-migration.js +18 -10
  15. package/dist/src/command-line/migrate/migrate-analytics.d.ts +6 -0
  16. package/dist/src/command-line/migrate/migrate-analytics.js +12 -0
  17. package/dist/src/command-line/migrate/migrate-commits.d.ts +4 -1
  18. package/dist/src/command-line/migrate/migrate-commits.js +10 -3
  19. package/dist/src/command-line/migrate/migrate-config.d.ts +6 -6
  20. package/dist/src/command-line/migrate/migrate-config.js +12 -6
  21. package/dist/src/command-line/migrate/migrate.d.ts +3 -30
  22. package/dist/src/command-line/migrate/migrate.js +206 -237
  23. package/dist/src/command-line/migrate/run/agent-output.d.ts +1 -0
  24. package/dist/src/command-line/migrate/run/agent-output.js +5 -0
  25. package/dist/src/command-line/migrate/run/broker.d.ts +14 -5
  26. package/dist/src/command-line/migrate/run/broker.js +68 -20
  27. package/dist/src/command-line/migrate/run/existing-run-report.d.ts +1 -1
  28. package/dist/src/command-line/migrate/run/existing-run-report.js +7 -5
  29. package/dist/src/command-line/migrate/run/index.d.ts +6 -5
  30. package/dist/src/command-line/migrate/run/index.js +12 -1
  31. package/dist/src/command-line/migrate/run/orchestrator.d.ts +21 -0
  32. package/dist/src/command-line/migrate/run/orchestrator.js +149 -32
  33. package/dist/src/command-line/migrate/run/run-state.d.ts +13 -0
  34. package/dist/src/command-line/migrate/run/run-state.js +21 -0
  35. package/dist/src/command-line/migrate/run/runbook.js +19 -0
  36. package/dist/src/command-line/migrate/run/state-machine.js +4 -1
  37. package/dist/src/command-line/migrate/run/util.d.ts +3 -0
  38. package/dist/src/command-line/migrate/run/util.js +7 -1
  39. package/dist/src/command-line/migrate/sort-migrations.d.ts +1 -7
  40. package/dist/src/command-line/migrate/sort-migrations.js +1 -12
  41. package/dist/src/command-line/show/show-target/info.js +1 -1
  42. package/dist/src/config/nx-json.d.ts +13 -4
  43. package/dist/src/config/task-graph.d.ts +1 -1
  44. package/dist/src/config/workspace-json-project-json.d.ts +72 -0
  45. package/dist/src/core/graph/main.js +1 -1
  46. package/dist/src/devkit-exports.d.ts +1 -1
  47. package/dist/src/hasher/check-task-files.js +4 -4
  48. package/dist/src/hasher/native-task-hasher-impl.js +3 -1
  49. package/dist/src/hasher/task-hasher.d.ts +2 -0
  50. package/dist/src/hasher/task-hasher.js +4 -1
  51. package/dist/src/native/index.d.ts +92 -14
  52. package/dist/src/native/native-bindings.js +3 -0
  53. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  54. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  55. package/dist/src/project-graph/utils/project-configuration/target-normalization.js +6 -1
  56. package/dist/src/project-graph/utils/retrieve-workspace-files.js +27 -6
  57. package/dist/src/tasks-runner/create-task-graph.d.ts +7 -16
  58. package/dist/src/tasks-runner/create-task-graph.js +43 -57
  59. package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
  60. package/dist/src/tasks-runner/init-tasks-runner.js +13 -0
  61. package/dist/src/tasks-runner/life-cycle.d.ts +4 -1
  62. package/dist/src/tasks-runner/life-cycle.js +7 -0
  63. package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +5 -2
  64. package/dist/src/tasks-runner/life-cycles/performance-analysis.js +13 -7
  65. package/dist/src/tasks-runner/life-cycles/performance-life-cycle.d.ts +4 -3
  66. package/dist/src/tasks-runner/life-cycles/performance-life-cycle.js +9 -2
  67. package/dist/src/tasks-runner/readiness/probes.d.ts +9 -0
  68. package/dist/src/tasks-runner/readiness/probes.js +62 -0
  69. package/dist/src/tasks-runner/readiness/ready-when.d.ts +38 -0
  70. package/dist/src/tasks-runner/readiness/ready-when.js +190 -0
  71. package/dist/src/tasks-runner/run-command.js +7 -6
  72. package/dist/src/tasks-runner/running-tasks/batch-process.js +6 -0
  73. package/dist/src/tasks-runner/running-tasks/node-child-process.js +5 -4
  74. package/dist/src/tasks-runner/task-graph-utils.d.ts +9 -6
  75. package/dist/src/tasks-runner/task-graph-utils.js +17 -12
  76. package/dist/src/tasks-runner/task-orchestrator.d.ts +37 -10
  77. package/dist/src/tasks-runner/task-orchestrator.js +459 -79
  78. package/dist/src/tasks-runner/tasks-runner.d.ts +1 -1
  79. package/dist/src/tasks-runner/tasks-schedule.d.ts +18 -1
  80. package/dist/src/tasks-runner/tasks-schedule.js +64 -6
  81. package/dist/src/tasks-runner/utils.js +6 -22
  82. package/dist/src/utils/child-process.js +1 -0
  83. package/dist/src/utils/git-utils.d.ts +6 -1
  84. package/dist/src/utils/git-utils.js +26 -5
  85. package/dist/src/utils/plugins/core-plugins.js +4 -0
  86. package/dist/src/utils/spawn-without-terminal.d.ts +27 -0
  87. package/dist/src/utils/spawn-without-terminal.js +110 -0
  88. package/package.json +12 -11
  89. package/schemas/nx-schema.json +93 -4
  90. package/schemas/project-schema.json +84 -2
@@ -16,6 +16,7 @@ export interface AgentMessage {
16
16
  export declare function safeLines(lines: readonly string[]): string[];
17
17
  export declare function logToAgent(message: AgentMessage): void;
18
18
  export declare function warnToAgent(message: AgentMessage): void;
19
+ export declare function logLineToAgent(line: string): void;
19
20
  export declare function emitStepBlock(runId: string, stepId: string, action: string, payload: object): void;
20
21
  export declare function emitPromptBlock(migrationId: string, payload: object): void;
21
22
  export declare function emitStepPromptBlock(stepId: string, payload: object): void;
@@ -13,10 +13,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.safeLines = safeLines;
14
14
  exports.logToAgent = logToAgent;
15
15
  exports.warnToAgent = warnToAgent;
16
+ exports.logLineToAgent = logLineToAgent;
16
17
  exports.emitStepBlock = emitStepBlock;
17
18
  exports.emitPromptBlock = emitPromptBlock;
18
19
  exports.emitStepPromptBlock = emitStepPromptBlock;
19
20
  exports.emitRunbookBlock = emitRunbookBlock;
21
+ const logger_1 = require("../../../utils/logger");
20
22
  const output_1 = require("../../../utils/output");
21
23
  const print_dropped_agent_context_1 = require("../agentic/print-dropped-agent-context");
22
24
  const text_1 = require("../text");
@@ -40,6 +42,9 @@ function logToAgent(message) {
40
42
  function warnToAgent(message) {
41
43
  output_1.output.warn(safe(message));
42
44
  }
45
+ function logLineToAgent(line) {
46
+ logger_1.logger.info((0, text_1.singleLine)(line));
47
+ }
43
48
  /**
44
49
  * Serializes a block payload. `<` becomes its JSON unicode escape so a raw one
45
50
  * in a value cannot forge the closing tag, and the result stays valid JSON for
@@ -91,8 +91,8 @@ export declare function acquireTreeOperation(dir: string, request: TreeOperation
91
91
  export declare function releaseTreeOperation(dir: string, owner: string, markedStepId?: string): void;
92
92
  /** The reservation a live process other than `owner` holds, if any. */
93
93
  export declare function liveTreeOperation(state: MigrateRunState, owner?: string): MigrateTreeOperation | undefined;
94
- export declare function treeBusyMessage(held: MigrateTreeOperation): string;
95
- export declare function treeOperationLabel(held: Pick<MigrateTreeOperation, 'kind' | 'stepId'>): string;
94
+ export declare function treeBusyMessage(held: MigrateTreeOperation, stepName?: string): string;
95
+ export declare function treeOperationLabel(held: Pick<MigrateTreeOperation, 'kind' | 'stepId'>, stepName?: string): string;
96
96
  export declare function brokerDir(runDirPath: string): string;
97
97
  /**
98
98
  * Runs the step's install and commit where they can land: in this process
@@ -119,6 +119,15 @@ export declare function resetStepTree(dir: string, step: MigrateStep, resetInPro
119
119
  * reservation it runs with, so the caller writes no transition of its own.
120
120
  */
121
121
  export declare function giveUpStepTree(root: string, dir: string, step: MigrateStep, skipInstall: boolean, reconcileCommand: string, scope: TreeScope): Promise<GiveUpOutcome>;
122
+ export declare const COMMIT_INSTALLS_FIRST = "A commit first installs any dependency changes.";
123
+ export declare function commitsStep(kind: MigrateTreeOperation['kind']): boolean;
124
+ export declare function sessionOperationWayOut(operation: string): string;
125
+ export declare function formatElapsed(ms: number): string;
126
+ export interface InFlightOperation {
127
+ request: BrokerRequest;
128
+ startedAt: number;
129
+ stepName: string;
130
+ }
122
131
  /**
123
132
  * The parent side. Holds one exclusive lock for the session's lifetime so a
124
133
  * waiting step can tell a slow parent from a dead one, answers each request
@@ -138,13 +147,13 @@ export declare class MigrateCommitBroker {
138
147
  private inFlight;
139
148
  private readonly lock;
140
149
  constructor(root: string, dir: string, reconcileCommand: string, policy: MigrateRunPolicy);
141
- /** The request whose operation this process is running right now. */
142
- get requestInFlight(): BrokerRequest | null;
150
+ /** The request whose operation this process is running right now, and since when. */
151
+ get requestInFlight(): InFlightOperation | null;
143
152
  /** Answers this session's unanswered requests, one at a time. */
144
153
  service(): Promise<void>;
145
154
  private record;
146
155
  private answer;
147
- /** Releases the lock; call after the last `service` settled. */
156
+ /** Releases the lock; call after the last `service` settled, or once giving up on it. */
148
157
  close(): void;
149
158
  private notADirectory;
150
159
  }
@@ -8,7 +8,7 @@
8
8
  // every file the parent could consult is writable from the sandbox, so the
9
9
  // parent's own invocation decides what it installs and commits.
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.MigrateCommitBroker = exports.TreeBusyError = exports.BrokerUnavailableError = exports.BrokerStaleRequestError = exports.BROKER_ENV_VAR = void 0;
11
+ exports.MigrateCommitBroker = exports.COMMIT_INSTALLS_FIRST = exports.TreeBusyError = exports.BrokerUnavailableError = exports.BrokerStaleRequestError = exports.BROKER_ENV_VAR = void 0;
12
12
  exports.acquireTreeOperation = acquireTreeOperation;
13
13
  exports.releaseTreeOperation = releaseTreeOperation;
14
14
  exports.liveTreeOperation = liveTreeOperation;
@@ -19,16 +19,21 @@ exports.commitStepTree = commitStepTree;
19
19
  exports.installStepTree = installStepTree;
20
20
  exports.resetStepTree = resetStepTree;
21
21
  exports.giveUpStepTree = giveUpStepTree;
22
+ exports.commitsStep = commitsStep;
23
+ exports.sessionOperationWayOut = sessionOperationWayOut;
24
+ exports.formatElapsed = formatElapsed;
22
25
  const crypto_1 = require("crypto");
23
26
  const fs_1 = require("fs");
24
27
  const path_1 = require("path");
25
28
  const native_1 = require("../../../native");
26
29
  const fileutils_1 = require("../../../utils/fileutils");
27
30
  const json_1 = require("../../../utils/json");
31
+ const pretty_time_1 = require("../../../tasks-runner/life-cycles/pretty-time");
28
32
  const handoff_1 = require("../agentic/handoff");
29
33
  const deferred_output_1 = require("../deferred-output");
30
34
  const execute_migration_1 = require("../execute-migration");
31
35
  const migrate_commits_1 = require("../migrate-commits");
36
+ const agent_output_1 = require("./agent-output");
32
37
  const atomic_write_1 = require("./atomic-write");
33
38
  const give_up_1 = require("./give-up");
34
39
  const run_state_1 = require("./run-state");
@@ -40,6 +45,9 @@ const util_1 = require("./util");
40
45
  exports.BROKER_ENV_VAR = 'NX_MIGRATE_BROKER';
41
46
  const BROKER_DIR_NAME = 'broker';
42
47
  const CHILD_POLL_INTERVAL_MS = 250;
48
+ // The runbook's "Long-running commands" section states both intervals.
49
+ const FIRST_WAITING_LINE_MS = 15_000;
50
+ const WAITING_LINE_INTERVAL_MS = 60_000;
43
51
  /** The request no longer matches the step: another attempt owns it. */
44
52
  class BrokerStaleRequestError extends Error {
45
53
  }
@@ -74,7 +82,7 @@ function acquireTreeOperation(dir, request, owner = (0, crypto_1.randomBytes)(4)
74
82
  if (held)
75
83
  throw new TreeBusyError(treeBusyMessage(held));
76
84
  marks =
77
- (request.kind === 'commit' || request.kind === 'give-up') &&
85
+ commitsStep(request.kind) &&
78
86
  fresh.steps.find((s) => s.id === request.stepId)?.commitStarted !== true;
79
87
  return {
80
88
  ...(marks ? (0, state_machine_1.markCommitStarted)(fresh, request.stepId) : fresh),
@@ -113,22 +121,22 @@ function liveTreeOperation(state, owner) {
113
121
  return undefined;
114
122
  return held;
115
123
  }
116
- function treeBusyMessage(held) {
117
- return `The working tree is held by process ${held.pid} for ${treeOperationLabel(held)}; run the reconcile again once it finishes.`;
124
+ function treeBusyMessage(held, stepName) {
125
+ return `The working tree is held by process ${held.pid} for ${treeOperationLabel(held, stepName)}; run the reconcile again once it finishes.`;
118
126
  }
119
- function treeOperationLabel(held) {
127
+ function treeOperationLabel(held, stepName = `step '${held.stepId}'`) {
120
128
  switch (held.kind) {
121
129
  case 'checkpoint':
122
130
  return 'the checkpoint commit';
123
131
  case 'commit':
124
132
  case 'give-up':
125
- return `the commit of step '${held.stepId}'`;
133
+ return `the commit of ${stepName}`;
126
134
  case 'reset':
127
- return `the reset of step '${held.stepId}'`;
135
+ return `the reset of ${stepName}`;
128
136
  case 'install':
129
137
  case 'fold-install':
130
138
  case 'action-install':
131
- return `the install of step '${held.stepId}'`;
139
+ return `the install of ${stepName}`;
132
140
  default: {
133
141
  const exhaustive = held.kind;
134
142
  throw new Error(`Unhandled tree operation '${exhaustive}'.`);
@@ -204,7 +212,7 @@ async function commitStepTree(dir, step, absorbedStepIds, commitInProcess, scope
204
212
  lease.markedStepId = undefined;
205
213
  return { result, absorbedStepIds, recorded: false };
206
214
  }
207
- const answer = await ask(dir, nonce, request);
215
+ const answer = await ask(dir, nonce, request, (0, state_machine_1.stepLabel)(step));
208
216
  if (answer.kind !== 'commit') {
209
217
  throw new Error(`Unexpected '${answer.kind}' answer to a commit request.`);
210
218
  }
@@ -229,7 +237,7 @@ async function installStepTree(dir, step, seam, installInProcess, scope) {
229
237
  scope.lease = acquireTreeOperation(dir, request);
230
238
  return installInProcess();
231
239
  }
232
- const answer = await ask(dir, nonce, request);
240
+ const answer = await ask(dir, nonce, request, (0, state_machine_1.stepLabel)(step));
233
241
  if (answer.kind !== 'installed') {
234
242
  throw new Error(`Unexpected '${answer.kind}' answer to an install request.`);
235
243
  }
@@ -251,7 +259,7 @@ async function resetStepTree(dir, step, resetInProcess, scope) {
251
259
  scope.lease = acquireTreeOperation(dir, request);
252
260
  return resetInProcess();
253
261
  }
254
- const answer = await ask(dir, nonce, request);
262
+ const answer = await ask(dir, nonce, request, (0, state_machine_1.stepLabel)(step));
255
263
  if (answer.kind !== 'reset') {
256
264
  throw new Error(`Unexpected '${answer.kind}' answer to a reset request.`);
257
265
  }
@@ -280,13 +288,13 @@ async function giveUpStepTree(root, dir, step, skipInstall, reconcileCommand, sc
280
288
  reconcileCommand,
281
289
  });
282
290
  }
283
- const answer = await ask(dir, nonce, request);
291
+ const answer = await ask(dir, nonce, request, (0, state_machine_1.stepLabel)(step));
284
292
  if (answer.kind !== 'give-up') {
285
293
  throw new Error(`Unexpected '${answer.kind}' answer to a give-up request.`);
286
294
  }
287
295
  return answer.outcome;
288
296
  }
289
- async function ask(dir, nonce, request) {
297
+ async function ask(dir, nonce, request, stepName) {
290
298
  const id = `${nonce}-${request.stepId}-${request.attempt}-${request.kind}${request.invocation ? `-${request.invocation}` : ''}${request.commitAs !== undefined ? `-${request.commitAs}` : ''}`;
291
299
  const path = resultPath(dir, id);
292
300
  // A repeat reads the first answer, whatever became of the session since.
@@ -313,6 +321,8 @@ async function ask(dir, nonce, request) {
313
321
  catch (e) {
314
322
  throw notAccepting(e);
315
323
  }
324
+ const askedAt = Date.now();
325
+ let nextWaitingLineAt = askedAt + FIRST_WAITING_LINE_MS;
316
326
  for (;;) {
317
327
  if ((0, fs_1.existsSync)(path)) {
318
328
  return settle((0, fileutils_1.readJsonFile)(path));
@@ -323,9 +333,49 @@ async function ask(dir, nonce, request) {
323
333
  continue;
324
334
  throw new BrokerUnavailableError(`The nx migrate session that started this step ended before its request was answered. The install or the commit may still have landed; check the working tree and git log.`);
325
335
  }
336
+ if (Date.now() >= nextWaitingLineAt) {
337
+ nextWaitingLineAt = Date.now() + WAITING_LINE_INTERVAL_MS;
338
+ (0, agent_output_1.logLineToAgent)(waitingLine(request, stepName, Date.now() - askedAt));
339
+ }
326
340
  await new Promise((resolve) => setTimeout(resolve, CHILD_POLL_INTERVAL_MS));
327
341
  }
328
342
  }
343
+ function waitingLine(request, stepName, waitedMs) {
344
+ return [
345
+ `[nx] Waiting for the nx process that started this session to finish ${treeOperationLabel(request, stepName)} (${formatElapsed(waitedMs)} so far).`,
346
+ ...(commitsStep(request.kind)
347
+ ? [
348
+ exports.COMMIT_INSTALLS_FIRST,
349
+ 'A signing popup or a security key can also hold a commit until the user answers it.',
350
+ ]
351
+ : []),
352
+ `If it seems stuck, the user can ${sessionOperationWayOut('it')}.`,
353
+ ].join(' ');
354
+ }
355
+ exports.COMMIT_INSTALLS_FIRST = 'A commit first installs any dependency changes.';
356
+ function commitsStep(kind) {
357
+ switch (kind) {
358
+ case 'commit':
359
+ case 'give-up':
360
+ return true;
361
+ case 'checkpoint':
362
+ case 'install':
363
+ case 'fold-install':
364
+ case 'action-install':
365
+ case 'reset':
366
+ return false;
367
+ default: {
368
+ const exhaustive = kind;
369
+ throw new Error(`Unhandled tree operation '${exhaustive}'.`);
370
+ }
371
+ }
372
+ }
373
+ function sessionOperationWayOut(operation) {
374
+ return `quit this session, then press Ctrl+C in the terminal to end ${operation}, and resume the run afterwards`;
375
+ }
376
+ function formatElapsed(ms) {
377
+ return (0, pretty_time_1.prettyTime)(Math.max(0, Math.round(ms)) * 1e6, 's');
378
+ }
329
379
  function notAccepting(e) {
330
380
  return new BrokerUnavailableError(`The nx migrate session that started this step is not accepting its request (${e instanceof Error ? e.message : String(e)}).`);
331
381
  }
@@ -387,7 +437,7 @@ class MigrateCommitBroker {
387
437
  this.lock = native_1.IS_WASM ? null : new native_1.FileLock(lockPath(dir, this.nonce));
388
438
  this.lock?.lock();
389
439
  }
390
- /** The request whose operation this process is running right now. */
440
+ /** The request whose operation this process is running right now, and since when. */
391
441
  get requestInFlight() {
392
442
  return this.inFlight;
393
443
  }
@@ -423,8 +473,6 @@ class MigrateCommitBroker {
423
473
  this.handled.add(id);
424
474
  let result;
425
475
  try {
426
- if (lease)
427
- this.inFlight = request;
428
476
  result = lease ? await this.answer(request, lease) : { kind: 'stale' };
429
477
  // Recorded by the process that ran the commit, before the answer: the
430
478
  // step reading it can die with the commit already in history. A failed
@@ -466,13 +514,13 @@ class MigrateCommitBroker {
466
514
  const step = state.steps.find((s) => s.id === request.stepId);
467
515
  if (!Object.hasOwn(SEAM_STATUSES, request.kind) ||
468
516
  !isAtSeam(step, request) ||
469
- ((request.kind === 'commit' ||
470
- request.kind === 'reset' ||
471
- request.kind === 'give-up') &&
517
+ ((commitsStep(request.kind) || request.kind === 'reset') &&
472
518
  !this.policy.createCommits) ||
473
519
  (request.commitAs !== undefined && request.commitAs !== 'adopt')) {
474
520
  return { kind: 'stale' };
475
521
  }
522
+ const stepName = (0, state_machine_1.stepLabel)(step);
523
+ this.inFlight = { request, startedAt: Date.now(), stepName };
476
524
  if (request.kind === 'give-up') {
477
525
  const output = new deferred_output_1.DeferredOutputCollector();
478
526
  const outcome = await (0, give_up_1.giveUpWithCommit)({
@@ -540,7 +588,7 @@ class MigrateCommitBroker {
540
588
  };
541
589
  }
542
590
  }
543
- /** Releases the lock; call after the last `service` settled. */
591
+ /** Releases the lock; call after the last `service` settled, or once giving up on it. */
544
592
  close() {
545
593
  this.lock?.unlock();
546
594
  // A reservation this session still holds would only expire with its pid.
@@ -41,7 +41,7 @@ export interface ExistingRunCommands {
41
41
  migrationsPath: string;
42
42
  };
43
43
  }
44
- export declare function renderExistingRunCommands(root: string, facts: ExistingRunFacts, migrationsPath: string | undefined, agentId?: string): ExistingRunCommands;
44
+ export declare function renderExistingRunCommands(root: string, facts: ExistingRunFacts, migrationsPath: string | undefined, agentic?: string | false): ExistingRunCommands;
45
45
  /**
46
46
  * Title plus body lines, in the shape the agent-output writers take. Every
47
47
  * body line goes through `singleLine`: branch names and timestamps came from
@@ -108,16 +108,18 @@ function otherActiveRuns(root, runId) {
108
108
  function renderContinueCommand(root, runId, policy, agentId) {
109
109
  return `${(0, util_1.pmExecPrefix)(root)} nx migrate --run-migrations --agentic${agentId === undefined ? '' : `=${agentId}`} --run-id=${runId} ${policy.createCommits ? '--create-commits' : '--no-create-commits'}${policy.skipInstall ? ' --skip-install' : ''}`;
110
110
  }
111
- function renderExistingRunCommands(root, facts, migrationsPath, agentId) {
111
+ // `agentic` echoes the invocation's choice into the start-fresh command; the
112
+ // continue command needs an agent, so it takes only an agent id.
113
+ function renderExistingRunCommands(root, facts, migrationsPath, agentic) {
112
114
  const flag = migrationsPath === undefined
113
115
  ? '--run-migrations'
114
116
  : (0, util_1.runMigrationsFlag)(migrationsPath);
115
117
  return {
116
- continueCommand: renderContinueCommand(root, facts.runId, facts.policy, agentId),
118
+ continueCommand: renderContinueCommand(root, facts.runId, facts.policy, agentic === false ? undefined : agentic),
117
119
  startFresh: flag === null
118
120
  ? { migrationsPath }
119
121
  : {
120
- command: `${(0, util_1.pmExecPrefix)(root)} nx migrate ${flag}${agentId === undefined ? '' : ` --agentic=${agentId}`} --start-fresh --run-id=${facts.runId}`,
122
+ command: `${(0, util_1.pmExecPrefix)(root)} nx migrate ${flag}${agentic === undefined ? '' : ` --agentic=${agentic}`} --start-fresh --run-id=${facts.runId}`,
121
123
  },
122
124
  };
123
125
  }
@@ -153,12 +155,12 @@ function renderExistingRunReport(facts, commands) {
153
155
  lines.push(` other active runs on disk: ${facts.otherActiveRuns.join(', ')}`);
154
156
  }
155
157
  if (facts.appliedStillPlanned !== undefined) {
156
- lines.push(` plan overlap: ${facts.appliedStillPlanned} of the applied migrations ${facts.appliedStillPlanned === 1 ? 'is' : 'are'} still in the plan; a new run applies ${facts.appliedStillPlanned === 1 ? 'it' : 'them'} again`);
158
+ lines.push(` plan overlap: ${facts.appliedStillPlanned} of the applied migrations ${facts.appliedStillPlanned === 1 ? 'is' : 'are'} still in the plan; running the plan applies ${facts.appliedStillPlanned === 1 ? 'it' : 'them'} again`);
157
159
  }
158
160
  if (commands) {
159
161
  lines.push(``, `To continue the run: ${commands.continueCommand}`, `To start fresh (deletes the run record, then runs the whole plan again): ${'command' in commands.startFresh
160
162
  ? commands.startFresh.command
161
- : `re-run this command with --start-fresh --run-id=${facts.runId}, keeping the --run-migrations argument, which names ${displayPath(commands.startFresh.migrationsPath)}; that path cannot be rendered as a command for this shell`}`, `Run either command with NX_MIGRATE_ORCHESTRATOR=true set in the environment.`);
163
+ : `re-run this command with --start-fresh --run-id=${facts.runId}, keeping the --run-migrations argument, which names ${displayPath(commands.startFresh.migrationsPath)}; that path cannot be rendered as a command for this shell`}`);
162
164
  }
163
165
  return {
164
166
  title: `A migrate run is already active: ${facts.runId}`,
@@ -1,12 +1,13 @@
1
- export { CURRENT_RUN_STATE_FORMAT_VERSION, NewerRunStateFormatError, migrateRunsDir, runDir, runHandoffsDir, readRunState, writeRunState, findActiveRun, createRun, } from './run-state';
2
- export type { MigrateRunStatus, MigrateRunRound, MigrateStepStatus, PromptOutcomeStatus, MigrateStepAwaitingKind, MigrateStepOutcome, MigrateStepPromptOutcome, MigrateStep, MigrateCommitKind, MigrateCommitLedgerEntry, MigrateIssueDisposition, MigrateRunIssue, MigrateRunAnalytics, MigrateRunNoProgress, MigrateRunPolicy, MigrateRunState, } from './run-state';
3
- export { applyStepEvent, completionSummaryLines, hasPendingCommitDebt, latestRound, runTallies, tallySteps, } from './state-machine';
1
+ export { CURRENT_RUN_STATE_FORMAT_VERSION, NewerRunStateFormatError, migrateRunsDir, runDir, runHandoffsDir, readRunState, writeRunState, findActiveRun, createRun, TERMINAL_STEP_STATUSES, migrationIdProblems, } from './run-state';
2
+ export type { MigrateRunStatus, MigrateRunRound, MigrateStepStatus, PromptOutcomeStatus, MigrateStepAwaitingKind, MigrateStepOutcome, MigrateStepPromptOutcome, MigrateStep, MigrateCommitKind, MigrateCommitLedgerEntry, MigrateIssueDisposition, MigrateRunIssue, MigrateRunAnalytics, MigrateRunNoProgress, MigrateRunPolicy, MigrateRunState, MigrationIdProblem, } from './run-state';
3
+ export { applyStepEvent, completionSummaryLines, hasPendingCommitDebt, latestRound, runTallies, stepLabel, tallySteps, } from './state-machine';
4
4
  export { hasUnresolvedIssues } from './issues';
5
5
  export type { StepAction, StepEvent, ApplyStepEventResult, } from './state-machine';
6
6
  export { createRunId } from './run-id';
7
+ export { pmInstallCommand } from './util';
7
8
  export { runSingleMigrationWorker } from './worker';
8
9
  export type { RunSingleMigrationWorkerInput } from './worker';
9
- export { activeRunToReplace, completionWarnings, holdRunToContinue, releaseRunToHandOff, runOrchestratorInit, runOrchestratorReconcile, runOrchestratorResume, } from './orchestrator';
10
+ export { activeRunForClassic, activeRunToReplace, checkRunForStartFresh, completionWarnings, deleteRunForStartFresh, holdRunToContinue, releaseRunToHandOff, runOrchestratorInit, runOrchestratorReconcile, runOrchestratorResume, } from './orchestrator';
10
11
  export type { OrchestratorInitResult, RunOrchestratorInitInput, RunOrchestratorReconcileInput, } from './orchestrator';
11
12
  export { renderContinueCommand, renderExistingRunCommands, renderExistingRunReport, } from './existing-run-report';
12
- export { BROKER_ENV_VAR, MigrateCommitBroker, treeOperationLabel, } from './broker';
13
+ export { BROKER_ENV_VAR, COMMIT_INSTALLS_FIRST, formatElapsed, MigrateCommitBroker, commitsStep, treeOperationLabel, } from './broker';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.treeOperationLabel = exports.MigrateCommitBroker = exports.BROKER_ENV_VAR = exports.renderExistingRunReport = exports.renderExistingRunCommands = exports.renderContinueCommand = exports.runOrchestratorResume = exports.runOrchestratorReconcile = exports.runOrchestratorInit = exports.releaseRunToHandOff = exports.holdRunToContinue = exports.completionWarnings = exports.activeRunToReplace = exports.runSingleMigrationWorker = exports.createRunId = exports.hasUnresolvedIssues = exports.tallySteps = exports.runTallies = exports.latestRound = exports.hasPendingCommitDebt = exports.completionSummaryLines = exports.applyStepEvent = exports.createRun = exports.findActiveRun = exports.writeRunState = exports.readRunState = exports.runHandoffsDir = exports.runDir = exports.migrateRunsDir = exports.NewerRunStateFormatError = exports.CURRENT_RUN_STATE_FORMAT_VERSION = void 0;
3
+ exports.treeOperationLabel = exports.commitsStep = exports.MigrateCommitBroker = exports.formatElapsed = exports.COMMIT_INSTALLS_FIRST = exports.BROKER_ENV_VAR = exports.renderExistingRunReport = exports.renderExistingRunCommands = exports.renderContinueCommand = exports.runOrchestratorResume = exports.runOrchestratorReconcile = exports.runOrchestratorInit = exports.releaseRunToHandOff = exports.holdRunToContinue = exports.deleteRunForStartFresh = exports.completionWarnings = exports.checkRunForStartFresh = exports.activeRunToReplace = exports.activeRunForClassic = exports.runSingleMigrationWorker = exports.pmInstallCommand = exports.createRunId = exports.hasUnresolvedIssues = exports.tallySteps = exports.stepLabel = exports.runTallies = exports.latestRound = exports.hasPendingCommitDebt = exports.completionSummaryLines = exports.applyStepEvent = exports.migrationIdProblems = exports.TERMINAL_STEP_STATUSES = exports.createRun = exports.findActiveRun = exports.writeRunState = exports.readRunState = exports.runHandoffsDir = exports.runDir = exports.migrateRunsDir = exports.NewerRunStateFormatError = exports.CURRENT_RUN_STATE_FORMAT_VERSION = void 0;
4
4
  var run_state_1 = require("./run-state");
5
5
  Object.defineProperty(exports, "CURRENT_RUN_STATE_FORMAT_VERSION", { enumerable: true, get: function () { return run_state_1.CURRENT_RUN_STATE_FORMAT_VERSION; } });
6
6
  Object.defineProperty(exports, "NewerRunStateFormatError", { enumerable: true, get: function () { return run_state_1.NewerRunStateFormatError; } });
@@ -11,22 +11,30 @@ Object.defineProperty(exports, "readRunState", { enumerable: true, get: function
11
11
  Object.defineProperty(exports, "writeRunState", { enumerable: true, get: function () { return run_state_1.writeRunState; } });
12
12
  Object.defineProperty(exports, "findActiveRun", { enumerable: true, get: function () { return run_state_1.findActiveRun; } });
13
13
  Object.defineProperty(exports, "createRun", { enumerable: true, get: function () { return run_state_1.createRun; } });
14
+ Object.defineProperty(exports, "TERMINAL_STEP_STATUSES", { enumerable: true, get: function () { return run_state_1.TERMINAL_STEP_STATUSES; } });
15
+ Object.defineProperty(exports, "migrationIdProblems", { enumerable: true, get: function () { return run_state_1.migrationIdProblems; } });
14
16
  var state_machine_1 = require("./state-machine");
15
17
  Object.defineProperty(exports, "applyStepEvent", { enumerable: true, get: function () { return state_machine_1.applyStepEvent; } });
16
18
  Object.defineProperty(exports, "completionSummaryLines", { enumerable: true, get: function () { return state_machine_1.completionSummaryLines; } });
17
19
  Object.defineProperty(exports, "hasPendingCommitDebt", { enumerable: true, get: function () { return state_machine_1.hasPendingCommitDebt; } });
18
20
  Object.defineProperty(exports, "latestRound", { enumerable: true, get: function () { return state_machine_1.latestRound; } });
19
21
  Object.defineProperty(exports, "runTallies", { enumerable: true, get: function () { return state_machine_1.runTallies; } });
22
+ Object.defineProperty(exports, "stepLabel", { enumerable: true, get: function () { return state_machine_1.stepLabel; } });
20
23
  Object.defineProperty(exports, "tallySteps", { enumerable: true, get: function () { return state_machine_1.tallySteps; } });
21
24
  var issues_1 = require("./issues");
22
25
  Object.defineProperty(exports, "hasUnresolvedIssues", { enumerable: true, get: function () { return issues_1.hasUnresolvedIssues; } });
23
26
  var run_id_1 = require("./run-id");
24
27
  Object.defineProperty(exports, "createRunId", { enumerable: true, get: function () { return run_id_1.createRunId; } });
28
+ var util_1 = require("./util");
29
+ Object.defineProperty(exports, "pmInstallCommand", { enumerable: true, get: function () { return util_1.pmInstallCommand; } });
25
30
  var worker_1 = require("./worker");
26
31
  Object.defineProperty(exports, "runSingleMigrationWorker", { enumerable: true, get: function () { return worker_1.runSingleMigrationWorker; } });
27
32
  var orchestrator_1 = require("./orchestrator");
33
+ Object.defineProperty(exports, "activeRunForClassic", { enumerable: true, get: function () { return orchestrator_1.activeRunForClassic; } });
28
34
  Object.defineProperty(exports, "activeRunToReplace", { enumerable: true, get: function () { return orchestrator_1.activeRunToReplace; } });
35
+ Object.defineProperty(exports, "checkRunForStartFresh", { enumerable: true, get: function () { return orchestrator_1.checkRunForStartFresh; } });
29
36
  Object.defineProperty(exports, "completionWarnings", { enumerable: true, get: function () { return orchestrator_1.completionWarnings; } });
37
+ Object.defineProperty(exports, "deleteRunForStartFresh", { enumerable: true, get: function () { return orchestrator_1.deleteRunForStartFresh; } });
30
38
  Object.defineProperty(exports, "holdRunToContinue", { enumerable: true, get: function () { return orchestrator_1.holdRunToContinue; } });
31
39
  Object.defineProperty(exports, "releaseRunToHandOff", { enumerable: true, get: function () { return orchestrator_1.releaseRunToHandOff; } });
32
40
  Object.defineProperty(exports, "runOrchestratorInit", { enumerable: true, get: function () { return orchestrator_1.runOrchestratorInit; } });
@@ -38,5 +46,8 @@ Object.defineProperty(exports, "renderExistingRunCommands", { enumerable: true,
38
46
  Object.defineProperty(exports, "renderExistingRunReport", { enumerable: true, get: function () { return existing_run_report_1.renderExistingRunReport; } });
39
47
  var broker_1 = require("./broker");
40
48
  Object.defineProperty(exports, "BROKER_ENV_VAR", { enumerable: true, get: function () { return broker_1.BROKER_ENV_VAR; } });
49
+ Object.defineProperty(exports, "COMMIT_INSTALLS_FIRST", { enumerable: true, get: function () { return broker_1.COMMIT_INSTALLS_FIRST; } });
50
+ Object.defineProperty(exports, "formatElapsed", { enumerable: true, get: function () { return broker_1.formatElapsed; } });
41
51
  Object.defineProperty(exports, "MigrateCommitBroker", { enumerable: true, get: function () { return broker_1.MigrateCommitBroker; } });
52
+ Object.defineProperty(exports, "commitsStep", { enumerable: true, get: function () { return broker_1.commitsStep; } });
42
53
  Object.defineProperty(exports, "treeOperationLabel", { enumerable: true, get: function () { return broker_1.treeOperationLabel; } });
@@ -69,6 +69,27 @@ export declare function activeRunToReplace(root: string, runId: string | undefin
69
69
  * exclusive one refuses while this process still holds.
70
70
  */
71
71
  export declare function releaseRunToHandOff(root: string, runId: string): void;
72
+ /**
73
+ * The active run a classic `--run-migrations` must not run over, held while
74
+ * the caller reports it or asks what to do; null when no run is active. Run
75
+ * directories that cannot be read refuse as they do for init.
76
+ */
77
+ export declare function activeRunForClassic(root: string, plannedIds: readonly string[]): {
78
+ runId: string;
79
+ facts: ExistingRunFacts;
80
+ } | null;
81
+ /**
82
+ * Throws when a classic start fresh could not delete the active run `runId`.
83
+ * Run before the commit prompt, as init does, so the user is not asked for a
84
+ * run that is then refused; deleteRunForStartFresh repeats the checks.
85
+ */
86
+ export declare function checkRunForStartFresh(root: string, runId: string): void;
87
+ /**
88
+ * Deletes the record of the active run `runId` for a classic start fresh,
89
+ * under the refusals init applies before it replaces a run. The classic loop
90
+ * records no run of its own afterwards.
91
+ */
92
+ export declare function deleteRunForStartFresh(root: string, runId: string): void;
72
93
  export declare function runOrchestratorReconcile(input: RunOrchestratorReconcileInput): Promise<void>;
73
94
  /**
74
95
  * What a completed run leaves behind for whoever reads its summary, one line