nx 23.3.0 → 24.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +3 -6
  2. package/dist/src/adapter/ngcli-adapter.js +1 -0
  3. package/dist/src/command-line/configure-ai-agents/configure-ai-agents.js +0 -12
  4. package/dist/src/command-line/graph/graph.js +3 -5
  5. package/dist/src/command-line/init/command-object.js +0 -12
  6. package/dist/src/command-line/init/init-v2.js +0 -2
  7. package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +17 -12
  8. package/dist/src/command-line/release/utils/remote-release-clients/github.js +5 -6
  9. package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +5 -6
  10. package/dist/src/command-line/run/executor-utils.js +1 -0
  11. package/dist/src/command-line/run/run-one.d.ts +20 -1
  12. package/dist/src/command-line/run/run-one.js +153 -5
  13. package/dist/src/command-line/show/show-target/utils.js +1 -0
  14. package/dist/src/command-line/watch/command-object.js +3 -22
  15. package/dist/src/command-line/watch/watch.d.ts +0 -7
  16. package/dist/src/command-line/watch/watch.js +1 -1
  17. package/dist/src/config/misc-interfaces.d.ts +12 -0
  18. package/dist/src/config/workspace-json-project-json.d.ts +5 -0
  19. package/dist/src/daemon/client/client.d.ts +9 -0
  20. package/dist/src/daemon/client/client.js +89 -37
  21. package/dist/src/daemon/server/shutdown-utils.js +0 -3
  22. package/dist/src/daemon/socket-utils.d.ts +9 -4
  23. package/dist/src/daemon/socket-utils.js +12 -49
  24. package/dist/src/daemon/tmp-dir.d.ts +19 -14
  25. package/dist/src/daemon/tmp-dir.js +142 -354
  26. package/dist/src/devkit-internals.d.ts +1 -1
  27. package/dist/src/devkit-internals.js +1 -0
  28. package/dist/src/hasher/file-hasher.js +9 -7
  29. package/dist/src/hasher/hash-task.js +4 -0
  30. package/dist/src/hasher/native-task-hasher-impl.js +1 -1
  31. package/dist/src/migrations/update-24-0-0/find-custom-hashers.d.ts +3 -0
  32. package/dist/src/migrations/update-24-0-0/find-custom-hashers.js +100 -0
  33. package/dist/src/migrations/update-24-0-0/find-custom-hashers.md +63 -0
  34. package/dist/src/migrations/update-24-0-0/move-custom-hashers-to-inputs.md +145 -0
  35. package/dist/src/native/index.d.ts +127 -8
  36. package/dist/src/native/native-bindings.js +5 -0
  37. package/dist/src/native/nx.wasi-browser.js +1 -0
  38. package/dist/src/native/nx.wasi.cjs +1 -0
  39. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  40. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  41. package/dist/src/nx-cloud/update-manager.d.ts +7 -0
  42. package/dist/src/nx-cloud/update-manager.js +237 -50
  43. package/dist/src/project-graph/affected/affected-tasks.js +1 -0
  44. package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +7 -0
  45. package/dist/src/tasks-runner/create-task-graph.d.ts +10 -0
  46. package/dist/src/tasks-runner/create-task-graph.js +37 -2
  47. package/dist/src/tasks-runner/task-env.d.ts +10 -0
  48. package/dist/src/tasks-runner/task-env.js +26 -5
  49. package/dist/src/tasks-runner/task-orchestrator.d.ts +10 -4
  50. package/dist/src/tasks-runner/task-orchestrator.js +87 -53
  51. package/dist/src/tasks-runner/utils.d.ts +20 -5
  52. package/dist/src/tasks-runner/utils.js +80 -29
  53. package/dist/src/ultracache/overrides.js +4 -0
  54. package/dist/src/utils/owned-private-dir.d.ts +1 -17
  55. package/dist/src/utils/owned-private-dir.js +10 -62
  56. package/dist/src/utils/perf-hooks.d.ts +1 -0
  57. package/dist/src/utils/plugins/core-plugins.js +1 -1
  58. package/dist/src/utils/string-similarity.d.ts +38 -0
  59. package/dist/src/utils/string-similarity.js +108 -0
  60. package/migrations.json +7 -0
  61. package/package.json +11 -20
  62. package/readme-template.md +3 -3
  63. package/schemas/nx-schema.json +5 -0
  64. package/schemas/project-schema.json +5 -0
  65. package/dist/src/tasks-runner/legacy-depends-on-warning.d.ts +0 -18
  66. package/dist/src/tasks-runner/legacy-depends-on-warning.js +0 -109
