@visulima/task-runner 1.0.0-alpha.6 → 1.0.0-alpha.8

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 (54) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/index.d.ts +2507 -49
  3. package/dist/index.js +9 -7
  4. package/dist/packem_shared/{TaskOrchestrator-rf45vW5c.js → TaskOrchestrator-UCMHCx8c.js} +68 -2
  5. package/dist/packem_shared/{buildForwardDependencyMap-DLPgKEto.js → buildForwardDependencyMap-0BJFMMPv.js} +1 -2
  6. package/dist/packem_shared/{computeTaskHash-DYqfrDGq.js → computeTaskHash-B5APHW7e.js} +1 -1
  7. package/dist/packem_shared/{createTaskGraph-B7nH0kY_.js → createTaskGraph-B5YrfAMx.js} +6 -2
  8. package/dist/packem_shared/{defaultTaskRunner-Cp7jCmIl.js → defaultTaskRunner-DzR0ld8F.js} +36 -4
  9. package/dist/packem_shared/expandTokensInString-C03AGAjh.js +46 -0
  10. package/dist/packem_shared/{extractPackageName-BllKetnz.js → extractPackageName-CbVNW-dr.js} +1 -2
  11. package/dist/packem_shared/getCurrentBranch-DsKPDoVj.js +153 -0
  12. package/dist/packem_shared/{parseCommands-D-IgF8Zh.js → parseCommands-CJ16ohOB.js} +7 -2
  13. package/index.js +556 -723
  14. package/package.json +14 -14
  15. package/dist/affected.d.ts +0 -82
  16. package/dist/archive.d.ts +0 -38
  17. package/dist/cache.d.ts +0 -138
  18. package/dist/chrome-trace.d.ts +0 -53
  19. package/dist/command-parser/expand-arguments.d.ts +0 -11
  20. package/dist/command-parser/expand-shortcut.d.ts +0 -15
  21. package/dist/command-parser/expand-wildcard.d.ts +0 -13
  22. package/dist/command-parser/index.d.ts +0 -18
  23. package/dist/command-parser/strip-quotes.d.ts +0 -6
  24. package/dist/concurrent-fallback.d.ts +0 -16
  25. package/dist/concurrent.d.ts +0 -23
  26. package/dist/default-task-runner.d.ts +0 -44
  27. package/dist/detect-shell.d.ts +0 -19
  28. package/dist/file-access-tracker.d.ts +0 -59
  29. package/dist/fingerprint.d.ts +0 -54
  30. package/dist/flow-controllers/index.d.ts +0 -7
  31. package/dist/flow-controllers/input-handler.d.ts +0 -44
  32. package/dist/flow-controllers/log-timings.d.ts +0 -18
  33. package/dist/flow-controllers/restart-process.d.ts +0 -21
  34. package/dist/flow-controllers/teardown.d.ts +0 -22
  35. package/dist/framework-inference.d.ts +0 -35
  36. package/dist/graph-visualizer.d.ts +0 -74
  37. package/dist/incremental-hasher.d.ts +0 -76
  38. package/dist/life-cycle.d.ts +0 -38
  39. package/dist/lockfile-hasher.d.ts +0 -73
  40. package/dist/log-reporter.d.ts +0 -34
  41. package/dist/native-binding.d.ts +0 -106
  42. package/dist/output-resolver.d.ts +0 -20
  43. package/dist/project-constraints.d.ts +0 -9
  44. package/dist/remote-cache.d.ts +0 -100
  45. package/dist/run-summary.d.ts +0 -111
  46. package/dist/task-graph-utils.d.ts +0 -39
  47. package/dist/task-graph.d.ts +0 -22
  48. package/dist/task-hasher.d.ts +0 -104
  49. package/dist/task-orchestrator.d.ts +0 -38
  50. package/dist/task-scheduler.d.ts +0 -41
  51. package/dist/terminal-buffer.d.ts +0 -29
  52. package/dist/tracked-executor.d.ts +0 -46
  53. package/dist/types.d.ts +0 -757
  54. package/dist/utils.d.ts +0 -39
