@visulima/task-runner 1.0.0-alpha.3 → 1.0.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +193 -51
- package/dist/affected.d.ts +37 -3
- package/dist/cache.d.ts +8 -1
- package/dist/command-parser/expand-arguments.d.ts +11 -0
- package/dist/command-parser/expand-shortcut.d.ts +15 -0
- package/dist/command-parser/expand-wildcard.d.ts +13 -0
- package/dist/command-parser/index.d.ts +18 -0
- package/dist/command-parser/strip-quotes.d.ts +6 -0
- package/dist/concurrent-fallback.d.ts +16 -0
- package/dist/concurrent.d.ts +23 -0
- package/dist/detect-shell.d.ts +19 -0
- package/dist/flow-controllers/index.d.ts +7 -0
- package/dist/flow-controllers/input-handler.d.ts +44 -0
- package/dist/flow-controllers/log-timings.d.ts +18 -0
- package/dist/flow-controllers/restart-process.d.ts +21 -0
- package/dist/flow-controllers/teardown.d.ts +22 -0
- package/dist/index.d.ts +14 -4
- package/dist/index.js +26 -12
- package/dist/native-binding.d.ts +44 -2
- package/dist/packem_shared/{Cache-IYpTYVUC.js → Cache-iAjRMV2d.js} +5 -5
- package/dist/packem_shared/{FingerprintManager-D6Y0erg-.js → FingerprintManager-Cu-ta9ee.js} +0 -1
- package/dist/packem_shared/{IncrementalFileHasher-Ds3J6dgb.js → IncrementalFileHasher-Cm_kJY5V.js} +1 -1
- package/dist/packem_shared/{TaskOrchestrator-BvYs3ONw.js → TaskOrchestrator-lLn-PH1m.js} +2 -5
- package/dist/packem_shared/TerminalBuffer-CnPyFgPB.js +266 -0
- package/dist/packem_shared/{filterAffectedTasks-I-18zPg6.js → buildForwardDependencyMap-0BJFMMPv.js} +61 -21
- package/dist/packem_shared/{computeTaskHash-BoCnnvIJ.js → computeTaskHash-B2SVZqgp.js} +1 -2
- package/dist/packem_shared/createInputHandler-DTfePcTG.js +37 -0
- package/dist/packem_shared/{defaultTaskRunner-CrW4v5Ye.js → defaultTaskRunner-BdFTifsh.js} +6 -7
- package/dist/packem_shared/detectScriptShell-CR-xXKA4.js +53 -0
- package/dist/packem_shared/enforceProjectConstraints-C5Jp_C3u.js +111 -0
- package/dist/packem_shared/expandArguments-0AwD2BIA.js +26 -0
- package/dist/packem_shared/expandShortcut-BVG05ee4.js +23 -0
- package/dist/packem_shared/expandWildcard-B0xN_knq.js +107 -0
- package/dist/packem_shared/{findCycle-DF4_BRdO.js → findCycle-DefgNYhg.js} +1 -1
- package/dist/packem_shared/formatTimingTable-3qtCM552.js +46 -0
- package/dist/packem_shared/isNativeAvailable-BpD28A6Z.js +44 -0
- package/dist/packem_shared/parseCommands-D-IgF8Zh.js +26 -0
- package/dist/packem_shared/{TaskScheduler-CJilHDta.js → parsePartition-C4-P5RjK.js} +44 -1
- package/dist/packem_shared/{projectGraphToDot-VdTjHcVp.js → projectGraphToDot-C8uYeaPo.js} +20 -3
- package/dist/packem_shared/runConcurrentFallback-CGHz_f-Q.js +371 -0
- package/dist/packem_shared/runConcurrently-qrkWyzXW.js +67 -0
- package/dist/packem_shared/runTeardown-BAezH79J.js +49 -0
- package/dist/packem_shared/stripQuotes-Cey-zwFf.js +9 -0
- package/dist/packem_shared/withRestart-BREjRJa4.js +49 -0
- package/dist/project-constraints.d.ts +9 -0
- package/dist/task-scheduler.d.ts +23 -0
- package/dist/terminal-buffer.d.ts +29 -0
- package/dist/types.d.ts +239 -1
- package/index.js +769 -0
- package/package.json +14 -13
- package/binding.js +0 -204
- package/dist/packem_shared/isNativeAvailable-BWhnZ4ES.js +0 -19
- package/dist/packem_shared/{RemoteCache-BDqrnDEi.js → RemoteCache-BFceSe4a.js} +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,61 @@
|
|
|
1
|
+
## @visulima/task-runner [1.0.0-alpha.5](https://github.com/visulima/visulima/compare/@visulima/task-runner@1.0.0-alpha.4...@visulima/task-runner@1.0.0-alpha.5) (2026-04-15)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* Add comprehensive workspace configuration and command infrastructure ([#609](https://github.com/visulima/visulima/issues/609)) ([f4347bf](https://github.com/visulima/visulima/commit/f4347bfdcdd1b228cd9d842a927e446aaf23f035))
|
|
6
|
+
* **vis:** add cache command for task runner cache ([#607](https://github.com/visulima/visulima/issues/607)) ([6752769](https://github.com/visulima/visulima/commit/67527692562b3dd9c03bb6a67c084ff1e694a560))
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **tooling:** resolve eslint and formatting issues ([399d292](https://github.com/visulima/visulima/commit/399d29282be5b29bb26b4e5b24d45e2a6cdeeca3))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Dependencies
|
|
14
|
+
|
|
15
|
+
* **@visulima/humanizer:** upgraded to 3.0.0-alpha.10
|
|
16
|
+
* **@visulima/path:** upgraded to 3.0.0-alpha.9
|
|
17
|
+
|
|
18
|
+
## @visulima/task-runner [1.0.0-alpha.4](https://github.com/visulima/visulima/compare/@visulima/task-runner@1.0.0-alpha.3...@visulima/task-runner@1.0.0-alpha.4) (2026-04-08)
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* Add native Rust bindings for package manager operations ([#596](https://github.com/visulima/visulima/issues/596)) ([2ec22d0](https://github.com/visulima/visulima/commit/2ec22d023eade3fed67fb811696fbd8f7b52569d))
|
|
23
|
+
* **task-runner, vis:** project constraints, CI partitioning, affected scopes ([29295e9](https://github.com/visulima/visulima/commit/29295e989ecdfe2019469d1917a6c90a92e17bcf))
|
|
24
|
+
* **task-runner:** add concurrent process runner with Rust NAPI bindings ([c4f5d93](https://github.com/visulima/visulima/commit/c4f5d930e81a5eb641ceb3ab925c3b10a885bb6a))
|
|
25
|
+
* **vis:** expand devcontainer command with templates, validation, and config properties ([807e730](https://github.com/visulima/visulima/commit/807e730a43f0ea644d016b4f5506706972d2ff41))
|
|
26
|
+
* **vis:** group CLI commands into logical categories for help output ([0a4cac8](https://github.com/visulima/visulima/commit/0a4cac859c8edf7aacdacca7b9a03219967d525a))
|
|
27
|
+
* **vis:** replace inline TUI with full-screen Nx-style interactive task runner ([1409aad](https://github.com/visulima/visulima/commit/1409aad879c713051bba12298a3feb1d5ba852f2))
|
|
28
|
+
|
|
29
|
+
### Bug Fixes
|
|
30
|
+
|
|
31
|
+
* **ci:** make native-binding tests work with and without compiled binary ([9a40fb4](https://github.com/visulima/visulima/commit/9a40fb40d5cba9fcd2e0176eea8b7bf8d9792c7d))
|
|
32
|
+
* **task-runner,tui:** guard null native events and increase CI test timeout ([e76a791](https://github.com/visulima/visulima/commit/e76a791d90043537e08be0545f706e35acaa555d))
|
|
33
|
+
* **task-runner:** deno.json support, Windows Job Objects, docs, and review fixes ([4fb27f0](https://github.com/visulima/visulima/commit/4fb27f081b4b50b41dbb86b5b1a962b63f7a6df3))
|
|
34
|
+
* **task-runner:** fix Windows cross-compilation by upgrading windows-sys to 0.61 ([b56b95e](https://github.com/visulima/visulima/commit/b56b95e2a39ca972398859e6eb87e528f4463d97))
|
|
35
|
+
* **task-runner:** resolve eslint errors ([f0a21a6](https://github.com/visulima/visulima/commit/f0a21a689bc9e1d8b091a513e21cb11b77103ba4))
|
|
36
|
+
* **task-runner:** use JS fallback for onEvent streaming, fix StaticRender ref ([1a7165c](https://github.com/visulima/visulima/commit/1a7165cd9eb71472895cd08682983fa25703dc93))
|
|
37
|
+
* **tsconfig:** add node types and fix implicit any parameter ([1744d82](https://github.com/visulima/visulima/commit/1744d82a07fca03f2e6ff660b918e9b2623acf69))
|
|
38
|
+
|
|
39
|
+
### Miscellaneous Chores
|
|
40
|
+
|
|
41
|
+
* added og images ([02d9d1e](https://github.com/visulima/visulima/commit/02d9d1e47be3ce75679ea89e857dc4e4bfe4946b))
|
|
42
|
+
* **task-runner:** add tsconfig.eslint.json for type-aware linting ([83e0bf2](https://github.com/visulima/visulima/commit/83e0bf23511a169b801f6edf652a8be7ee968c24))
|
|
43
|
+
* **task-runner:** apply prettier formatting ([521afc2](https://github.com/visulima/visulima/commit/521afc22d94a2626c7246062cecfc0627f929ee4))
|
|
44
|
+
* **task-runner:** expand inline if-return to block syntax ([0f48a96](https://github.com/visulima/visulima/commit/0f48a96ed11d7339c62f3f147c7b2c8fcc605b03))
|
|
45
|
+
* **task-runner:** migrate .prettierrc.cjs to prettier.config.js ([cd1c045](https://github.com/visulima/visulima/commit/cd1c045e133f685a274924034ec70cf374edd5ba))
|
|
46
|
+
|
|
47
|
+
### Build System
|
|
48
|
+
|
|
49
|
+
* regenerate NAPI-RS bindings as ESM ([f202caf](https://github.com/visulima/visulima/commit/f202caf3dc383a2ec24815c4935d8d68c29f33d0))
|
|
50
|
+
* switch NAPI-RS native builds to ESM output ([3d7cd61](https://github.com/visulima/visulima/commit/3d7cd615ad830392005915735c11771e0247ef3f))
|
|
51
|
+
* **task-runner:** move publish-native-addons to shared scripts/ ([73b5482](https://github.com/visulima/visulima/commit/73b5482e1ca0707aa8f191429deffbd7324a632d))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
### Dependencies
|
|
55
|
+
|
|
56
|
+
* **@visulima/humanizer:** upgraded to 3.0.0-alpha.9
|
|
57
|
+
* **@visulima/path:** upgraded to 3.0.0-alpha.8
|
|
58
|
+
|
|
1
59
|
## @visulima/task-runner [1.0.0-alpha.3](https://github.com/visulima/visulima/compare/@visulima/task-runner@1.0.0-alpha.2...@visulima/task-runner@1.0.0-alpha.3) (2026-03-26)
|
|
2
60
|
|
|
3
61
|
### Features
|
package/README.md
CHANGED
|
@@ -27,11 +27,17 @@
|
|
|
27
27
|
|
|
28
28
|
## Features
|
|
29
29
|
|
|
30
|
+
- **Concurrent process runner**: Run multiple commands in parallel with native Rust performance (NAPI bindings) and JS fallback
|
|
31
|
+
- **Process tree management**: Proper cleanup via setsid/killpg (Unix) and Job Objects (Windows)
|
|
32
|
+
- **Command parser pipeline**: `npm:build` shortcuts, `npm run watch-*` wildcard expansion, `{1}` argument placeholders
|
|
33
|
+
- **Flow controllers**: Restart with backoff, stdin routing, timing summaries, teardown commands
|
|
34
|
+
- **npm script-shell support**: Honors `npm config set script-shell` for custom shells (Git Bash, etc.)
|
|
35
|
+
- **Long-running process support**: Configurable stdin mode (null/pipe/inherit), bounded output buffers
|
|
30
36
|
- **Two caching modes**: Nx-style explicit inputs or Vite Task-style auto-fingerprinting
|
|
31
37
|
- **Smart lockfile hashing**: Only hashes resolved versions relevant to each package (like Turborepo)
|
|
32
38
|
- **Framework env inference**: Auto-detects Next.js, Vite, CRA, Gatsby, Nuxt, and more
|
|
33
39
|
- **Remote caching**: Turborepo-compatible HTTP cache protocol
|
|
34
|
-
- **Native Rust addon**:
|
|
40
|
+
- **Native Rust addon**: Parallel file hashing (xxHash), concurrent process management via tokio
|
|
35
41
|
- **Dependency-aware scheduling**: Topological task ordering with priority-based batching
|
|
36
42
|
- **Incremental file hashing**: mtime-based change detection for near-instant cache checks
|
|
37
43
|
- **Affected detection**: Git diff-based filtering to only run tasks for changed packages
|
|
@@ -61,32 +67,144 @@ pnpm add @visulima/task-runner
|
|
|
61
67
|
```typescript
|
|
62
68
|
import { defaultTaskRunner } from "@visulima/task-runner";
|
|
63
69
|
|
|
64
|
-
const results = await defaultTaskRunner(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
const results = await defaultTaskRunner(
|
|
71
|
+
tasks,
|
|
72
|
+
{
|
|
73
|
+
// Nx-style: explicit inputs
|
|
74
|
+
namedInputs: {
|
|
75
|
+
production: ["{projectRoot}/src/**/*"],
|
|
76
|
+
},
|
|
77
|
+
globalInputs: ["pnpm-lock.yaml", "tsconfig.base.json"],
|
|
78
|
+
globalEnv: ["NODE_ENV"],
|
|
79
|
+
|
|
80
|
+
// Or: auto-fingerprinting (Vite Task-style)
|
|
81
|
+
// autoFingerprint: true,
|
|
82
|
+
|
|
83
|
+
// Smart lockfile hashing (only bust cache for affected packages)
|
|
84
|
+
smartLockfileHashing: true,
|
|
85
|
+
|
|
86
|
+
// Auto-detect framework env vars (NEXT_PUBLIC_*, VITE_*, etc.)
|
|
87
|
+
frameworkInference: true,
|
|
88
|
+
|
|
89
|
+
// Remote cache (Turborepo-compatible)
|
|
90
|
+
remoteCache: {
|
|
91
|
+
url: "https://cache.example.com",
|
|
92
|
+
token: process.env.CACHE_TOKEN,
|
|
93
|
+
teamId: "my-team",
|
|
94
|
+
},
|
|
68
95
|
},
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
// Or: auto-fingerprinting (Vite Task-style)
|
|
73
|
-
// autoFingerprint: true,
|
|
96
|
+
context,
|
|
97
|
+
);
|
|
98
|
+
```
|
|
74
99
|
|
|
75
|
-
|
|
76
|
-
smartLockfileHashing: true,
|
|
100
|
+
## Concurrent Process Runner
|
|
77
101
|
|
|
78
|
-
|
|
79
|
-
frameworkInference: true,
|
|
102
|
+
Run multiple commands in parallel with real-time output streaming, process tree management, and automatic native acceleration.
|
|
80
103
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
104
|
+
```typescript
|
|
105
|
+
import { runConcurrently } from "@visulima/task-runner";
|
|
106
|
+
|
|
107
|
+
// Basic usage
|
|
108
|
+
const result = await runConcurrently(["npm run build", "npm run test", "npm run lint"]);
|
|
109
|
+
console.log(result.success ? "All passed" : "Some failed");
|
|
110
|
+
|
|
111
|
+
// With options
|
|
112
|
+
const result = await runConcurrently(
|
|
113
|
+
[
|
|
114
|
+
{ command: "vite dev", name: "web", stdin: "inherit" },
|
|
115
|
+
{ command: "node api.js", name: "api" },
|
|
116
|
+
],
|
|
117
|
+
{
|
|
118
|
+
maxProcesses: 4,
|
|
119
|
+
killOthers: ["failure"], // Kill all if one fails
|
|
120
|
+
successCondition: "all", // All must exit 0
|
|
121
|
+
onEvent: (event) => {
|
|
122
|
+
// Real-time streaming
|
|
123
|
+
if (event.kind === "stdout") {
|
|
124
|
+
console.log(`[${event.index}] ${event.text}`);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
86
127
|
},
|
|
87
|
-
|
|
128
|
+
);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Command Parser
|
|
132
|
+
|
|
133
|
+
Use `parseCommands` to expand shortcuts and wildcards before passing to `runConcurrently`:
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
import { parseCommands, runConcurrently } from "@visulima/task-runner";
|
|
137
|
+
|
|
138
|
+
const commands = parseCommands([
|
|
139
|
+
"npm:build", // -> npm run build
|
|
140
|
+
"pnpm:test", // -> pnpm run test
|
|
141
|
+
'"quoted command"', // -> quoted command (quotes stripped)
|
|
142
|
+
"npm run watch-*", // -> expands to all matching scripts in package.json
|
|
143
|
+
"deno task dev-*", // -> expands from deno.json/deno.jsonc tasks
|
|
144
|
+
]);
|
|
145
|
+
|
|
146
|
+
await runConcurrently(commands);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Flow Controllers
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { runConcurrently } from "@visulima/task-runner";
|
|
153
|
+
|
|
154
|
+
// Restart failed commands with exponential backoff
|
|
155
|
+
await runConcurrently(["flaky-command"], {
|
|
156
|
+
restart: { tries: 3, delay: "exponential" },
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Print timing summary after completion
|
|
160
|
+
await runConcurrently(["npm run build", "npm run test"], {
|
|
161
|
+
timings: true,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Run cleanup commands after all processes finish
|
|
165
|
+
await runConcurrently(["npm run dev"], {
|
|
166
|
+
teardown: ["docker compose down", "rm -rf .cache"],
|
|
167
|
+
});
|
|
88
168
|
```
|
|
89
169
|
|
|
170
|
+
### Shell Configuration
|
|
171
|
+
|
|
172
|
+
The runner automatically detects `npm config set script-shell` for custom shells (e.g., Git Bash on Windows):
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { runConcurrently, detectScriptShell } from "@visulima/task-runner";
|
|
176
|
+
|
|
177
|
+
// Auto-detected from npm config
|
|
178
|
+
await runConcurrently(["echo hello"]);
|
|
179
|
+
|
|
180
|
+
// Or override explicitly
|
|
181
|
+
await runConcurrently(["echo hello"], {
|
|
182
|
+
shellPath: "/usr/bin/bash",
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Stdin Modes
|
|
187
|
+
|
|
188
|
+
For long-running processes like dev servers:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
await runConcurrently([
|
|
192
|
+
{ command: "vite dev", stdin: "inherit" }, // Child reads terminal directly
|
|
193
|
+
{ command: "node worker.js", stdin: "null" }, // No stdin (default)
|
|
194
|
+
{ command: "node repl.js", stdin: "pipe" }, // Programmatic stdin access
|
|
195
|
+
]);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Native vs Fallback
|
|
199
|
+
|
|
200
|
+
The runner automatically uses the Rust NAPI addon when available for:
|
|
201
|
+
|
|
202
|
+
- Process tree killing via setsid/killpg (Unix) and Job Objects (Windows)
|
|
203
|
+
- Async I/O multiplexing via tokio
|
|
204
|
+
- Signal propagation (SIGINT/SIGTERM/SIGHUP)
|
|
205
|
+
|
|
206
|
+
Falls back to a pure JavaScript implementation when the native addon is not compiled.
|
|
207
|
+
|
|
90
208
|
## Caching Modes
|
|
91
209
|
|
|
92
210
|
### Nx-style (explicit inputs)
|
|
@@ -94,19 +212,19 @@ const results = await defaultTaskRunner(tasks, {
|
|
|
94
212
|
Declare which files, env vars, and runtime values should be included in the cache hash:
|
|
95
213
|
|
|
96
214
|
```typescript
|
|
97
|
-
const results = await defaultTaskRunner(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
{ env: "NODE_ENV" },
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
test: { inputs: ["production", "{projectRoot}/**/*.test.ts"] },
|
|
215
|
+
const results = await defaultTaskRunner(
|
|
216
|
+
tasks,
|
|
217
|
+
{
|
|
218
|
+
namedInputs: {
|
|
219
|
+
production: ["{projectRoot}/src/**/*", { env: "NODE_ENV" }, { runtime: "node --version" }],
|
|
220
|
+
},
|
|
221
|
+
targetDefaults: {
|
|
222
|
+
build: { inputs: ["production"] },
|
|
223
|
+
test: { inputs: ["production", "{projectRoot}/**/*.test.ts"] },
|
|
224
|
+
},
|
|
108
225
|
},
|
|
109
|
-
|
|
226
|
+
context,
|
|
227
|
+
);
|
|
110
228
|
```
|
|
111
229
|
|
|
112
230
|
### Auto-fingerprint (Vite Task-style)
|
|
@@ -114,11 +232,15 @@ const results = await defaultTaskRunner(tasks, {
|
|
|
114
232
|
Automatically tracks which files a task accesses during execution:
|
|
115
233
|
|
|
116
234
|
```typescript
|
|
117
|
-
const results = await defaultTaskRunner(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
235
|
+
const results = await defaultTaskRunner(
|
|
236
|
+
tasks,
|
|
237
|
+
{
|
|
238
|
+
autoFingerprint: true,
|
|
239
|
+
fingerprintEnvPatterns: ["VITE_*", "NODE_ENV"],
|
|
240
|
+
cacheDiagnostics: true, // Shows why cache misses occur
|
|
241
|
+
},
|
|
242
|
+
context,
|
|
243
|
+
);
|
|
122
244
|
```
|
|
123
245
|
|
|
124
246
|
## API
|
|
@@ -127,27 +249,47 @@ const results = await defaultTaskRunner(tasks, {
|
|
|
127
249
|
|
|
128
250
|
The main entry point. Runs tasks with caching, scheduling, and lifecycle support.
|
|
129
251
|
|
|
252
|
+
### `runConcurrently(commands, options?)`
|
|
253
|
+
|
|
254
|
+
Run commands concurrently with process management and output streaming.
|
|
255
|
+
|
|
256
|
+
| Option | Type | Description |
|
|
257
|
+
| ------------------ | ---------------------------- | --------------------------------------------------- |
|
|
258
|
+
| `maxProcesses` | `number` | Max simultaneous processes (0 = unlimited) |
|
|
259
|
+
| `killOthers` | `("failure" \| "success")[]` | Kill others when a process exits |
|
|
260
|
+
| `killSignal` | `string` | Signal for killing (default: "SIGTERM") |
|
|
261
|
+
| `killTimeout` | `number` | Ms before SIGKILL after kill signal (default: 5000) |
|
|
262
|
+
| `successCondition` | `string` | "all", "first", "last", "command-\<name\>" |
|
|
263
|
+
| `shellPath` | `string` | Custom shell path (auto-detected from npm config) |
|
|
264
|
+
| `restart` | `{ tries, delay }` | Restart failed commands with backoff |
|
|
265
|
+
| `teardown` | `string[]` | Cleanup commands to run after completion |
|
|
266
|
+
| `timings` | `boolean` | Print timing summary table |
|
|
267
|
+
| `onEvent` | `(event) => void` | Real-time stdout/stderr/close/error events |
|
|
268
|
+
|
|
130
269
|
### Key Options
|
|
131
270
|
|
|
132
|
-
| Option
|
|
133
|
-
|
|
134
|
-
| `parallel`
|
|
135
|
-
| `smartLockfileHashing` | `boolean`
|
|
136
|
-
| `frameworkInference`
|
|
137
|
-
| `autoFingerprint`
|
|
138
|
-
| `globalInputs`
|
|
139
|
-
| `globalEnv`
|
|
140
|
-
| `remoteCache`
|
|
141
|
-
| `dryRun`
|
|
142
|
-
| `summarize`
|
|
143
|
-
| `cacheDiagnostics`
|
|
144
|
-
| `maxCacheSize`
|
|
145
|
-
| `maxCacheAge`
|
|
271
|
+
| Option | Type | Description |
|
|
272
|
+
| ---------------------- | ------------------- | ----------------------------------------------- |
|
|
273
|
+
| `parallel` | `number \| boolean` | Max parallel tasks (default: 3) |
|
|
274
|
+
| `smartLockfileHashing` | `boolean` | Hash only relevant lockfile entries per package |
|
|
275
|
+
| `frameworkInference` | `boolean` | Auto-detect framework env var prefixes |
|
|
276
|
+
| `autoFingerprint` | `boolean` | Enable Vite Task-style auto-fingerprinting |
|
|
277
|
+
| `globalInputs` | `string[]` | Files that invalidate all caches when changed |
|
|
278
|
+
| `globalEnv` | `string[]` | Env vars that invalidate all caches |
|
|
279
|
+
| `remoteCache` | `object` | Remote cache server configuration |
|
|
280
|
+
| `dryRun` | `boolean` | Compute hashes without executing |
|
|
281
|
+
| `summarize` | `boolean` | Generate JSON run summary |
|
|
282
|
+
| `cacheDiagnostics` | `boolean` | Log cache miss reasons |
|
|
283
|
+
| `maxCacheSize` | `string` | Max cache size (e.g., "1GB") |
|
|
284
|
+
| `maxCacheAge` | `number` | Max cache entry age in ms |
|
|
146
285
|
|
|
147
286
|
### Exports
|
|
148
287
|
|
|
149
288
|
The package exports many building blocks for custom task runners:
|
|
150
289
|
|
|
290
|
+
- **Concurrent Runner**: `runConcurrently`, `runConcurrentFallback`, `detectScriptShell`
|
|
291
|
+
- **Command Parser**: `parseCommands`, `expandShortcut`, `expandWildcard`, `expandArguments`, `stripQuotes`
|
|
292
|
+
- **Flow Controllers**: `withRestart`, `createInputHandler`, `logTimings`, `formatTimingTable`, `runTeardown`
|
|
151
293
|
- **Task Graph**: `createTaskGraph`, `findCycle`, `walkTaskGraph`, `makeAcyclic`
|
|
152
294
|
- **Hashing**: `InProcessTaskHasher`, `IncrementalFileHasher`, `computeTaskHash`
|
|
153
295
|
- **Caching**: `Cache`, `RemoteCache`, `FingerprintManager`
|
package/dist/affected.d.ts
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
import type { ProjectConfiguration, ProjectGraph } from "./types.d.ts";
|
|
1
|
+
import type { AffectedScope, ProjectConfiguration, ProjectGraph } from "./types.d.ts";
|
|
2
2
|
/**
|
|
3
3
|
* Options for determining affected projects.
|
|
4
4
|
*/
|
|
5
5
|
interface AffectedOptions {
|
|
6
6
|
/** The base ref to compare against (default: "main") */
|
|
7
7
|
base?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Control how far downstream (dependents of changed projects) to include.
|
|
10
|
+
* @default "deep"
|
|
11
|
+
*/
|
|
12
|
+
downstream?: AffectedScope;
|
|
8
13
|
/** The head ref to compare (default: "HEAD") */
|
|
9
14
|
head?: string;
|
|
10
15
|
/** Project graph for dependency resolution */
|
|
11
16
|
projectGraph: ProjectGraph;
|
|
12
17
|
/** All project configurations keyed by name */
|
|
13
18
|
projects: Record<string, ProjectConfiguration>;
|
|
19
|
+
/**
|
|
20
|
+
* Control how far upstream (dependencies of changed projects) to include.
|
|
21
|
+
* @default "none"
|
|
22
|
+
*/
|
|
23
|
+
upstream?: AffectedScope;
|
|
14
24
|
/** The workspace root directory */
|
|
15
25
|
workspaceRoot: string;
|
|
16
26
|
}
|
|
@@ -18,13 +28,37 @@ interface AffectedOptions {
|
|
|
18
28
|
* Result of affected detection.
|
|
19
29
|
*/
|
|
20
30
|
interface AffectedResult {
|
|
21
|
-
/**
|
|
31
|
+
/** All affected projects (union of changed, downstream, and upstream) */
|
|
22
32
|
affectedProjects: string[];
|
|
23
33
|
/** Files that changed between base and head */
|
|
24
34
|
changedFiles: string[];
|
|
25
35
|
/** Projects that were directly changed */
|
|
26
36
|
changedProjects: string[];
|
|
37
|
+
/** Projects affected because they depend on changed projects */
|
|
38
|
+
downstreamProjects: string[];
|
|
39
|
+
/** Projects that changed projects depend on */
|
|
40
|
+
upstreamProjects: string[];
|
|
27
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Builds a map from each project to the set of projects that depend on it (reverse/downstream).
|
|
44
|
+
*/
|
|
45
|
+
declare const buildReverseDependencyMap: (projectGraph: ProjectGraph) => Map<string, Set<string>>;
|
|
46
|
+
/**
|
|
47
|
+
* Builds a map from each project to the set of projects it depends on (forward/upstream).
|
|
48
|
+
*/
|
|
49
|
+
declare const buildForwardDependencyMap: (projectGraph: ProjectGraph) => Map<string, Set<string>>;
|
|
50
|
+
/**
|
|
51
|
+
* Expands a set of changed projects based on upstream/downstream scope settings.
|
|
52
|
+
* Returns a new set containing all affected projects.
|
|
53
|
+
*/
|
|
54
|
+
declare const expandAffected: (changedProjects: Set<string>, projectGraph: ProjectGraph, options: {
|
|
55
|
+
downstream: AffectedScope;
|
|
56
|
+
upstream: AffectedScope;
|
|
57
|
+
}) => {
|
|
58
|
+
affected: Set<string>;
|
|
59
|
+
downstream: Set<string>;
|
|
60
|
+
upstream: Set<string>;
|
|
61
|
+
};
|
|
28
62
|
/**
|
|
29
63
|
* Gets the list of files changed between two git refs.
|
|
30
64
|
* Uses execFile with argument arrays to prevent command injection.
|
|
@@ -45,4 +79,4 @@ declare const getAffectedProjects: (options: AffectedOptions) => Promise<Affecte
|
|
|
45
79
|
*/
|
|
46
80
|
declare const filterAffectedTasks: (taskIds: string[], affectedProjects: Set<string>) => string[];
|
|
47
81
|
export type { AffectedOptions, AffectedResult };
|
|
48
|
-
export { filterAffectedTasks, getAffectedProjects, getChangedFiles };
|
|
82
|
+
export { buildForwardDependencyMap, buildReverseDependencyMap, expandAffected, filterAffectedTasks, getAffectedProjects, getChangedFiles };
|
package/dist/cache.d.ts
CHANGED
|
@@ -25,6 +25,13 @@ interface CacheOptions {
|
|
|
25
25
|
/** The workspace root directory */
|
|
26
26
|
workspaceRoot: string;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Directory name (relative to `workspaceRoot`) where the task runner writes
|
|
30
|
+
* its cache by default. Exported so callers that manage the cache from the
|
|
31
|
+
* outside — e.g. a CLI `cache clean` command — can reach the same default
|
|
32
|
+
* without hard-coding the literal.
|
|
33
|
+
*/
|
|
34
|
+
declare const DEFAULT_CACHE_DIRECTORY_NAME = ".task-runner-cache";
|
|
28
35
|
/**
|
|
29
36
|
* Parses a human-readable cache size string into bytes.
|
|
30
37
|
* Delegates to @visulima/humanizer's parseBytes with base-2 (1024) multipliers.
|
|
@@ -100,4 +107,4 @@ declare class Cache {
|
|
|
100
107
|
clear(): Promise<void>;
|
|
101
108
|
}
|
|
102
109
|
export type { CachedResult, CacheOptions };
|
|
103
|
-
export { Cache, formatCacheSize, parseCacheSize };
|
|
110
|
+
export { Cache, DEFAULT_CACHE_DIRECTORY_NAME, formatCacheSize, parseCacheSize };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ConcurrentCommandConfig } from "../types.d.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Expands argument placeholders in command strings.
|
|
4
|
+
*
|
|
5
|
+
* Placeholders:
|
|
6
|
+
* {1}, {2}, ... -> specific positional argument
|
|
7
|
+
* {@} -> all arguments, individually quoted
|
|
8
|
+
* {*} -> all arguments as a single quoted string
|
|
9
|
+
* \{1} -> literal {1} (escaped)
|
|
10
|
+
*/
|
|
11
|
+
export declare const expandArguments: (config: ConcurrentCommandConfig, additionalArguments: string[]) => ConcurrentCommandConfig;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ConcurrentCommandConfig } from "../types.d.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Expands package manager shortcuts into full commands.
|
|
4
|
+
*
|
|
5
|
+
* This parser transforms shorthand notation into proper package manager
|
|
6
|
+
* invocations. No user input is involved -- command strings originate
|
|
7
|
+
* from the calling code which reads package.json scripts.
|
|
8
|
+
*
|
|
9
|
+
* Examples:
|
|
10
|
+
* npm:build -> npm run build
|
|
11
|
+
* pnpm:test -> pnpm run test
|
|
12
|
+
* node:script -> node --run script
|
|
13
|
+
* deno:task -> deno task task
|
|
14
|
+
*/
|
|
15
|
+
export declare const expandShortcut: (config: ConcurrentCommandConfig) => ConcurrentCommandConfig;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ConcurrentCommandConfig } from "../types.d.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Expands wildcard patterns in package manager "run" commands.
|
|
4
|
+
*
|
|
5
|
+
* Reads scripts from package.json and matches against the wildcard pattern.
|
|
6
|
+
* Returns one ConcurrentCommandConfig per matching script.
|
|
7
|
+
*
|
|
8
|
+
* Example: "npm run watch-*" with scripts { "watch-js": "...", "watch-css": "..." }
|
|
9
|
+
* -> ["npm run watch-js", "npm run watch-css"]
|
|
10
|
+
*
|
|
11
|
+
* No user input is involved -- patterns come from the calling code.
|
|
12
|
+
*/
|
|
13
|
+
export declare const expandWildcard: (config: ConcurrentCommandConfig) => ConcurrentCommandConfig | ConcurrentCommandConfig[];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ConcurrentCommandConfig, ConcurrentCommandInput } from "../types.d.ts";
|
|
2
|
+
export interface ParseCommandsOptions {
|
|
3
|
+
/** Additional arguments for placeholder expansion ({1}, {@}, {*}). */
|
|
4
|
+
additionalArguments?: string[];
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Parse and expand command inputs through the full pipeline:
|
|
8
|
+
* 1. Normalize string inputs to config objects
|
|
9
|
+
* 2. Strip surrounding quotes
|
|
10
|
+
* 3. Expand package manager shortcuts (npm:build -> npm run build)
|
|
11
|
+
* 4. Expand wildcard patterns (npm run watch-* -> multiple commands)
|
|
12
|
+
* 5. Expand argument placeholders ({1}, {@}, {*})
|
|
13
|
+
*/
|
|
14
|
+
export declare const parseCommands: (inputs: ConcurrentCommandInput[], options?: ParseCommandsOptions) => ConcurrentCommandConfig[];
|
|
15
|
+
export { expandArguments } from "./expand-arguments.d.ts";
|
|
16
|
+
export { expandShortcut } from "./expand-shortcut.d.ts";
|
|
17
|
+
export { expandWildcard } from "./expand-wildcard.d.ts";
|
|
18
|
+
export { stripQuotes } from "./strip-quotes.d.ts";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure JavaScript fallback for the concurrent process runner.
|
|
3
|
+
* Used when the native Rust addon is not available.
|
|
4
|
+
*
|
|
5
|
+
* SECURITY NOTE: Commands executed here originate from package.json scripts
|
|
6
|
+
* (trusted input, not user-supplied). Shell execution via spawn() with
|
|
7
|
+
* explicit shell binary (sh -c / cmd.exe /s /c) is intentional -- package
|
|
8
|
+
* scripts require shell features (pipes, redirects, env expansion).
|
|
9
|
+
* This is the same approach used by npm/pnpm/yarn themselves.
|
|
10
|
+
*/
|
|
11
|
+
import type { ConcurrentCommandConfig, ConcurrentRunnerOptions, ConcurrentRunResult } from "./types.d.ts";
|
|
12
|
+
/**
|
|
13
|
+
* Run commands concurrently using pure JavaScript (child_process.spawn).
|
|
14
|
+
* This is the fallback when the native Rust addon is unavailable.
|
|
15
|
+
*/
|
|
16
|
+
export declare const runConcurrentFallback: (commands: ConcurrentCommandConfig[], options: ConcurrentRunnerOptions) => Promise<ConcurrentRunResult>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API for the concurrent process runner.
|
|
3
|
+
*
|
|
4
|
+
* Uses the native Rust addon when available, falling back to
|
|
5
|
+
* a pure JavaScript implementation. Integrates flow controllers
|
|
6
|
+
* (restart, teardown, timings) around the core runner.
|
|
7
|
+
*/
|
|
8
|
+
import type { ConcurrentCommandInput, ConcurrentRunnerOptions, ConcurrentRunResult } from "./types.d.ts";
|
|
9
|
+
/**
|
|
10
|
+
* Run commands concurrently with output streaming and process management.
|
|
11
|
+
*
|
|
12
|
+
* Automatically uses the native Rust addon for performance when available,
|
|
13
|
+
* falling back to a pure JavaScript implementation.
|
|
14
|
+
*
|
|
15
|
+
* Supports flow controllers:
|
|
16
|
+
* - `restart`: retry failed commands with configurable delay/backoff
|
|
17
|
+
* - `teardown`: run cleanup commands after all processes complete
|
|
18
|
+
* - `timings`: print a timing summary table
|
|
19
|
+
* @param commands Array of command strings or config objects
|
|
20
|
+
* @param options Runner options (maxProcesses, killOthers, restart, teardown, etc.)
|
|
21
|
+
* @returns Promise resolving to the run result with close events and success status
|
|
22
|
+
*/
|
|
23
|
+
export declare const runConcurrently: (commands: ConcurrentCommandInput[], options?: ConcurrentRunnerOptions) => Promise<ConcurrentRunResult>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detects the configured script shell for npm/pnpm/yarn.
|
|
3
|
+
*
|
|
4
|
+
* Resolution order:
|
|
5
|
+
* 1. `npm_config_script_shell` env var (set by npm when running scripts)
|
|
6
|
+
* 2. `npm config get script-shell` subprocess (cached after first call)
|
|
7
|
+
* 3. Platform default (undefined = let the runner use /bin/sh or cmd.exe)
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Detect the npm script-shell configuration.
|
|
11
|
+
*
|
|
12
|
+
* Returns the shell path if configured, or undefined to use platform defaults.
|
|
13
|
+
* The result is cached after the first call.
|
|
14
|
+
*/
|
|
15
|
+
export declare const detectScriptShell: () => string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Reset the cached shell path. Useful for testing.
|
|
18
|
+
*/
|
|
19
|
+
export declare const resetShellCache: () => void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { InputHandlerOptions } from "./input-handler.d.ts";
|
|
2
|
+
export { createInputHandler } from "./input-handler.d.ts";
|
|
3
|
+
export { formatTimingTable, logTimings } from "./log-timings.d.ts";
|
|
4
|
+
export type { RestartOptions } from "./restart-process.d.ts";
|
|
5
|
+
export { withRestart } from "./restart-process.d.ts";
|
|
6
|
+
export type { TeardownOptions } from "./teardown.d.ts";
|
|
7
|
+
export { runTeardown } from "./teardown.d.ts";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input handler flow controller.
|
|
3
|
+
*
|
|
4
|
+
* Routes stdin data to specific child processes based on a prefix pattern.
|
|
5
|
+
* Input prefixed with "name:" or "index:" is routed to that command's stdin.
|
|
6
|
+
* Unprefixed input goes to the default target (index 0).
|
|
7
|
+
*
|
|
8
|
+
* NOTE: This module does NOT execute commands -- it only pipes user-typed
|
|
9
|
+
* stdin data to already-running child process stdin streams. No shell
|
|
10
|
+
* invocation or command injection risk.
|
|
11
|
+
*
|
|
12
|
+
* LIMITATION: This is a standalone utility -- it is NOT integrated into
|
|
13
|
+
* runConcurrently() because the concurrent runner does not expose child
|
|
14
|
+
* stdin streams. To use this, spawn processes manually with stdin: "pipe"
|
|
15
|
+
* and pass the writable streams to createInputHandler().
|
|
16
|
+
*
|
|
17
|
+
* TODO: To fully integrate stdin routing into runConcurrently(), we would need:
|
|
18
|
+
* 1. A new "started" ProcessEvent that carries a writable stdin reference
|
|
19
|
+
* 2. On the Rust side: expose tokio::process::ChildStdin through NAPI
|
|
20
|
+
* (requires a custom wrapper since ChildStdin can't cross FFI directly)
|
|
21
|
+
* 3. In the JS fallback: return child.stdin from spawnCommand()
|
|
22
|
+
*/
|
|
23
|
+
import type { Readable, Writable } from "node:stream";
|
|
24
|
+
export interface InputHandlerOptions {
|
|
25
|
+
/** Default command index to route unprefixed input to. Default: 0. */
|
|
26
|
+
defaultTarget?: number;
|
|
27
|
+
/** Stream to read input from. Default: process.stdin. */
|
|
28
|
+
inputStream?: Readable;
|
|
29
|
+
/** Whether to pause the input stream when all processes finish. Default: true. */
|
|
30
|
+
pauseOnFinish?: boolean;
|
|
31
|
+
}
|
|
32
|
+
interface CommandStdin {
|
|
33
|
+
index: number;
|
|
34
|
+
name?: string;
|
|
35
|
+
stdin: Writable;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Creates an input handler that routes stdin to child processes.
|
|
39
|
+
* @param commands Map of command index/name to their stdin streams
|
|
40
|
+
* @param options Input handler configuration
|
|
41
|
+
* @returns cleanup function to call when done
|
|
42
|
+
*/
|
|
43
|
+
export declare const createInputHandler: (commands: CommandStdin[], options?: InputHandlerOptions) => (() => void);
|
|
44
|
+
export {};
|