@@ -98,7 +98,7 @@ function taskGraphFingerprint(taskGraph, ultracacheConfigurations) {
98
98
  ];
99
99
  for (const id of Object.keys(taskGraph.tasks).sort()) {
100
100
  const task = taskGraph.tasks[id];
101
- parts.push(id, task.target.project, task.target.target, task.target.configuration ?? '', (task.outputs ?? []).join(','), (taskGraph.dependencies[id] ?? []).join(','), (taskGraph.continuousDependencies[id] ?? []).join(','));
101
+ parts.push(id, task.target.project, task.target.target, task.target.configuration ?? '', (task.outputs ?? []).join(','), (taskGraph.dependencies[id] ?? []).join(','), (taskGraph.continuousDependencies[id] ?? []).join(','), (taskGraph.continuousDependenciesWithoutInputs?.[id] ?? []).join(','));
102
102
  }
103
103
  return (0, native_1.hashArray)(parts);
104
104
  }
@@ -0,0 +1,3 @@
1
+ import type { MigrationReturnObject } from '../../config/misc-interfaces';
2
+ import type { Tree } from '../../generators/tree';
3
+ export default function findCustomHashers(tree: Tree): Promise<MigrationReturnObject>;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = findCustomHashers;
4
+ const glob_1 = require("../../generators/utils/glob");
5
+ const json_1 = require("../../utils/json");
6
+ const path_1 = require("../../utils/path");
7
+ const node_path_1 = require("node:path");
8
+ const DOCS_URL = 'https://nx.dev/docs/kb/local-executors#replace-a-custom-hasher-with-inputs';
9
+ async function findCustomHashers(tree) {
10
+ const hits = new Set();
11
+ const malformed = new Set();
12
+ const unparseable = [];
13
+ const visited = new Set();
14
+ for (const packageJsonPath of await (0, glob_1.globAsync)(tree, ['**/package.json'])) {
15
+ if (packageJsonPath.split('/').includes('node_modules')) {
16
+ continue;
17
+ }
18
+ const content = tree.read(packageJsonPath, 'utf-8');
19
+ if (!content.includes('"executors"') && !content.includes('"builders"')) {
20
+ continue;
21
+ }
22
+ const packageJson = tryParse(content);
23
+ if (!packageJson) {
24
+ unparseable.push(packageJsonPath);
25
+ continue;
26
+ }
27
+ const packageRoot = node_path_1.posix.dirname(packageJsonPath);
28
+ // A nameless local plugin is referenced by its relative path.
29
+ const pluginName = packageJson.name ?? (packageRoot === '.' ? '.' : `./${packageRoot}`);
30
+ for (const field of [packageJson.executors, packageJson.builders]) {
31
+ if (typeof field !== 'string') {
32
+ continue;
33
+ }
34
+ const executorsJsonPath = (0, path_1.joinPathFragments)(packageRoot, field);
35
+ if (visited.has(executorsJsonPath) || !tree.exists(executorsJsonPath)) {
36
+ continue;
37
+ }
38
+ visited.add(executorsJsonPath);
39
+ const executorsJson = tryParse(tree.read(executorsJsonPath, 'utf-8'));
40
+ if (!executorsJson) {
41
+ unparseable.push(executorsJsonPath);
42
+ continue;
43
+ }
44
+ const entries = [];
45
+ for (const map of [executorsJson.executors, executorsJson.builders]) {
46
+ if (map === undefined) {
47
+ continue;
48
+ }
49
+ if (!isPlainObject(map)) {
50
+ unparseable.push(executorsJsonPath);
51
+ break;
52
+ }
53
+ entries.push(...Object.entries(map));
54
+ }
55
+ for (const [name, entry] of entries) {
56
+ if (typeof entry === 'string') {
57
+ continue;
58
+ }
59
+ if (!isPlainObject(entry) || !isValidHasher(entry.hasher)) {
60
+ malformed.add(`Entry "${name}" in "${executorsJsonPath}" is not a valid executor entry. Check it by hand for a "hasher".`);
61
+ continue;
62
+ }
63
+ if (entry.hasher === undefined) {
64
+ continue;
65
+ }
66
+ const hasherPath = (0, path_1.joinPathFragments)(node_path_1.posix.dirname(executorsJsonPath), entry.hasher);
67
+ hits.add(`Executor "${pluginName}:${name}" declares a custom hasher at "${hasherPath}" in "${executorsJsonPath}".`);
68
+ }
69
+ }
70
+ }
71
+ if (hits.size === 0 && malformed.size === 0 && unparseable.length === 0) {
72
+ return { skipAgentic: true };
73
+ }
74
+ const manualNotes = [
75
+ ...malformed,
76
+ ...unparseable.map((path) => `Could not parse "${path}". Check it by hand for executors that declare a "hasher".`),
77
+ ];
78
+ return {
79
+ nextSteps: [
80
+ `Custom hashers are deprecated and will be removed in Nx 25. Replace each one with target inputs, then remove "hasher" from executors.json. See ${DOCS_URL}`,
81
+ ...hits,
82
+ ...manualNotes,
83
+ ],
84
+ agentContext: [...hits, ...manualNotes],
85
+ };
86
+ }
87
+ function isPlainObject(value) {
88
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
89
+ }
90
+ function isValidHasher(hasher) {
91
+ return hasher === undefined || typeof hasher === 'string';
92
+ }
93
+ function tryParse(content) {
94
+ try {
95
+ return (0, json_1.parseJson)(content);
96
+ }
97
+ catch {
98
+ return null;
99
+ }
100
+ }
@@ -0,0 +1,63 @@
1
+ #### Move custom executor hashers to target inputs
2
+
3
+ Custom hashers are deprecated in Nx 24 and will be removed in Nx 25.
4
+ A custom hasher is the `hasher` property of an executor in `executors.json`, pointing at a module that computes the task hash in code.
5
+ Target `inputs` replace them.
6
+
7
+ This migration finds every local plugin in the workspace whose `executors.json` (or `builders.json`) declares a `hasher`.
8
+ It doesn't edit any files.
9
+ When it finds one, it lists the executor, the hasher module, and the `executors.json` file in the migration's next steps.
10
+ It also lists files and executor entries it can't read, so you can check those by hand.
11
+ Under `nx migrate` with an AI agent, the agent reads each hasher and writes `inputs` that hash the same things.
12
+ A target that declares its own `inputs` doesn't inherit them from `targetDefaults`, so the agent checks every target that uses the executor and adds the inputs where they're missing.
13
+ It removes the `hasher` only once every one of those targets is covered.
14
+ If something the hasher hashes can't be expressed as an input, the agent leaves the hasher in place and tells you why.
15
+
16
+ Packages installed in `node_modules` aren't scanned.
17
+ If a third-party plugin you use declares a hasher, Nx warns about it when it hashes one of its tasks.
18
+
19
+ #### Sample code changes
20
+
21
+ Given a local plugin whose `echo` executor hashes the project, its dependencies, and the `API_URL` environment variable:
22
+
23
+ ##### Before
24
+
25
+ ```json title="tools/my-plugin/executors.json"
26
+ {
27
+ "executors": {
28
+ "echo": {
29
+ "implementation": "./src/executors/echo/executor",
30
+ "hasher": "./src/executors/echo/hasher",
31
+ "schema": "./src/executors/echo/schema.json"
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ ##### After
38
+
39
+ ```json title="nx.json"
40
+ {
41
+ "targetDefaults": {
42
+ "@acme/my-plugin:echo": {
43
+ "inputs": ["default", "^default", { "env": "API_URL" }]
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ ```json title="tools/my-plugin/executors.json"
50
+ {
51
+ "executors": {
52
+ "echo": {
53
+ "implementation": "./src/executors/echo/executor",
54
+ "schema": "./src/executors/echo/schema.json"
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ #### Reference
61
+
62
+ - [Replace a custom hasher with inputs](https://nx.dev/docs/kb/local-executors#replace-a-custom-hasher-with-inputs)
63
+ - [Inputs reference](https://nx.dev/docs/reference/inputs)
@@ -0,0 +1,145 @@
1
+ # Move custom executor hashers to target inputs
2
+
3
+ Custom hashers (the `hasher` property of an executor in `executors.json`) are
4
+ deprecated in Nx 24 and removed in Nx 25. Each one should become target `inputs`
5
+ that hash the same things, so the targets keep caching correctly once the hasher
6
+ is gone.
7
+
8
+ The generator half of this migration only scans. It edits no files, and it lists
9
+ every executor that declares a hasher in the advisory context, one line each,
10
+ with the executor name, the hasher path, and the `executors.json` path. Lines
11
+ starting with `Could not parse` name files the scan skipped, and lines starting
12
+ with `Entry` name executor entries it could not read.
13
+
14
+ Do not touch executors that declare no hasher, executors installed from
15
+ `node_modules`, or any other caching configuration.
16
+
17
+ ## First, check whether there is anything to do
18
+
19
+ Confirm this before changing anything. If it fails, make no changes and stop:
20
+
21
+ 1. The advisory context lists at least one executor that declares a custom
22
+ hasher, or at least one file or entry it could not read. Read each of those
23
+ yourself; if it declares no `hasher`, drop it from the list.
24
+
25
+ ## Step 1: Read what each hasher hashes
26
+
27
+ Open the hasher module named in the advisory context. Work out every value it
28
+ feeds into the hash it returns:
29
+
30
+ - `context.hasher.hashTask(task, ...)` alone is Nx default hashing.
31
+ - Files it reads, globs it walks, or other projects it hashes.
32
+ - Environment variables it reads.
33
+ - Commands it runs, or data it fetches (a remote API, a registry lookup).
34
+
35
+ ## Step 2: Write equivalent inputs
36
+
37
+ Map each value to an input:
38
+
39
+ | What the hasher hashes | Input |
40
+ | ----------------------------------------------------- | ------------------------------------------------------- |
41
+ | The project and its dependencies (Nx default hashing) | `"default"` and `"^default"` |
42
+ | Files of specific other projects | `{ "input": "default", "projects": ["shared-config"] }` |
43
+ | A subset of the files in the project | `{ "fileset": "{projectRoot}/src/**/*.graphql" }` |
44
+ | A file outside any project | `{ "fileset": "{workspaceRoot}/schema.json" }` |
45
+ | An environment variable | `{ "env": "API_URL" }` |
46
+ | The output of a command, such as a tool version | `{ "runtime": "node --version" }` |
47
+
48
+ If the workspace defines named inputs such as `production`, prefer them over
49
+ `default` where the hasher excluded test files.
50
+
51
+ ### Find every target that uses the executor
52
+
53
+ Write the resolved project graph and list every target whose `executor` is the
54
+ executor name (`"@acme/my-plugin:echo"`):
55
+
56
+ ```shell
57
+ npx nx graph --file=tmp/custom-hashers-graph.json
58
+ ```
59
+
60
+ Each target in `graph.nodes.<project>.data.targets` there is fully resolved: it
61
+ already reflects `targetDefaults` (including filtered array entries), inferred
62
+ targets, and project-level overrides. Record each consuming target's resolved
63
+ `inputs`. Every one of them must end up covered.
64
+
65
+ ### Place the inputs
66
+
67
+ A target that declares its own `inputs` replaces the `inputs` from
68
+ `targetDefaults` rather than merging with them. So a `targetDefaults` edit alone
69
+ does not reach a target that already declares `inputs`.
70
+
71
+ 1. Set the inputs in `nx.json` `targetDefaults` under the executor name. If that
72
+ key already exists, add `inputs` to it, and merge with any `inputs` it already
73
+ declares rather than replacing them. If its value is an array of filtered
74
+ entries, add the inputs to every entry that applies to a consuming target.
75
+ 2. For every consuming target that declares its own `inputs`, add the
76
+ replacement inputs to that target as well, keeping the inputs it already has.
77
+ It is declared in `project.json`, in the `nx.targets` block of
78
+ `package.json`, or by the plugin that infers the target. For an inferred
79
+ target, set `inputs` in `project.json` to the full resolved list plus the
80
+ replacement inputs.
81
+ 3. Write the graph again and confirm that every consuming target's resolved
82
+ `inputs` now contains every replacement input. Fix any that do not.
83
+
84
+ **Before:**
85
+
86
+ ```json
87
+ // tools/my-plugin/executors.json
88
+ {
89
+ "executors": {
90
+ "echo": {
91
+ "implementation": "./src/executors/echo/executor",
92
+ "hasher": "./src/executors/echo/hasher",
93
+ "schema": "./src/executors/echo/schema.json"
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ **After:**
100
+
101
+ ```json
102
+ // nx.json
103
+ {
104
+ "targetDefaults": {
105
+ "@acme/my-plugin:echo": {
106
+ "inputs": ["default", "^default", { "env": "API_URL" }]
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
112
+ ```json
113
+ // tools/my-plugin/executors.json
114
+ {
115
+ "executors": {
116
+ "echo": {
117
+ "implementation": "./src/executors/echo/executor",
118
+ "schema": "./src/executors/echo/schema.json"
119
+ }
120
+ }
121
+ }
122
+ ```
123
+
124
+ ## Step 3: Remove the hasher only when the inputs cover it
125
+
126
+ Remove `hasher` from `executors.json` and delete the hasher module (and its
127
+ spec) only once the resolved inputs of every consuming target cover everything
128
+ the hasher hashed.
129
+
130
+ If a value has no file, environment variable, or project to point at, such as
131
+ data fetched from a remote service, use a `runtime` input whose command prints
132
+ that value. If no command can reproduce it, leave the hasher in place and tell
133
+ the user which value blocks the move and why.
134
+
135
+ ## Post-Migration Validation
136
+
137
+ 1. `npx nx show target <project>:<target>` for every consuming target found in
138
+ Step 2. Confirm each one lists the replacement inputs. After the hasher is
139
+ removed, `npx nx show target <project>:<target> inputs` also shows the files
140
+ and values those inputs resolve to.
141
+ 2. `npx nx run-many -t <target>` twice for the targets that used the executor.
142
+ The second run should be a cache hit. Change a file the hasher used to hash
143
+ and confirm the next run is a cache miss.
144
+ 3. `npx nx run-many -t build,test,lint -p <plugin project>` if you deleted hasher
145
+ files. Fix failures caused by this migration and re-run until green.
@@ -236,6 +236,10 @@ export declare class RunningTasksService {
236
236
  constructor(db: ExternalObject<NxDbConnection>)
237
237
  getRunningTasks(ids: Array<string>): Array<string>
238
238
  addRunningTask(taskId: string): void
239
+ /**
240
+ * Release this process's claim on a task. A row another process has since
241
+ * taken over is left in place.
242
+ */
239
243
  removeRunningTask(taskId: string): void
240
244
  }
241
245
 
@@ -282,14 +286,42 @@ export declare class TaskHasher {
282
286
  hashPlansFor(hashPlans: ExternalObject<Record<string, Array<HashInstruction>>>, taskIds: Array<string>, perTaskEnvs: Record<string, Record<string, string>>, cwd: string, collectTaskInputs?: boolean | undefined | null): Record<string, HashDetails>
283
287
  }
284
288
 
289
+ /**
290
+ * Tracks which tasks each Nx process in a nested process tree is running, so
291
+ * that a task which re-invokes itself can be reported instead of looping
292
+ * forever.
293
+ *
294
+ * Every process in the tree shares a `root_pid`, but sharing a root does not
295
+ * imply a parent/child relationship: sibling Nx processes are common and
296
+ * legitimate (N atomized e2e specs each spawning the same `serve-static` web
297
+ * server, or two parallel tasks that each shell out to `nx run lib:build`).
298
+ * Only an invocation belonging to an actual *ancestor* of this process is a
299
+ * loop, so the check is scoped to `ancestor_pids` rather than to the whole
300
+ * tree.
301
+ */
285
302
  export declare class TaskInvocationTracker {
286
- constructor(db: ExternalObject<NxDbConnection>, rootPid: number)
287
- /** Register a task as invoked. Throws if the task was already registered (loop detected). */
288
- registerTask(parentPid: number, taskId: string): void
289
- /** Remove a task invocation record after task completes. */
290
- unregisterTask(taskId: string): void
291
- /** Get all invocations for this root_pid, ordered by creation time. */
292
- getInvocationChain(): Array<InvocationRecord>
303
+ constructor(db: ExternalObject<NxDbConnection>, rootPid: number, ancestorPids: Array<number>)
304
+ /**
305
+ * Register a task as invoked by the process identified by `pid`.
306
+ *
307
+ * Returns the invocation chain when an ancestor process is already running
308
+ * this task, which is a genuine loop. The chain lists every task invoked
309
+ * along the ancestry path, outermost first. Returns `null` when the task
310
+ * was registered, including when a *sibling* process is already running it.
311
+ *
312
+ * An ancestor running this task with the *same* overrides is a loop
313
+ * immediately. An ancestor running it with different overrides is allowed
314
+ * up to `MAX_ANCESTOR_INVOCATIONS_PER_TASK`, which lets a terminating
315
+ * `app:build -> app:build --flag` chain through while still bounding a
316
+ * recursion whose forwarded arguments grow on every hop.
317
+ */
318
+ registerTask(pid: number, taskId: string, overridesHash: string): Array<InvocationRecord> | null
319
+ /**
320
+ * Remove a task invocation record after the task completes. Scoped to the
321
+ * registering process so that a sibling finishing the same task does not
322
+ * drop this process's record.
323
+ */
324
+ unregisterTask(pid: number, taskId: string): void
293
325
  /** Clean up stale invocations older than 1 day (handles PID recycling). */
294
326
  cleanupStale(): void
295
327
  }
@@ -886,7 +918,7 @@ export declare function installNxConsole(): Promise<boolean>
886
918
  export declare function installNxConsoleForEditor(editor: SupportedEditor): Promise<boolean>
887
919
 
888
920
  export interface InvocationRecord {
889
- parentPid: number
921
+ pid: number
890
922
  taskId: string
891
923
  }
892
924
 
@@ -1012,6 +1044,14 @@ export interface NxWorkspaceFilesExternals {
1012
1044
  ignoredIndex: ExternalObject<IgnoredIndexReader>
1013
1045
  }
1014
1046
 
1047
+ /**
1048
+ * Open `url` in the user's default browser. Returns `true` if an opener
1049
+ * process was spawned, `false` if none could be (e.g. no `xdg-open`) or `url`
1050
+ * isn't `http(s)`, so the caller can tell the user instead of failing
1051
+ * silently. Never throws.
1052
+ */
1053
+ export declare function openUrl(url: string): boolean
1054
+
1015
1055
  /** A workspace-relative file with the stamp it was left with. */
1016
1056
  export interface OutputFile {
1017
1057
  path: string
@@ -1078,6 +1118,32 @@ export interface ProjectGraph {
1078
1118
 
1079
1119
  export declare function remove(src: string): void
1080
1120
 
1121
+ /**
1122
+ * The daemon's own socket. Per run — the directory name hashes the pid, and
1123
+ * clients read the daemon's path back out of the process cache rather than
1124
+ * deriving it.
1125
+ */
1126
+ export declare function resolveDaemonSocketPath(workspaceRoot: string, env?: Record<string, string> | undefined | null): SocketDirDetails
1127
+
1128
+ /** A forked task process's socket, in the daemon's per-run directory. */
1129
+ export declare function resolveForkedProcessSocketPath(workspaceRoot: string, id: string, env?: Record<string, string> | undefined | null): SocketDirDetails
1130
+
1131
+ /**
1132
+ * Where the Nx Console socket lives, for whoever binds or connects to it.
1133
+ *
1134
+ * `env` is for callers that load a workspace `.env` into a copy rather than
1135
+ * into their own environment, and `workspaceRoot` for callers that do not run
1136
+ * inside the workspace — Nx Console is both, since it runs in the editor's
1137
+ * extension host.
1138
+ */
1139
+ export declare function resolveNxConsoleSocketPath(workspaceRoot: string, env?: Record<string, string> | undefined | null): SocketDirDetails
1140
+
1141
+ /**
1142
+ * Plugin worker sockets get their own workspace-scoped directory rather than
1143
+ * sitting in the shared system temp dir, which cannot be locked down.
1144
+ */
1145
+ export declare function resolvePluginSocketPath(workspaceRoot: string, id: string, env?: Record<string, string> | undefined | null): SocketDirDetails
1146
+
1081
1147
  export declare function restoreTerminal(): void
1082
1148
 
1083
1149
  export declare const enum RunMode {
@@ -1089,6 +1155,53 @@ export interface RuntimeInput {
1089
1155
  runtime: string
1090
1156
  }
1091
1157
 
1158
+ /**
1159
+ * One resolved socket location, and everything `daemon/tmp-dir.ts` needs to
1160
+ * explain it. Every user-facing sentence is rendered on the TypeScript side,
1161
+ * so this carries facts rather than prose.
1162
+ */
1163
+ export interface SocketDirDetails {
1164
+ /** The socket itself, which on Windows is a named pipe rather than a path. */
1165
+ path: string
1166
+ /** The directory holding it, for the caller that deletes it on shutdown. */
1167
+ dir: string
1168
+ /**
1169
+ * Whether `path` exceeds what the platform will bind. Reported rather than
1170
+ * thrown because which advice is correct depends on the other fields.
1171
+ */
1172
+ tooLong: boolean
1173
+ /**
1174
+ * Set when `path` is a directory Nx refuses to *be* the socket directory:
1175
+ * `shared-with-other-users`, `nx-managed`, or `os-temp-root`. The caller
1176
+ * throws on it rather than using `path`.
1177
+ */
1178
+ invalidReason?: string
1179
+ /** The preferred root that was skipped, when a later tier was used. */
1180
+ demotedFrom?: string
1181
+ /**
1182
+ * The default-root directory Nx tried before falling back, when there was
1183
+ * one.
1184
+ */
1185
+ attemptedDir?: string
1186
+ /**
1187
+ * The `NX_SOCKET_DIR` that was refused, when that is why this is a
1188
+ * fallback. Tracked apart from the other reasons so a later length error
1189
+ * stops telling someone to shorten a directory refused for another one.
1190
+ */
1191
+ refusedConfiguredDir?: string
1192
+ /** Why that configured directory was refused. */
1193
+ refusalError?: string
1194
+ /**
1195
+ * Whether this landed in the workspace data dir, which the caller warns
1196
+ * about once per process.
1197
+ */
1198
+ usedWorkspaceFallback: boolean
1199
+ /** Deduplicated advice for the refusals collected along the way. */
1200
+ remedies: Array<string>
1201
+ /** Every refusal as one sentence, for `--verbose`. */
1202
+ refusalDetails?: string
1203
+ }
1204
+
1092
1205
  export declare const enum SupportedEditor {
1093
1206
  VSCode = 0,
1094
1207
  VSCodeInsiders = 1,
@@ -1177,6 +1290,11 @@ export interface TaskGraph {
1177
1290
  /** Map of Task IDs to IDs of tasks which the task depends on */
1178
1291
  dependencies: Record<string, Array<string>>
1179
1292
  continuousDependencies: Record<string, Array<string>>
1293
+ /**
1294
+ * The subset of `continuous_dependencies` from `dependsOn` entries with
1295
+ * `inputs: false`: still run, but their inputs are not hashed into the task.
1296
+ */
1297
+ continuousDependenciesWithoutInputs?: Record<string, Array<string>>
1180
1298
  }
1181
1299
 
1182
1300
  /** Details about the composition of a task's hash */
@@ -1346,6 +1464,7 @@ export interface UltracacheDiagnostic {
1346
1464
  export interface UltracacheEligibilityOptions {
1347
1465
  /** Tasks whose executor ships a custom hasher. */
1348
1466
  customHasherTaskIds?: Array<string>
1467
+ continuousTaskIds?: Array<string>
1349
1468
  }
1350
1469
 
1351
1470
  /**
@@ -638,8 +638,13 @@ module.exports.locateTouchedProjects = nativeBinding.locateTouchedProjects
638
638
  module.exports.logDebug = nativeBinding.logDebug
639
639
  module.exports.matchGlobPaths = nativeBinding.matchGlobPaths
640
640
  module.exports.matchOutputPaths = nativeBinding.matchOutputPaths
641
+ module.exports.openUrl = nativeBinding.openUrl
641
642
  module.exports.parseTaskStatus = nativeBinding.parseTaskStatus
642
643
  module.exports.remove = nativeBinding.remove
644
+ module.exports.resolveDaemonSocketPath = nativeBinding.resolveDaemonSocketPath
645
+ module.exports.resolveForkedProcessSocketPath = nativeBinding.resolveForkedProcessSocketPath
646
+ module.exports.resolveNxConsoleSocketPath = nativeBinding.resolveNxConsoleSocketPath
647
+ module.exports.resolvePluginSocketPath = nativeBinding.resolvePluginSocketPath
643
648
  module.exports.restoreTerminal = nativeBinding.restoreTerminal
644
649
  module.exports.RunMode = nativeBinding.RunMode
645
650
  module.exports.SupportedEditor = nativeBinding.SupportedEditor
@@ -124,6 +124,7 @@ export const installNxConsole = __napiModule.exports.installNxConsole
124
124
  export const IS_WASM = __napiModule.exports.IS_WASM
125
125
  export const isAiAgent = __napiModule.exports.isAiAgent
126
126
  export const logDebug = __napiModule.exports.logDebug
127
+ export const openUrl = __napiModule.exports.openUrl
127
128
  export const remove = __napiModule.exports.remove
128
129
  export const testOnlyTransferFileMap = __napiModule.exports.testOnlyTransferFileMap
129
130
  export const transferProjectGraph = __napiModule.exports.transferProjectGraph
@@ -154,6 +154,7 @@ module.exports.installNxConsole = __napiModule.exports.installNxConsole
154
154
  module.exports.IS_WASM = __napiModule.exports.IS_WASM
155
155
  module.exports.isAiAgent = __napiModule.exports.isAiAgent
156
156
  module.exports.logDebug = __napiModule.exports.logDebug
157
+ module.exports.openUrl = __napiModule.exports.openUrl
157
158
  module.exports.remove = __napiModule.exports.remove
158
159
  module.exports.testOnlyTransferFileMap = __napiModule.exports.testOnlyTransferFileMap
159
160
  module.exports.transferProjectGraph = __napiModule.exports.transferProjectGraph
Binary file
@@ -1,7 +1,12 @@
1
+ import { HttpClient } from '../utils/http-client';
1
2
  import type { CloudTaskRunnerOptions } from './nx-cloud-tasks-runner-shell';
2
3
  import type { ReadUltracacheConfigurationsOptions, ReadUltracacheConfigurationsResult } from '../ultracache/fetch';
3
4
  import { TasksRunner } from '../tasks-runner/tasks-runner';
4
5
  import { RemoteCacheV2 } from '../tasks-runner/default-tasks-runner';
6
+ interface CloudBundleInstall {
7
+ version: string;
8
+ fullPath: string;
9
+ }
5
10
  export declare class NxCloudEnterpriseOutdatedError extends Error {
6
11
  constructor(url: string);
7
12
  }
@@ -24,3 +29,5 @@ export declare function verifyOrUpdateNxCloudClient(options?: {
24
29
  version: string;
25
30
  } | null>;
26
31
  export declare function getBundleInstallDefaultLocation(): string;
32
+ export declare function downloadAndExtractClientBundle(httpClient: HttpClient, version: string, url: string): Promise<CloudBundleInstall>;
33
+ export {};