@visulima/task-runner 1.0.0-alpha.8 → 1.0.0-alpha.9
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 +31 -0
- package/README.md +3 -1
- package/dist/index.d.ts +791 -205
- package/dist/index.js +28 -20
- package/dist/packem_chunks/index.js +5593 -0
- package/dist/packem_shared/{Cache-CWaX_c8U.js → Cache-CbhoA268.js} +151 -10
- package/dist/packem_shared/{FileAccessTracker-CQ5Ot7Hd.js → FileAccessTracker-D8zIURPU.js} +1 -1
- package/dist/packem_shared/{FingerprintManager-CV7U4f4f.js → FingerprintManager-78DjwWQ4.js} +1 -1
- package/dist/packem_shared/HttpRemoteCache-BTXUBH7t.js +290 -0
- package/dist/packem_shared/INPUT_URI_SCHEMES-DRm76YI5.js +69 -0
- package/dist/packem_shared/{IncrementalFileHasher-BRS76-mb.js → IncrementalFileHasher-BBhVK491.js} +1 -1
- package/dist/packem_shared/ReapiRemoteCache-vgRxDMmu.js +1012 -0
- package/dist/packem_shared/{TaskOrchestrator-UCMHCx8c.js → TaskOrchestrator-CdRaQhTO.js} +34 -11
- package/dist/packem_shared/{TrackedTaskExecutor-CFPpQfXF.js → TrackedTaskExecutor-CWSMfHAW.js} +2 -2
- package/dist/packem_shared/V2_ROOT-DKBLxKo4.js +14 -0
- package/dist/packem_shared/actionDigestForTaskHash-BRE-9MT6.js +121 -0
- package/dist/packem_shared/archive-CnggHWb-.js +152 -0
- package/dist/packem_shared/{collectFiles-ClXHnHhg.js → collectFiles-cc1gokGU.js} +2 -1
- package/dist/packem_shared/{computeTaskHash-B5APHW7e.js → computeTaskHash-DHoBJ_-V.js} +10 -4
- package/dist/packem_shared/containsBlob-CwGB0a_q.js +125 -0
- package/dist/packem_shared/{createTaskGraph-B5YrfAMx.js → createTaskGraph-Bwl4hwAf.js} +17 -0
- package/dist/packem_shared/{defaultTaskRunner-DzR0ld8F.js → defaultTaskRunner-BaX4ZbFv.js} +24 -13
- package/dist/packem_shared/{detectFrameworks-CeFzKE6J.js → detectFrameworks-D7nyTc-o.js} +1 -1
- package/dist/packem_shared/{detectScriptShell-CR-xXKA4.js → detectScriptShell-CzxCM9-t.js} +1 -1
- package/dist/packem_shared/digestBuffer-CPdI2E1d.js +48 -0
- package/dist/packem_shared/{expandArguments-0AwD2BIA.js → expandArguments-Ba-hHYff.js} +2 -1
- package/dist/packem_shared/{expandTokensInString-C03AGAjh.js → expandTokensInString-Bb7nYehP.js} +2 -1
- package/dist/packem_shared/{extractPackageName-CbVNW-dr.js → extractPackageName-CMHjqGj_.js} +1 -1
- package/dist/packem_shared/{generateRunSummary-BE1jnQ3H.js → generateRunSummary-Bah7CFay.js} +1 -1
- package/dist/packem_shared/{getCurrentBranch-DsKPDoVj.js → getCurrentBranch-DVNikt0P.js} +11 -8
- package/dist/packem_shared/getMainWorktreeRoot-iBqToQJ4.js +114 -0
- package/dist/packem_shared/{parseCommands-CJ16ohOB.js → parseCommands-DDdIxaH5.js} +3 -3
- package/dist/packem_shared/resolveCacheMode-CsmHT_0o.js +21 -0
- package/dist/packem_shared/{runConcurrently-CmfC4r-f.js → runConcurrently-BCGQ9fJl.js} +1 -1
- package/dist/packem_shared/shell-quote-DWJJbt21.js +3 -0
- package/dist/packem_shared/{utils-zO0ZRgtf.js → utils-Bmnj-H2J.js} +4 -1
- package/index.js +52 -52
- package/package.json +23 -10
- package/dist/packem_shared/RemoteCache-DSU3lc87.js +0 -219
- package/dist/packem_shared/archive-UQHAnZUa.js +0 -102
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,353 @@
|
|
|
1
1
|
import { Readable, Writable } from 'node:stream';
|
|
2
2
|
/**
|
|
3
|
+
* Represents a file access recorded during task execution.
|
|
4
|
+
*
|
|
5
|
+
* Write-intent accesses (`"write"`) are emitted when a task opens a file
|
|
6
|
+
* with `O_WRONLY`/`O_RDWR`/`O_CREAT`/`O_TRUNC` flags (strace) or calls
|
|
7
|
+
* `writeFile`/`appendFile`/`unlink`/`rename` (preload script).
|
|
8
|
+
* The orchestrator uses the overlap of reads and writes to the same
|
|
9
|
+
* workspace path to detect self-modifying tasks and skip caching.
|
|
10
|
+
*/
|
|
11
|
+
interface FileAccess {
|
|
12
|
+
/** The absolute path of the file */
|
|
13
|
+
path: string;
|
|
14
|
+
/** The type of access */
|
|
15
|
+
type: "missing" | "read" | "readdir" | "stat" | "write";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Result of tracking file accesses during a command execution.
|
|
19
|
+
*/
|
|
20
|
+
interface TrackingResult {
|
|
21
|
+
/** All file accesses recorded */
|
|
22
|
+
accesses: FileAccess[];
|
|
23
|
+
/** The command exit code */
|
|
24
|
+
code: number;
|
|
25
|
+
/** The command stdout + stderr output */
|
|
26
|
+
output: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Tracks which files a child process accesses during execution.
|
|
30
|
+
*
|
|
31
|
+
* Uses `strace` on Linux to intercept syscalls (open, openat, stat, lstat, access, getdents).
|
|
32
|
+
* Falls back to no tracking on unsupported platforms.
|
|
33
|
+
*/
|
|
34
|
+
declare class FileAccessTracker {
|
|
35
|
+
#private;
|
|
36
|
+
constructor(workspaceRoot: string, excludePatterns?: RegExp[]);
|
|
37
|
+
/**
|
|
38
|
+
* Returns true if file access tracking is supported on the current platform.
|
|
39
|
+
*/
|
|
40
|
+
isSupported(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Runs a command and tracks all file system accesses.
|
|
43
|
+
* On unsupported platforms, runs the command without tracking.
|
|
44
|
+
*/
|
|
45
|
+
track(command: string, options?: {
|
|
46
|
+
cwd?: string;
|
|
47
|
+
env?: Record<string, string | undefined>;
|
|
48
|
+
}): Promise<TrackingResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Kills all active child processes. Called on abort/signal to prevent orphans.
|
|
51
|
+
*/
|
|
52
|
+
killAll(): void;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generates a preload script that can be used with NODE_OPTIONS to
|
|
56
|
+
* track file accesses in Node.js child processes.
|
|
57
|
+
*
|
|
58
|
+
* This is an alternative to strace that works cross-platform for Node.js processes.
|
|
59
|
+
*/
|
|
60
|
+
declare const generatePreloadScript: (outputPath: string) => string;
|
|
61
|
+
/**
|
|
62
|
+
* Represents a stored fingerprint for a task execution.
|
|
63
|
+
*/
|
|
64
|
+
interface TaskFingerprint {
|
|
65
|
+
/** Hash of the command arguments */
|
|
66
|
+
commandHash: string;
|
|
67
|
+
/** Directory listings recorded during execution (path -> sorted entries) */
|
|
68
|
+
directoryListings: Record<string, string[]>;
|
|
69
|
+
/** Hashes of fingerprinted environment variables */
|
|
70
|
+
envHashes: Record<string, string>;
|
|
71
|
+
/** Content hashes of files that were read during execution */
|
|
72
|
+
fileHashes: Record<string, string>;
|
|
73
|
+
/** Paths of files that were probed but didn't exist (ENOENT) */
|
|
74
|
+
missingFiles: string[];
|
|
75
|
+
/**
|
|
76
|
+
* Workspace-relative paths that were both read **and** written
|
|
77
|
+
* during execution. Populated when the tracker emits
|
|
78
|
+
* {@link FileAccess} entries with `"write"` type. The orchestrator
|
|
79
|
+
* uses a non-empty value here to skip caching a self-modifying
|
|
80
|
+
* task, whose fingerprint would otherwise capture post-write state
|
|
81
|
+
* and trigger false cache hits.
|
|
82
|
+
*/
|
|
83
|
+
modifiedInputs?: string[];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Describes why a cache miss occurred.
|
|
87
|
+
*/
|
|
88
|
+
interface CacheMissReason {
|
|
89
|
+
currentHash?: string;
|
|
90
|
+
detail: string;
|
|
91
|
+
previousHash?: string;
|
|
92
|
+
type: "file-changed" | "file-created" | "file-deleted" | "directory-changed" | "env-changed" | "args-changed" | "no-fingerprint";
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Manages task fingerprints for auto-detection caching.
|
|
96
|
+
*
|
|
97
|
+
* Records which files a task accesses during execution, stores content
|
|
98
|
+
* hashes, and on subsequent runs checks if any accessed file has changed.
|
|
99
|
+
*/
|
|
100
|
+
declare class FingerprintManager {
|
|
101
|
+
#private;
|
|
102
|
+
constructor(workspaceRoot: string);
|
|
103
|
+
createFingerprint(accesses: FileAccess[], command: string, args: Record<string, unknown>, envVariables: Record<string, string | undefined>, envPatterns?: string[], untrackedEnvVariables?: string[]): Promise<TaskFingerprint>;
|
|
104
|
+
/**
|
|
105
|
+
* Validates a stored fingerprint against the current state.
|
|
106
|
+
* Returns null if valid (cache hit), or an array of reasons (cache miss).
|
|
107
|
+
*
|
|
108
|
+
* Does NOT use the file hash cache — validation must see current disk state.
|
|
109
|
+
*/
|
|
110
|
+
validate(fingerprint: TaskFingerprint): Promise<CacheMissReason[] | undefined>;
|
|
111
|
+
validateCommand(fingerprint: TaskFingerprint, command: string, args: Record<string, unknown>): CacheMissReason | undefined;
|
|
112
|
+
formatMissReasons(reasons: CacheMissReason[]): string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Content-Addressable Storage digest. Mirrors REAPI's `Digest` message:
|
|
116
|
+
* a content hash and the size in bytes of the addressed blob.
|
|
117
|
+
*
|
|
118
|
+
* The hash is the lowercase hex sha256 of the blob's raw bytes. Size is
|
|
119
|
+
* the byte length of those bytes. Together they uniquely identify a CAS
|
|
120
|
+
* entry across HTTP and gRPC (REAPI) backends.
|
|
121
|
+
*/
|
|
122
|
+
interface CasDigest {
|
|
123
|
+
/** Lowercase hex sha256 of the blob bytes. */
|
|
124
|
+
hash: string;
|
|
125
|
+
/** Size of the blob bytes, in bytes. */
|
|
126
|
+
sizeBytes: number;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Result of executing a single Action. Mirrors REAPI's `ActionResult`
|
|
130
|
+
* shape, with a vis-specific `fingerprint` extension for auto-fingerprint
|
|
131
|
+
* mode. Persisted as JSON locally; serialized as a protobuf over gRPC.
|
|
132
|
+
*
|
|
133
|
+
* Output paths are workspace-relative.
|
|
134
|
+
*/
|
|
135
|
+
interface ActionResult {
|
|
136
|
+
/** Process exit code from the cached run. */
|
|
137
|
+
exitCode: number;
|
|
138
|
+
/** Optional vis-specific fingerprint (auto-fingerprint mode). */
|
|
139
|
+
fingerprint?: TaskFingerprint;
|
|
140
|
+
/**
|
|
141
|
+
* Per-output-directory entries. The `treeDigest` points to a CAS
|
|
142
|
+
* blob that is itself a serialized REAPI `Tree` message describing
|
|
143
|
+
* the directory hierarchy and its file digests.
|
|
144
|
+
*/
|
|
145
|
+
outputDirectories: ReadonlyArray<{
|
|
146
|
+
path: string;
|
|
147
|
+
treeDigest: CasDigest;
|
|
148
|
+
}>;
|
|
149
|
+
/** Per-output-file entries. Workspace-relative paths. */
|
|
150
|
+
outputFiles: ReadonlyArray<{
|
|
151
|
+
digest: CasDigest;
|
|
152
|
+
isExecutable: boolean;
|
|
153
|
+
path: string;
|
|
154
|
+
}>;
|
|
155
|
+
/**
|
|
156
|
+
* CAS digest of the captured stdout/stderr stream. Optional because
|
|
157
|
+
* tasks with no output emit nothing. Most tasks emit at least
|
|
158
|
+
* "Done in Xs", so dedup across tasks is real.
|
|
159
|
+
*/
|
|
160
|
+
stdoutDigest?: CasDigest;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Lazy handle for a CAS blob. Backends call `open()` only when they're
|
|
164
|
+
* ready to stream the bytes — keeps memory flat for multi-hundred-MB
|
|
165
|
+
* artifacts and avoids buffering blobs the server reports as already
|
|
166
|
+
* present (REAPI `FindMissingBlobs`).
|
|
167
|
+
*/
|
|
168
|
+
interface BlobSource {
|
|
169
|
+
digest: CasDigest;
|
|
170
|
+
open: () => Promise<NodeJS.ReadableStream>;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Canonical cache-mode enum, replacing the original `read` / `write`
|
|
174
|
+
* boolean pair. One flag, three values, no implicit env-detection.
|
|
175
|
+
*
|
|
176
|
+
* - `"read"`: Pull cache hits, never push. Default for local dev when
|
|
177
|
+
* developers shouldn't poison the shared cache.
|
|
178
|
+
* - `"write"`: Push results, never read. Useful for refill / warm-up
|
|
179
|
+
* jobs that should always re-execute and re-upload.
|
|
180
|
+
* - `"readwrite"`: Both. Default for CI.
|
|
181
|
+
*/
|
|
182
|
+
type CacheMode = "read" | "readwrite" | "write";
|
|
183
|
+
/**
|
|
184
|
+
* Compression algorithm used for artifact tarballs on the wire.
|
|
185
|
+
*
|
|
186
|
+
* - `"gzip"` (default): tar+gzip, matches Turborepo's protocol format
|
|
187
|
+
* and stays interop-safe with existing remote cache servers.
|
|
188
|
+
* - `"brotli"`: tar + Node brotli (BROTLI_MODE_TEXT, quality 4) — a
|
|
189
|
+
* solid ratio/speed trade-off for source-tree tarballs. Both upload
|
|
190
|
+
* and download sides must agree; switching invalidates existing
|
|
191
|
+
* remote entries (they will simply re-populate on next run).
|
|
192
|
+
*
|
|
193
|
+
* HTTP-only — REAPI servers negotiate compression via the
|
|
194
|
+
* `Capabilities` RPC + `grpc-encoding` metadata on the wire.
|
|
195
|
+
*/
|
|
196
|
+
type RemoteCacheCompression = "brotli" | "gzip";
|
|
197
|
+
/**
|
|
198
|
+
* HMAC signing configuration for the HTTP backend.
|
|
199
|
+
*
|
|
200
|
+
* When set, every upload carries an `X-Artifact-Signature` header
|
|
201
|
+
* containing the HMAC-SHA256 digest of `hash | body`. On download,
|
|
202
|
+
* the client recomputes the HMAC and rejects any artifact whose
|
|
203
|
+
* signature doesn't match (constant-time comparison). REAPI servers
|
|
204
|
+
* do not consume this — REAPI integrity rides on sha256
|
|
205
|
+
* content-addressing instead.
|
|
206
|
+
*/
|
|
207
|
+
interface RemoteCacheSigning {
|
|
208
|
+
/** Shared secret. Must be at least 16 characters. */
|
|
209
|
+
secret: string;
|
|
210
|
+
/**
|
|
211
|
+
* Reject downloads whose signature doesn't match or is missing.
|
|
212
|
+
* Set to `true` once every upload on your server is signed.
|
|
213
|
+
* @default false
|
|
214
|
+
*/
|
|
215
|
+
verifyOnDownload?: boolean;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Canonical remote-cache configuration consumed by
|
|
219
|
+
* `createRemoteCacheBackend`. Both `HttpRemoteCache` and
|
|
220
|
+
* `ReapiRemoteCache` accept this shape directly — backend-specific
|
|
221
|
+
* fields (e.g. `signing`, `compression` for HTTP; `bearerToken`,
|
|
222
|
+
* `instanceName` for REAPI) are read by the corresponding constructor
|
|
223
|
+
* and ignored by the other.
|
|
224
|
+
*
|
|
225
|
+
* Living in `backends/types.ts` rather than each backend file keeps a
|
|
226
|
+
* single source of truth for `TaskRunnerOptions.remoteCache` and the
|
|
227
|
+
* `vis-config` typed surface.
|
|
228
|
+
*/
|
|
229
|
+
interface RemoteCacheOptions {
|
|
230
|
+
/**
|
|
231
|
+
* Opt out of the REAPI safety check that refuses to send a bearer
|
|
232
|
+
* token over cleartext gRPC. Required only when the connection
|
|
233
|
+
* terminates inside a trusted boundary (loopback dev cache, mesh
|
|
234
|
+
* mTLS sidecar that strips/re-encrypts on the next hop). Default
|
|
235
|
+
* `false` — production callers should reach for `grpcs://` first.
|
|
236
|
+
*
|
|
237
|
+
* REAPI-only.
|
|
238
|
+
*/
|
|
239
|
+
allowInsecureBearer?: boolean;
|
|
240
|
+
/**
|
|
241
|
+
* Wire-protocol selector. `"http"` is the Turborepo-compatible
|
|
242
|
+
* single-tarball cache; `"reapi"` switches to the Bazel Remote
|
|
243
|
+
* Execution API gRPC client, unlocking `bazel-remote`,
|
|
244
|
+
* BuildBuddy, BuildBarn, EngFlow as drop-in backends.
|
|
245
|
+
* @default "http"
|
|
246
|
+
*/
|
|
247
|
+
backend?: "http" | "reapi";
|
|
248
|
+
/**
|
|
249
|
+
* Bearer token sent in REAPI's `authorization: Bearer {token}`
|
|
250
|
+
* gRPC metadata header. REAPI-only — HTTP backend uses `token`.
|
|
251
|
+
*/
|
|
252
|
+
bearerToken?: string;
|
|
253
|
+
/** HTTP-only: tarball compression on the wire. @default "gzip" */
|
|
254
|
+
compression?: RemoteCacheCompression;
|
|
255
|
+
/**
|
|
256
|
+
* REAPI-only `instance_name` for multi-tenant servers (a single
|
|
257
|
+
* gRPC endpoint can host multiple logical caches keyed on the
|
|
258
|
+
* `instance_name` prefix).
|
|
259
|
+
*/
|
|
260
|
+
instanceName?: string;
|
|
261
|
+
/**
|
|
262
|
+
* Local CAS root used by the per-blob {@link RemoteCacheBackend}
|
|
263
|
+
* methods. The HTTP wire format is still single-tarball; on
|
|
264
|
+
* retrieve the bridge extracts blobs into this root so a follow-up
|
|
265
|
+
* `fetchBlob` is just a local read.
|
|
266
|
+
*/
|
|
267
|
+
localCasRoot?: string;
|
|
268
|
+
/**
|
|
269
|
+
* Canonical cache mode flag.
|
|
270
|
+
*
|
|
271
|
+
* - `"read"`: Pull cache hits, never push. Sensible default for
|
|
272
|
+
* local dev so a developer doesn't poison the shared cache while
|
|
273
|
+
* their workspace is dirty.
|
|
274
|
+
* - `"write"`: Push results, never read. Useful for refill /
|
|
275
|
+
* warm-up jobs that should always re-execute and re-upload.
|
|
276
|
+
* - `"readwrite"`: Both. Default for CI.
|
|
277
|
+
* @default "readwrite"
|
|
278
|
+
*/
|
|
279
|
+
mode?: CacheMode;
|
|
280
|
+
/**
|
|
281
|
+
* Called when a fire-and-forget upload fails. Uploads are
|
|
282
|
+
* non-blocking, so without this hook errors are silently dropped.
|
|
283
|
+
* Provide it to log or report upload failures.
|
|
284
|
+
*/
|
|
285
|
+
onUploadError?: (hash: string, error: unknown) => void;
|
|
286
|
+
/** HTTP-only: HMAC-SHA256 signing for upload integrity. */
|
|
287
|
+
signing?: RemoteCacheSigning;
|
|
288
|
+
/** Team / namespace for cache isolation. */
|
|
289
|
+
teamId?: string;
|
|
290
|
+
/** Per-call request timeout in milliseconds. @default 30000 */
|
|
291
|
+
timeout?: number;
|
|
292
|
+
/**
|
|
293
|
+
* HTTP authentication token sent as `Authorization: Bearer …`.
|
|
294
|
+
* For REAPI, use `bearerToken` instead — same wire mechanic, but
|
|
295
|
+
* a separate field so REAPI's cleartext-bearer guard can distinguish
|
|
296
|
+
* "user explicitly opted into a gRPC token" from "user set HTTP
|
|
297
|
+
* auth and accidentally selected the REAPI backend".
|
|
298
|
+
*/
|
|
299
|
+
token?: string;
|
|
300
|
+
/**
|
|
301
|
+
* Cache server URL.
|
|
302
|
+
*
|
|
303
|
+
* - HTTP: `https://cache.example.com`
|
|
304
|
+
* - REAPI: `grpcs://host:port` (TLS, recommended) or `grpc://host:port`
|
|
305
|
+
* (cleartext — bearer tokens are refused unless `allowInsecureBearer`).
|
|
306
|
+
*/
|
|
307
|
+
url: string;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Pluggable backend boundary for the remote cache. Implementations:
|
|
311
|
+
* - `HttpRemoteCache`: Turborepo wire-protocol-compatible HTTP cache.
|
|
312
|
+
* Bridges the single-tarball protocol to per-blob semantics by
|
|
313
|
+
* synthesizing an `ActionResult` from the extracted tarball contents.
|
|
314
|
+
* - `ReapiRemoteCache`: Bazel Remote Execution API gRPC client.
|
|
315
|
+
* Speaks `ActionCache` + `ContentAddressableStorage` services
|
|
316
|
+
* natively, unlocking bazel-remote / BuildBuddy / BuildBarn / EngFlow.
|
|
317
|
+
*/
|
|
318
|
+
interface RemoteCacheBackend {
|
|
319
|
+
/**
|
|
320
|
+
* Release any persistent resources held by the backend (gRPC
|
|
321
|
+
* channels, HTTP keep-alive agents). Safe to call multiple times
|
|
322
|
+
* and safe to call when no work has been issued. Implementations
|
|
323
|
+
* must not throw — close failures are best-effort.
|
|
324
|
+
*/
|
|
325
|
+
close: () => Promise<void>;
|
|
326
|
+
/**
|
|
327
|
+
* HEAD-equivalent existence check. REAPI: `GetActionResult` with
|
|
328
|
+
* `inline_*` fields disabled. HTTP: `HEAD /v8/artifacts/{hash}`.
|
|
329
|
+
*/
|
|
330
|
+
containsAction: (actionDigest: CasDigest) => Promise<boolean>;
|
|
331
|
+
/**
|
|
332
|
+
* Stream a single CAS blob to disk. Returns `true` on success.
|
|
333
|
+
* Used to materialize output files referenced by an `ActionResult`.
|
|
334
|
+
*/
|
|
335
|
+
fetchBlob: (digest: CasDigest, destinationPath: string) => Promise<boolean>;
|
|
336
|
+
/**
|
|
337
|
+
* Look up an Action's cached result. Resolves to `null` on miss.
|
|
338
|
+
* Implementations are responsible for fetching any CAS blobs the
|
|
339
|
+
* caller needs to materialize the outputs (or returning enough
|
|
340
|
+
* metadata for the caller to fetch them via `fetchBlob`).
|
|
341
|
+
*/
|
|
342
|
+
retrieveAction: (actionDigest: CasDigest) => Promise<ActionResult | null>;
|
|
343
|
+
/**
|
|
344
|
+
* Persist an `ActionResult` and any blobs it references. Backends
|
|
345
|
+
* must enforce blobs-before-AC ordering on the wire so a partial
|
|
346
|
+
* failure cannot leave a cached result pointing at missing bytes.
|
|
347
|
+
*/
|
|
348
|
+
storeAction: (actionDigest: CasDigest, result: ActionResult, blobs: ReadonlyArray<BlobSource>) => Promise<boolean>;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
3
351
|
* A predicate clause that can match a single value, a list of values
|
|
4
352
|
* (any-of), or — for env vars only — a `{ name, equals?, exists? }`
|
|
5
353
|
* triplet. `not.*` mirrors of every clause provide a negative form
|
|
@@ -145,6 +493,22 @@ interface Task {
|
|
|
145
493
|
always?: boolean;
|
|
146
494
|
/** Whether this task is eligible for caching */
|
|
147
495
|
cache?: boolean;
|
|
496
|
+
/**
|
|
497
|
+
* When `false`, exit-0 runs whose output matched any
|
|
498
|
+
* {@link Task.warningPattern} are NOT written to the cache. Defaults
|
|
499
|
+
* to `true` — warnings are recorded on the result but don't suppress
|
|
500
|
+
* caching, matching the rushstack#1402 / Theme P expectation that a
|
|
501
|
+
* succeeded-with-warnings build is still incremental on the next run.
|
|
502
|
+
*
|
|
503
|
+
* Carried over from {@link TargetConfiguration.cacheOnWarning}.
|
|
504
|
+
*/
|
|
505
|
+
cacheOnWarning?: boolean;
|
|
506
|
+
/**
|
|
507
|
+
* Per-task overrides for cache restore fidelity. Carried over
|
|
508
|
+
* from {@link TargetConfiguration.cacheRestore}. When absent, the
|
|
509
|
+
* runner uses faithful defaults (mtime + mode preserved).
|
|
510
|
+
*/
|
|
511
|
+
cacheRestore?: CacheRestoreOptions;
|
|
148
512
|
/** Hash of the task inputs for caching */
|
|
149
513
|
hash?: string;
|
|
150
514
|
/** Detailed hash information */
|
|
@@ -172,6 +536,16 @@ interface Task {
|
|
|
172
536
|
/** The target this task executes */
|
|
173
537
|
target: TaskTarget;
|
|
174
538
|
/**
|
|
539
|
+
* Regex strings (JavaScript flavor, anchored as the user writes them)
|
|
540
|
+
* that classify a successful task's terminal output as "succeeded
|
|
541
|
+
* with warnings". When any pattern matches, {@link TaskResult.hadWarnings}
|
|
542
|
+
* is set on the result. Combined with {@link Task.cacheOnWarning} this
|
|
543
|
+
* controls whether the run still seeds the cache.
|
|
544
|
+
*
|
|
545
|
+
* Carried over from {@link TargetConfiguration.warningPattern}.
|
|
546
|
+
*/
|
|
547
|
+
warningPattern?: string[];
|
|
548
|
+
/**
|
|
175
549
|
* Predicate that gates execution. Evaluated by the orchestrator
|
|
176
550
|
* just before the task is launched; tasks whose `when` returns
|
|
177
551
|
* `false` are marked `"skipped"` without ever invoking the
|
|
@@ -224,6 +598,14 @@ interface TaskResult {
|
|
|
224
598
|
/** The end time of the task */
|
|
225
599
|
endTime?: number;
|
|
226
600
|
/**
|
|
601
|
+
* Set when the task exited 0 and at least one configured
|
|
602
|
+
* {@link Task.warningPattern} matched the terminal output. Surfaced
|
|
603
|
+
* to lifecycle reporters and the run summary so users can see that
|
|
604
|
+
* a "green" build still emitted warnings, and gates the optional
|
|
605
|
+
* `cacheOnWarning: false` cache-suppression path.
|
|
606
|
+
*/
|
|
607
|
+
hadWarnings?: boolean;
|
|
608
|
+
/**
|
|
227
609
|
* Set when the task modified one or more of its own tracked input
|
|
228
610
|
* files during execution. Caching is skipped in this case — the
|
|
229
611
|
* fingerprint captured before the run would mismatch the post-run
|
|
@@ -268,6 +650,30 @@ interface ProjectConfiguration {
|
|
|
268
650
|
targets?: Record<string, TargetConfiguration>;
|
|
269
651
|
}
|
|
270
652
|
/**
|
|
653
|
+
* Per-target controls over how the cache rehydrates outputs.
|
|
654
|
+
*
|
|
655
|
+
* Both default to `true` — faithful restoration is the contract:
|
|
656
|
+
* cached outputs come back with the same mtime and mode bits the
|
|
657
|
+
* task originally produced. Override only when downstream tooling
|
|
658
|
+
* needs the opposite (e.g. a bundler that uses "newer than source"
|
|
659
|
+
* heuristics, or a CI step that compares mtimes against a deploy
|
|
660
|
+
* artifact).
|
|
661
|
+
*/
|
|
662
|
+
interface CacheRestoreOptions {
|
|
663
|
+
/**
|
|
664
|
+
* Restore each file's modification time from the captured tar
|
|
665
|
+
* header (second precision). When `false`, restored files take
|
|
666
|
+
* the current wall-clock time, matching the legacy behaviour.
|
|
667
|
+
*/
|
|
668
|
+
preserveMtime?: boolean;
|
|
669
|
+
/**
|
|
670
|
+
* Restore each file's POSIX mode bits (rwx triplets, low 12
|
|
671
|
+
* bits). When `false`, restored files take the process umask.
|
|
672
|
+
* Only meaningful on POSIX hosts; Windows ignores tar mode.
|
|
673
|
+
*/
|
|
674
|
+
preservePerms?: boolean;
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
271
677
|
* Configuration for a target within a project.
|
|
272
678
|
*/
|
|
273
679
|
interface TargetConfiguration {
|
|
@@ -281,6 +687,22 @@ interface TargetConfiguration {
|
|
|
281
687
|
always?: boolean;
|
|
282
688
|
/** Whether this target is cacheable */
|
|
283
689
|
cache?: boolean;
|
|
690
|
+
/**
|
|
691
|
+
* When `false`, exit-0 runs whose terminal output matched any
|
|
692
|
+
* {@link TargetConfiguration.warningPattern} are not seeded into the
|
|
693
|
+
* cache. Defaults to `true` — warnings are surfaced on the result
|
|
694
|
+
* (`hadWarnings: true`) but caching still happens, matching the
|
|
695
|
+
* "succeeded with warnings is incremental" behaviour rush, lage and
|
|
696
|
+
* wireit users have repeatedly asked for.
|
|
697
|
+
*/
|
|
698
|
+
cacheOnWarning?: boolean;
|
|
699
|
+
/**
|
|
700
|
+
* Fine-grained controls over how cached outputs are rehydrated.
|
|
701
|
+
* See {@link CacheRestoreOptions}. Both fields default to `true`
|
|
702
|
+
* (faithful restore); flip individually when downstream tooling
|
|
703
|
+
* needs the legacy "now"-stamped behaviour.
|
|
704
|
+
*/
|
|
705
|
+
cacheRestore?: CacheRestoreOptions;
|
|
284
706
|
/** The command to run (alternative to executor) */
|
|
285
707
|
command?: string;
|
|
286
708
|
/** Named configurations (e.g., "production", "development") */
|
|
@@ -298,6 +720,19 @@ interface TargetConfiguration {
|
|
|
298
720
|
/** Whether this target supports parallel execution */
|
|
299
721
|
parallelism?: boolean;
|
|
300
722
|
/**
|
|
723
|
+
* Regex source string(s) that mark a successful task as having
|
|
724
|
+
* emitted warnings. The orchestrator scans the task's combined
|
|
725
|
+
* terminal output after a 0-exit and, on first match, sets
|
|
726
|
+
* `hadWarnings` on the result. Combine with `cacheOnWarning: false`
|
|
727
|
+
* to skip caching for warning-tainted runs. Both bare strings and
|
|
728
|
+
* arrays are accepted; arrays are tested in order.
|
|
729
|
+
*
|
|
730
|
+
* ```ts
|
|
731
|
+
* warningPattern: ["\\bwarning\\b", "TS\\d{4}"]
|
|
732
|
+
* ```
|
|
733
|
+
*/
|
|
734
|
+
warningPattern?: string | string[];
|
|
735
|
+
/**
|
|
301
736
|
* Predicate that gates execution. When the condition evaluates
|
|
302
737
|
* to `false` for the current environment, the task is skipped
|
|
303
738
|
* (marked `"skipped"`, not failed). Combine with `os`, `env`,
|
|
@@ -617,27 +1052,11 @@ interface TaskRunnerOptions {
|
|
|
617
1052
|
parallel?: number | boolean;
|
|
618
1053
|
/**
|
|
619
1054
|
* Remote cache configuration.
|
|
620
|
-
* When configured, the task runner
|
|
621
|
-
*
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
* Called when a fire-and-forget upload fails.
|
|
626
|
-
* Since uploads are non-blocking, errors are silently swallowed by default.
|
|
627
|
-
* Provide this callback to log or report upload failures.
|
|
628
|
-
*/
|
|
629
|
-
onUploadError?: (hash: string, error: unknown) => void;
|
|
630
|
-
/** Enable remote reads (default: true) */
|
|
631
|
-
read?: boolean;
|
|
632
|
-
/** Team/namespace for cache isolation */
|
|
633
|
-
teamId?: string;
|
|
634
|
-
/** Authentication token */
|
|
635
|
-
token?: string;
|
|
636
|
-
/** Remote cache server URL */
|
|
637
|
-
url: string;
|
|
638
|
-
/** Enable remote writes (default: true) */
|
|
639
|
-
write?: boolean;
|
|
640
|
-
};
|
|
1055
|
+
* When configured, the task runner checks the remote cache after a
|
|
1056
|
+
* local miss and uploads results after execution. See
|
|
1057
|
+
* {@link RemoteCacheOptions} for the full HTTP and REAPI surface.
|
|
1058
|
+
*/
|
|
1059
|
+
remoteCache?: RemoteCacheOptions;
|
|
641
1060
|
/** Whether to skip cache reads */
|
|
642
1061
|
skipNxCache?: boolean;
|
|
643
1062
|
/**
|
|
@@ -974,116 +1393,174 @@ declare const getAffectedProjects: (options: AffectedOptions) => Promise<Affecte
|
|
|
974
1393
|
*/
|
|
975
1394
|
declare const filterAffectedTasks: (taskIds: string[], affectedProjects: Set<string>) => string[];
|
|
976
1395
|
/**
|
|
977
|
-
*
|
|
1396
|
+
* Resolves the canonical {@link CacheMode}. `mode` defaults to
|
|
1397
|
+
* `"readwrite"` when unset — the safe choice for CI and the most
|
|
1398
|
+
* common config in dev. Kept as a separate helper so vis-side code
|
|
1399
|
+
* (CLI flag merge, doctor probes) can reuse the resolution rule.
|
|
1400
|
+
*/
|
|
1401
|
+
declare const resolveCacheMode: (options: {
|
|
1402
|
+
mode?: CacheMode;
|
|
1403
|
+
}) => CacheMode;
|
|
1404
|
+
/**
|
|
1405
|
+
* Construct the configured remote cache backend. Selects between the
|
|
1406
|
+
* Turborepo-compatible HTTP client and the Bazel REAPI gRPC client
|
|
1407
|
+
* via `options.backend`.
|
|
1408
|
+
*/
|
|
1409
|
+
declare const createRemoteCacheBackend: (options: RemoteCacheOptions) => RemoteCacheBackend;
|
|
1410
|
+
/**
|
|
1411
|
+
* Derive a stable {@link CasDigest} from the orchestrator's task hash
|
|
1412
|
+
* (xxh3-128, 32 hex chars). REAPI servers reject non-sha256 digests on
|
|
1413
|
+
* the wire, so we sha256 a namespaced key. The HTTP backend uses the
|
|
1414
|
+
* resulting digest as the artifact URL component.
|
|
978
1415
|
*
|
|
979
|
-
*
|
|
980
|
-
*
|
|
981
|
-
* `
|
|
982
|
-
*
|
|
983
|
-
*
|
|
1416
|
+
* `sizeBytes` is set to `0` because this digest identifies an *action*
|
|
1417
|
+
* (an `ActionResult` keyed in the AC), not a stored CAS blob. REAPI
|
|
1418
|
+
* `Digest` size_bytes only carries meaning for blobs in the CAS — for
|
|
1419
|
+
* action keys it's ignored by the server. Setting it to the byte
|
|
1420
|
+
* length of the prehash key would be semantically wrong: the server
|
|
1421
|
+
* would believe a blob of that exact length exists at this hash, and
|
|
1422
|
+
* a downstream `BatchReadBlobs` against this digest would mismatch.
|
|
984
1423
|
*/
|
|
985
|
-
|
|
986
|
-
/** The absolute path of the file */
|
|
987
|
-
path: string;
|
|
988
|
-
/** The type of access */
|
|
989
|
-
type: "missing" | "read" | "readdir" | "stat" | "write";
|
|
990
|
-
}
|
|
1424
|
+
declare const actionDigestForTaskHash: (taskHash: string) => CasDigest;
|
|
991
1425
|
/**
|
|
992
|
-
*
|
|
1426
|
+
* Probe whether a cached entry exists on the remote backend, keyed by
|
|
1427
|
+
* the orchestrator's task hash. Resolves `false` on any wire failure —
|
|
1428
|
+
* the orchestrator treats existence checks as best-effort.
|
|
993
1429
|
*/
|
|
994
|
-
|
|
995
|
-
/** All file accesses recorded */
|
|
996
|
-
accesses: FileAccess[];
|
|
997
|
-
/** The command exit code */
|
|
998
|
-
code: number;
|
|
999
|
-
/** The command stdout + stderr output */
|
|
1000
|
-
output: string;
|
|
1001
|
-
}
|
|
1430
|
+
declare const containsByTaskHash: (backend: RemoteCacheBackend, taskHash: string) => Promise<boolean>;
|
|
1002
1431
|
/**
|
|
1003
|
-
*
|
|
1432
|
+
* Download the cached entry for `taskHash` and extract it into
|
|
1433
|
+
* `{localCacheDirectory}/{taskHash}/`. Returns `true` only when the
|
|
1434
|
+
* directory has been fully populated; partial-extract failures clean
|
|
1435
|
+
* up after themselves so the local cache never observes a half-populated
|
|
1436
|
+
* entry.
|
|
1437
|
+
*/
|
|
1438
|
+
declare const retrieveByTaskHash: (backend: RemoteCacheBackend, taskHash: string, localCacheDirectory: string) => Promise<boolean>;
|
|
1439
|
+
/**
|
|
1440
|
+
* Tar `{localCacheDirectory}/{taskHash}/` and upload as a single CAS
|
|
1441
|
+
* blob via {@link RemoteCacheBackend.storeAction}. Skips the upload
|
|
1442
|
+
* unless `.commit` is present so we never publish a half-written entry.
|
|
1004
1443
|
*
|
|
1005
|
-
*
|
|
1006
|
-
*
|
|
1444
|
+
* The lazy {@link BlobSource.open} returns a fresh `createReadStream`
|
|
1445
|
+
* each call so REAPI's `FindMissingBlobs` → `BatchUpdateBlobs` →
|
|
1446
|
+
* fallback `Write` flow can re-read the file as many times as it needs
|
|
1447
|
+
* to without requiring the bridge to buffer the bytes in memory.
|
|
1448
|
+
*
|
|
1449
|
+
* Bridge-local failures (`createTarGz`, `digestFile`) are surfaced
|
|
1450
|
+
* through `onUploadError` when provided, then swallowed so the
|
|
1451
|
+
* fire-and-forget call site stays non-throwing. A missing `.commit`
|
|
1452
|
+
* marker is *not* an error — it's the normal "skip this upload" path.
|
|
1007
1453
|
*/
|
|
1008
|
-
declare
|
|
1454
|
+
declare const storeByTaskHash: (backend: RemoteCacheBackend, taskHash: string, localCacheDirectory: string, onUploadError?: (hash: string, error: unknown) => void) => Promise<boolean>;
|
|
1455
|
+
/**
|
|
1456
|
+
* HTTP-based remote cache compatible with the Turborepo remote cache protocol.
|
|
1457
|
+
*
|
|
1458
|
+
* Protocol:
|
|
1459
|
+
* - GET /v8/artifacts/{hash}?teamId={team} -> retrieve cached artifact (gzipped tar)
|
|
1460
|
+
* - PUT /v8/artifacts/{hash}?teamId={team} -> store artifact
|
|
1461
|
+
* - POST /v8/artifacts/events -> analytics (optional)
|
|
1462
|
+
*
|
|
1463
|
+
* Authentication via `Authorization: Bearer {token}` header.
|
|
1464
|
+
*
|
|
1465
|
+
* The cache entry is a gzipped tarball containing the cache directory contents
|
|
1466
|
+
* (code, terminalOutput, fingerprint.json, outputs/, .commit).
|
|
1467
|
+
*/
|
|
1468
|
+
declare class HttpRemoteCache implements RemoteCacheBackend {
|
|
1009
1469
|
#private;
|
|
1010
|
-
constructor(
|
|
1470
|
+
constructor(options: RemoteCacheOptions);
|
|
1011
1471
|
/**
|
|
1012
|
-
*
|
|
1472
|
+
* No-op. The HTTP backend uses Node's global `fetch`, which has no
|
|
1473
|
+
* persistent connection to release. Implemented to satisfy the
|
|
1474
|
+
* {@link RemoteCacheBackend.close} contract uniformly.
|
|
1013
1475
|
*/
|
|
1014
|
-
|
|
1476
|
+
close(): Promise<void>;
|
|
1015
1477
|
/**
|
|
1016
|
-
*
|
|
1017
|
-
*
|
|
1478
|
+
* {@link RemoteCacheBackend.containsAction}: HEAD on the artifact URL.
|
|
1479
|
+
* Resolves `false` on any wire failure — existence checks are best
|
|
1480
|
+
* effort and never block the caller.
|
|
1018
1481
|
*/
|
|
1019
|
-
|
|
1020
|
-
cwd?: string;
|
|
1021
|
-
env?: Record<string, string | undefined>;
|
|
1022
|
-
}): Promise<TrackingResult>;
|
|
1482
|
+
containsAction(actionDigest: CasDigest): Promise<boolean>;
|
|
1023
1483
|
/**
|
|
1024
|
-
*
|
|
1484
|
+
* {@link RemoteCacheBackend.fetchBlob}: streams a blob out of the
|
|
1485
|
+
* local CAS that was hydrated by a previous {@link retrieveAction}
|
|
1486
|
+
* call. The HTTP wire ships one tarball per action, so per-blob
|
|
1487
|
+
* fetches are local-only — there's no remote endpoint to call.
|
|
1025
1488
|
*/
|
|
1026
|
-
|
|
1027
|
-
}
|
|
1028
|
-
/**
|
|
1029
|
-
* Generates a preload script that can be used with NODE_OPTIONS to
|
|
1030
|
-
* track file accesses in Node.js child processes.
|
|
1031
|
-
*
|
|
1032
|
-
* This is an alternative to strace that works cross-platform for Node.js processes.
|
|
1033
|
-
*/
|
|
1034
|
-
declare const generatePreloadScript: (outputPath: string) => string;
|
|
1035
|
-
/**
|
|
1036
|
-
* Represents a stored fingerprint for a task execution.
|
|
1037
|
-
*/
|
|
1038
|
-
interface TaskFingerprint {
|
|
1039
|
-
/** Hash of the command arguments */
|
|
1040
|
-
commandHash: string;
|
|
1041
|
-
/** Directory listings recorded during execution (path -> sorted entries) */
|
|
1042
|
-
directoryListings: Record<string, string[]>;
|
|
1043
|
-
/** Hashes of fingerprinted environment variables */
|
|
1044
|
-
envHashes: Record<string, string>;
|
|
1045
|
-
/** Content hashes of files that were read during execution */
|
|
1046
|
-
fileHashes: Record<string, string>;
|
|
1047
|
-
/** Paths of files that were probed but didn't exist (ENOENT) */
|
|
1048
|
-
missingFiles: string[];
|
|
1489
|
+
fetchBlob(digest: CasDigest, destinationPath: string): Promise<boolean>;
|
|
1049
1490
|
/**
|
|
1050
|
-
*
|
|
1051
|
-
*
|
|
1052
|
-
*
|
|
1053
|
-
*
|
|
1054
|
-
*
|
|
1055
|
-
* and trigger false cache hits.
|
|
1491
|
+
* {@link RemoteCacheBackend.retrieveAction}: GETs the artifact at
|
|
1492
|
+
* `/v8/artifacts/{actionDigest.hash}`, ingests the response bytes
|
|
1493
|
+
* as a single CAS blob in the local store, and synthesises an
|
|
1494
|
+
* {@link ActionResult} that points at that blob. Resolves to `null`
|
|
1495
|
+
* on a 404 / signature mismatch / missing local CAS root.
|
|
1056
1496
|
*/
|
|
1057
|
-
|
|
1497
|
+
retrieveAction(actionDigest: CasDigest): Promise<ActionResult | null>;
|
|
1498
|
+
/**
|
|
1499
|
+
* {@link RemoteCacheBackend.storeAction}: takes the single blob
|
|
1500
|
+
* referenced by `result.outputFiles[0]`, streams its bytes as the
|
|
1501
|
+
* PUT body, and signs the body when a signing secret is configured.
|
|
1502
|
+
* Per-digest in-flight dedup means parallel writers racing on the
|
|
1503
|
+
* same action upload exactly once.
|
|
1504
|
+
*/
|
|
1505
|
+
storeAction(actionDigest: CasDigest, result: ActionResult, blobs: ReadonlyArray<BlobSource>): Promise<boolean>;
|
|
1058
1506
|
}
|
|
1059
1507
|
/**
|
|
1060
|
-
*
|
|
1508
|
+
* REAPI-specific options accepted by {@link ReapiRemoteCache}. A type
|
|
1509
|
+
* alias rather than its own interface so callers can hand the same
|
|
1510
|
+
* object to the backend factory or to the constructor directly without
|
|
1511
|
+
* rewriting field names. HTTP-only fields (`signing`, `compression`)
|
|
1512
|
+
* are silently ignored here.
|
|
1061
1513
|
*/
|
|
1062
|
-
|
|
1063
|
-
currentHash?: string;
|
|
1064
|
-
detail: string;
|
|
1065
|
-
previousHash?: string;
|
|
1066
|
-
type: "file-changed" | "file-created" | "file-deleted" | "directory-changed" | "env-changed" | "args-changed" | "no-fingerprint";
|
|
1067
|
-
}
|
|
1514
|
+
type ReapiRemoteCacheOptions = RemoteCacheOptions;
|
|
1068
1515
|
/**
|
|
1069
|
-
*
|
|
1516
|
+
* Bazel REAPI gRPC backend. Implements {@link RemoteCacheBackend} over
|
|
1517
|
+
* `ContentAddressableStorage` + `ActionCache` + `Capabilities` +
|
|
1518
|
+
* `google.bytestream.ByteStream`. Battle-tested REAPI servers
|
|
1519
|
+
* (`bazel-remote`, BuildBuddy, BuildBarn, EngFlow) become drop-in
|
|
1520
|
+
* backends with no per-server adapter.
|
|
1070
1521
|
*
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1522
|
+
* Wire flow:
|
|
1523
|
+
* - retrieveAction → GetActionResult → fetchBlob (BatchReadBlobs|Read)
|
|
1524
|
+
* - storeAction → FindMissingBlobs → BatchUpdateBlobs|Write → UpdateActionResult
|
|
1073
1525
|
*/
|
|
1074
|
-
declare class
|
|
1526
|
+
declare class ReapiRemoteCache implements RemoteCacheBackend {
|
|
1075
1527
|
#private;
|
|
1076
|
-
constructor(
|
|
1077
|
-
createFingerprint(accesses: FileAccess[], command: string, args: Record<string, unknown>, envVariables: Record<string, string | undefined>, envPatterns?: string[], untrackedEnvVariables?: string[]): Promise<TaskFingerprint>;
|
|
1528
|
+
constructor(options: ReapiRemoteCacheOptions);
|
|
1078
1529
|
/**
|
|
1079
|
-
*
|
|
1080
|
-
*
|
|
1530
|
+
* Close all gRPC channels held by this backend. Idempotent — safe
|
|
1531
|
+
* to call multiple times, and safe to call before any RPC was
|
|
1532
|
+
* issued. If `#getClients` is currently in flight we await its
|
|
1533
|
+
* resolution so the underlying channels are observable to close.
|
|
1534
|
+
*/
|
|
1535
|
+
close(): Promise<void>;
|
|
1536
|
+
/**
|
|
1537
|
+
* Diagnostic probe — fetches the server's `Capabilities` RPC response
|
|
1538
|
+
* (or the cached value, if a previous call already negotiated). Used
|
|
1539
|
+
* by `vis cache doctor` to surface what the server advertises without
|
|
1540
|
+
* forcing the operator to issue a real CAS RPC.
|
|
1081
1541
|
*
|
|
1082
|
-
*
|
|
1542
|
+
* Bypasses the read/write mode gate intentionally: a probe must work
|
|
1543
|
+
* even on a cache configured `mode: "write"` so the operator can
|
|
1544
|
+
* verify the connection regardless of how the runner uses it.
|
|
1083
1545
|
*/
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1546
|
+
probeCapabilities(): Promise<{
|
|
1547
|
+
digestFunctions: ReadonlyArray<string>;
|
|
1548
|
+
maxBatchTotalSizeBytes: number;
|
|
1549
|
+
}>;
|
|
1550
|
+
containsAction(actionDigest: CasDigest): Promise<boolean>;
|
|
1551
|
+
fetchBlob(digest: CasDigest, destinationPath: string): Promise<boolean>;
|
|
1552
|
+
retrieveAction(actionDigest: CasDigest): Promise<ActionResult | null>;
|
|
1553
|
+
storeAction(actionDigest: CasDigest, result: ActionResult, blobs: ReadonlyArray<BlobSource>): Promise<boolean>;
|
|
1554
|
+
}
|
|
1555
|
+
/**
|
|
1556
|
+
* Per-call control over restore fidelity. Both default to `true` —
|
|
1557
|
+
* the cache's job is to recreate exactly what was captured, and any
|
|
1558
|
+
* deviation is opt-in. Callers (e.g. vis target config) can flip
|
|
1559
|
+
* either off when downstream tooling needs a "fresh" mtime/mode.
|
|
1560
|
+
*/
|
|
1561
|
+
interface ExtractOptions {
|
|
1562
|
+
preserveMtime?: boolean;
|
|
1563
|
+
preservePerms?: boolean;
|
|
1087
1564
|
}
|
|
1088
1565
|
/**
|
|
1089
1566
|
* Represents a cached task result.
|
|
@@ -1166,6 +1643,40 @@ declare class Cache {
|
|
|
1166
1643
|
*/
|
|
1167
1644
|
get cacheDirectory(): string;
|
|
1168
1645
|
/**
|
|
1646
|
+
* Root for v2 CAS-shaped reads/writes. Backend implementations
|
|
1647
|
+
* (HTTP today, REAPI gRPC next) take this path so they can
|
|
1648
|
+
* hydrate fetched blobs into the same CAS the local cache reads
|
|
1649
|
+
* from. Equal to {@link cacheDirectory} — `v2/` lives under that.
|
|
1650
|
+
*/
|
|
1651
|
+
get casRoot(): string;
|
|
1652
|
+
/**
|
|
1653
|
+
* Read a v2 {@link ActionResult} by action digest. Resolves to
|
|
1654
|
+
* `null` on miss. The orchestrator is expected to follow up with
|
|
1655
|
+
* {@link materializeOutputs} to place the referenced blobs into
|
|
1656
|
+
* the workspace.
|
|
1657
|
+
*/
|
|
1658
|
+
getActionResult(actionDigest: CasDigest): Promise<ActionResult | null>;
|
|
1659
|
+
/**
|
|
1660
|
+
* Look up an action digest by the legacy task hash. Returns
|
|
1661
|
+
* `null` when the bridge file isn't present — caller falls
|
|
1662
|
+
* through to the legacy `<hash>/` layout (or executes the task).
|
|
1663
|
+
*/
|
|
1664
|
+
resolveActionDigestForTaskHash(taskHash: string): Promise<string | null>;
|
|
1665
|
+
/**
|
|
1666
|
+
* Persist a v2 entry: writes the AC JSON, copies referenced
|
|
1667
|
+
* blobs into the CAS via the lazy {@link BlobSource} handles,
|
|
1668
|
+
* and binds the task hash → action digest redirect last so a
|
|
1669
|
+
* partial failure can't surface a half-written entry.
|
|
1670
|
+
*/
|
|
1671
|
+
putActionResult(taskHash: string, actionDigest: CasDigest, result: ActionResult, blobs: ReadonlyArray<BlobSource>): Promise<void>;
|
|
1672
|
+
/**
|
|
1673
|
+
* Materialize an action's outputs into the workspace. Streams
|
|
1674
|
+
* each referenced blob from the local CAS to its workspace path.
|
|
1675
|
+
* Returns `false` when any blob is missing — caller treats that
|
|
1676
|
+
* as a cache miss and re-executes.
|
|
1677
|
+
*/
|
|
1678
|
+
materializeOutputs(result: ActionResult, workspaceRoot: string): Promise<boolean>;
|
|
1679
|
+
/**
|
|
1169
1680
|
* Retrieves a cached result for the given task hash.
|
|
1170
1681
|
* Returns undefined if no valid cache entry exists.
|
|
1171
1682
|
*/
|
|
@@ -1196,7 +1707,7 @@ declare class Cache {
|
|
|
1196
1707
|
* extracted staging become the set of swap roots. Still accepted
|
|
1197
1708
|
* for backward compat.
|
|
1198
1709
|
*/
|
|
1199
|
-
restoreOutputs(hash: string, _outputs?: OutputSpec[]): Promise<boolean>;
|
|
1710
|
+
restoreOutputs(hash: string, _outputs?: OutputSpec[], options?: ExtractOptions): Promise<boolean>;
|
|
1200
1711
|
/**
|
|
1201
1712
|
* Retrieves the most recent cached result for a task by its ID.
|
|
1202
1713
|
* Used in auto-fingerprint mode where the hash is derived from
|
|
@@ -1220,6 +1731,91 @@ declare class Cache {
|
|
|
1220
1731
|
clear(): Promise<void>;
|
|
1221
1732
|
}
|
|
1222
1733
|
/**
|
|
1734
|
+
* Compute the sha256 digest of a buffer's bytes. Lowercase hex, matching
|
|
1735
|
+
* REAPI's `Digest.hash` format. Used for synchronous payloads (small
|
|
1736
|
+
* AC metadata, action proto bytes) where streaming isn't worth it.
|
|
1737
|
+
*/
|
|
1738
|
+
declare const digestBuffer: (bytes: Buffer) => CasDigest;
|
|
1739
|
+
/**
|
|
1740
|
+
* Compute the sha256 digest of a file's contents by streaming. Avoids
|
|
1741
|
+
* loading multi-hundred-MB outputs into memory. Returns `undefined`
|
|
1742
|
+
* when the file can't be opened (caller decides whether that's fatal).
|
|
1743
|
+
*/
|
|
1744
|
+
declare const digestFile: (filePath: string) => Promise<CasDigest | undefined>;
|
|
1745
|
+
/**
|
|
1746
|
+
* v2 layout root inside the cache directory. Coexists with the legacy
|
|
1747
|
+
* `<cacheDir>/<hash>/` entries until the migration window closes.
|
|
1748
|
+
*/
|
|
1749
|
+
declare const V2_ROOT = "v2";
|
|
1750
|
+
/**
|
|
1751
|
+
* Sub-roots under `v2/`. CAS holds raw blob bytes, AC holds JSON
|
|
1752
|
+
* `ActionResult` entries, the task-hash index bridges xxh3 task hashes
|
|
1753
|
+
* to sha256 action digests, tmp stages atomic renames.
|
|
1754
|
+
*/
|
|
1755
|
+
declare const V2_CAS = "cas";
|
|
1756
|
+
declare const V2_AC = "ac";
|
|
1757
|
+
declare const V2_INDEX = "task-hash-index";
|
|
1758
|
+
declare const V2_TMP = "tmp";
|
|
1759
|
+
/**
|
|
1760
|
+
* Resolve the on-disk path for a CAS blob. `<root>/v2/cas/<aa>/<hash>`.
|
|
1761
|
+
*/
|
|
1762
|
+
declare const casBlobPath: (root: string, hash: string) => string;
|
|
1763
|
+
/**
|
|
1764
|
+
* Resolve the on-disk path for an Action Cache entry. AC entries are
|
|
1765
|
+
* JSON, suffix kept off-disk to match REAPI semantics (the action
|
|
1766
|
+
* digest is the file name).
|
|
1767
|
+
*/
|
|
1768
|
+
declare const acEntryPath: (root: string, actionHash: string) => string;
|
|
1769
|
+
/**
|
|
1770
|
+
* Resolve the path for the task-hash → action-digest redirect. 64-byte
|
|
1771
|
+
* file containing the action digest hex; lets `Cache.get(taskHash)`
|
|
1772
|
+
* jump to the AC entry without recomputing the action proto.
|
|
1773
|
+
*/
|
|
1774
|
+
declare const taskHashIndexPath: (root: string, taskHash: string) => string;
|
|
1775
|
+
/**
|
|
1776
|
+
* Returns `true` if the CAS blob already exists on disk for the given
|
|
1777
|
+
* digest. Caller uses this for `FindMissingBlobs`-style elision and to
|
|
1778
|
+
* avoid re-uploading bytes the local cache already holds.
|
|
1779
|
+
*/
|
|
1780
|
+
declare const containsBlob: (root: string, digest: CasDigest) => Promise<boolean>;
|
|
1781
|
+
/**
|
|
1782
|
+
* Stream a CAS blob from a source path into the store. The blob is
|
|
1783
|
+
* staged under `v2/tmp/` and renamed into `v2/cas/<aa>/<digest>` after
|
|
1784
|
+
* the bytes land. Idempotent: a concurrent writer racing on the same
|
|
1785
|
+
* digest results in two POSIX renames over byte-identical content,
|
|
1786
|
+
* which is atomic per POSIX. On Windows we treat `EEXIST` as success.
|
|
1787
|
+
*
|
|
1788
|
+
* `digest.hash` is trusted — the caller is responsible for computing
|
|
1789
|
+
* the sha256 of the source file first. Re-hashing here would double
|
|
1790
|
+
* the IO on every put.
|
|
1791
|
+
*/
|
|
1792
|
+
declare const putBlobFromFile: (root: string, digest: CasDigest, sourcePath: string) => Promise<void>;
|
|
1793
|
+
/**
|
|
1794
|
+
* Same as {@link putBlobFromFile} but for in-memory bytes. Used for
|
|
1795
|
+
* tiny payloads (the AC entry's stdout digest, tree protos) where
|
|
1796
|
+
* streaming would be more code than it's worth.
|
|
1797
|
+
*/
|
|
1798
|
+
declare const putBlobFromBytes: (root: string, digest: CasDigest, bytes: Buffer) => Promise<void>;
|
|
1799
|
+
/**
|
|
1800
|
+
* Materialize a CAS blob to a destination path. Streams; safe for
|
|
1801
|
+
* large outputs. Returns `false` if the blob isn't in the local store.
|
|
1802
|
+
*/
|
|
1803
|
+
declare const fetchBlobToFile: (root: string, digest: CasDigest, destinationPath: string) => Promise<boolean>;
|
|
1804
|
+
/**
|
|
1805
|
+
* Verify a blob's bytes match its expected digest. Used during legacy
|
|
1806
|
+
* → v2 migration where we trust nothing — sha256 every staged file
|
|
1807
|
+
* before the rename so a bit-flipped legacy artifact doesn't poison
|
|
1808
|
+
* the new CAS.
|
|
1809
|
+
*/
|
|
1810
|
+
declare const verifyBlob: (filePath: string, expected: CasDigest) => Promise<boolean>;
|
|
1811
|
+
/**
|
|
1812
|
+
* Bump mtime/atime on a blob. Drives mark-and-sweep GC: the sweeper
|
|
1813
|
+
* evicts blobs whose mtime is older than `maxCacheAge` AND not
|
|
1814
|
+
* referenced by any AC entry. Touching on hit means LRU tracks real
|
|
1815
|
+
* usage rather than write-time.
|
|
1816
|
+
*/
|
|
1817
|
+
declare const touchBlob: (root: string, digest: CasDigest) => Promise<void>;
|
|
1818
|
+
/**
|
|
1223
1819
|
* Summary of a single task execution.
|
|
1224
1820
|
*/
|
|
1225
1821
|
interface TaskSummary {
|
|
@@ -2047,110 +2643,56 @@ declare const isNativeAvailable: () => boolean;
|
|
|
2047
2643
|
*/
|
|
2048
2644
|
declare const resolveOutputs: (workspaceRoot: string, outputs: OutputSpec[] | undefined, autoWrites?: ReadonlyArray<string>) => Promise<string[]>;
|
|
2049
2645
|
/**
|
|
2050
|
-
*
|
|
2051
|
-
*
|
|
2052
|
-
*
|
|
2053
|
-
*
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
*
|
|
2058
|
-
* - `
|
|
2059
|
-
*
|
|
2060
|
-
*
|
|
2061
|
-
*
|
|
2062
|
-
*
|
|
2063
|
-
*
|
|
2646
|
+
* URI schemes recognized by {@link parseInputUri}. Each maps to one of the
|
|
2647
|
+
* existing structured `InputDefinition` shapes — the URI form is a sugar
|
|
2648
|
+
* over the object form so the same hash semantics apply unchanged.
|
|
2649
|
+
*
|
|
2650
|
+
* - `file://<path>` and `glob://<pattern>` → {@link FileSetInput}
|
|
2651
|
+
* (both produce a fileset; the split is purely documentary so a reader
|
|
2652
|
+
* can tell at a glance whether the author meant a single path or a glob).
|
|
2653
|
+
* - `env://<NAME>` → {@link EnvironmentInput}.
|
|
2654
|
+
* - `func://<command>` → {@link RuntimeInput} (runtime command output).
|
|
2655
|
+
* - `dep://<a,b,c>` → {@link ExternalDependencyInput} (comma-separated names).
|
|
2656
|
+
*
|
|
2657
|
+
* `{projectRoot}` and `{workspaceRoot}` tokens are honored inside `file://`
|
|
2658
|
+
* and `glob://` bodies, matching the bare-string form. Negation works for
|
|
2659
|
+
* filesets only (`!file://...`, `!glob://...`); attempting to negate the
|
|
2660
|
+
* other schemes throws because there is no semantic for "not this env var".
|
|
2064
2661
|
*/
|
|
2065
|
-
|
|
2662
|
+
declare const INPUT_URI_SCHEMES: readonly ["file", "glob", "env", "func", "dep"];
|
|
2663
|
+
type InputUriScheme = (typeof INPUT_URI_SCHEMES)[number];
|
|
2066
2664
|
/**
|
|
2067
|
-
*
|
|
2665
|
+
* Thrown when a string carries a URI-shaped prefix but the scheme is
|
|
2666
|
+
* unrecognized or the body violates a scheme-specific constraint
|
|
2667
|
+
* (e.g. negating a non-fileset scheme).
|
|
2068
2668
|
*
|
|
2069
|
-
*
|
|
2070
|
-
*
|
|
2071
|
-
*
|
|
2072
|
-
* signature doesn't match using a constant-time comparison.
|
|
2073
|
-
*
|
|
2074
|
-
* Prevents cache poisoning in shared team environments where a
|
|
2075
|
-
* compromised cache server (or a MITM) could inject malicious
|
|
2076
|
-
* artifacts. Unsigned entries (written before signing was enabled)
|
|
2077
|
-
* are accepted only when `verifyOnDownload === false` — the default.
|
|
2669
|
+
* Surfaces as a config-load error rather than degrading silently into a
|
|
2670
|
+
* fileset glob — silent fallback would let typos like `gob://**` mask
|
|
2671
|
+
* cache-correctness bugs that only show up at hash-divergence time.
|
|
2078
2672
|
*/
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
secret: string;
|
|
2082
|
-
/**
|
|
2083
|
-
* Reject downloads whose signature doesn't match or is missing.
|
|
2084
|
-
* Set to `true` once every upload on your server is signed.
|
|
2085
|
-
* @default false
|
|
2086
|
-
*/
|
|
2087
|
-
verifyOnDownload?: boolean;
|
|
2673
|
+
declare class InvalidInputUriError extends Error {
|
|
2674
|
+
constructor(message: string);
|
|
2088
2675
|
}
|
|
2089
2676
|
/**
|
|
2090
|
-
*
|
|
2677
|
+
* Parses a URI-prefixed input string into its structured `InputDefinition`.
|
|
2678
|
+
* Returns `undefined` for strings that don't carry a URI scheme — callers
|
|
2679
|
+
* fall back to existing handling (named-input lookup, bare globs).
|
|
2091
2680
|
*/
|
|
2092
|
-
|
|
2093
|
-
/**
|
|
2094
|
-
* Compression format for artifact tarballs. Defaults to `"gzip"`
|
|
2095
|
-
* for Turborepo protocol compatibility.
|
|
2096
|
-
*/
|
|
2097
|
-
compression?: RemoteCacheCompression;
|
|
2098
|
-
/**
|
|
2099
|
-
* Called when a fire-and-forget upload fails.
|
|
2100
|
-
* Since uploads are non-blocking, errors are silently swallowed by default.
|
|
2101
|
-
* Provide this callback to log or report upload failures.
|
|
2102
|
-
*/
|
|
2103
|
-
onUploadError?: (hash: string, error: unknown) => void;
|
|
2104
|
-
/** Whether to enable remote cache reads */
|
|
2105
|
-
read?: boolean;
|
|
2106
|
-
/**
|
|
2107
|
-
* HMAC-SHA256 signing for upload integrity. When set, every
|
|
2108
|
-
* uploaded artifact carries an `X-Artifact-Signature` header;
|
|
2109
|
-
* downloads with `verifyOnDownload: true` reject unsigned or
|
|
2110
|
-
* tampered payloads.
|
|
2111
|
-
*/
|
|
2112
|
-
signing?: RemoteCacheSigning;
|
|
2113
|
-
/** Team ID or namespace for cache isolation */
|
|
2114
|
-
teamId?: string;
|
|
2115
|
-
/** Request timeout in milliseconds (default: 30000) */
|
|
2116
|
-
timeout?: number;
|
|
2117
|
-
/** Authentication token for the remote cache */
|
|
2118
|
-
token?: string;
|
|
2119
|
-
/** Remote cache server URL (e.g., "https://cache.example.com") */
|
|
2120
|
-
url: string;
|
|
2121
|
-
/** Whether to enable remote cache writes */
|
|
2122
|
-
write?: boolean;
|
|
2123
|
-
}
|
|
2681
|
+
declare const parseInputUri: (input: string) => InputDefinition | undefined;
|
|
2124
2682
|
/**
|
|
2125
|
-
*
|
|
2126
|
-
*
|
|
2127
|
-
*
|
|
2128
|
-
*
|
|
2129
|
-
* - PUT /v8/artifacts/{hash}?teamId={team} -> store artifact
|
|
2130
|
-
* - POST /v8/artifacts/events -> analytics (optional)
|
|
2131
|
-
*
|
|
2132
|
-
* Authentication via `Authorization: Bearer {token}` header.
|
|
2133
|
-
*
|
|
2134
|
-
* The cache entry is a gzipped tarball containing the cache directory contents
|
|
2135
|
-
* (code, terminalOutput, fingerprint.json, outputs/, .commit).
|
|
2683
|
+
* Cheap predicate used by callers that only need to know whether a string
|
|
2684
|
+
* looks like a URI — saves them re-parsing when they want to short-circuit
|
|
2685
|
+
* other handling (e.g. file-group lookup) before delegating to
|
|
2686
|
+
* {@link parseInputUri} downstream.
|
|
2136
2687
|
*/
|
|
2137
|
-
declare
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
/**
|
|
2146
|
-
* Stores a cache entry in the remote cache.
|
|
2147
|
-
*/
|
|
2148
|
-
store(hash: string, localCacheDirectory: string): Promise<boolean>;
|
|
2149
|
-
/**
|
|
2150
|
-
* Checks if an artifact exists in the remote cache without downloading it.
|
|
2151
|
-
*/
|
|
2152
|
-
exists(hash: string): Promise<boolean>;
|
|
2153
|
-
}
|
|
2688
|
+
declare const looksLikeInputUri: (input: string) => boolean;
|
|
2689
|
+
/**
|
|
2690
|
+
* Enforces project dependency constraints on a project graph.
|
|
2691
|
+
* @param projectGraph The workspace project graph to validate.
|
|
2692
|
+
* @param constraints The constraint rules to enforce.
|
|
2693
|
+
* @returns Array of violations found. Empty means all constraints pass.
|
|
2694
|
+
*/
|
|
2695
|
+
declare const enforceProjectConstraints: (projectGraph: ProjectGraph, constraints: ConstraintsConfig) => ConstraintViolation[];
|
|
2154
2696
|
interface CreateTaskGraphOptions {
|
|
2155
2697
|
/** The project graph */
|
|
2156
2698
|
projectGraph: ProjectGraph;
|
|
@@ -2368,7 +2910,14 @@ interface TaskOrchestratorOptions {
|
|
|
2368
2910
|
dryRun?: boolean;
|
|
2369
2911
|
fingerprintEnvPatterns?: string[];
|
|
2370
2912
|
lifeCycle: LifeCycleInterface;
|
|
2371
|
-
|
|
2913
|
+
/**
|
|
2914
|
+
* Surfaces bridge-local upload pipeline failures (tar / digest)
|
|
2915
|
+
* for fire-and-forget remote-cache writes. Wire-level errors are
|
|
2916
|
+
* already reported by the backend's own `onUploadError`; this
|
|
2917
|
+
* fills the gap for steps the backend never sees.
|
|
2918
|
+
*/
|
|
2919
|
+
onRemoteUploadError?: (hash: string, error: unknown) => void;
|
|
2920
|
+
remoteCache?: RemoteCacheBackend;
|
|
2372
2921
|
resolveCommand?: (task: Task) => string | undefined;
|
|
2373
2922
|
scheduler: TaskScheduler;
|
|
2374
2923
|
skipCache?: boolean;
|
|
@@ -2500,8 +3049,45 @@ declare const readPackageDeps: (packageJsonPath: string, options?: {
|
|
|
2500
3049
|
peer?: boolean;
|
|
2501
3050
|
}) => Promise<Set<string> | undefined>;
|
|
2502
3051
|
/**
|
|
2503
|
-
* Generates a unique ID for temporary files/directories
|
|
2504
|
-
*
|
|
3052
|
+
* Generates a unique ID for temporary files/directories using
|
|
3053
|
+
* `crypto.randomUUID()`. Used for staging-path names that briefly
|
|
3054
|
+
* coexist on disk during atomic writes — collisions would clobber a
|
|
3055
|
+
* concurrent writer's staging directory, so the extra entropy over
|
|
3056
|
+
* `Date.now() + Math.random()` is worth the cycles. UUID v4 from
|
|
3057
|
+
* Node's crypto module is itself uniformly random, making this
|
|
3058
|
+
* cheaper than the previous string concat.
|
|
2505
3059
|
*/
|
|
2506
3060
|
declare const uniqueId: () => string;
|
|
2507
|
-
|
|
3061
|
+
/**
|
|
3062
|
+
* Returns the absolute path to the *main* git worktree root when
|
|
3063
|
+
* `workspaceRoot` is a linked worktree, or `undefined` for primary
|
|
3064
|
+
* checkouts and non-git directories.
|
|
3065
|
+
*
|
|
3066
|
+
* Result is memoized for the lifetime of the process — worktree topology
|
|
3067
|
+
* does not change at runtime, so the second call is a hash lookup.
|
|
3068
|
+
*
|
|
3069
|
+
* Detection logic:
|
|
3070
|
+
* 1. If `{workspaceRoot}/.git` is a *directory*, this is a primary checkout
|
|
3071
|
+
* (or vanilla repo). Returns `undefined`.
|
|
3072
|
+
* 2. If `{workspaceRoot}/.git` is a *file* (gitlink), resolves to the parent
|
|
3073
|
+
* of `git rev-parse --git-common-dir` — that is the main worktree root.
|
|
3074
|
+
* 3. On any error (missing git binary, shallow CI checkout, etc.), returns
|
|
3075
|
+
* `undefined` so the caller falls back to the workspace-local cache.
|
|
3076
|
+
* @param workspaceRoot Absolute path to the candidate workspace root.
|
|
3077
|
+
* @returns The main worktree root, or `undefined` if not a linked worktree.
|
|
3078
|
+
*/
|
|
3079
|
+
declare const getMainWorktreeRoot: (workspaceRoot: string) => string | undefined;
|
|
3080
|
+
/**
|
|
3081
|
+
* Returns `true` when `{workspaceRoot}/.git` is a regular file (the gitlink
|
|
3082
|
+
* pointer used by `git worktree add`), `false` otherwise. Cheap pre-flight
|
|
3083
|
+
* before invoking `git rev-parse`.
|
|
3084
|
+
* @param workspaceRoot Absolute path to the candidate workspace root.
|
|
3085
|
+
*/
|
|
3086
|
+
declare const isLinkedWorktree: (workspaceRoot: string) => boolean;
|
|
3087
|
+
/**
|
|
3088
|
+
* Clears the in-process detection cache. Tests must call this between
|
|
3089
|
+
* scenarios because the cache key is the canonicalized workspace path —
|
|
3090
|
+
* recreating a fixture at the same path would otherwise leak stale results.
|
|
3091
|
+
*/
|
|
3092
|
+
declare const resetWorktreeCache: () => void;
|
|
3093
|
+
export { type ActionResult, type AffectedOptions, type AffectedResult, type AffectedScope, type BlobSource, Cache, type CacheMissReason, type CacheMode, type CacheOptions, type CacheRestoreOptions, type CachedResult, type CasDigest, type ChromeTraceEvent, CompositeLifeCycle, type ConcurrentCloseEvent, type ConcurrentCommandConfig, type ConcurrentCommandInput, type ConcurrentRunResult, type ConcurrentRunnerOptions, ConsoleLifeCycle, type ConstraintViolation, type ConstraintsConfig, DEFAULT_CACHE_DIRECTORY_NAME, type DependencyKindRules, type DependencyType, type DetectedFramework, EmptyLifeCycle, type EnvMatcher, type EnvironmentInput, type ExternalDependencyInput, type FileAccess, FileAccessTracker, type FileSetBase, type FileSetInput, type FileSetPattern, type FileSnapshot, FingerprintManager, type GraphFormat, type GraphJson, type GraphVisualizerOptions, HttpRemoteCache, INPUT_URI_SCHEMES, InProcessTaskHasher, IncrementalFileHasher, type IncrementalHasherOptions, type InputDefinition, type InputHandlerOptions, type InputUriScheme, InvalidInputUriError, type LifeCycleInterface, LockfileHasher, type LogMode, LogReporter, type NamedInputs, type NodePlatform, type OutputSpec, type PackageLockfileHash, type ParseCommandsOptions, type PartitionOptions, type ProcessEvent, type ProjectConfiguration, type ProjectGraph, type ProjectGraphDependency, type ProjectGraphProjectNode, ReapiRemoteCache, type ReapiRemoteCacheOptions, type RemoteCacheBackend, type RemoteCacheCompression, type RemoteCacheOptions, type RemoteCacheSigning, type ResolvedDependency, type RestartOptions, type RunSummary, type RuntimeInput, type TagRelationships, type TargetConfiguration, type TargetDependencyConfig, type Task, type TaskExecutionOptions, type TaskExecutor, type TaskFingerprint, type TaskGraph, type TaskHashDetails, type TaskHasher, type TaskHasherOptions, TaskOrchestrator, type TaskOrchestratorOptions, type TaskPriority, type TaskResult, type TaskResults, type TaskRunnerContext, type TaskRunnerOptions, TaskScheduler, type TaskStatus, type TaskSummary, type TaskTarget, type TasksRunner, type TeardownOptions, TerminalBuffer, type TokenContext, type TrackedExecutionResult, TrackedTaskExecutor, type TrackingResult, type TypeBoundaries, V2_AC, V2_CAS, V2_INDEX, V2_ROOT, V2_TMP, type WhenCondition, type WhenContext, type WorkspaceConfiguration, acEntryPath, actionDigestForTaskHash, buildForwardDependencyMap, buildReverseDependencyMap, casBlobPath, collectFiles, computeTaskHash, containsBlob, containsByTaskHash, createFailureResult, createInputHandler, createLogReporter, createRemoteCacheBackend, createTaskGraph, defaultTaskRunner, detectFrameworks, detectScriptShell, digestBuffer, digestFile, enforceProjectConstraints, evaluateWhen, expandAffected, expandArguments, expandShortcut, expandTokens, expandTokensInString, expandWildcard, explainWhen, extractPackageName, fetchBlobToFile, filterAffectedTasks, findCycle, findCycles, formatCacheSize, formatTimingTable, generatePreloadScript, generateRunSummary, getAffectedProjects, getChangedFiles, getCurrentBranch, getDependentTasks, getFrameworkEnvVariables, getLastRunSummaryPath, getLeafTasks, getMainWorktreeRoot, getTaskId, getTransitiveDependencies, hashFile, hashStrings, inferFrameworkEnvPatterns, isLinkedWorktree, isNativeAvailable, loadNativeBindings, logTimings, looksLikeInputUri, makeAcyclic, parseCacheSize, parseCommands, parseInputUri, parseNpmLockfile, parsePartition, parsePnpmLockfile, parseTaskId, parseYarnLockfile, projectGraphToDot, putBlobFromBytes, putBlobFromFile, readLastRunSummary, readPackageDeps, resetBranchCache, resetWorktreeCache, resolveCacheMode, resolveOutputs, resolveTaskCwd, retrieveByTaskHash, reverseTaskGraph, runConcurrentFallback, runConcurrently, runTeardown, sortObjectKeys, storeByTaskHash, stripQuotes, taskHashIndexPath, toChromeTrace, toGraphAscii, toGraphHtml, toGraphJson, toGraphvizDot, touchBlob, uniqueId, verifyBlob, walkTaskGraph, withRestart, writeChromeTrace, writeLastRunSummary, writeRunSummary };
|