nx 23.2.1 → 23.3.0-beta.1

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 (149) hide show
  1. package/dist/src/command-line/format/format.js +2 -18
  2. package/dist/src/command-line/graph/graph.js +42 -3
  3. package/dist/src/command-line/init/implementation/format.js +2 -3
  4. package/dist/src/command-line/migrate/agentic/definitions.js +75 -19
  5. package/dist/src/command-line/migrate/agentic/format-command.d.ts +14 -0
  6. package/dist/src/command-line/migrate/agentic/format-command.js +44 -0
  7. package/dist/src/command-line/migrate/agentic/handoff-gitignore.d.ts +3 -3
  8. package/dist/src/command-line/migrate/agentic/handoff-gitignore.js +3 -3
  9. package/dist/src/command-line/migrate/agentic/handoff.d.ts +27 -17
  10. package/dist/src/command-line/migrate/agentic/handoff.js +107 -24
  11. package/dist/src/command-line/migrate/agentic/instruction-files.d.ts +21 -0
  12. package/dist/src/command-line/migrate/agentic/instruction-files.js +36 -0
  13. package/dist/src/command-line/migrate/agentic/prompts/fragments.d.ts +16 -0
  14. package/dist/src/command-line/migrate/agentic/prompts/fragments.js +70 -0
  15. package/dist/src/command-line/migrate/agentic/prompts/generic-validation.js +4 -3
  16. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.d.ts +25 -1
  17. package/dist/src/command-line/migrate/agentic/prompts/system-prompt.js +57 -34
  18. package/dist/src/command-line/migrate/agentic/run-step.js +28 -4
  19. package/dist/src/command-line/migrate/agentic/runner.d.ts +17 -8
  20. package/dist/src/command-line/migrate/agentic/runner.js +110 -55
  21. package/dist/src/command-line/migrate/agentic/types.d.ts +23 -8
  22. package/dist/src/command-line/migrate/agentic/types.js +10 -7
  23. package/dist/src/command-line/migrate/migrate-commits.d.ts +1 -0
  24. package/dist/src/command-line/migrate/migrate-commits.js +9 -0
  25. package/dist/src/command-line/migrate/migrate-output.d.ts +3 -7
  26. package/dist/src/command-line/migrate/migrate-output.js +3 -7
  27. package/dist/src/command-line/migrate/migrate.js +21 -8
  28. package/dist/src/command-line/migrate/run/agent-output.d.ts +10 -0
  29. package/dist/src/command-line/migrate/run/agent-output.js +16 -2
  30. package/dist/src/command-line/migrate/run/agent-work-payload.d.ts +37 -0
  31. package/dist/src/command-line/migrate/run/agent-work-payload.js +142 -0
  32. package/dist/src/command-line/migrate/run/atomic-write.d.ts +8 -0
  33. package/dist/src/command-line/migrate/run/atomic-write.js +17 -0
  34. package/dist/src/command-line/migrate/run/index.d.ts +1 -1
  35. package/dist/src/command-line/migrate/run/issues.d.ts +106 -0
  36. package/dist/src/command-line/migrate/run/issues.js +980 -0
  37. package/dist/src/command-line/migrate/run/orchestrator.d.ts +1 -0
  38. package/dist/src/command-line/migrate/run/orchestrator.js +662 -105
  39. package/dist/src/command-line/migrate/run/run-state.d.ts +43 -8
  40. package/dist/src/command-line/migrate/run/run-state.js +184 -20
  41. package/dist/src/command-line/migrate/run/runbook.d.ts +17 -0
  42. package/dist/src/command-line/migrate/run/runbook.js +97 -0
  43. package/dist/src/command-line/migrate/run/state-lock.d.ts +2 -2
  44. package/dist/src/command-line/migrate/run/state-lock.js +2 -2
  45. package/dist/src/command-line/migrate/run/state-machine.d.ts +5 -1
  46. package/dist/src/command-line/migrate/run/state-machine.js +27 -1
  47. package/dist/src/command-line/migrate/run/worker.js +206 -56
  48. package/dist/src/command-line/nx-cloud/connect/connect-to-nx-cloud.js +5 -1
  49. package/dist/src/command-line/release/publish.js +11 -4
  50. package/dist/src/command-line/release/utils/remote-release-clients/github.js +3 -3
  51. package/dist/src/command-line/release/utils/remote-release-clients/gitlab.js +3 -3
  52. package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.d.ts +2 -0
  53. package/dist/src/command-line/release/utils/remote-release-clients/remote-release-client.js +35 -0
  54. package/dist/src/command-line/yargs-utils/shared-options.d.ts +1 -1
  55. package/dist/src/command-line/yargs-utils/shared-options.js +22 -4
  56. package/dist/src/config/workspace-json-project-json.d.ts +2 -0
  57. package/dist/src/core/graph/main.js +1 -1
  58. package/dist/src/daemon/client/client.d.ts +4 -2
  59. package/dist/src/daemon/client/client.js +20 -11
  60. package/dist/src/daemon/message-types/run-tasks-execution-hooks.d.ts +3 -2
  61. package/dist/src/daemon/server/handle-hash-tasks.d.ts +8 -2
  62. package/dist/src/daemon/server/handle-hash-tasks.js +16 -3
  63. package/dist/src/daemon/server/handle-outputs-changes.d.ts +2 -2
  64. package/dist/src/daemon/server/handle-outputs-changes.js +21 -6
  65. package/dist/src/daemon/server/handle-tasks-execution-hooks.d.ts +3 -2
  66. package/dist/src/daemon/server/outputs-tracking.d.ts +6 -0
  67. package/dist/src/daemon/server/outputs-tracking.js +18 -0
  68. package/dist/src/daemon/server/project-graph-incremental-recomputation.d.ts +22 -7
  69. package/dist/src/daemon/server/project-graph-incremental-recomputation.js +99 -69
  70. package/dist/src/daemon/server/restart-checks.d.ts +22 -0
  71. package/dist/src/daemon/server/restart-checks.js +77 -0
  72. package/dist/src/daemon/server/server.js +28 -18
  73. package/dist/src/daemon/server/shutdown-utils.d.ts +0 -5
  74. package/dist/src/daemon/server/shutdown-utils.js +3 -26
  75. package/dist/src/hasher/hash-task.js +20 -16
  76. package/dist/src/hasher/native-task-hasher-impl.d.ts +8 -0
  77. package/dist/src/hasher/native-task-hasher-impl.js +46 -3
  78. package/dist/src/hasher/task-hasher.d.ts +9 -0
  79. package/dist/src/hasher/task-hasher.js +14 -0
  80. package/dist/src/native/index.d.ts +202 -21
  81. package/dist/src/native/index.js +3 -3
  82. package/dist/src/native/native-bindings.js +3 -1
  83. package/dist/src/native/nx.wasm32-wasi.debug.wasm +0 -0
  84. package/dist/src/native/nx.wasm32-wasi.wasm +0 -0
  85. package/dist/src/plugins/js/lock-file/pnpm-parser.js +1 -1
  86. package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.d.ts +2 -0
  87. package/dist/src/plugins/js/lock-file/utils/pnpm-normalizer.js +22 -0
  88. package/dist/src/plugins/js/utils/register.js +2 -1
  89. package/dist/src/project-graph/plugins/isolation/isolated-plugin.js +2 -1
  90. package/dist/src/project-graph/plugins/isolation/messaging.d.ts +3 -2
  91. package/dist/src/project-graph/plugins/isolation/plugin-worker.js +5 -1
  92. package/dist/src/project-graph/plugins/loaded-nx-plugin.d.ts +3 -2
  93. package/dist/src/project-graph/plugins/loaded-nx-plugin.js +5 -1
  94. package/dist/src/project-graph/plugins/task-results-stub.d.ts +50 -0
  95. package/dist/src/project-graph/plugins/task-results-stub.js +111 -0
  96. package/dist/src/project-graph/plugins/tasks-execution-hooks.d.ts +3 -2
  97. package/dist/src/project-graph/plugins/tasks-execution-hooks.js +2 -1
  98. package/dist/src/project-graph/project-graph.js +2 -0
  99. package/dist/src/tasks-runner/batch/run-batch.js +15 -0
  100. package/dist/src/tasks-runner/cache.d.ts +35 -0
  101. package/dist/src/tasks-runner/cache.js +40 -0
  102. package/dist/src/tasks-runner/create-task-graph.js +1 -0
  103. package/dist/src/tasks-runner/default-tasks-runner.js +1 -1
  104. package/dist/src/tasks-runner/forked-process-task-runner.d.ts +1 -1
  105. package/dist/src/tasks-runner/forked-process-task-runner.js +8 -7
  106. package/dist/src/tasks-runner/init-tasks-runner.js +5 -1
  107. package/dist/src/tasks-runner/is-tui-enabled.js +4 -3
  108. package/dist/src/tasks-runner/life-cycle.d.ts +7 -0
  109. package/dist/src/tasks-runner/life-cycle.js +7 -0
  110. package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.d.ts +35 -0
  111. package/dist/src/tasks-runner/life-cycles/summary-terminal-output-life-cycle.js +146 -0
  112. package/dist/src/tasks-runner/prune-task-graph.d.ts +17 -0
  113. package/dist/src/tasks-runner/prune-task-graph.js +45 -0
  114. package/dist/src/tasks-runner/run-command.js +14 -3
  115. package/dist/src/tasks-runner/running-tasks/batch-process.d.ts +93 -19
  116. package/dist/src/tasks-runner/running-tasks/batch-process.js +184 -88
  117. package/dist/src/tasks-runner/task-orchestrator.d.ts +64 -2
  118. package/dist/src/tasks-runner/task-orchestrator.js +232 -46
  119. package/dist/src/tasks-runner/terminal-output-path.d.ts +11 -0
  120. package/dist/src/tasks-runner/terminal-output-path.js +18 -0
  121. package/dist/src/tasks-runner/utils.js +5 -2
  122. package/dist/src/utils/ab-testing.d.ts +3 -0
  123. package/dist/src/utils/ab-testing.js +11 -3
  124. package/dist/src/utils/chunkify.d.ts +1 -7
  125. package/dist/src/utils/chunkify.js +2 -8
  126. package/dist/src/utils/command-line-utils.d.ts +19 -0
  127. package/dist/src/utils/command-line-utils.js +10 -3
  128. package/dist/src/utils/formatters/index.d.ts +6 -0
  129. package/dist/src/utils/formatters/index.js +5 -0
  130. package/dist/src/utils/formatters/prettier.d.ts +0 -8
  131. package/dist/src/utils/formatters/prettier.js +4 -26
  132. package/dist/src/utils/installed-nx-version.js +2 -48
  133. package/dist/src/utils/min-release-age/packument.js +1 -1
  134. package/dist/src/utils/output.d.ts +22 -3
  135. package/dist/src/utils/output.js +28 -5
  136. package/dist/src/utils/package-json.d.ts +25 -0
  137. package/dist/src/utils/package-json.js +41 -6
  138. package/dist/src/utils/package-manager.d.ts +6 -0
  139. package/dist/src/utils/package-manager.js +10 -0
  140. package/dist/src/utils/provenance.js +20 -4
  141. package/dist/src/utils/workspace-context.d.ts +47 -3
  142. package/dist/src/utils/workspace-context.js +162 -10
  143. package/package.json +12 -12
  144. package/schemas/nx-schema.json +4 -0
  145. package/schemas/project-schema.json +4 -0
  146. package/dist/src/daemon/server/file-watching/route-workspace-changes.d.ts +0 -9
  147. package/dist/src/daemon/server/file-watching/route-workspace-changes.js +0 -76
  148. package/dist/src/daemon/server/watcher.d.ts +0 -18
  149. package/dist/src/daemon/server/watcher.js +0 -126
