@vzn/vx 0.0.651 → 0.0.652
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/README.md +2 -3
- package/package.json +5 -5
- package/schemas/show.json +14 -20
- package/src/bin.ts +12 -0
- package/src/cache/archive.ts +1 -1
- package/src/cache/cache.ts +19 -5
- package/src/cache/history-stream.ts +134 -0
- package/src/cache/history-writer.ts +76 -0
- package/src/cache/index.ts +2 -0
- package/src/cache/inputs.ts +74 -14
- package/src/cache/layer.ts +6 -6
- package/src/cache/lockfile-memo.ts +2 -1
- package/src/cache/run-history.ts +46 -17
- package/src/cache/schema.ts +4 -1
- package/src/cli/cache.ts +2 -2
- package/src/cli/help.ts +2 -2
- package/src/cli/index.ts +24 -0
- package/src/cli/info.ts +1 -1
- package/src/cli/last.ts +34 -2
- package/src/cli/plugin-templates.ts +36 -45
- package/src/cli/show.ts +7 -10
- package/src/cli/watch-judge.ts +1 -1
- package/src/cli/watch-set.ts +4 -4
- package/src/cli/watch.ts +11 -8
- package/src/config.ts +47 -30
- package/src/exec/executor.ts +40 -1
- package/src/exec/index.ts +1 -0
- package/src/exec/sandbox-paths.ts +3 -1
- package/src/exec/sandbox-runtime.ts +314 -29
- package/src/exec/task-proxy.ts +93 -0
- package/src/graph/definition.ts +16 -3
- package/src/graph/scheduler.ts +3 -1
- package/src/graph/task-graph.ts +24 -23
- package/src/history/failure-mode.ts +24 -1
- package/src/history/index.ts +1 -0
- package/src/history/metrics.ts +5 -5
- package/src/index.ts +4 -2
- package/src/orchestrator/admission.ts +1 -1
- package/src/orchestrator/command-windows.ts +1 -1
- package/src/orchestrator/deferred-outputs.ts +1 -1
- package/src/orchestrator/download-policy.ts +5 -7
- package/src/orchestrator/excluded-keys.ts +1 -1
- package/src/orchestrator/execute-task.ts +51 -18
- package/src/orchestrator/hit-restore.ts +5 -6
- package/src/orchestrator/keyed-projects.ts +28 -0
- package/src/orchestrator/local-shortcircuit.ts +2 -2
- package/src/orchestrator/miss-save.ts +27 -8
- package/src/orchestrator/persistent-task.ts +2 -0
- package/src/orchestrator/placement.ts +1 -1
- package/src/orchestrator/plan.ts +2 -2
- package/src/orchestrator/plugin-host.ts +6 -2
- package/src/orchestrator/plugin.ts +6 -0
- package/src/orchestrator/remote-prefetch.ts +1 -1
- package/src/orchestrator/run-failures.ts +61 -12
- package/src/orchestrator/run-keys.ts +1 -1
- package/src/orchestrator/run-records.ts +86 -67
- package/src/orchestrator/run-report.ts +1 -1
- package/src/orchestrator/run.ts +92 -19
- package/src/orchestrator/sandbox-request.ts +50 -7
- package/src/orchestrator/shell-verdict.ts +9 -0
- package/src/orchestrator/stable-keys.ts +17 -18
- package/src/orchestrator/task-artifacts.ts +1 -1
- package/src/orchestrator/task-hash.ts +4 -4
- package/src/orchestrator/telemetry.ts +5 -1
- package/src/report/events.ts +3 -3
- package/src/report/framed-output.ts +16 -7
- package/src/report/logger.ts +1 -1
- package/src/report/plain-output.ts +2 -0
- package/src/report/summary.ts +5 -5
- package/src/settings.ts +8 -8
- package/src/util/config-frame.ts +128 -6
- package/src/util/paths.ts +1 -1
- package/src/util/settle.ts +2 -1
- package/src/util/tail.ts +4 -1
- package/src/workspace/bracket-literal.ts +2 -2
- package/src/workspace/config-schema.ts +66 -61
- package/src/workspace/filter.ts +8 -1
- package/src/workspace/migration.ts +12 -6
package/src/config.ts
CHANGED
|
@@ -28,6 +28,10 @@ export interface WorkspaceConfig {
|
|
|
28
28
|
baseBranch?: string
|
|
29
29
|
run?: RunSettings
|
|
30
30
|
cache?: CacheSettings
|
|
31
|
+
/** Input defaults for every task. */
|
|
32
|
+
inputs?: WorkspaceInputs
|
|
33
|
+
/** Output defaults for every task. */
|
|
34
|
+
outputs?: WorkspaceOutputs
|
|
31
35
|
lock?: LockSettings
|
|
32
36
|
watch?: WatchSettings
|
|
33
37
|
/**
|
|
@@ -76,6 +80,18 @@ export interface RunSettings {
|
|
|
76
80
|
rules?: WorkspaceRules
|
|
77
81
|
}
|
|
78
82
|
|
|
83
|
+
/** `WorkspaceConfig.inputs`. */
|
|
84
|
+
export interface WorkspaceInputs {
|
|
85
|
+
/** The `inputs.stability` of every task that does not set its own. */
|
|
86
|
+
stability?: InputStability
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** `WorkspaceConfig.outputs`. */
|
|
90
|
+
export interface WorkspaceOutputs {
|
|
91
|
+
/** The `outputs.clean` of every task that does not set its own. */
|
|
92
|
+
clean?: boolean
|
|
93
|
+
}
|
|
94
|
+
|
|
79
95
|
/** `WorkspaceConfig.cache`: where the cache lives and what a run does with it. */
|
|
80
96
|
export interface CacheSettings {
|
|
81
97
|
/**
|
|
@@ -93,10 +109,6 @@ export interface CacheSettings {
|
|
|
93
109
|
policy?: string
|
|
94
110
|
/** Which remote hits land on disk: `all` (the default), only the requested tasks' (`toplevel`), or `none`. */
|
|
95
111
|
download?: 'all' | 'toplevel' | 'none'
|
|
96
|
-
/** The `cache.inputStability` of every task that does not set its own. */
|
|
97
|
-
inputStability?: InputStability
|
|
98
|
-
/** The `cache.outputs.clean` of every task that does not set its own. */
|
|
99
|
-
outputs?: { clean?: boolean }
|
|
100
112
|
/**
|
|
101
113
|
* Which runs keep a failed task's log and the files its outputs left in
|
|
102
114
|
* the remote: CI runs (`'ci'`, the default), runs off CI (`'local'`), or
|
|
@@ -305,13 +317,15 @@ export interface TaskConfig {
|
|
|
305
317
|
* keyed group: its inputs are a key its dependents fold, with no process.
|
|
306
318
|
*/
|
|
307
319
|
inputs?: InputsConfig
|
|
320
|
+
/** What the task produces: saved on a miss, restored on a hit. Needs `cache: true`. */
|
|
321
|
+
outputs?: TaskOutputs
|
|
308
322
|
/**
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
* Requires `exec` and `
|
|
312
|
-
* runs nothing to cache.
|
|
323
|
+
* `true` caches the task. **Caching is opt-in.** Omitted or `false`, the
|
|
324
|
+
* task always runs and nothing is read from or written to the cache.
|
|
325
|
+
* Requires `exec`, `inputs` and `outputs`: the key is the task's inputs,
|
|
326
|
+
* and a group runs nothing to cache.
|
|
313
327
|
*/
|
|
314
|
-
cache?:
|
|
328
|
+
cache?: boolean
|
|
315
329
|
}
|
|
316
330
|
|
|
317
331
|
/**
|
|
@@ -335,7 +349,7 @@ export interface TaskConfig {
|
|
|
335
349
|
* from the other coupled them both ways — a declaration added for
|
|
336
350
|
* caching silently widened the sandbox, and a path the task needed had
|
|
337
351
|
* to be laundered through the cache key to get it (2026-09-05).
|
|
338
|
-
* A declared `
|
|
352
|
+
* A declared `outputs` is NOT a write grant; the request
|
|
339
353
|
* `sandbox-request.ts` builds carries no write of its own and binds
|
|
340
354
|
* `allow.write` alone. This comment claimed the opposite — here and on
|
|
341
355
|
* both grant fields — while the file beside it and `schema.md` both said
|
|
@@ -391,6 +405,13 @@ export interface SandboxConfig {
|
|
|
391
405
|
weakerWhenNested?: boolean
|
|
392
406
|
/** Accept weaker network isolation (host proxy) for lower overhead. */
|
|
393
407
|
weakerNetworkIsolation?: boolean
|
|
408
|
+
/**
|
|
409
|
+
* Refuse every read outside the workspace too (`/usr`, `~/.cache`, the
|
|
410
|
+
* system toolchain), not only the workspace's other projects. A path
|
|
411
|
+
* outside it is readable only when `allow.read` names it; the shell a
|
|
412
|
+
* task runs in stays readable, so a task can start.
|
|
413
|
+
*/
|
|
414
|
+
hermetic?: boolean
|
|
394
415
|
}
|
|
395
416
|
|
|
396
417
|
/** The denials `sandbox.ignore` can leave out of the report: patterns per class. */
|
|
@@ -410,9 +431,9 @@ export interface SandboxGrants {
|
|
|
410
431
|
read?: readonly string[]
|
|
411
432
|
/**
|
|
412
433
|
* Writable paths or globs. The task can write NOTHING without these:
|
|
413
|
-
* declaring `
|
|
434
|
+
* declaring `outputs.files` grants no write, and a task whose
|
|
414
435
|
* only declaration is its outputs writes into a tmpfs that evaporates
|
|
415
|
-
* (vx then warns that `
|
|
436
|
+
* (vx then warns that `outputs` matched no files).
|
|
416
437
|
*/
|
|
417
438
|
write?: readonly string[]
|
|
418
439
|
/**
|
|
@@ -585,17 +606,6 @@ export interface ExecEnv {
|
|
|
585
606
|
secret?: readonly string[]
|
|
586
607
|
}
|
|
587
608
|
|
|
588
|
-
export interface CacheConfig {
|
|
589
|
-
/** What this task produces. Captured for restore on a cache hit. */
|
|
590
|
-
outputs: CacheOutputs
|
|
591
|
-
/**
|
|
592
|
-
* What a write to an input while the command runs means. Each field,
|
|
593
|
-
* highest first: its env var, this, the workspace's `inputStability`,
|
|
594
|
-
* the default (`'immutable'`, `'warn'`).
|
|
595
|
-
*/
|
|
596
|
-
inputStability?: InputStability
|
|
597
|
-
}
|
|
598
|
-
|
|
599
609
|
export interface InputStability {
|
|
600
610
|
/**
|
|
601
611
|
* `'immutable'` (the default): any write to an input during the command
|
|
@@ -615,7 +625,7 @@ export interface InputStability {
|
|
|
615
625
|
severity?: 'warn' | 'error'
|
|
616
626
|
}
|
|
617
627
|
|
|
618
|
-
export interface
|
|
628
|
+
export interface TaskOutputs {
|
|
619
629
|
/**
|
|
620
630
|
* Files produced by this task, as project-relative globs. Pass `[]`
|
|
621
631
|
* when the task has no files to capture (e.g. `lint`, `typecheck`).
|
|
@@ -640,7 +650,7 @@ export interface CacheOutputs {
|
|
|
640
650
|
* (tsc's `.tsbuildinfo`) instead of removing them first. A run that
|
|
641
651
|
* leaves a file it found untouched saves nothing, so an entry holds only
|
|
642
652
|
* what a clean run would leave. A retry still starts clean. Omitted →
|
|
643
|
-
* the workspace's `
|
|
653
|
+
* the workspace's `outputs.clean`, else `true`.
|
|
644
654
|
*/
|
|
645
655
|
clean?: boolean
|
|
646
656
|
}
|
|
@@ -716,6 +726,13 @@ export interface InputsConfig {
|
|
|
716
726
|
* tool versions, OS info, etc.
|
|
717
727
|
*/
|
|
718
728
|
workspaceRuntime?: readonly string[]
|
|
729
|
+
/**
|
|
730
|
+
* What a write to an input while the command runs means for the save.
|
|
731
|
+
* Each field, highest first: its env var, this, the workspace's
|
|
732
|
+
* `inputs.stability`, the default (`'immutable'`, `'warn'`). Needs
|
|
733
|
+
* `cache: true`.
|
|
734
|
+
*/
|
|
735
|
+
stability?: InputStability
|
|
719
736
|
}
|
|
720
737
|
|
|
721
738
|
/**
|
|
@@ -785,9 +802,7 @@ export function defineProject<const T extends ProjectConfig>(
|
|
|
785
802
|
dependsOn?: readonly DependsOnEntry<Extract<keyof NonNullable<T['tasks']>, string>>[]
|
|
786
803
|
exec?: Known<At<NonNullable<T['tasks']>[K], 'exec'>, ExecConfig>
|
|
787
804
|
inputs?: Known<At<NonNullable<T['tasks']>[K], 'inputs'>, InputsConfig>
|
|
788
|
-
|
|
789
|
-
outputs?: Known<At<At<NonNullable<T['tasks']>[K], 'cache'>, 'outputs'>, CacheOutputs>
|
|
790
|
-
}
|
|
805
|
+
outputs?: Known<At<NonNullable<T['tasks']>[K], 'outputs'>, TaskOutputs>
|
|
791
806
|
}
|
|
792
807
|
}
|
|
793
808
|
},
|
|
@@ -801,9 +816,11 @@ export function defineWorkspace<T extends WorkspaceConfig>(
|
|
|
801
816
|
run?: Known<At<T, 'run'>, RunSettings> & {
|
|
802
817
|
rules?: Known<At<At<T, 'run'>, 'rules'>, WorkspaceRules>
|
|
803
818
|
}
|
|
804
|
-
cache?: Known<At<T, 'cache'>, CacheSettings>
|
|
805
|
-
|
|
819
|
+
cache?: Known<At<T, 'cache'>, CacheSettings>
|
|
820
|
+
inputs?: Known<At<T, 'inputs'>, WorkspaceInputs> & {
|
|
821
|
+
stability?: Known<At<At<T, 'inputs'>, 'stability'>, InputStability>
|
|
806
822
|
}
|
|
823
|
+
outputs?: Known<At<T, 'outputs'>, WorkspaceOutputs>
|
|
807
824
|
lock?: Known<At<T, 'lock'>, LockSettings>
|
|
808
825
|
watch?: Known<At<T, 'watch'>, WatchSettings>
|
|
809
826
|
},
|
package/src/exec/executor.ts
CHANGED
|
@@ -43,6 +43,11 @@ export interface ExecuteSandbox {
|
|
|
43
43
|
* machine's paths and platform, hands `sandboxRequestFor`.
|
|
44
44
|
*/
|
|
45
45
|
readonly keyed?: readonly string[]
|
|
46
|
+
/**
|
|
47
|
+
* The dependencies' outputs it may read (absolute), which an executor
|
|
48
|
+
* that builds the request again hands `sandboxRequestFor` too.
|
|
49
|
+
*/
|
|
50
|
+
readonly dependencyReads?: readonly string[]
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
/** One declared input file, as the cache key saw it. */
|
|
@@ -108,7 +113,7 @@ export interface ExecuteRequest {
|
|
|
108
113
|
/** `${project}#${task}` — for executors that route or log by task. */
|
|
109
114
|
readonly taskId: string
|
|
110
115
|
readonly workspaceRoot: string
|
|
111
|
-
/** Present for cacheable tasks (the miss path); absent
|
|
116
|
+
/** Present for cacheable tasks (the miss path); absent for a task without `cache: true`. */
|
|
112
117
|
readonly inputs?: TaskInputs
|
|
113
118
|
/**
|
|
114
119
|
* The task's cache key (present when the task is cacheable). An executor
|
|
@@ -145,6 +150,12 @@ export interface ExecuteRequest {
|
|
|
145
150
|
* executor's `platforms`: its key includes it. Absent when the task names none.
|
|
146
151
|
*/
|
|
147
152
|
readonly platform?: string
|
|
153
|
+
/**
|
|
154
|
+
* Which attempt of the task this is, from 2 when it retries; absent on
|
|
155
|
+
* the first. An executor that can, runs a retry somewhere other than
|
|
156
|
+
* the attempt before it, so the machine is not the flake.
|
|
157
|
+
*/
|
|
158
|
+
readonly attempt?: number
|
|
148
159
|
/**
|
|
149
160
|
* Whether this task's outputs must land on the submitter's disk now.
|
|
150
161
|
* 'eager' (or absent) = materialise as today. 'deferred' = leave them
|
|
@@ -377,6 +388,13 @@ export interface TaskExecutor {
|
|
|
377
388
|
* anything but a finite number, reports none.
|
|
378
389
|
*/
|
|
379
390
|
idealMs?(): number | undefined
|
|
391
|
+
/**
|
|
392
|
+
* The workers that would have run the run best, judged after it from
|
|
393
|
+
* what each task took: for the run summary, so its reader can change
|
|
394
|
+
* how many workers the executor may start and of what size. Asked once
|
|
395
|
+
* at the end, only when a sink is on. A throw reports none.
|
|
396
|
+
*/
|
|
397
|
+
advice?(): readonly WorkerAdvice[]
|
|
380
398
|
/**
|
|
381
399
|
* Its own Chrome-trace events for `vx run --profile` (the machines it ran
|
|
382
400
|
* tasks on, in time), asked once at the end, only when the flag is set.
|
|
@@ -423,6 +441,27 @@ export interface MachineReport {
|
|
|
423
441
|
startMs?: number
|
|
424
442
|
}
|
|
425
443
|
|
|
444
|
+
/**
|
|
445
|
+
* Workers that would have run the run best (`TaskExecutor.advice`): `of`
|
|
446
|
+
* says on what. `declared`: as many of each size the executor may start
|
|
447
|
+
* as end it soonest; `more`: past each size's limit, when that ends it
|
|
448
|
+
* sooner; `any`: one shape a platform, of any cores, ending as soon for
|
|
449
|
+
* the least core time.
|
|
450
|
+
*/
|
|
451
|
+
export interface WorkerAdvice {
|
|
452
|
+
of: 'declared' | 'more' | 'any'
|
|
453
|
+
/** The run's end on them, from its start. */
|
|
454
|
+
endMs: number
|
|
455
|
+
workers: readonly {
|
|
456
|
+
count: number
|
|
457
|
+
cores: number
|
|
458
|
+
memoryBytes: number
|
|
459
|
+
platform?: string
|
|
460
|
+
/** The size it is, for `declared` and `more`. */
|
|
461
|
+
size?: string
|
|
462
|
+
}[]
|
|
463
|
+
}
|
|
464
|
+
|
|
426
465
|
/**
|
|
427
466
|
* What a remote executor rejects with when it gives a task back: core runs
|
|
428
467
|
* the same request on the local floor and says `reason` once (a remote that
|
package/src/exec/index.ts
CHANGED
|
@@ -102,6 +102,8 @@ export function sandboxReads(
|
|
|
102
102
|
readonly config: {
|
|
103
103
|
readonly allowRead: readonly string[]
|
|
104
104
|
readonly allowWrite: readonly string[]
|
|
105
|
+
/** Denies the whole host, not only `baseDenyRead`: only a grant reads. */
|
|
106
|
+
readonly hermetic?: boolean
|
|
105
107
|
}
|
|
106
108
|
},
|
|
107
109
|
file: string,
|
|
@@ -109,7 +111,7 @@ export function sandboxReads(
|
|
|
109
111
|
const real = toRealPath(file)
|
|
110
112
|
const under = (g: string): boolean => atOrUnder(real, toRealPath(g))
|
|
111
113
|
return (
|
|
112
|
-
!sandbox.baseDenyRead.some(under) ||
|
|
114
|
+
(sandbox.config.hermetic !== true && !sandbox.baseDenyRead.some(under)) ||
|
|
113
115
|
[...sandbox.baseAllowRead, ...sandbox.config.allowRead, ...sandbox.config.allowWrite].some(
|
|
114
116
|
under,
|
|
115
117
|
)
|