package/dist/types.d.ts DELETED
@@ -1,757 +0,0 @@
1
- /**
2
- * Represents a target that a task executes against.
3
- */
4
- export interface TaskTarget {
5
- /** Optional configuration name */
6
- configuration?: string;
7
- /** The project name */
8
- project: string;
9
- /** The target name (e.g., "build", "test", "lint") */
10
- target: string;
11
- }
12
- /**
13
- * Represents a single task to be executed.
14
- */
15
- /**
16
- * Scheduling priority hint. The scheduler picks higher-priority tasks
17
- * out of the ready-queue first; ties fall through to the graph-derived
18
- * signals (dependent count, project depth).
19
- *
20
- * Use `"high"` for long-running leaves you want to kick off early
21
- * (integration tests, e2e suites) so their wall-clock overlaps with
22
- * the main build phase. Use `"low"` for work you don't mind deferring
23
- * (linters, coverage uploads) when faster tasks contend for slots.
24
- */
25
- export type TaskPriority = "high" | "low" | "normal";
26
- /**
27
- * A single entry in a task's `outputs` list.
28
- *
29
- * - `string` — a literal path *or* a glob pattern relative to the
30
- * workspace root. Prefix with `!` to exclude files the positive
31
- * patterns would otherwise include (e.g. `"!dist/cache/**"`).
32
- * - `{ auto: true }` — use whatever files the task actually wrote
33
- * during execution (resolved from the file-access tracker). Lets
34
- * authors who don't know their exact output layout cache results
35
- * without listing every path. Silently behaves as "no outputs" when
36
- * tracking isn't active for this task.
37
- */
38
- export type OutputSpec = string | {
39
- auto: true;
40
- };
41
- export interface Task {
42
- /** Whether this task is eligible for caching */
43
- cache?: boolean;
44
- /** Hash of the task inputs for caching */
45
- hash?: string;
46
- /** Detailed hash information */
47
- hashDetails?: TaskHashDetails;
48
- /** Unique identifier for the task, typically "project:target:configuration" */
49
- id: string;
50
- /**
51
- * Output patterns this task produces. Each entry is either a
52
- * literal path, a glob (`"dist/**"`), a negative glob
53
- * (`"!dist/cache/**"`), or `{ auto: true }` to pick up whatever
54
- * files the task wrote during execution.
55
- */
56
- outputs: OutputSpec[];
57
- /** Overrides/extra options passed to the task */
58
- overrides: Record<string, unknown>;
59
- /** Whether this task supports parallel execution */
60
- parallelism?: boolean;
61
- /**
62
- * Explicit scheduling priority. Outranks the scheduler's
63
- * graph-derived heuristics. Defaults to `"normal"` when absent.
64
- */
65
- priority?: TaskPriority;
66
- /** The project root directory */
67
- projectRoot?: string;
68
- /** The target this task executes */
69
- target: TaskTarget;
70
- }
71
- /**
72
- * Represents detailed hash information for a task.
73
- */
74
- export interface TaskHashDetails {
75
- /** The command hash */
76
- command: string;
77
- /** Hash of implicit dependencies */
78
- implicitDeps?: Record<string, string>;
79
- /** Hashes of input files */
80
- nodes: Record<string, string>;
81
- /** Hash of runtime values */
82
- runtime?: Record<string, string>;
83
- }
84
- /**
85
- * Represents a directed acyclic graph of tasks.
86
- */
87
- export interface TaskGraph {
88
- /** Dependencies for each task */
89
- dependencies: Record<string, string[]>;
90
- /** Top-level tasks that no other task depends on (the final outputs to run) */
91
- roots: string[];
92
- /** All tasks in the graph, keyed by task ID */
93
- tasks: Record<string, Task>;
94
- }
95
- /**
96
- * Possible states of a task after execution.
97
- */
98
- export type TaskStatus = "success" | "failure" | "skipped" | "local-cache" | "local-cache-kept-existing" | "remote-cache";
99
- /**
100
- * Result of executing a task.
101
- */
102
- export interface TaskResult {
103
- /** The exit code, if applicable */
104
- code?: number;
105
- /**
106
- * Set when auto-fingerprint tracking was attempted for this task but
107
- * returned zero workspace accesses — usually a static binary on
108
- * macOS/Windows, where the Node preload can't attach. Caching is
109
- * skipped to avoid persisting an empty fingerprint that would
110
- * produce false cache hits on every subsequent run.
111
- */
112
- emptyFingerprint?: boolean;
113
- /** The end time of the task */
114
- endTime?: number;
115
- /**
116
- * Set when the task modified one or more of its own tracked input
117
- * files during execution. Caching is skipped in this case — the
118
- * fingerprint captured before the run would mismatch the post-run
119
- * contents and produce false cache hits on subsequent runs.
120
- */
121
- selfModified?: boolean;
122
- /** The start time of the task */
123
- startTime?: number;
124
- status: TaskStatus;
125
- task: Task;
126
- /** The terminal output produced during execution */
127
- terminalOutput?: string;
128
- }
129
- /**
130
- * Map of task results, keyed by task ID.
131
- */
132
- export type TaskResults = Map<string, TaskResult>;
133
- /**
134
- * Configuration for a project in the workspace.
135
- */
136
- export interface ProjectConfiguration {
137
- /** Implicit dependencies on other projects */
138
- implicitDependencies?: string[];
139
- /**
140
- * Project layer in the dependency hierarchy. Used by
141
- * `enforceLayerRelationships` to ensure projects only depend on
142
- * projects at the same or lower layer.
143
- *
144
- * Hierarchy (lowest → highest):
145
- * `configuration < library < scaffolding < tool < automation < application`
146
- */
147
- layer?: "application" | "automation" | "configuration" | "library" | "scaffolding" | "tool";
148
- /** The project type */
149
- projectType?: "library" | "application";
150
- /** The root directory of the project, relative to workspace root */
151
- root: string;
152
- /** The source root directory */
153
- sourceRoot?: string;
154
- /** Tags for filtering */
155
- tags?: string[];
156
- /** Named targets and their configurations */
157
- targets?: Record<string, TargetConfiguration>;
158
- }
159
- /**
160
- * Configuration for a target within a project.
161
- */
162
- export interface TargetConfiguration {
163
- /** Whether this target is cacheable */
164
- cache?: boolean;
165
- /** The command to run (alternative to executor) */
166
- command?: string;
167
- /** Named configurations (e.g., "production", "development") */
168
- configurations?: Record<string, Record<string, unknown>>;
169
- /** Other targets this target depends on */
170
- dependsOn?: (string | TargetDependencyConfig)[];
171
- /** The executor/command to run */
172
- executor?: string;
173
- /** Input patterns for cache invalidation */
174
- inputs?: (string | InputDefinition)[];
175
- /** Options passed to the executor */
176
- options?: Record<string, unknown>;
177
- /** Output patterns produced by this target */
178
- outputs?: string[];
179
- /** Whether this target supports parallel execution */
180
- parallelism?: boolean;
181
- }
182
- /**
183
- * Defines a dependency on another target.
184
- */
185
- export interface TargetDependencyConfig {
186
- /** Whether this is a dependency on the same project */
187
- dependencies?: boolean;
188
- /** Params to pass through */
189
- params?: "forward" | "ignore";
190
- /** The project name (if different from the current project) */
191
- projects?: string | string[];
192
- /** The target name */
193
- target: string;
194
- }
195
- /**
196
- * Defines an input for cache invalidation.
197
- */
198
- export type InputDefinition = FileSetInput | RuntimeInput | EnvironmentInput | ExternalDependencyInput;
199
- /**
200
- * Controls how a glob pattern is anchored.
201
- * - "package" (default): pattern is resolved relative to the project root
202
- * - "workspace": pattern is resolved relative to the workspace root
203
- */
204
- export type FileSetBase = "package" | "workspace";
205
- /**
206
- * An input based on file patterns.
207
- *
208
- * `fileset` may be a bare glob string (package-root relative) or an object
209
- * form `{ pattern, base }` to anchor explicitly to the workspace root.
210
- * Negation (`!` prefix) works in both forms.
211
- */
212
- export interface FileSetInput {
213
- fileset: FileSetPattern | string;
214
- }
215
- /**
216
- * Object form of a fileset pattern, for anchoring to the workspace root.
217
- */
218
- export interface FileSetPattern {
219
- /** Anchor for the pattern. */
220
- base: FileSetBase;
221
- /** Glob pattern (may start with `!` for negation). */
222
- pattern: string;
223
- }
224
- /**
225
- * An input based on a runtime command.
226
- */
227
- export interface RuntimeInput {
228
- runtime: string;
229
- }
230
- /**
231
- * An input based on environment variables.
232
- */
233
- export interface EnvironmentInput {
234
- env: string;
235
- }
236
- /**
237
- * An input based on external dependency versions.
238
- */
239
- export interface ExternalDependencyInput {
240
- externalDependencies: string[];
241
- }
242
- /**
243
- * Defines tag-based dependency rules.
244
- * Each key is a tag name. The value is the list of tags that a dependency
245
- * must have at least one of, when the source project has that tag.
246
- *
247
- * Example: `{ "frontend": ["shared", "frontend"] }` means a project tagged
248
- * "frontend" can only depend on projects tagged "shared" or "frontend".
249
- */
250
- export type TagRelationships = Record<string, string[]>;
251
- /**
252
- * Defines project-type-based dependency rules.
253
- */
254
- export interface TypeBoundaries {
255
- /**
256
- * Custom rules mapping project types to allowed dependency types.
257
- * Example: `{ "application": ["library"] }` means applications can only
258
- * depend on libraries.
259
- */
260
- allowedDependencyTypes?: Record<string, string[]>;
261
- /**
262
- * When true, no project may depend on an "application" type project.
263
- * Applications are typically deployment targets, not libraries.
264
- * @default true
265
- */
266
- enforceApplicationBoundary?: boolean;
267
- }
268
- /**
269
- * Rules based on the dependency kind (dependencies vs devDependencies vs peerDependencies).
270
- */
271
- export interface DependencyKindRules {
272
- /**
273
- * When true, a "library" project must not have workspace-internal devDependencies
274
- * on other libraries that are also in its production dependencies.
275
- * Prevents publishing libraries that silently rely on dev-only workspace packages.
276
- * @default false
277
- */
278
- noDevDependencyOnProductionDep?: boolean;
279
- /**
280
- * When true, production `dependencies` must not point to "application" type projects.
281
- * devDependencies on applications are allowed (e.g., for testing).
282
- * @default false
283
- */
284
- noProductionDependencyOnApplication?: boolean;
285
- }
286
- /**
287
- * Configuration for project constraint enforcement.
288
- */
289
- export interface ConstraintsConfig {
290
- /** Rules based on the dependency kind (static vs devDependency vs peerDependency) */
291
- dependencyKindRules?: DependencyKindRules;
292
- /**
293
- * When true, projects can only depend on projects at the same or
294
- * lower layer in the hierarchy:
295
- *
296
- * configuration < library < scaffolding < tool < automation < application
297
- *
298
- * Projects without an explicit `layer` are unconstrained.
299
- * @default false
300
- */
301
- enforceLayerRelationships?: boolean;
302
- /** Tag-based dependency rules */
303
- tagRelationships?: TagRelationships;
304
- /** Project-type-based dependency rules */
305
- typeBoundaries?: TypeBoundaries;
306
- }
307
- /**
308
- * A single constraint violation detected in the project graph.
309
- */
310
- export interface ConstraintViolation {
311
- /** The project being depended on */
312
- dependencyProject: string;
313
- /** Human-readable description of the violation */
314
- message: string;
315
- /** The type of rule that was violated */
316
- rule: "dependency-kind" | "layer-relationship" | "tag-relationship" | "type-boundary";
317
- /** The project that has the invalid dependency */
318
- sourceProject: string;
319
- }
320
- /**
321
- * Controls how far to traverse the dependency graph in a given direction.
322
- * - "none": Don't traverse — only directly changed projects are included.
323
- * - "direct": Include only immediate neighbors (one hop).
324
- * - "deep": Include all transitive neighbors (full chain).
325
- */
326
- export type AffectedScope = "deep" | "direct" | "none";
327
- /**
328
- * Workspace configuration containing all project configurations.
329
- */
330
- export interface WorkspaceConfiguration {
331
- /** All projects in the workspace, keyed by project name */
332
- projects: Record<string, ProjectConfiguration>;
333
- }
334
- /**
335
- * The kind of dependency relationship between projects.
336
- * - "static": Production dependency (from `dependencies` in package.json)
337
- * - "dynamic": Dynamically resolved dependency (e.g., lazy imports)
338
- * - "implicit": Declared via `implicitDependencies` in project config
339
- * - "devDependency": Development-only dependency (from `devDependencies`)
340
- * - "peerDependency": Peer dependency (from `peerDependencies`)
341
- */
342
- export type DependencyType = "devDependency" | "dynamic" | "implicit" | "peerDependency" | "static";
343
- /**
344
- * A dependency relationship in the project graph.
345
- */
346
- export interface ProjectGraphDependency {
347
- /** The source project */
348
- source: string;
349
- /** The target project */
350
- target: string;
351
- /** The type of dependency */
352
- type: DependencyType;
353
- }
354
- /**
355
- * A node in the project graph.
356
- */
357
- export interface ProjectGraphProjectNode {
358
- /** The project configuration */
359
- data: ProjectConfiguration;
360
- /** The project name */
361
- name: string;
362
- /** The type of project */
363
- type: "library" | "application";
364
- }
365
- /**
366
- * The project graph represents the dependency relationships between projects.
367
- */
368
- export interface ProjectGraph {
369
- /** All dependency relationships */
370
- dependencies: Record<string, ProjectGraphDependency[]>;
371
- /** All project nodes, keyed by project name */
372
- nodes: Record<string, ProjectGraphProjectNode>;
373
- }
374
- /**
375
- * Named input definitions that can be referenced by name.
376
- */
377
- export interface NamedInputs {
378
- [name: string]: (string | InputDefinition)[];
379
- }
380
- /**
381
- * Configuration for the task runner.
382
- */
383
- export interface TaskRunnerOptions {
384
- /**
385
- * Scan each task's resolved command text for `$VAR`/`${VAR}`
386
- * references and automatically fingerprint those env vars. Catches
387
- * tasks like `curl ${VERCEL_URL}/api` where the user forgot to
388
- * declare the reference in `envVars`/`globalEnv`.
389
- * @default false
390
- */
391
- autoEnvVars?: boolean;
392
- /**
393
- * Enable auto-fingerprinting mode (Vite Task-style).
394
- * When enabled, the task runner automatically tracks which files
395
- * a task accesses during execution and uses that for cache invalidation
396
- * instead of requiring manual input configuration.
397
- *
398
- * Falls back to explicit inputs (Nx-style) when file tracking
399
- * is not supported on the current platform.
400
- * @default false
401
- */
402
- autoFingerprint?: boolean;
403
- /**
404
- * Whether to show cache miss diagnostics (why a cache miss occurred).
405
- * @default false
406
- */
407
- cacheDiagnostics?: boolean;
408
- /** Directory for storing cache */
409
- cacheDirectory?: string;
410
- /**
411
- * Dry-run mode: compute hashes and check cache but don't execute tasks.
412
- * Useful for debugging cache hits/misses.
413
- * @default false
414
- */
415
- dryRun?: boolean;
416
- /** Custom environment variables to include in hash */
417
- envVars?: string[];
418
- /**
419
- * Environment variable patterns to include in auto-fingerprint.
420
- * Supports wildcard patterns like "VITE_*".
421
- * Only used when autoFingerprint is enabled.
422
- */
423
- fingerprintEnvPatterns?: string[];
424
- /**
425
- * Enable framework environment variable inference.
426
- * When true, automatically detects common frontend frameworks and includes
427
- * their public env var prefixes in the task hash:
428
- * - Next.js: NEXT_PUBLIC_*
429
- * - Vite: VITE_*
430
- * - Create React App: REACT_APP_*
431
- * - Gatsby: GATSBY_*
432
- * - Nuxt: NUXT_PUBLIC_*
433
- * - Expo: EXPO_PUBLIC_*
434
- *
435
- * Matches Turborepo's framework inference behavior.
436
- * @default false
437
- */
438
- frameworkInference?: boolean;
439
- /**
440
- * Global environment variables that invalidate ALL task hashes.
441
- * Matches Turborepo's `globalEnv`.
442
- */
443
- globalEnv?: string[];
444
- /**
445
- * Global input files that invalidate ALL task hashes when changed.
446
- * These are workspace-root-relative paths.
447
- *
448
- * Default: ["package-lock.json", "pnpm-lock.yaml", "yarn.lock",
449
- * "tsconfig.base.json", ".env"]
450
- *
451
- * When any global input changes, every task's hash changes,
452
- * forcing a full rebuild. This matches Turborepo's `globalDependencies`.
453
- */
454
- globalInputs?: string[];
455
- /**
456
- * When `true`, file hashes are cached in a persistent mtime+size
457
- * indexed snapshot under `node_modules/.cache/task-runner/`. On
458
- * subsequent runs, unchanged files skip content re-reads — cuts
459
- * cold-cache fingerprint time dramatically on large workspaces.
460
- *
461
- * Changed or new files still get full content hashing. Safe to
462
- * leave on by default; overhead when nothing matches is a single
463
- * `stat` call per file.
464
- * @default false
465
- */
466
- incrementalFileHashing?: boolean;
467
- /** Maximum age of cache entries in milliseconds */
468
- maxCacheAge?: number;
469
- /** Maximum cache size (e.g., "1GB") */
470
- maxCacheSize?: string;
471
- /** Named inputs for cache invalidation */
472
- namedInputs?: NamedInputs;
473
- /**
474
- * When `true`, the cache directory is partitioned by a hash of
475
- * the resolved `globalEnv` values. Changing a globalEnv var moves
476
- * cache writes into a new namespace; rolling it back reuses the
477
- * old namespace and its hits. Without this option, any globalEnv
478
- * change silently busts every cached entry.
479
- *
480
- * Keep disabled when globalEnv is stable across runs — the extra
481
- * path depth offers no value, and misconfigured namespaces can
482
- * hide stale hits.
483
- * @default false
484
- */
485
- namespaceByGlobalEnv?: boolean;
486
- /** Maximum number of parallel tasks */
487
- parallel?: number | boolean;
488
- /**
489
- * Remote cache configuration.
490
- * When configured, the task runner will check the remote cache
491
- * after a local cache miss, and upload results after execution.
492
- */
493
- remoteCache?: {
494
- /**
495
- * Called when a fire-and-forget upload fails.
496
- * Since uploads are non-blocking, errors are silently swallowed by default.
497
- * Provide this callback to log or report upload failures.
498
- */
499
- onUploadError?: (hash: string, error: unknown) => void;
500
- /** Enable remote reads (default: true) */
501
- read?: boolean;
502
- /** Team/namespace for cache isolation */
503
- teamId?: string;
504
- /** Authentication token */
505
- token?: string;
506
- /** Remote cache server URL */
507
- url: string;
508
- /** Enable remote writes (default: true) */
509
- write?: boolean;
510
- };
511
- /** Whether to skip cache reads */
512
- skipNxCache?: boolean;
513
- /**
514
- * Enable smart lockfile hashing.
515
- * Instead of hashing the entire lockfile (which busts ALL caches),
516
- * only hash the resolved versions of each package's actual dependencies.
517
- * This matches Turborepo's smart lockfile hashing behavior.
518
- * @default false
519
- */
520
- smartLockfileHashing?: boolean;
521
- /**
522
- * Generate a detailed JSON run summary after execution.
523
- * When true, writes a summary file to `.task-runner/runs/` containing
524
- * all task inputs, outputs, hashes, timings, and cache status.
525
- *
526
- * Useful for debugging cache misses and comparing runs.
527
- * Matches Turborepo's `--summarize` flag.
528
- * @default false
529
- */
530
- summarize?: boolean;
531
- /** Target-specific default configurations */
532
- targetDefaults?: Record<string, Partial<TargetConfiguration>>;
533
- /**
534
- * Environment variables that should be passed to tasks but NOT
535
- * included in the cache fingerprint. Useful for CI-specific vars.
536
- * Only used when autoFingerprint is enabled.
537
- */
538
- untrackedEnvVars?: string[];
539
- }
540
- /**
541
- * Options for executing a task.
542
- */
543
- export interface TaskExecutionOptions {
544
- /** Whether to capture output */
545
- captureOutput?: boolean;
546
- /** The working directory */
547
- cwd?: string;
548
- /** Environment variables */
549
- env?: Record<string, string>;
550
- /** Stream output as it arrives */
551
- streamOutput?: boolean;
552
- }
553
- /**
554
- * A task executor function.
555
- */
556
- export type TaskExecutor = (task: Task, options: TaskExecutionOptions) => Promise<{
557
- code: number;
558
- terminalOutput: string;
559
- }>;
560
- /**
561
- * The function type for a task runner.
562
- */
563
- export type TasksRunner = (tasks: Task[], options: TaskRunnerOptions, context: TaskRunnerContext) => Promise<TaskResults>;
564
- /**
565
- * Context provided to the task runner.
566
- */
567
- export interface TaskRunnerContext {
568
- /** Lifecycle hooks */
569
- lifeCycle: LifeCycleInterface;
570
- /** The project graph */
571
- projectGraph: ProjectGraph;
572
- /** The task executor */
573
- taskExecutor: TaskExecutor;
574
- /** The task graph */
575
- taskGraph: TaskGraph;
576
- /** The workspace root directory */
577
- workspaceRoot: string;
578
- }
579
- /**
580
- * Input for a concurrent command -- either a string or a config object.
581
- */
582
- export type ConcurrentCommandInput = string | {
583
- command: string;
584
- cwd?: string;
585
- env?: Record<string, string>;
586
- name?: string;
587
- /** Initial PTY dimensions (only used when stdin is "pty"). */
588
- ptySize?: {
589
- cols: number;
590
- rows: number;
591
- };
592
- stdin?: "inherit" | "null" | "pipe" | "pty";
593
- };
594
- /**
595
- * Configuration for a single command to run concurrently.
596
- */
597
- export interface ConcurrentCommandConfig {
598
- /** The command string to execute (passed to shell). */
599
- command: string;
600
- /** Working directory for the command. */
601
- cwd?: string;
602
- /** Additional environment variables merged with process env. */
603
- env?: Record<string, string>;
604
- /** Human-readable name for this command (used in prefixes/logs). */
605
- name?: string;
606
- /**
607
- * Initial PTY dimensions. Only used when stdin is "pty".
608
- * Defaults to 80x24 if not specified.
609
- */
610
- ptySize?: {
611
- cols: number;
612
- rows: number;
613
- };
614
- /** Whether to use shell execution (default: true). */
615
- shell?: boolean;
616
- /**
617
- * Stdin mode for the child process.
618
- * - "null" (default): stdin closed, child cannot read input
619
- * - "pipe": stdin is piped, can be written to programmatically
620
- * - "inherit": child inherits parent's stdin (for interactive commands like vite dev)
621
- * - "pty": child runs inside a pseudo-terminal (isatty() returns true, enables interactive prompts)
622
- */
623
- stdin?: "inherit" | "null" | "pipe" | "pty";
624
- }
625
- /**
626
- * Options controlling the concurrent runner behavior.
627
- */
628
- export interface ConcurrentRunnerOptions {
629
- /** Conditions under which to kill other processes: "success", "failure". */
630
- killOthers?: ("failure" | "success")[];
631
- /** Signal to send when killing processes (default: "SIGTERM"). */
632
- killSignal?: string;
633
- /** Milliseconds to wait after kill signal before sending SIGKILL (default: 5000). */
634
- killTimeout?: number;
635
- /** Maximum number of processes to run simultaneously. 0 = unlimited. */
636
- maxProcesses?: number;
637
- /** Callback for real-time process events. */
638
- onEvent?: (event: ProcessEvent) => void;
639
- /** Restart options for failed commands. */
640
- restart?: {
641
- /** Delay between restarts in ms. "exponential" for 2^attempt * 1000ms. */
642
- delay?: number | "exponential";
643
- /** Maximum restart attempts per command. 0 = no restarts. -1 = infinite. */
644
- tries: number;
645
- };
646
- /**
647
- * Custom shell path for command execution.
648
- * Overrides the platform default (/bin/sh on Unix, cmd.exe on Windows).
649
- * Automatically detected from npm's `script-shell` config if not set.
650
- */
651
- shellPath?: string;
652
- /** Success condition: "first", "last", "all", or "command-&lt;name|index>". */
653
- successCondition?: string;
654
- /** Commands to run sequentially after all processes complete. */
655
- teardown?: string[];
656
- /** Working directory for teardown commands. */
657
- teardownCwd?: string;
658
- /** Print a timing summary table after completion. Default: false. */
659
- timings?: boolean;
660
- }
661
- /**
662
- * An event emitted during concurrent execution.
663
- */
664
- export interface ProcessEvent {
665
- /** Command name (for close events). */
666
- commandName?: string;
667
- /** Duration in milliseconds (for close events). */
668
- durationMs?: number;
669
- /** Exit code (for close events). */
670
- exitCode?: number;
671
- /** Index of the command that produced this event. */
672
- index: number;
673
- /** Kill the child process/PTY. Only present on "started" events. */
674
- kill?: (signal?: string) => void;
675
- /** Whether the process was killed (for close events). */
676
- killed?: boolean;
677
- /** Event type: "stdout", "stderr", "close", "error", "started". */
678
- kind: "close" | "error" | "started" | "stderr" | "stdout";
679
- /** Error message (for error events). */
680
- message?: string;
681
- /** Resize the child's PTY. Only present on "started" events with stdin "pty". */
682
- resize?: (cols: number, rows: number) => void;
683
- /** Text content (for stdout/stderr events). */
684
- text?: string;
685
- /** Write data to the child's stdin (pipe) or PTY. Only present on "started" events. */
686
- write?: (data: string) => void;
687
- }
688
- /**
689
- * Result of a close event for a single command.
690
- */
691
- export interface ConcurrentCloseEvent {
692
- /** The command string that was executed. */
693
- command: string;
694
- /** Duration in milliseconds. */
695
- durationMs: number;
696
- /** Exit code. -1 if killed by signal. */
697
- exitCode: number;
698
- /** Index of the command. */
699
- index: number;
700
- /** Whether the process was forcefully killed. */
701
- killed: boolean;
702
- /** The command name (if provided). */
703
- name?: string;
704
- }
705
- /**
706
- * Overall result of a concurrent run.
707
- */
708
- export interface ConcurrentRunResult {
709
- /** Close events for all commands, in completion order. */
710
- closeEvents: ConcurrentCloseEvent[];
711
- /** Whether the run succeeded according to the success condition. */
712
- success: boolean;
713
- }
714
- /**
715
- * Interface for lifecycle event handlers.
716
- */
717
- export interface LifeCycleInterface {
718
- endCommand?: () => void;
719
- endTasks?: (taskResults: TaskResult[]) => void;
720
- /**
721
- * Called when a running task emits data on stderr, in the order the
722
- * data arrives. Executors that support streaming output (`vis run`'s
723
- * concurrent executor) forward chunks here verbatim. Executors that
724
- * only buffer full output (e.g. the simple test executor) skip this
725
- * hook — rely on `printTaskTerminalOutput` for the final dump.
726
- *
727
- * Handlers should be non-blocking; the orchestrator doesn't await.
728
- */
729
- onTaskStderr?: (task: Task, chunk: string) => void;
730
- /**
731
- * Called when a running task emits data on stdout, in the order the
732
- * data arrives. See {@link LifeCycleInterface.onTaskStderr} for
733
- * semantics — same contract, different stream.
734
- */
735
- onTaskStdout?: (task: Task, chunk: string) => void;
736
- /** Called when a cache miss occurs with diagnostic information */
737
- printCacheMiss?: (task: Task, reasons: string) => void;
738
- /**
739
- * Called when caching was skipped because auto-fingerprint tracking
740
- * came back empty — a signal that the tracker (strace or Node
741
- * preload) couldn't observe the task's file access, typically
742
- * because it's a static binary on a platform without strace.
743
- * `reason` is a short human-readable diagnostic.
744
- */
745
- printEmptyFingerprintWarning?: (task: Task, reason: string) => void;
746
- /**
747
- * Called when caching is skipped because the task modified one or
748
- * more of its own tracked inputs. `modifiedFiles` lists the
749
- * workspace-relative paths that changed between pre- and
750
- * post-execution hashes.
751
- */
752
- printSelfModifyingSkip?: (task: Task, modifiedFiles: string[]) => void;
753
- printTaskTerminalOutput?: (task: Task, status: TaskStatus, terminalOutput: string) => void;
754
- scheduleTask?: (task: Task) => void;
755
- startCommand?: () => void;
756
- startTasks?: (tasks: Task[]) => void;
757
- }