@@ -104,6 +104,14 @@ export declare class HttpRemoteCache {
104
104
  store(hash: string, cacheDirectory: string, terminalOutput: string, code: number): Promise<boolean>
105
105
  }
106
106
 
107
+ /**
108
+ * The hasher's handle on an index: lists only after catching up with the
109
+ * watch behind it.
110
+ */
111
+ export declare class IgnoredIndexReader {
112
+
113
+ }
114
+
107
115
  export declare class ImportResult {
108
116
  file: string
109
117
  sourceProject: string
@@ -122,6 +130,25 @@ export declare class NxCache {
122
130
  getBatch(hashes: Array<string>): Array<CachedResult | undefined | null>
123
131
  put(hash: string, terminalOutput: string, outputs: Array<string>, code: number): Array<string>
124
132
  applyRemoteCacheResults(hash: string, result: CachedResult, outputs?: Array<string> | undefined | null): void
133
+ /**
134
+ * Register terminal outputs that were written without a cache entry —
135
+ * uncacheable tasks, and cacheable ones run with `--skip-nx-cache`.
136
+ *
137
+ * Without a row the file is invisible to `remove_old_cache_records`,
138
+ * which only ever walks hashes it finds in the database, so these files
139
+ * would accumulate forever. The row carries `is_cache_entry = FALSE` so it
140
+ * can never be served as a cache hit.
141
+ *
142
+ * On conflict `accessed_at` always moves: the reads filter these rows out,
143
+ * so they would otherwise age from the first write and be collected out
144
+ * from under a task that is still being run daily. `size` moves only while
145
+ * the row is still output-only (`NOT is_cache_entry`), so a task rerun with
146
+ * a longer log stops undercounting against `maxCacheSize`. `is_cache_entry`
147
+ * is never touched, and a row that already has artifacts keeps the size
148
+ * `put` recorded, so a rewrite can neither demote a real entry nor replace
149
+ * its whole-entry size with the terminal output's.
150
+ */
151
+ recordTerminalOutputs(records: Array<TerminalOutputRecord>): void
125
152
  getTaskOutputsPath(hash: string): string
126
153
  getCacheSize(): number
127
154
  copyFilesFromCache(cachedResult: CachedResult, outputs: Array<string>): number
@@ -204,7 +231,7 @@ export declare class TaskDetails {
204
231
  }
205
232
 
206
233
  export declare class TaskHasher {
207
- constructor(workspaceRoot: string, projectGraph: ExternalObject<ProjectGraph>, projectFileMap: ExternalObject<Record<string, Array<FileData>>>, allWorkspaceFiles: ExternalObject<Array<FileData>>, tsConfig: Buffer, tsConfigPaths: Record<string, Array<string>>, rootTsconfigPath?: string | undefined | null, options?: HasherOptions | undefined | null)
234
+ constructor(workspaceRoot: string, projectGraph: ExternalObject<ProjectGraph>, projectFileMap: ExternalObject<Record<string, Array<FileData>>>, allWorkspaceFiles: ExternalObject<Array<FileData>>, tsConfig: Buffer, tsConfigPaths: Record<string, Array<string>>, rootTsconfigPath: string | undefined | null, options: HasherOptions | undefined | null, ignoredIndex: ExternalObject<IgnoredIndexReader>)
208
235
  /**
209
236
  * Hash each task's instructions using the env map keyed by `task.id`.
210
237
  * Every task in `hash_plans` must have an entry in `per_task_envs` —
@@ -214,6 +241,21 @@ export declare class TaskHasher {
214
241
  * every task id.
215
242
  */
216
243
  hashPlans(hashPlans: ExternalObject<Record<string, Array<HashInstruction>>>, perTaskEnvs: Record<string, Record<string, string>>, cwd: string, collectTaskInputs?: boolean | undefined | null): Record<string, HashDetails>
244
+ /**
245
+ * Like `hash_plans`, but only for the plans the planner did not defer
246
+ * (`HashPlans::deferred`: a task that reads another task's outputs, or a
247
+ * disk-backed fileset whose directory contains, or sits inside, an
248
+ * upstream task's output). The rest are left out and hash once those
249
+ * tasks have run; their ids are absent from the result and need no entry
250
+ * in `per_task_envs`.
251
+ */
252
+ hashPlansUpfront(hashPlans: ExternalObject<Record<string, Array<HashInstruction>>>, perTaskEnvs: Record<string, Record<string, string>>, cwd: string, collectTaskInputs?: boolean | undefined | null): Record<string, HashDetails>
253
+ /**
254
+ * Hashes `task_ids` from plans built earlier, so a task the up-front batch
255
+ * deferred needs no second planning pass. Ids without a plan are absent
256
+ * from the result.
257
+ */
258
+ 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>
217
259
  }
218
260
 
219
261
  export declare class TaskInvocationTracker {
@@ -228,28 +270,39 @@ export declare class TaskInvocationTracker {
228
270
  cleanupStale(): void
229
271
  }
230
272
 
231
- export declare class Watcher {
232
- origin: string
273
+ export declare class WorkspaceContext {
274
+ workspaceRoot: string
275
+ constructor(workspaceRoot: string, cacheDir: string, options?: WorkspaceContextOptions | undefined | null)
233
276
  /**
234
- * Always applies HARDCODED_IGNORE_PATTERNS plus watcher-specific
235
- * patterns (vite/vitest timestamp files), regardless of `use_ignore`.
277
+ * Loads the files the last walk recorded instead of walking. For a
278
+ * process whose host already walked, such as a plugin worker.
236
279
  */
237
- constructor(origin: string, additionalGlobs?: Array<string> | undefined | null, useIgnore?: boolean | undefined | null)
238
- watch(callbackTsfn: (err: string | null, events: WatchEvent[]) => void): void
239
- stop(): Promise<void>
280
+ static fromArchive(workspaceRoot: string, cacheDir: string, options?: WorkspaceContextOptions | undefined | null): WorkspaceContext
240
281
  /**
241
- * Synchronously drains the accumulator. Used by the daemon before
242
- * serving a cached project graph so events buffered inside the
243
- * IDLE_WINDOW debounce don't go missing. Returns an empty vec if
244
- * the watcher hasn't started, the loop has exited, or no events
245
- * are buffered.
282
+ * Bumped once per applied batch that changed anything. Equal values
283
+ * mean equal files, so a consumer that remembers the value it computed
284
+ * from can skip recomputing.
246
285
  */
247
- forceFlushPending(): Array<WatchEvent>
248
- }
249
-
250
- export declare class WorkspaceContext {
251
- workspaceRoot: string
252
- constructor(workspaceRoot: string, cacheDir: string)
286
+ changeSeq(): number
287
+ /**
288
+ * Walks the workspace again into this context, so it and the archive
289
+ * include writes made since the last walk. Does nothing while a walk is
290
+ * in progress. Await `ready()` before reading. What the walk finds
291
+ * changed goes to the subscriber.
292
+ *
293
+ * For a graph built without the daemon, where nothing watches: see
294
+ * `refreshWorkspaceContext`, called by
295
+ * `buildProjectGraphAndSourceMapsWithoutDaemon`.
296
+ */
297
+ refresh(): boolean
298
+ /**
299
+ * Resolves once the files behind this context exist. The readers below
300
+ * block the calling thread until they do; awaiting this first keeps a
301
+ * plugin host responsive while its workers are connecting.
302
+ */
303
+ ready(): Promise<void>
304
+ /** On wasm the files are gathered when the context is constructed. */
305
+ ready(): void
253
306
  getWorkspaceFiles(projectRootMap: Record<string, string>): NxWorkspaceFiles
254
307
  glob(globs: Array<string>, exclude?: Array<string> | undefined | null): Array<string>
255
308
  /**
@@ -261,10 +314,60 @@ export declare class WorkspaceContext {
261
314
  multiGlob(globs: Array<string>, exclude?: Array<string> | undefined | null): Array<Array<string>>
262
315
  hashFilesMatchingGlobs(globGroups: Array<Array<string>>): Array<string>
263
316
  hashFilesMatchingGlob(globs: Array<string>, exclude?: Array<string> | undefined | null): string
264
- incrementalUpdate(updatedFiles: Array<string>, deletedFiles: Array<string>): Record<string, string>
317
+ /**
318
+ * Applies changes a caller learned of on its own. Waits through a walk in
319
+ * progress so the answer reflects them. Returns what really changed; the
320
+ * batch is not published to subscribers.
321
+ */
322
+ incrementalUpdate(updatedFiles: Array<string>, deletedFiles: Array<string>): ChangeBatch
265
323
  updateProjectFiles(projectRootMappings: Record<string, string>, projectFiles: ExternalObject<Record<string, Array<FileData>>>, globalFiles: ExternalObject<Array<FileData>>, updatedFiles: Record<string, string>, deletedFiles: Array<string>): UpdatedWorkspaceFiles
266
324
  allFileData(): Array<FileData>
325
+ /**
326
+ * Recover from dropped watch events: re-walk, and report what changed
327
+ * against the files this context was holding. The fresh files are
328
+ * adopted, so the caller only has to feed the returned changes through
329
+ * its normal recomputation path; subscribers do not see them.
330
+ */
331
+ rescanAndDiff(): ChangeBatch
332
+ /**
333
+ * The subset of `paths` the file map holds: what the watch tracks, with
334
+ * the ignore rules applied. A path it does not hold is gitignored, gone,
335
+ * or not yet reported. Applies what the watch delivered first, as every
336
+ * other read of the files does, so a write already reported counts.
337
+ */
338
+ trackedFiles(paths: Array<string>): Array<string>
267
339
  getFilesInDirectory(directory: string): Array<string>
340
+ /**
341
+ * Subscribes to the context's changes: the callback is called whenever
342
+ * something was applied or delivered, with everything not yet taken by
343
+ * it or by `settle`. Replaces any earlier subscriber.
344
+ */
345
+ onChanges(callback: (err: Error | null, batch: ChangeBatch | null) => void): void
346
+ /**
347
+ * Subscribes to every event the watch delivers, whether or not it
348
+ * concerns the files: writes under ignored directories included, and
349
+ * the `rescan` marker when the kernel dropped events. Replaces any
350
+ * earlier subscriber. Batches applied to the files are `onChanges`.
351
+ */
352
+ onWatchEvents(callback: (err: Error | null, events: WatchEvent[] | null) => void): void
353
+ /**
354
+ * Applies everything the watch has delivered, waiting out the kernel hop,
355
+ * then takes every change applied and not yet taken, one entry per path
356
+ * at its latest state. The change subscriber takes from the same place,
357
+ * so no change is handed out twice.
358
+ */
359
+ settle(): ChangeBatch
360
+ /**
361
+ * Takes every change applied and not yet taken, without waiting for the
362
+ * watch: for a caller that just applied changes itself, through
363
+ * `incrementalUpdate` or `rescanAndDiff`.
364
+ */
365
+ takeAppliedChanges(): ChangeBatch
366
+ /**
367
+ * Stops the watcher and forgets the subscribers. The files stay as they
368
+ * were; reads no longer pull anything in.
369
+ */
370
+ stopWatching(): void
268
371
  }
269
372
 
270
373
  export interface BatchInfo {
@@ -298,6 +401,20 @@ export declare function canInstallNxConsole(): Promise<boolean>
298
401
 
299
402
  export declare function canInstallNxConsoleForEditor(editor: SupportedEditor): Promise<boolean>
300
403
 
404
+ /**
405
+ * What one application of changes did to the files. `seq` is the context's
406
+ * change sequence afterwards; it is unchanged, and the lists empty, when
407
+ * nothing the batch reported was really different. A path can reach a
408
+ * consumer in more than one batch (see `settle`): the one with the higher
409
+ * `seq` holds its later state.
410
+ */
411
+ export interface ChangeBatch {
412
+ seq: number
413
+ createdFiles: Array<FileData>
414
+ updatedFiles: Array<FileData>
415
+ deletedFiles: Array<string>
416
+ }
417
+
301
418
  export declare function closeDbConnection(connection: ExternalObject<NxDbConnection>): void
302
419
 
303
420
  export declare function connectToNxDb(cacheDir: string, dbName?: string | undefined | null): ExternalObject<NxDbConnection>
@@ -357,9 +474,17 @@ export interface EventDimensions {
357
474
  export declare const enum EventType {
358
475
  delete = 'delete',
359
476
  update = 'update',
360
- create = 'create'
477
+ create = 'create',
478
+ /**
479
+ * The kernel dropped events (e.g. an inotify queue overflow); per-path
480
+ * events cannot be trusted complete and consumers must re-walk.
481
+ */
482
+ rescan = 'rescan'
361
483
  }
362
484
 
485
+ /** The files an `includeIgnored` fileset group matches on disk, sorted. */
486
+ export declare function expandFilesInput(workspaceRoot: string, globs: Array<string>): Array<string>
487
+
363
488
  export declare function expandOutputs(directory: string, entries: Array<string>): Array<string>
364
489
 
365
490
  export interface ExternalDependenciesInput {
@@ -385,6 +510,11 @@ export interface FileMap {
385
510
  export interface FileSetInput {
386
511
  fileset: string
387
512
  dependencies?: boolean
513
+ /**
514
+ * Hash the glob straight from disk (so gitignored/generated files count)
515
+ * instead of the workspace file map.
516
+ */
517
+ includeIgnored?: boolean
388
518
  }
389
519
 
390
520
  export declare function findImports(projectFileMap: Record<string, Array<string>>): Array<ImportResult>
@@ -624,6 +754,7 @@ export interface NxWorkspaceFilesExternals {
624
754
  projectFiles: ExternalObject<Record<string, Array<FileData>>>
625
755
  globalFiles: ExternalObject<Array<FileData>>
626
756
  allWorkspaceFiles: ExternalObject<Array<FileData>>
757
+ ignoredIndex: ExternalObject<IgnoredIndexReader>
627
758
  }
628
759
 
629
760
  export declare function parseTaskStatus(stringStatus: string): TaskStatus
@@ -702,6 +833,31 @@ export declare const enum SupportedEditor {
702
833
  Unknown = 5
703
834
  }
704
835
 
836
+ /**
837
+ * A free function, not a method: `BatchProcess` writes these logs whichever
838
+ * cache implementation is active, so the sweep must not be reachable only
839
+ * through the DB-backed one.
840
+ *
841
+ * Deletes batch logs by age, then oldest-first while the directory is over
842
+ * budget.
843
+ *
844
+ * No database rows: nothing looks a batch log up by key, so a row would be
845
+ * write-only bookkeeping that a hard-killed process could skip, orphaning
846
+ * the file forever. The filesystem cannot drift from itself, and the file
847
+ * is appended to for the life of its batch, so a size recorded anywhere
848
+ * else is wrong until that batch ends.
849
+ *
850
+ * The budget is separate from `maxCacheSize` on purpose: these are debug
851
+ * artifacts, and sharing a budget would let one evict a replayable cache
852
+ * entry — trading a rebuild for a text file.
853
+ *
854
+ * The age sweep deletes at `BATCH_OUTPUT_MAX_AGE`; the eviction skips
855
+ * anything written within `BATCH_OUTPUT_MIN_EVICTION_AGE`. That is
856
+ * last-write, not creation, so a batch silent through a long quiet phase is
857
+ * not protected.
858
+ */
859
+ export declare function sweepBatchOutputs(cachePath: string): void
860
+
705
861
  /** System information (static system-level data) */
706
862
  export interface SystemInfo {
707
863
  cpuCores: number
@@ -811,6 +967,15 @@ export interface TaskTarget {
811
967
  configuration?: string
812
968
  }
813
969
 
970
+ export interface TerminalOutputRecord {
971
+ hash: string
972
+ /**
973
+ * Byte length of the terminal output written for this hash, so these
974
+ * files are counted against `maxCacheSize` like any other cache content.
975
+ */
976
+ size: number
977
+ }
978
+
814
979
  export declare function testOnlyTransferFileMap(projectFiles: Record<string, Array<FileData>>, nonProjectFiles: Array<FileData>): NxWorkspaceFilesExternals
815
980
 
816
981
  /** Track an event using the global telemetry instance */
@@ -851,6 +1016,22 @@ export interface WorkingDirectoryInput {
851
1016
  workingDirectory: string
852
1017
  }
853
1018
 
1019
+ export interface WorkspaceContextOptions {
1020
+ /**
1021
+ * Keep the files current from a watcher the context owns. Watching
1022
+ * starts before the scan, so nothing written after construction is
1023
+ * missed. Off by default; ignored on wasm, which has no watcher.
1024
+ */
1025
+ watch?: boolean
1026
+ /**
1027
+ * Paths the watch reports even though a hardcoded ignore covers them,
1028
+ * as the daemon does for its own process file. They reach the event
1029
+ * stream only, never the files: the workspace ignore rules still decide
1030
+ * what enters those.
1031
+ */
1032
+ alwaysWatch?: Array<string>
1033
+ }
1034
+
854
1035
  /** Public NAPI error codes that are for Node */
855
1036
  export declare const enum WorkspaceErrors {
856
1037
  ParseError = 'ParseError',
@@ -210,7 +210,7 @@ Module._load = function (request, parent, isMain) {
210
210
 
211
211
  const indexModulePath = require.resolve('./native-bindings.js');
212
212
  delete require.cache[indexModulePath];
213
- const indexModule = require('./native-bindings.js');
214
-
215
- module.exports = indexModule;
213
+ // A direct re-export: node's CommonJS export lexer follows this form, so ESM
214
+ // importers see the named exports. Assigning via a variable hides them.
215
+ module.exports = require('./native-bindings.js');
216
216
  Module._load = originalLoad;
@@ -582,6 +582,7 @@ module.exports.FileLock = nativeBinding.FileLock
582
582
  module.exports.HashPlanInspector = nativeBinding.HashPlanInspector
583
583
  module.exports.HashPlanner = nativeBinding.HashPlanner
584
584
  module.exports.HttpRemoteCache = nativeBinding.HttpRemoteCache
585
+ module.exports.IgnoredIndexReader = nativeBinding.IgnoredIndexReader
585
586
  module.exports.ImportResult = nativeBinding.ImportResult
586
587
  module.exports.NxCache = nativeBinding.NxCache
587
588
  module.exports.NxConsolePreferences = nativeBinding.NxConsolePreferences
@@ -592,7 +593,6 @@ module.exports.RustPseudoTerminal = nativeBinding.RustPseudoTerminal
592
593
  module.exports.TaskDetails = nativeBinding.TaskDetails
593
594
  module.exports.TaskHasher = nativeBinding.TaskHasher
594
595
  module.exports.TaskInvocationTracker = nativeBinding.TaskInvocationTracker
595
- module.exports.Watcher = nativeBinding.Watcher
596
596
  module.exports.WorkspaceContext = nativeBinding.WorkspaceContext
597
597
  module.exports.BatchStatus = nativeBinding.BatchStatus
598
598
  module.exports.canInstallNxConsole = nativeBinding.canInstallNxConsole
@@ -602,6 +602,7 @@ module.exports.connectToNxDb = nativeBinding.connectToNxDb
602
602
  module.exports.copy = nativeBinding.copy
603
603
  module.exports.detectAiAgent = nativeBinding.detectAiAgent
604
604
  module.exports.EventType = nativeBinding.EventType
605
+ module.exports.expandFilesInput = nativeBinding.expandFilesInput
605
606
  module.exports.expandOutputs = nativeBinding.expandOutputs
606
607
  module.exports.findImports = nativeBinding.findImports
607
608
  module.exports.flushTelemetry = nativeBinding.flushTelemetry
@@ -633,6 +634,7 @@ module.exports.remove = nativeBinding.remove
633
634
  module.exports.restoreTerminal = nativeBinding.restoreTerminal
634
635
  module.exports.RunMode = nativeBinding.RunMode
635
636
  module.exports.SupportedEditor = nativeBinding.SupportedEditor
637
+ module.exports.sweepBatchOutputs = nativeBinding.sweepBatchOutputs
636
638
  module.exports.TaskStatus = nativeBinding.TaskStatus
637
639
  module.exports.testOnlyTransferFileMap = nativeBinding.testOnlyTransferFileMap
638
640
  module.exports.trackEvent = nativeBinding.trackEvent
Binary file
@@ -663,7 +663,7 @@ function stringifyPnpmLockfile(graph, rootLockFileContent, packageJson, workspac
663
663
  }
664
664
  output.packages = (0, object_sort_1.sortObjectByKeys)(output.packages);
665
665
  stripStandaloneLockfileConfig(output);
666
- return (0, pnpm_normalizer_1.stringifyToPnpmYaml)(output);
666
+ return (0, pnpm_normalizer_1.joinPnpmLockfileDocuments)((0, pnpm_normalizer_1.extractEnvLockfileDocument)(rootLockFileContent), (0, pnpm_normalizer_1.stringifyToPnpmYaml)(output));
667
667
  }
668
668
  /**
669
669
  * Removes settings a standalone, pruned lockfile cannot satisfy on its own.
@@ -15,6 +15,8 @@ export declare function loadPnpmHoistedDepsDefinition(): any;
15
15
  */
16
16
  export declare function parseAndNormalizePnpmLockfile(content: string): Lockfile;
17
17
  export declare function extractMainLockfileDocument(content: string): string;
18
+ export declare function extractEnvLockfileDocument(content: string): string | null;
19
+ export declare function joinPnpmLockfileDocuments(envDocument: string | null, mainDocument: string): string;
18
20
  /**
19
21
  * Mapping and writing logic from pnpm lockfile `write` function
20
22
  */
@@ -9,6 +9,8 @@ exports.usesLeadingDash = usesLeadingDash;
9
9
  exports.loadPnpmHoistedDepsDefinition = loadPnpmHoistedDepsDefinition;
10
10
  exports.parseAndNormalizePnpmLockfile = parseAndNormalizePnpmLockfile;
11
11
  exports.extractMainLockfileDocument = extractMainLockfileDocument;
12
+ exports.extractEnvLockfileDocument = extractEnvLockfileDocument;
13
+ exports.joinPnpmLockfileDocuments = joinPnpmLockfileDocuments;
12
14
  exports.stringifyToPnpmYaml = stringifyToPnpmYaml;
13
15
  const node_fs_1 = require("node:fs");
14
16
  const semver_1 = require("semver");
@@ -68,6 +70,26 @@ function extractMainLockfileDocument(content) {
68
70
  }
69
71
  return content.slice(separatorIndex + YAML_DOCUMENT_SEPARATOR.length);
70
72
  }
73
+ // The package-manager document (`packageManagerDependencies`) must ship with a
74
+ // pruned lockfile whenever the pruned manifest keeps `packageManager`: pnpm
75
+ // refuses a frozen install when the pin is not recorded in the lockfile.
76
+ function extractEnvLockfileDocument(content) {
77
+ content = content.replace(/\r\n/g, '\n');
78
+ if (!content.startsWith(YAML_DOCUMENT_START)) {
79
+ return null;
80
+ }
81
+ const separatorIndex = content.indexOf(YAML_DOCUMENT_SEPARATOR, YAML_DOCUMENT_START.length);
82
+ if (separatorIndex === -1) {
83
+ return null;
84
+ }
85
+ return content.slice(YAML_DOCUMENT_START.length, separatorIndex);
86
+ }
87
+ function joinPnpmLockfileDocuments(envDocument, mainDocument) {
88
+ if (envDocument === null) {
89
+ return mainDocument;
90
+ }
91
+ return `${YAML_DOCUMENT_START}${envDocument}${YAML_DOCUMENT_SEPARATOR}${mainDocument}`;
92
+ }
71
93
  // https://github.com/pnpm/pnpm/blob/50e37072f42bcca6d393a74bed29f7f0e029805d/lockfile/lockfile-file/src/write.ts#L22
72
94
  const LOCKFILE_YAML_FORMAT = {
73
95
  blankLines: true,
@@ -24,6 +24,7 @@ exports.registerTsConfigPaths = registerTsConfigPaths;
24
24
  exports.getTsNodeCompilerOptions = getTsNodeCompilerOptions;
25
25
  const path_1 = require("path");
26
26
  const fs_1 = require("fs");
27
+ const fileutils_1 = require("../../../utils/fileutils");
27
28
  const logger_1 = require("../../../utils/logger");
28
29
  const workspace_root_1 = require("../../../utils/workspace-root");
29
30
  const typescript_1 = require("./typescript");
@@ -1208,7 +1209,7 @@ function resolvePathsBaseUrl(tsconfigPath) {
1208
1209
  const absolute = (0, path_1.resolve)(queue.shift());
1209
1210
  const dir = (0, path_1.dirname)(absolute);
1210
1211
  try {
1211
- const raw = JSON.parse((0, fs_1.readFileSync)(absolute, 'utf-8'));
1212
+ const raw = (0, fileutils_1.readJsonFile)(absolute);
1212
1213
  chain.push({ dir, raw });
1213
1214
  const exts = raw.extends
1214
1215
  ? Array.isArray(raw.extends)
@@ -20,6 +20,7 @@ const installation_directory_1 = require("../../../utils/installation-directory"
20
20
  const is_sandbox_1 = require("../../../utils/is-sandbox");
21
21
  const logger_2 = require("../../../utils/logger");
22
22
  const progress_topics_1 = require("../../../utils/progress-topics");
23
+ const task_results_stub_1 = require("../task-results-stub");
23
24
  const wait_for_socket_connection_1 = require("../../../utils/wait-for-socket-connection");
24
25
  const workspace_root_1 = require("../../../utils/workspace-root");
25
26
  const resolve_plugin_1 = require("../resolve-plugin");
@@ -268,7 +269,7 @@ class IsolatedPlugin {
268
269
  if (loadResult.hasPostTasksExecution) {
269
270
  this.postTasksExecution = wrap('postTasksExecution', async (context) => {
270
271
  const result = await this.sendRequest('postTasksExecution', {
271
- context,
272
+ context: (0, task_results_stub_1.stubTerminalOutputs)(context),
272
273
  });
273
274
  if (result.success === false) {
274
275
  throw result.error;
@@ -3,7 +3,8 @@ import type { Socket } from 'net';
3
3
  import type { PluginConfiguration } from '../../../config/nx-json';
4
4
  import type { ProjectGraph } from '../../../config/project-graph';
5
5
  import type { LoadedNxPlugin } from '../loaded-nx-plugin';
6
- import type { CreateDependenciesContext, CreateMetadataContext, CreateNodesContext, PostTasksExecutionContext, PreTasksExecutionContext } from '../public-api';
6
+ import type { MaybeStubbedPostTasksExecutionContext } from '../task-results-stub';
7
+ import type { CreateDependenciesContext, CreateMetadataContext, CreateNodesContext, PreTasksExecutionContext } from '../public-api';
7
8
  import type { AllMessages, AllResults, DefineMessages, Handlers, ResultOf, WithResult } from './message-types';
8
9
  /**
9
10
  * All plugin worker message definitions in one place.
@@ -88,7 +89,7 @@ type PluginMessageDefs = DefineMessages<{
88
89
  };
89
90
  postTasksExecution: {
90
91
  payload: {
91
- context: PostTasksExecutionContext;
92
+ context: MaybeStubbedPostTasksExecutionContext;
92
93
  };
93
94
  result: {
94
95
  success: true;
@@ -42,6 +42,10 @@ if (!socketPath || !expectedPluginName || !hostWorkspaceRoot) {
42
42
  process.exit(1);
43
43
  }
44
44
  const CONNECT_TIMEOUT_MS = 30_000;
45
+ // Runs in this worker's own loop from the moment it accepts, while the host is
46
+ // loading every plugin at once and may sit in a synchronous workspace walk for
47
+ // over ten seconds. A host that has died closes the socket; 'end' covers that.
48
+ const LOAD_TIMEOUT_MS = 60_000;
45
49
  let connectErrorTimeout = setErrorTimeout(CONNECT_TIMEOUT_MS, `The plugin worker for ${expectedPluginName} is exiting as it was not connected to within ${CONNECT_TIMEOUT_MS / 1000} seconds. ` +
46
50
  'Plugin workers expect to receive a socket connection from the parent process shortly after being started. ' +
47
51
  'If you are seeing this issue, please report it to the Nx team at https://github.com/nrwl/nx/issues.');
@@ -55,7 +59,7 @@ const server = (0, net_1.createServer)((socket) => {
55
59
  // This handles cases where the host process was killed
56
60
  // after the worker connected but before the worker was
57
61
  // instructed to load the plugin.
58
- let loadErrorTimeout = setErrorTimeout(10_000, `Plugin Worker for ${expectedPluginName} is exiting as it did not receive a load message within 10 seconds of connecting. ` +
62
+ let loadErrorTimeout = setErrorTimeout(LOAD_TIMEOUT_MS, `Plugin Worker for ${expectedPluginName} is exiting as it did not receive a load message within ${LOAD_TIMEOUT_MS / 1000} seconds of connecting. ` +
59
63
  'This likely indicates that the host process was terminated before the worker could be instructed to load the plugin. ' +
60
64
  'If you are seeing this issue, please report it to the Nx team at https://github.com/nrwl/nx/issues.');
61
65
  socket.on('data', (0, consume_messages_from_socket_1.consumeMessagesFromSocket)((raw) => {
@@ -1,7 +1,8 @@
1
1
  import type { ProjectGraph } from '../../config/project-graph';
2
2
  import { type PluginConfiguration } from '../../config/nx-json';
3
3
  import type { RawProjectGraphDependency } from '../project-graph-builder';
4
- import type { CreateDependenciesContext, CreateMetadataContext, CreateNodesContext, CreateNodesResult, NxPlugin, PostTasksExecutionContext, PreTasksExecutionContext, ProjectsMetadata } from './public-api';
4
+ import type { CreateDependenciesContext, CreateMetadataContext, CreateNodesContext, CreateNodesResult, NxPlugin, PreTasksExecutionContext, ProjectsMetadata } from './public-api';
5
+ import { type MaybeStubbedPostTasksExecutionContext } from './task-results-stub';
5
6
  /**
6
7
  * NOTE: Avoid using `import type` with this class. It causes issues with
7
8
  * jest's module resolution when running tests in projects that import
@@ -17,7 +18,7 @@ export declare class LoadedNxPlugin {
17
18
  readonly createDependencies?: (context: CreateDependenciesContext) => Promise<RawProjectGraphDependency[]>;
18
19
  readonly createMetadata?: (graph: ProjectGraph, context: CreateMetadataContext) => Promise<ProjectsMetadata>;
19
20
  readonly preTasksExecution?: (context: PreTasksExecutionContext) => Promise<NodeJS.ProcessEnv>;
20
- readonly postTasksExecution?: (context: PostTasksExecutionContext) => Promise<void>;
21
+ readonly postTasksExecution?: (context: MaybeStubbedPostTasksExecutionContext) => Promise<void>;
21
22
  readonly options?: unknown;
22
23
  readonly include?: string[];
23
24
  readonly exclude?: string[];
@@ -5,6 +5,7 @@ const analytics_1 = require("../../analytics");
5
5
  const error_types_1 = require("../error-types");
6
6
  const enabled_1 = require("./isolation/enabled");
7
7
  const client_1 = require("../../daemon/client/client");
8
+ const task_results_stub_1 = require("./task-results-stub");
8
9
  /**
9
10
  * NOTE: Avoid using `import type` with this class. It causes issues with
10
11
  * jest's module resolution when running tests in projects that import
@@ -97,7 +98,10 @@ class LoadedNxPlugin {
97
98
  };
98
99
  }
99
100
  if (plugin.postTasksExecution) {
100
- this.postTasksExecution = async (context) => plugin.postTasksExecution(this.options, context);
101
+ // The single rehydration point: every transport hands its context
102
+ // straight here, so a context bound for an isolated plugin stays stubbed
103
+ // across that second hop rather than being read and re-stubbed.
104
+ this.postTasksExecution = async (context) => plugin.postTasksExecution(this.options, await (0, task_results_stub_1.rehydrateTerminalOutputs)(context));
101
105
  }
102
106
  }
103
107
  }
@@ -0,0 +1,50 @@
1
+ import type { PostTasksExecutionContext } from './public-api';
2
+ /**
3
+ * A {@link PostTasksExecutionContext} whose terminal outputs have been lifted
4
+ * out of `taskResults` and into a map of the paths holding them, so it can
5
+ * cross a process boundary.
6
+ *
7
+ * `taskResults` carries every task's full output inline, so the sender copies
8
+ * every one of those strings into the serialized payload and pushes the whole
9
+ * thing across the socket, once per boundary. The strings themselves exist
10
+ * either way: the runner puts them on each result as its task completes, and
11
+ * the receiver reads them back eagerly. The bytes are
12
+ * already on disk at `<cacheDir>/terminalOutputs/<hash>`, so transports carry
13
+ * paths and each receiver reads them back before any plugin sees the context.
14
+ *
15
+ * This is no longer a crash fix. The fallback used to be
16
+ * `v8.serialize(...).toString('binary')`, which put an oversized payload back
17
+ * through V8's maximum string length after `JSON.stringify` had already hit it,
18
+ * so both arms threw. `serialize` returns bytes now and the ceiling is gone;
19
+ * what is left is the cost of moving the payload at all.
20
+ *
21
+ * The paths live here rather than in `terminalOutput` so that field never
22
+ * holds two meanings: a stubbed result carries no `terminalOutput` at all, so
23
+ * a transport that forgets to rehydrate hands a plugin a missing value rather
24
+ * than a filename shaped exactly like real output. The map is required, so a
25
+ * stubbed context cannot typecheck without one.
26
+ */
27
+ export type StubbedPostTasksExecutionContext = PostTasksExecutionContext & {
28
+ /**
29
+ * Path to the terminal output of each stubbed task, keyed by task id. Out of
30
+ * band because a task can print anything, so no in-band marker is safe from
31
+ * a task that prints it.
32
+ */
33
+ stubbedTerminalOutputs: Record<string, string>;
34
+ };
35
+ export type MaybeStubbedPostTasksExecutionContext = PostTasksExecutionContext | StubbedPostTasksExecutionContext;
36
+ /**
37
+ * Swaps outputs out for paths ahead of a transport. Idempotent, so a context
38
+ * already stubbed for the daemon can be passed on to a plugin worker as-is.
39
+ */
40
+ export declare function stubTerminalOutputs(context: MaybeStubbedPostTasksExecutionContext): MaybeStubbedPostTasksExecutionContext;
41
+ /**
42
+ * Reads the outputs back. A no-op on a context that was never stubbed, which
43
+ * is every in-process plugin run without the daemon.
44
+ *
45
+ * The reads are issued together rather than awaited one at a time: a run has
46
+ * one file per task, they are independent, and this sits between the tasks
47
+ * finishing and the first plugin seeing the results - so serializing it would
48
+ * add up every file's latency in front of that.
49
+ */
50
+ export declare function rehydrateTerminalOutputs(context: MaybeStubbedPostTasksExecutionContext): Promise<PostTasksExecutionContext>;