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.
- package/dist/nx-cloud-internals.d.ts +1 -0
- package/dist/nx-cloud-internals.js +7 -1
- package/dist/src/command-line/graph/graph.js +2 -1
- package/dist/src/command-line/migrate/agentic/close-agent-session.d.ts +1 -1
- package/dist/src/command-line/migrate/agentic/close-agent-session.js +4 -3
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +19 -23
- package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +16 -19
- package/dist/src/command-line/migrate/agentic/master/run-master-session.js +25 -13
- package/dist/src/command-line/migrate/agentic/master/spawn-master.js +82 -22
- package/dist/src/command-line/migrate/agentic/select.js +3 -3
- package/dist/src/command-line/migrate/agentic/types.js +1 -3
- package/dist/src/command-line/migrate/command-object.js +5 -9
- package/dist/src/command-line/migrate/execute-migration.d.ts +2 -2
- package/dist/src/command-line/migrate/execute-migration.js +18 -10
- package/dist/src/command-line/migrate/migrate-analytics.d.ts +6 -0
- package/dist/src/command-line/migrate/migrate-analytics.js +12 -0
- package/dist/src/command-line/migrate/migrate-commits.d.ts +4 -1
- package/dist/src/command-line/migrate/migrate-commits.js +10 -3
- package/dist/src/command-line/migrate/migrate-config.d.ts +6 -6
- package/dist/src/command-line/migrate/migrate-config.js +12 -6
- package/dist/src/command-line/migrate/migrate.d.ts +3 -30
- package/dist/src/command-line/migrate/migrate.js +206 -237
- package/dist/src/command-line/migrate/run/agent-output.d.ts +1 -0
- package/dist/src/command-line/migrate/run/agent-output.js +5 -0
- package/dist/src/command-line/migrate/run/broker.d.ts +14 -5
- package/dist/src/command-line/migrate/run/broker.js +68 -20
- package/dist/src/command-line/migrate/run/existing-run-report.d.ts +1 -1
- package/dist/src/command-line/migrate/run/existing-run-report.js +7 -5
- package/dist/src/command-line/migrate/run/index.d.ts +6 -5
- package/dist/src/command-line/migrate/run/index.js +12 -1
- package/dist/src/command-line/migrate/run/orchestrator.d.ts +21 -0
- package/dist/src/command-line/migrate/run/orchestrator.js +149 -32
- package/dist/src/command-line/migrate/run/run-state.d.ts +13 -0
- package/dist/src/command-line/migrate/run/run-state.js +21 -0
- package/dist/src/command-line/migrate/run/runbook.js +19 -0
- package/dist/src/command-line/migrate/run/state-machine.js +4 -1
- package/dist/src/command-line/migrate/run/util.d.ts +3 -0
- package/dist/src/command-line/migrate/run/util.js +7 -1
- package/dist/src/command-line/migrate/sort-migrations.d.ts +1 -7
- package/dist/src/command-line/migrate/sort-migrations.js +1 -12
- package/dist/src/command-line/show/show-target/info.js +1 -1
- package/dist/src/config/nx-json.d.ts +13 -4
- package/dist/src/config/task-graph.d.ts +1 -1
- package/dist/src/config/workspace-json-project-json.d.ts +72 -0
- package/dist/src/core/graph/main.js +1 -1
- package/dist/src/devkit-exports.d.ts +1 -1
- package/dist/src/hasher/check-task-files.js +4 -4
- package/dist/src/hasher/native-task-hasher-impl.js +3 -1
- package/dist/src/hasher/task-hasher.d.ts +2 -0
- package/dist/src/hasher/task-hasher.js +4 -1
- package/dist/src/native/index.d.ts +92 -14
- package/dist/src/native/native-bindings.js +3 -0
- package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
- package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
- package/dist/src/project-graph/utils/project-configuration/target-normalization.js +6 -1
- package/dist/src/project-graph/utils/retrieve-workspace-files.js +27 -6
- package/dist/src/tasks-runner/create-task-graph.d.ts +7 -16
- package/dist/src/tasks-runner/create-task-graph.js +43 -57
- package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
- package/dist/src/tasks-runner/init-tasks-runner.js +13 -0
- package/dist/src/tasks-runner/life-cycle.d.ts +4 -1
- package/dist/src/tasks-runner/life-cycle.js +7 -0
- package/dist/src/tasks-runner/life-cycles/performance-analysis.d.ts +5 -2
- package/dist/src/tasks-runner/life-cycles/performance-analysis.js +13 -7
- package/dist/src/tasks-runner/life-cycles/performance-life-cycle.d.ts +4 -3
- package/dist/src/tasks-runner/life-cycles/performance-life-cycle.js +9 -2
- package/dist/src/tasks-runner/readiness/probes.d.ts +9 -0
- package/dist/src/tasks-runner/readiness/probes.js +62 -0
- package/dist/src/tasks-runner/readiness/ready-when.d.ts +38 -0
- package/dist/src/tasks-runner/readiness/ready-when.js +190 -0
- package/dist/src/tasks-runner/run-command.js +7 -6
- package/dist/src/tasks-runner/running-tasks/batch-process.js +6 -0
- package/dist/src/tasks-runner/running-tasks/node-child-process.js +5 -4
- package/dist/src/tasks-runner/task-graph-utils.d.ts +9 -6
- package/dist/src/tasks-runner/task-graph-utils.js +17 -12
- package/dist/src/tasks-runner/task-orchestrator.d.ts +37 -10
- package/dist/src/tasks-runner/task-orchestrator.js +459 -79
- package/dist/src/tasks-runner/tasks-runner.d.ts +1 -1
- package/dist/src/tasks-runner/tasks-schedule.d.ts +18 -1
- package/dist/src/tasks-runner/tasks-schedule.js +64 -6
- package/dist/src/tasks-runner/utils.js +6 -22
- package/dist/src/utils/child-process.js +1 -0
- package/dist/src/utils/git-utils.d.ts +6 -1
- package/dist/src/utils/git-utils.js +26 -5
- package/dist/src/utils/plugins/core-plugins.js +4 -0
- package/dist/src/utils/spawn-without-terminal.d.ts +27 -0
- package/dist/src/utils/spawn-without-terminal.js +110 -0
- package/package.json +12 -11
- package/schemas/nx-schema.json +93 -4
- package/schemas/project-schema.json +84 -2
|
@@ -13,7 +13,6 @@ exports.isRunPhaseInvocation = isRunPhaseInvocation;
|
|
|
13
13
|
exports.migrate = migrate;
|
|
14
14
|
exports.readLocalNxVersion = readLocalNxVersion;
|
|
15
15
|
exports.runMigration = runMigration;
|
|
16
|
-
exports.resolveMigrationForRun = resolveMigrationForRun;
|
|
17
16
|
exports.nxCliPath = nxCliPath;
|
|
18
17
|
const tslib_1 = require("tslib");
|
|
19
18
|
const pc = tslib_1.__importStar(require("picocolors"));
|
|
@@ -37,6 +36,7 @@ const package_manager_1 = require("../../utils/package-manager");
|
|
|
37
36
|
const errors_1 = require("../../utils/min-release-age/errors");
|
|
38
37
|
const resolve_package_version_1 = require("./resolve-package-version");
|
|
39
38
|
const handle_errors_1 = require("../../utils/handle-errors");
|
|
39
|
+
const exit_codes_1 = require("../../utils/exit-codes");
|
|
40
40
|
const connect_to_nx_cloud_1 = require("../nx-cloud/connect/connect-to-nx-cloud");
|
|
41
41
|
const output_1 = require("../../utils/output");
|
|
42
42
|
const fs_1 = require("fs");
|
|
@@ -56,6 +56,7 @@ const multi_major_1 = require("./multi-major");
|
|
|
56
56
|
const prompt_files_1 = require("./prompt-files");
|
|
57
57
|
const command_object_1 = require("./command-object");
|
|
58
58
|
const migrate_config_1 = require("./migrate-config");
|
|
59
|
+
const types_1 = require("./agentic/types");
|
|
59
60
|
const migrate_commits_1 = require("./migrate-commits");
|
|
60
61
|
const migrate_output_1 = require("./migrate-output");
|
|
61
62
|
const migration_shape_1 = require("./migration-shape");
|
|
@@ -68,6 +69,7 @@ Object.defineProperty(exports, "normalizeVersion", { enumerable: true, get: func
|
|
|
68
69
|
const execute_migration_1 = require("./execute-migration");
|
|
69
70
|
const step_actions_1 = require("./step-actions");
|
|
70
71
|
const sort_migrations_1 = require("./sort-migrations");
|
|
72
|
+
const text_1 = require("./text");
|
|
71
73
|
const inception_1 = require("./agentic/inception");
|
|
72
74
|
const version_skew_guard_1 = require("./version-skew-guard");
|
|
73
75
|
const versions_1 = require("../../utils/versions");
|
|
@@ -88,20 +90,27 @@ function formatCommandFailure(command, error) {
|
|
|
88
90
|
.trim();
|
|
89
91
|
return [`Command failed: ${command}`, ...(details ? [details] : [])].join('\n');
|
|
90
92
|
}
|
|
93
|
+
// Ctrl+C is left to the child. Killed by it, this process would hand the
|
|
94
|
+
// terminal back to the shell while the child still runs.
|
|
91
95
|
function runOrReturnExitCode(run) {
|
|
96
|
+
const leaveSigintToChild = () => { };
|
|
97
|
+
process.on('SIGINT', leaveSigintToChild);
|
|
92
98
|
try {
|
|
93
99
|
run();
|
|
94
100
|
return 0;
|
|
95
101
|
}
|
|
96
102
|
catch (e) {
|
|
97
|
-
if (typeof e
|
|
98
|
-
e
|
|
99
|
-
|
|
100
|
-
|
|
103
|
+
if (typeof e !== 'object' || e === null)
|
|
104
|
+
throw e;
|
|
105
|
+
if ('signal' in e && e.signal === 'SIGINT')
|
|
106
|
+
(0, exit_codes_1.exitAsInterrupted)();
|
|
107
|
+
if ('status' in e && typeof e.status === 'number')
|
|
101
108
|
return e.status;
|
|
102
|
-
}
|
|
103
109
|
throw e;
|
|
104
110
|
}
|
|
111
|
+
finally {
|
|
112
|
+
process.removeListener('SIGINT', leaveSigintToChild);
|
|
113
|
+
}
|
|
105
114
|
}
|
|
106
115
|
function cleanSemver(version) {
|
|
107
116
|
return (0, semver_1.clean)(version) ?? (0, semver_1.coerce)(version);
|
|
@@ -777,9 +786,7 @@ async function parseMigrationsOptions(options, fetch) {
|
|
|
777
786
|
options.stepAction !== undefined) {
|
|
778
787
|
throw new Error(`Error: '--step-action' cannot be combined with '--run-migrations'.`);
|
|
779
788
|
}
|
|
780
|
-
// A bare '--run-id' reconciles the run it names.
|
|
781
|
-
// the id has to name a run directory that exists, and only a gated init
|
|
782
|
-
// ever creates one.
|
|
789
|
+
// A bare '--run-id' reconciles the run it names.
|
|
783
790
|
// yargs' choices already reject bad CLI values; this guards programmatic
|
|
784
791
|
// callers, where silently dropping the action would reconcile without it.
|
|
785
792
|
if (options.stepAction !== undefined && !(0, step_actions_1.isStepAction)(options.stepAction)) {
|
|
@@ -1752,23 +1759,12 @@ function formatSkippedPromptsNextStep(skipped) {
|
|
|
1752
1759
|
...skipped.map((m) => ` - ${m.prompt}`),
|
|
1753
1760
|
].join('\n');
|
|
1754
1761
|
}
|
|
1755
|
-
async function executeMigrations(root, migrations, isVerbose, shouldCreateCommits, commitPrefix, shouldSkipInstall = false,
|
|
1762
|
+
async function executeMigrations(root, migrations, isVerbose, shouldCreateCommits, commitPrefix, shouldSkipInstall = false,
|
|
1763
|
+
// An enabled agent drives the whole run from one session instead.
|
|
1764
|
+
agentic) {
|
|
1756
1765
|
const changedDepInstaller = new execute_migration_1.ChangedDepInstaller(root, shouldSkipInstall);
|
|
1757
1766
|
const migrationsWithNoChanges = [];
|
|
1758
|
-
const sortedMigrations = (0, sort_migrations_1.sortMigrations)(migrations
|
|
1759
|
-
hoistHandoffGitignore: agentic?.kind === 'enabled',
|
|
1760
|
-
});
|
|
1761
|
-
// Lazy-load the agentic chain so non-agentic runs don't pay its startup cost.
|
|
1762
|
-
let agenticRun;
|
|
1763
|
-
if (agentic?.kind === 'enabled' && sortedMigrations.length > 0) {
|
|
1764
|
-
const { initRunDir, resolveAgenticRunId } = require('./agentic/handoff');
|
|
1765
|
-
const { runAgenticPromptStep } = require('./agentic/run-step');
|
|
1766
|
-
agenticRun = {
|
|
1767
|
-
agentic,
|
|
1768
|
-
runDir: initRunDir(root, resolveAgenticRunId(sortedMigrations)),
|
|
1769
|
-
runStep: runAgenticPromptStep,
|
|
1770
|
-
};
|
|
1771
|
-
}
|
|
1767
|
+
const sortedMigrations = (0, sort_migrations_1.sortMigrations)(migrations);
|
|
1772
1768
|
const printDroppedAgentContext = agentic?.kind === 'inside-agent'
|
|
1773
1769
|
? require('./agentic/print-dropped-agent-context').printDroppedAgentContextForOuterAgent
|
|
1774
1770
|
: undefined;
|
|
@@ -1803,12 +1799,6 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
1803
1799
|
const pendingForCommitBody = () => outcomes
|
|
1804
1800
|
.filter((o) => o.commit.kind === 'failed')
|
|
1805
1801
|
.map((o) => ({ package: o.migration.package, name: o.migration.name }));
|
|
1806
|
-
// True while at least one prior migration's commit has failed and its
|
|
1807
|
-
// diff hasn't been absorbed yet. While true, the working tree carries
|
|
1808
|
-
// prior-migration state, so the `hasDiffContext` flag in the hybrid-
|
|
1809
|
-
// agentic and validation-agentic prompt branches is suppressed (the
|
|
1810
|
-
// prompt-only-with-agentic branch doesn't use `hasDiffContext`).
|
|
1811
|
-
const hasPendingCommitDebt = () => outcomes.some((o) => o.commit.kind === 'failed');
|
|
1812
1802
|
// Single funnel for per-migration commit attempts. Returns the
|
|
1813
1803
|
// `CommitState` to record on the migration's outcome. On `committed`,
|
|
1814
1804
|
// back-annotates any prior failed-commit outcomes to `kind: 'absorbed'`
|
|
@@ -1841,8 +1831,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
1841
1831
|
return { kind: 'landed', sha: result.sha };
|
|
1842
1832
|
}
|
|
1843
1833
|
if (result.status === 'failed') {
|
|
1844
|
-
//
|
|
1845
|
-
// until a later commit absorbs the backlog.
|
|
1834
|
+
// The diff stays in the working tree until a later commit absorbs it.
|
|
1846
1835
|
return { kind: 'failed' };
|
|
1847
1836
|
}
|
|
1848
1837
|
// `no-changes` and `disabled` — no commit attempted, nothing to record
|
|
@@ -1875,89 +1864,36 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
1875
1864
|
// Content-sensitive so a dirty→dirty case (this migration mutating an
|
|
1876
1865
|
// already-dirty shared file like `package.json`) doesn't collapse.
|
|
1877
1866
|
const baselineWorkingTreeSnapshot = (0, git_utils_1.getUncommittedChangesSnapshot)(root);
|
|
1878
|
-
// Tracks whether a failure originated in the agentic step so the error
|
|
1879
|
-
// event classifies it as 'agentic' rather than 'migration_exec'.
|
|
1880
|
-
let inAgenticStep = false;
|
|
1881
1867
|
try {
|
|
1882
|
-
// Read
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
const { resolvedCollection, documentationPath } = resolveMigrationForRun(root, m, !!agenticRun);
|
|
1868
|
+
// Read fresh per migration so a prior migration's reinstall is reflected.
|
|
1869
|
+
const resolvedCollection = (0, migration_shape_1.isPromptOnlyMigration)(m)
|
|
1870
|
+
? undefined
|
|
1871
|
+
: (0, execute_migration_1.readMigrationCollection)(m.package, root);
|
|
1887
1872
|
let outcome;
|
|
1888
1873
|
let commit = { kind: 'none' };
|
|
1889
|
-
// Set when
|
|
1890
|
-
//
|
|
1891
|
-
// prompt is owed in every agentic mode, so waiving it always counts; a
|
|
1892
|
-
// generator-only migration only counts when validation would have run.
|
|
1874
|
+
// Set when a hybrid returned `skipAgentic: true`, so the end-of-run
|
|
1875
|
+
// recaps can report the waived prompt.
|
|
1893
1876
|
let waivedAgenticStep = false;
|
|
1894
1877
|
if ((0, migration_shape_1.isPromptOnlyMigration)(m)) {
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
migration: m,
|
|
1900
|
-
agentic: agenticRun.agentic,
|
|
1901
|
-
runDir: agenticRun.runDir,
|
|
1902
|
-
installDepsIfChanged,
|
|
1903
|
-
documentationPath,
|
|
1904
|
-
});
|
|
1905
|
-
inAgenticStep = false;
|
|
1906
|
-
commit = await attemptMigrationCommit(m);
|
|
1907
|
-
(0, migrate_output_1.logAgenticSuccessOutcome)(stepResult.ambiguous ? 'Marked complete by user' : 'Applied', commit.kind === 'landed' ? commit.sha : null, stepResult.summary);
|
|
1908
|
-
outcome = 'applied';
|
|
1909
|
-
}
|
|
1910
|
-
else {
|
|
1911
|
-
logger_1.logger.info(pc.dim(`↷ Skipped — ${skipReason}. Listed in next steps.`));
|
|
1912
|
-
skippedPrompts.push(m);
|
|
1913
|
-
notRunMigrationsCount++;
|
|
1914
|
-
outcome = 'deferred';
|
|
1915
|
-
}
|
|
1878
|
+
logger_1.logger.info(pc.dim(`↷ Skipped — ${skipReason}. Listed in next steps.`));
|
|
1879
|
+
skippedPrompts.push(m);
|
|
1880
|
+
notRunMigrationsCount++;
|
|
1881
|
+
outcome = 'deferred';
|
|
1916
1882
|
}
|
|
1917
1883
|
else if ((0, migration_shape_1.isHybridMigration)(m)) {
|
|
1918
|
-
const {
|
|
1919
|
-
/* captureGeneratorOutput: */
|
|
1884
|
+
const { nextSteps, agentContext, skipAgentic, madeChanges } = await (0, execute_migration_1.runNxOrAngularMigration)(root, m, isVerbose,
|
|
1885
|
+
/* captureGeneratorOutput: */ false, resolvedCollection);
|
|
1920
1886
|
migrationEmittedNextSteps.push(...nextSteps);
|
|
1921
1887
|
if (skipAgentic) {
|
|
1922
1888
|
// The generator reported the prompt half unnecessary, so nothing is
|
|
1923
|
-
// owed: no
|
|
1924
|
-
// run the prompt themselves. Runs in all three agentic modes.
|
|
1889
|
+
// owed: no next-steps entry telling anyone to run the prompt.
|
|
1925
1890
|
(0, migrate_output_1.logWaivedAgenticStep)(m, agentContext);
|
|
1926
1891
|
waivedAgenticStep = true;
|
|
1927
1892
|
commit = await commitOrRecordNoChanges(m, madeChanges);
|
|
1928
1893
|
outcome = madeChanges ? 'applied' : 'no-changes';
|
|
1929
1894
|
}
|
|
1930
|
-
else if (agenticRun) {
|
|
1931
|
-
// Install any deps the deterministic phase added/bumped before the
|
|
1932
|
-
// agent runs — the prompt half may depend on them being present in
|
|
1933
|
-
// node_modules.
|
|
1934
|
-
await installDepsIfChanged();
|
|
1935
|
-
inAgenticStep = true;
|
|
1936
|
-
const stepResult = await agenticRun.runStep({
|
|
1937
|
-
root,
|
|
1938
|
-
migration: m,
|
|
1939
|
-
agentic: agenticRun.agentic,
|
|
1940
|
-
runDir: agenticRun.runDir,
|
|
1941
|
-
installDepsIfChanged,
|
|
1942
|
-
documentationPath,
|
|
1943
|
-
implContext: {
|
|
1944
|
-
logs,
|
|
1945
|
-
changes,
|
|
1946
|
-
agentContext,
|
|
1947
|
-
// When prior commits failed, the working tree carries their
|
|
1948
|
-
// diff. The git-inspect path of the prompt would mislead the
|
|
1949
|
-
// agent in that case; fall back to embedded `<files_changed>`.
|
|
1950
|
-
hasDiffContext: agenticHasDiffContext && !hasPendingCommitDebt(),
|
|
1951
|
-
},
|
|
1952
|
-
});
|
|
1953
|
-
inAgenticStep = false;
|
|
1954
|
-
commit = await attemptMigrationCommit(m);
|
|
1955
|
-
(0, migrate_output_1.logAgenticSuccessOutcome)(stepResult.ambiguous ? 'Marked complete by user' : 'Applied', commit.kind === 'landed' ? commit.sha : null, stepResult.summary);
|
|
1956
|
-
outcome = 'applied';
|
|
1957
|
-
}
|
|
1958
1895
|
else {
|
|
1959
|
-
// The
|
|
1960
|
-
// running inside an outer agent). Under `inside-agent`, surface the
|
|
1896
|
+
// The prompt half is deferred. Under `inside-agent`, surface the
|
|
1961
1897
|
// generator-emitted `agentContext` to stdout so the outer driving
|
|
1962
1898
|
// agent can ingest it. Under `disabled` the run is human-driven;
|
|
1963
1899
|
// agent-targeted context would only add noise — drop.
|
|
@@ -1971,59 +1907,16 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
1971
1907
|
}
|
|
1972
1908
|
}
|
|
1973
1909
|
else {
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
const validationRun = agenticRun && shouldRunValidation ? agenticRun : undefined;
|
|
1977
|
-
const { changes, nextSteps, agentContext, skipAgentic, logs, madeChanges, } = await (0, execute_migration_1.runNxOrAngularMigration)(root, m, isVerbose,
|
|
1978
|
-
/* captureGeneratorOutput: */ !!validationRun, resolvedCollection);
|
|
1910
|
+
const { nextSteps, agentContext, madeChanges } = await (0, execute_migration_1.runNxOrAngularMigration)(root, m, isVerbose,
|
|
1911
|
+
/* captureGeneratorOutput: */ false, resolvedCollection);
|
|
1979
1912
|
migrationEmittedNextSteps.push(...nextSteps);
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
const canRunValidation = validationApplies && !skipAgentic;
|
|
1985
|
-
if (canRunValidation) {
|
|
1986
|
-
// Install any deps the deterministic phase added/bumped before the
|
|
1987
|
-
// validation agent runs — the agent may run tasks that need them.
|
|
1988
|
-
await installDepsIfChanged();
|
|
1989
|
-
inAgenticStep = true;
|
|
1990
|
-
const stepResult = await validationRun.runStep({
|
|
1991
|
-
root,
|
|
1992
|
-
migration: m,
|
|
1993
|
-
agentic: validationRun.agentic,
|
|
1994
|
-
runDir: validationRun.runDir,
|
|
1995
|
-
installDepsIfChanged,
|
|
1996
|
-
documentationPath,
|
|
1997
|
-
implContext: {
|
|
1998
|
-
logs,
|
|
1999
|
-
changes,
|
|
2000
|
-
agentContext,
|
|
2001
|
-
// See the hybrid agentic branch above for the rationale on
|
|
2002
|
-
// why pending commit debt gates git-inspect context.
|
|
2003
|
-
hasDiffContext: agenticHasDiffContext && !hasPendingCommitDebt(),
|
|
2004
|
-
},
|
|
2005
|
-
mode: 'generic-validation',
|
|
2006
|
-
});
|
|
2007
|
-
inAgenticStep = false;
|
|
2008
|
-
commit = await attemptMigrationCommit(m);
|
|
2009
|
-
(0, migrate_output_1.logAgenticSuccessOutcome)(stepResult.ambiguous
|
|
2010
|
-
? 'Marked complete by user'
|
|
2011
|
-
: 'Validation passed', commit.kind === 'landed' ? commit.sha : null, stepResult.summary);
|
|
2012
|
-
outcome = 'applied';
|
|
2013
|
-
}
|
|
2014
|
-
else {
|
|
2015
|
-
if (skipAgentic && validationApplies) {
|
|
2016
|
-
(0, migrate_output_1.logWaivedAgenticStep)(m, agentContext);
|
|
2017
|
-
waivedAgenticStep = true;
|
|
2018
|
-
}
|
|
2019
|
-
else if (printDroppedAgentContext && agentContext.length > 0) {
|
|
2020
|
-
// Inner validation step didn't run. Surface `agentContext` under
|
|
2021
|
-
// `inside-agent` so the outer driving agent can ingest it.
|
|
2022
|
-
printDroppedAgentContext({ migration: m, agentContext });
|
|
2023
|
-
}
|
|
2024
|
-
commit = await commitOrRecordNoChanges(m, madeChanges);
|
|
2025
|
-
outcome = madeChanges ? 'applied' : 'no-changes';
|
|
1913
|
+
if (printDroppedAgentContext && agentContext.length > 0) {
|
|
1914
|
+
// Surface `agentContext` under `inside-agent` so the outer driving
|
|
1915
|
+
// agent can ingest it.
|
|
1916
|
+
printDroppedAgentContext({ migration: m, agentContext });
|
|
2026
1917
|
}
|
|
1918
|
+
commit = await commitOrRecordNoChanges(m, madeChanges);
|
|
1919
|
+
outcome = madeChanges ? 'applied' : 'no-changes';
|
|
2027
1920
|
}
|
|
2028
1921
|
outcomes.push({
|
|
2029
1922
|
migration: { package: m.package, name: m.name },
|
|
@@ -2053,9 +1946,7 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
2053
1946
|
(0, migrate_analytics_1.reportMigrateRunError)({
|
|
2054
1947
|
code: e instanceof execute_migration_1.NpmPeerDepsInstallError
|
|
2055
1948
|
? 'npm_install'
|
|
2056
|
-
:
|
|
2057
|
-
? 'agentic'
|
|
2058
|
-
: 'migration_exec',
|
|
1949
|
+
: 'migration_exec',
|
|
2059
1950
|
migrationPackage: m.package,
|
|
2060
1951
|
migrationName: m.name,
|
|
2061
1952
|
migrationCount: totalMigrations,
|
|
@@ -2117,8 +2008,70 @@ async function executeMigrations(root, migrations, isVerbose, shouldCreateCommit
|
|
|
2117
2008
|
retainedAtSuccess: (0, migrate_output_1.retainedMigrations)(outcomes).map((p) => `${p.package}: ${p.name}`),
|
|
2118
2009
|
};
|
|
2119
2010
|
}
|
|
2120
|
-
|
|
2121
|
-
|
|
2011
|
+
const CONTINUE_NEEDS_ORCHESTRATION = `'--run-id' continues an orchestrated migrate run, and this invocation is not orchestrated. Orchestration needs an enabled agent, or an AI agent running nx outside CI; --agentic=false and the WASM build turn it off.`;
|
|
2012
|
+
const ID_PROBLEM_LABELS = {
|
|
2013
|
+
'not-shell-safe': 'not shell-safe',
|
|
2014
|
+
duplicate: 'listed more than once',
|
|
2015
|
+
};
|
|
2016
|
+
// The classic loop records no run, so it must not run over an active one. The
|
|
2017
|
+
// run is reported or asked about before the default-branch prompt; a start
|
|
2018
|
+
// fresh is checked there too, and the caller deletes the run only after it.
|
|
2019
|
+
async function settleActiveRunForClassic(root, opts, migrations) {
|
|
2020
|
+
const { activeRunForClassic, checkRunForStartFresh, renderContinueCommand, renderExistingRunCommands, renderExistingRunReport, } = require('./run');
|
|
2021
|
+
const active = activeRunForClassic(root, migrations.map((m) => `${m.package}:${m.name}`));
|
|
2022
|
+
// With no active run left, the check refuses as init does: the run
|
|
2023
|
+
// completed after the pre-install check, so its plan already ran.
|
|
2024
|
+
if (opts.startFresh === true &&
|
|
2025
|
+
(active === null || active.runId === opts.runId)) {
|
|
2026
|
+
checkRunForStartFresh(root, opts.runId);
|
|
2027
|
+
return { kind: 'run', replaceRunId: opts.runId };
|
|
2028
|
+
}
|
|
2029
|
+
if (!active) {
|
|
2030
|
+
return { kind: 'run' };
|
|
2031
|
+
}
|
|
2032
|
+
const { runId, facts } = active;
|
|
2033
|
+
// Start fresh refuses while another process holds the run, so a held run
|
|
2034
|
+
// leaves nothing to ask; an agent cannot answer a prompt.
|
|
2035
|
+
const held = facts.otherHolders === 'unknown' || facts.otherHolders.length > 0;
|
|
2036
|
+
if (opts.startFresh !== true &&
|
|
2037
|
+
!held &&
|
|
2038
|
+
(0, safe_prompt_1.canPrompt)(opts.interactive) &&
|
|
2039
|
+
!(0, inception_1.isInsideAgent)()) {
|
|
2040
|
+
output_1.output.log(renderExistingRunReport(facts));
|
|
2041
|
+
const choice = await (0, safe_prompt_1.migrateChoice)({
|
|
2042
|
+
message: 'What do you want to do with the active migrate run?',
|
|
2043
|
+
choices: [
|
|
2044
|
+
{
|
|
2045
|
+
value: 'start-fresh',
|
|
2046
|
+
label: 'Start fresh',
|
|
2047
|
+
hint: 'deletes the run record, then runs the whole plan without an agent',
|
|
2048
|
+
},
|
|
2049
|
+
{ value: 'abort', label: 'Abort', hint: 'leaves the run as it is' },
|
|
2050
|
+
],
|
|
2051
|
+
});
|
|
2052
|
+
switch (choice) {
|
|
2053
|
+
case 'start-fresh':
|
|
2054
|
+
checkRunForStartFresh(root, runId);
|
|
2055
|
+
return { kind: 'run', replaceRunId: runId };
|
|
2056
|
+
case 'abort':
|
|
2057
|
+
output_1.output.log({
|
|
2058
|
+
title: `Leaving migrate run ${runId} as it is. To continue it with an agent, run ${renderContinueCommand(root, runId, facts.policy)}.`,
|
|
2059
|
+
});
|
|
2060
|
+
(0, migrate_analytics_1.reportMigrateRunStopped)('aborted');
|
|
2061
|
+
return { kind: 'stop', exitCode: undefined };
|
|
2062
|
+
default: {
|
|
2063
|
+
const unhandled = choice;
|
|
2064
|
+
throw new Error(`Unhandled choice: ${unhandled}`);
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
const report = renderExistingRunReport(facts, renderExistingRunCommands(root, facts, opts.runMigrations, opts.agentic === false ? false : undefined));
|
|
2069
|
+
if (native_1.IS_WASM) {
|
|
2070
|
+
report.bodyLines.push(`The WASM build can run neither command. Continue the run with the native nx binary, or make sure no nx migrate process is acting on it, remove ${types_1.MIGRATE_RUNS_RELATIVE_DIR}/${runId}, then run the plan again.`);
|
|
2071
|
+
}
|
|
2072
|
+
output_1.output.warn(report);
|
|
2073
|
+
(0, migrate_analytics_1.reportMigrateRunStopped)('existing_run');
|
|
2074
|
+
return { kind: 'stop', exitCode: 1 };
|
|
2122
2075
|
}
|
|
2123
2076
|
// nx is located at spawn time, after the gated pre-install, so the child runs
|
|
2124
2077
|
// the bytes that install put in place.
|
|
@@ -2134,20 +2087,18 @@ function handOffToLocalNx(args) {
|
|
|
2134
2087
|
return exitCode !== 0 ? exitCode : undefined;
|
|
2135
2088
|
}
|
|
2136
2089
|
async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, commitPrefix, shouldSkipInstall = false) {
|
|
2137
|
-
//
|
|
2138
|
-
|
|
2139
|
-
// before the install and before --if-exists could return silently.
|
|
2140
|
-
const orchestratorFlag = opts.startFresh === true
|
|
2141
|
-
? '--start-fresh'
|
|
2142
|
-
: opts.runId !== undefined
|
|
2143
|
-
? '--run-id'
|
|
2144
|
-
: undefined;
|
|
2145
|
-
if (orchestratorFlag !== undefined &&
|
|
2146
|
-
(process.env.NX_MIGRATE_ORCHESTRATOR !== 'true' ||
|
|
2147
|
-
(opts.agentic === false && !(0, inception_1.isInsideAgent)()))) {
|
|
2148
|
-
throw new Error(orchestratorFlagNeedsOrchestrator(orchestratorFlag));
|
|
2149
|
-
}
|
|
2090
|
+
// The WASM build lacks the native locks a durable run relies on.
|
|
2091
|
+
const outerAgentDrivesRun = (0, inception_1.isInsideAgent)() && opts.agentic !== false && !(0, is_ci_1.isCI)() && !native_1.IS_WASM;
|
|
2150
2092
|
const isContinue = opts.runId !== undefined && opts.startFresh !== true;
|
|
2093
|
+
// Refused before the install, and before --if-exists could return silently,
|
|
2094
|
+
// when neither the outer agent nor a master session (an agent enabled
|
|
2095
|
+
// outside one, off WASM) can continue the run. A start fresh may reach the
|
|
2096
|
+
// classic loop, which deletes the run's record and runs the plan.
|
|
2097
|
+
if (isContinue &&
|
|
2098
|
+
!outerAgentDrivesRun &&
|
|
2099
|
+
((0, inception_1.isInsideAgent)() || opts.agentic === false || native_1.IS_WASM)) {
|
|
2100
|
+
throw new Error(CONTINUE_NEEDS_ORCHESTRATION);
|
|
2101
|
+
}
|
|
2151
2102
|
let continued;
|
|
2152
2103
|
if (isContinue) {
|
|
2153
2104
|
// Before the install: a concurrent start-fresh must not delete the run
|
|
@@ -2161,7 +2112,35 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
|
|
|
2161
2112
|
activeRunToReplace(root, opts.runId);
|
|
2162
2113
|
}
|
|
2163
2114
|
if (!shouldSkipInstall && !process.env.NX_MIGRATE_SKIP_INSTALL) {
|
|
2164
|
-
|
|
2115
|
+
// The run must resume while the cause of a step's failed install persists.
|
|
2116
|
+
const failedInstallSteps = continued?.steps.filter((s) => s.installFailed === true) ?? [];
|
|
2117
|
+
if (failedInstallSteps.length > 0) {
|
|
2118
|
+
const { pmInstallCommand, stepLabel, TERMINAL_STEP_STATUSES } = require('./run');
|
|
2119
|
+
// A settled step keeps its mark, but no step action can retry it.
|
|
2120
|
+
const settled = failedInstallSteps.filter((s) => TERMINAL_STEP_STATUSES.has(s.status));
|
|
2121
|
+
const retryable = failedInstallSteps.filter((s) => !settled.includes(s));
|
|
2122
|
+
const notCompleted = (steps) => `The dependency install of ${steps
|
|
2123
|
+
.map(stepLabel)
|
|
2124
|
+
.join(', ')} did not complete earlier in this run.`;
|
|
2125
|
+
output_1.output.warn({
|
|
2126
|
+
title: 'Skipping the dependency install',
|
|
2127
|
+
bodyLines: [
|
|
2128
|
+
...(retryable.length > 0
|
|
2129
|
+
? [
|
|
2130
|
+
`${notCompleted(retryable)} Retrying that step installs again; any other choice leaves the install to you.`,
|
|
2131
|
+
]
|
|
2132
|
+
: []),
|
|
2133
|
+
...(settled.length > 0
|
|
2134
|
+
? [
|
|
2135
|
+
`${notCompleted(settled)} Run \`${pmInstallCommand(root)}\` once the cause of the failed install is fixed.`,
|
|
2136
|
+
]
|
|
2137
|
+
: []),
|
|
2138
|
+
].map(text_1.singleLine),
|
|
2139
|
+
});
|
|
2140
|
+
}
|
|
2141
|
+
else {
|
|
2142
|
+
await (0, execute_migration_1.runInstall)();
|
|
2143
|
+
}
|
|
2165
2144
|
}
|
|
2166
2145
|
if (!__dirname.startsWith(workspace_root_1.workspaceRoot)) {
|
|
2167
2146
|
// we are running from a temp installation with nx latest, switch to running
|
|
@@ -2214,11 +2193,19 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
|
|
|
2214
2193
|
validate: opts.validate,
|
|
2215
2194
|
finalValidation: opts.finalValidation,
|
|
2216
2195
|
});
|
|
2196
|
+
// Orchestration refuses ids it cannot dispense verbatim or resolve to one
|
|
2197
|
+
// step, so a new run with one falls back to the classic loop. A continue
|
|
2198
|
+
// has no classic fallback, since it runs the plan its run recorded, and a
|
|
2199
|
+
// start fresh still reaches init's refusal.
|
|
2200
|
+
const idProblems = isContinue || opts.startFresh === true
|
|
2201
|
+
? []
|
|
2202
|
+
: require('./run').migrationIdProblems(migrations);
|
|
2203
|
+
const idProblemLines = idProblems.map(({ id, problem }) => `- ${(0, text_1.singleLine)(id)} (${ID_PROBLEM_LABELS[problem]})`);
|
|
2217
2204
|
// An outer agent drives the loop, so hand off to the orchestrator instead of
|
|
2218
2205
|
// the classic loop: init starts a fresh run or reports an already-active
|
|
2219
2206
|
// one; `--run-id` continues that run. Bare `--run-id` reconciles are
|
|
2220
2207
|
// dispatched separately and never reach here.
|
|
2221
|
-
if (
|
|
2208
|
+
if (outerAgentDrivesRun && idProblems.length === 0) {
|
|
2222
2209
|
const { runOrchestratorInit, runOrchestratorResume } = require('./run');
|
|
2223
2210
|
// Orchestrated runs are agent-driven, so commits default on exactly as they
|
|
2224
2211
|
// do under `--agentic=enabled`; the orchestrator replaces `resolveAgentic`.
|
|
@@ -2279,11 +2266,20 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
|
|
|
2279
2266
|
});
|
|
2280
2267
|
return;
|
|
2281
2268
|
}
|
|
2269
|
+
if (outerAgentDrivesRun) {
|
|
2270
|
+
output_1.output.warn({
|
|
2271
|
+
title: 'Running the migrations without an orchestrated run: orchestrated runs need each migration id to be shell-safe (letters, digits and @/:._-) and listed once, and these are not:',
|
|
2272
|
+
bodyLines: [
|
|
2273
|
+
...idProblemLines,
|
|
2274
|
+
'No run is recorded, so --run-id cannot continue this one. Prompt work is listed as next steps for the AI agent driving this run, and no validation runs.',
|
|
2275
|
+
],
|
|
2276
|
+
});
|
|
2277
|
+
}
|
|
2282
2278
|
(0, migrate_analytics_1.reportMigrateRunStart)({
|
|
2283
2279
|
createCommits: shouldCreateCommits ?? false,
|
|
2284
2280
|
migrationCount: migrations.length,
|
|
2285
2281
|
});
|
|
2286
|
-
const { resolveAgentic
|
|
2282
|
+
const { resolveAgentic } = require('./agentic/select');
|
|
2287
2283
|
let agentic;
|
|
2288
2284
|
try {
|
|
2289
2285
|
agentic = await resolveAgentic({
|
|
@@ -2296,7 +2292,25 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
|
|
|
2296
2292
|
(0, migrate_analytics_1.reportMigrateRunError)({ code: 'agentic', error: e });
|
|
2297
2293
|
throw e;
|
|
2298
2294
|
}
|
|
2299
|
-
|
|
2295
|
+
// Resolved before the commit policy, which defaults on only for an agent.
|
|
2296
|
+
if (agentic.kind === 'enabled' && native_1.IS_WASM) {
|
|
2297
|
+
output_1.output.warn({
|
|
2298
|
+
title: 'Skipping the agentic flow: it needs the native nx binary, and this run loaded the WASM build.',
|
|
2299
|
+
bodyLines: ['Continuing the migration without the agentic flow.'],
|
|
2300
|
+
});
|
|
2301
|
+
agentic = { kind: 'disabled' };
|
|
2302
|
+
}
|
|
2303
|
+
if (agentic.kind === 'enabled' && idProblems.length > 0) {
|
|
2304
|
+
output_1.output.warn({
|
|
2305
|
+
title: 'Skipping the agentic flow: it needs each migration id to be shell-safe (letters, digits and @/:._-) and listed once, and these are not:',
|
|
2306
|
+
bodyLines: [
|
|
2307
|
+
...idProblemLines,
|
|
2308
|
+
'Continuing the migration without the agentic flow. Generators still run. Prompt-only migrations and the prompt part of hybrid migrations are skipped and listed as next steps, and no AI validation runs.',
|
|
2309
|
+
],
|
|
2310
|
+
});
|
|
2311
|
+
agentic = { kind: 'disabled' };
|
|
2312
|
+
}
|
|
2313
|
+
const { effective: effectiveCreateCommits, warning: createCommitsWarning, error: createCommitsError, } = (0, migrate_commits_1.resolveCreateCommits)({
|
|
2300
2314
|
createCommits: shouldCreateCommits,
|
|
2301
2315
|
mode: agentic.kind,
|
|
2302
2316
|
isGitRepo: (0, git_utils_1.isGitRepository)(root),
|
|
@@ -2314,12 +2328,8 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
|
|
|
2314
2328
|
const confirmNewRunCommits = async () => !effectiveCreateCommits ||
|
|
2315
2329
|
!(0, safe_prompt_1.canPrompt)(opts.interactive) ||
|
|
2316
2330
|
(0, migrate_commits_1.confirmMigrationCommitsOnDefaultBranch)(root, 'running migrations');
|
|
2317
|
-
//
|
|
2318
|
-
|
|
2319
|
-
// under WASM, where the broker has no native lock to detect a dead parent.
|
|
2320
|
-
if (agentic.kind === 'enabled' &&
|
|
2321
|
-
process.env.NX_MIGRATE_ORCHESTRATOR === 'true' &&
|
|
2322
|
-
!native_1.IS_WASM) {
|
|
2331
|
+
// The agent drives the whole run through the orchestrator from one session.
|
|
2332
|
+
if (agentic.kind === 'enabled') {
|
|
2323
2333
|
const init = orchestratorInitInput(effectiveCreateCommits);
|
|
2324
2334
|
const { runMasterSession } = require('./agentic/master/run-master-session');
|
|
2325
2335
|
return await runMasterSession({
|
|
@@ -2331,16 +2341,22 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
|
|
|
2331
2341
|
confirmStart: confirmNewRunCommits,
|
|
2332
2342
|
});
|
|
2333
2343
|
}
|
|
2334
|
-
if (
|
|
2335
|
-
throw new Error(
|
|
2344
|
+
if (isContinue) {
|
|
2345
|
+
throw new Error(CONTINUE_NEEDS_ORCHESTRATION);
|
|
2346
|
+
}
|
|
2347
|
+
const classicGate = await settleActiveRunForClassic(root, opts, migrations);
|
|
2348
|
+
if (classicGate.kind === 'stop') {
|
|
2349
|
+
return classicGate.exitCode;
|
|
2336
2350
|
}
|
|
2337
2351
|
if (!(await confirmNewRunCommits())) {
|
|
2352
|
+
(0, migrate_analytics_1.reportMigrateRunStopped)('declined_commits');
|
|
2338
2353
|
return;
|
|
2339
2354
|
}
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2355
|
+
// After the prompt, so declining it keeps the run.
|
|
2356
|
+
if (classicGate.replaceRunId !== undefined) {
|
|
2357
|
+
const { deleteRunForStartFresh } = require('./run');
|
|
2358
|
+
deleteRunForStartFresh(root, classicGate.replaceRunId);
|
|
2359
|
+
}
|
|
2344
2360
|
output_1.output.log({
|
|
2345
2361
|
title: `Running migrations from '${opts.runMigrations}'` +
|
|
2346
2362
|
(effectiveCreateCommits
|
|
@@ -2350,18 +2366,7 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
|
|
|
2350
2366
|
if (effectiveCreateCommits) {
|
|
2351
2367
|
(0, migrate_commits_1.commitCheckpointBeforeMigrations)(root, commitPrefix);
|
|
2352
2368
|
}
|
|
2353
|
-
|
|
2354
|
-
const { applyAgenticHandoffGitignoreFallback } = require('./agentic/handoff-gitignore');
|
|
2355
|
-
const { packageJson: nxPackageJson } = (0, package_json_1.readModulePackageJson)('nx', (0, installation_directory_1.getNxRequirePaths)(root));
|
|
2356
|
-
await applyAgenticHandoffGitignoreFallback({
|
|
2357
|
-
migrations,
|
|
2358
|
-
installedNxVersion: nxPackageJson.version,
|
|
2359
|
-
effectiveCreateCommits,
|
|
2360
|
-
commitPrefix,
|
|
2361
|
-
root,
|
|
2362
|
-
});
|
|
2363
|
-
}
|
|
2364
|
-
const { migrationsWithNoChanges, skippedPromptsCount, notRunMigrationsCount, skippedPrompts, migrationEmittedNextSteps, committedShasCount, waivedAgenticStepsCount, retainedAtSuccess, } = await executeMigrations(root, migrations, isVerbose, effectiveCreateCommits, commitPrefix, shouldSkipInstall, agentic, agenticHasDiffContext, shouldRunValidation);
|
|
2369
|
+
const { migrationsWithNoChanges, skippedPromptsCount, notRunMigrationsCount, skippedPrompts, migrationEmittedNextSteps, committedShasCount, waivedAgenticStepsCount, retainedAtSuccess, } = await executeMigrations(root, migrations, isVerbose, effectiveCreateCommits, commitPrefix, shouldSkipInstall, agentic);
|
|
2365
2370
|
const ranWithChangesCount = migrations.length - notRunMigrationsCount - migrationsWithNoChanges.length;
|
|
2366
2371
|
// The "applied" tally counts fully-completed migrations — those that
|
|
2367
2372
|
// left no deferred work behind. Hybrid migrations whose prompt half was
|
|
@@ -2391,9 +2396,13 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
|
|
|
2391
2396
|
? 'Finished running migrations with uncommitted state retained'
|
|
2392
2397
|
: 'Successfully finished running migrations';
|
|
2393
2398
|
if (notRunMigrationsCount === migrations.length && migrations.length > 0) {
|
|
2399
|
+
// Under WASM or with ids orchestration refuses, an --agentic re-run lands
|
|
2400
|
+
// here again.
|
|
2394
2401
|
const remediation = insideAgent
|
|
2395
2402
|
? 'The AI agent driving this run should apply each prompt — see next steps below.'
|
|
2396
|
-
:
|
|
2403
|
+
: native_1.IS_WASM || idProblems.length > 0
|
|
2404
|
+
? 'Apply each prompt yourself. See next steps below.'
|
|
2405
|
+
: 'Re-run with --agentic to apply them. See next steps below.';
|
|
2397
2406
|
output_1.output.warn({
|
|
2398
2407
|
title: `No migrations from '${opts.runMigrations}' were applied — every entry is a prompt-only migration. ${remediation}`,
|
|
2399
2408
|
bodyLines: tallyBody,
|
|
@@ -2449,7 +2458,6 @@ async function runMigrations(root, opts, args, isVerbose, shouldCreateCommits, c
|
|
|
2449
2458
|
}
|
|
2450
2459
|
(0, migrate_analytics_1.reportMigrateRunComplete)({
|
|
2451
2460
|
agenticOutcome: agentic.kind,
|
|
2452
|
-
agentUsed: agentic.kind === 'enabled' ? agentic.selectedAgent.id : undefined,
|
|
2453
2461
|
migrationCount: migrations.length,
|
|
2454
2462
|
appliedCount,
|
|
2455
2463
|
});
|
|
@@ -2834,45 +2842,6 @@ async function runMigration() {
|
|
|
2834
2842
|
return runLocalMigrate();
|
|
2835
2843
|
});
|
|
2836
2844
|
}
|
|
2837
|
-
/**
|
|
2838
|
-
* Resolves a migration's collection once and derives everything the run loop
|
|
2839
|
-
* needs from that single read: the implementation context (`collection` +
|
|
2840
|
-
* `collectionPath`, handed to `runNxOrAngularMigration`) and, for agentic runs,
|
|
2841
|
-
* the workspace-relative documentation path handed to the agent.
|
|
2842
|
-
*
|
|
2843
|
-
* Read fresh per migration (not cached across the loop) so a prior migration's
|
|
2844
|
-
* reinstall is reflected, exactly as before. Error handling matches each field's
|
|
2845
|
-
* role:
|
|
2846
|
-
* - Migrations that run an implementation REQUIRE the collection; an unreadable
|
|
2847
|
-
* collection throws and aborts that migration (caught by the run loop).
|
|
2848
|
-
* - Prompt-only migrations don't run an implementation, so the collection is
|
|
2849
|
-
* read only to resolve documentation - a failure there is non-fatal: the
|
|
2850
|
-
* prompt still runs and the supplementary doc is skipped with a warning.
|
|
2851
|
-
*/
|
|
2852
|
-
function resolveMigrationForRun(root, migration, resolveDocumentation) {
|
|
2853
|
-
let resolvedCollection;
|
|
2854
|
-
if (!(0, migration_shape_1.isPromptOnlyMigration)(migration)) {
|
|
2855
|
-
resolvedCollection = (0, execute_migration_1.readMigrationCollection)(migration.package, root);
|
|
2856
|
-
}
|
|
2857
|
-
else if (resolveDocumentation && migration.documentation) {
|
|
2858
|
-
try {
|
|
2859
|
-
resolvedCollection = (0, execute_migration_1.readMigrationCollection)(migration.package, root);
|
|
2860
|
-
}
|
|
2861
|
-
catch {
|
|
2862
|
-
// Non-fatal: documentation is supplementary; the warning below fires.
|
|
2863
|
-
}
|
|
2864
|
-
}
|
|
2865
|
-
let documentationPath;
|
|
2866
|
-
if (resolveDocumentation && migration.documentation) {
|
|
2867
|
-
documentationPath = resolvedCollection
|
|
2868
|
-
? (0, execute_migration_1.resolveDocumentationFileToWorkspacePath)(root, (0, path_1.dirname)(resolvedCollection.collectionPath), migration.documentation)
|
|
2869
|
-
: undefined;
|
|
2870
|
-
if (!documentationPath) {
|
|
2871
|
-
logger_1.logger.warn(`Could not resolve the "documentation" file "${migration.documentation}" declared for migration "${migration.package}: ${migration.name}". It will be skipped as additional context for the AI agent.`);
|
|
2872
|
-
}
|
|
2873
|
-
}
|
|
2874
|
-
return { resolvedCollection, documentationPath };
|
|
2875
|
-
}
|
|
2876
2845
|
async function nxCliPath(nxWorkspaceRoot) {
|
|
2877
2846
|
const version = process.env.NX_MIGRATE_CLI_VERSION || 'latest';
|
|
2878
2847
|
const isVerbose = process.env.NX_VERBOSE_LOGGING === 'true';
|