@vzn/vx 0.0.635 → 0.0.637
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 +47 -19
- package/docs/caching.md +222 -210
- package/docs/cli.md +699 -664
- package/docs/execution.md +67 -75
- package/docs/features.md +44 -40
- package/docs/patterns.md +31 -32
- package/docs/schema.md +418 -202
- package/docs/security.md +76 -39
- package/launcher.sh +43 -0
- package/package.json +5 -5
- package/schemas/cache.json +41 -19
- package/schemas/info.json +23 -11
- package/schemas/last.json +48 -2
- package/schemas/lock.json +1 -1
- package/schemas/plan.json +2 -2
- package/schemas/show.json +13 -4
- package/schemas/why.json +15 -1
- package/skills/vx/SKILL.md +16 -12
- package/src/bin.ts +17 -2
- package/src/cache/archive.ts +11 -0
- package/src/cache/cache.ts +105 -53
- package/src/cache/git-inputs.ts +277 -63
- package/src/cache/index.ts +7 -1
- package/src/cache/inputs.ts +125 -35
- package/src/cache/key-fold.ts +8 -7
- package/src/cache/layer.ts +8 -17
- package/src/cache/layered-cache.ts +16 -102
- package/src/cache/policy.ts +25 -29
- package/src/cache/run-history.ts +36 -14
- package/src/cache/schema.ts +21 -23
- package/src/cache/scoped-cache.ts +224 -0
- package/src/cli/cache.ts +150 -28
- package/src/cli/completions.ts +2 -2
- package/src/cli/core-alias.ts +1 -1
- package/src/cli/foreign-flags.ts +13 -12
- package/src/cli/help.ts +94 -61
- package/src/cli/index.ts +42 -13
- package/src/cli/info.ts +38 -23
- package/src/cli/init.ts +115 -406
- package/src/cli/last.ts +145 -4
- package/src/cli/lock.ts +333 -111
- package/src/cli/plan-format.ts +2 -2
- package/src/cli/plugin-commands.ts +5 -9
- package/src/cli/plugin-templates.ts +10 -10
- package/src/cli/run.ts +123 -144
- package/src/cli/select.ts +33 -39
- package/src/cli/show.ts +17 -19
- package/src/cli/task-verb.ts +2 -9
- package/src/cli/upgrade.ts +402 -145
- package/src/cli/watch-cycle.ts +9 -2
- package/src/cli/watch-filter.ts +33 -60
- package/src/cli/watch-fs.ts +29 -16
- package/src/cli/watch-judge.ts +12 -3
- package/src/cli/watch-set.ts +16 -42
- package/src/cli/watch.ts +188 -215
- package/src/cli/why.ts +28 -17
- package/src/cli/workspace-config.ts +31 -68
- package/src/config.ts +191 -71
- package/src/exec/env.ts +1 -31
- package/src/exec/executor.ts +1 -5
- package/src/exec/kill-tree.ts +2 -1
- package/src/exec/sandbox-runtime.ts +12 -1
- package/src/exec/sandbox-violations.ts +9 -1
- package/src/graph/dependency-spec.ts +1 -1
- package/src/graph/index.ts +1 -0
- package/src/graph/priorities.ts +1 -1
- package/src/graph/scheduler.ts +19 -7
- package/src/graph/task-graph.ts +44 -20
- package/src/handoff.ts +169 -0
- package/src/index.ts +25 -57
- package/src/orchestrator/affected-tasks.ts +7 -5
- package/src/orchestrator/command-windows.ts +44 -0
- package/src/orchestrator/deferred-outputs.ts +12 -10
- package/src/orchestrator/doctor.ts +98 -110
- package/src/orchestrator/download-policy.ts +3 -3
- package/src/orchestrator/events.ts +19 -3
- package/src/orchestrator/excluded-keys.ts +0 -2
- package/src/orchestrator/execute-task.ts +192 -70
- package/src/orchestrator/fingerprint-watch.ts +18 -15
- package/src/orchestrator/forecast.ts +10 -2
- package/src/orchestrator/framed-output.ts +8 -3
- package/src/orchestrator/graph-stage.ts +5 -5
- package/src/orchestrator/history.ts +70 -30
- package/src/orchestrator/hit-restore.ts +15 -3
- package/src/orchestrator/index.ts +18 -4
- package/src/orchestrator/local-shortcircuit.ts +2 -1
- package/src/orchestrator/lockfile-claim.ts +79 -20
- package/src/orchestrator/logger.ts +71 -39
- package/src/orchestrator/metrics.ts +71 -6
- package/src/orchestrator/miss-save.ts +3 -0
- package/src/orchestrator/options.ts +43 -28
- package/src/orchestrator/output-host.ts +72 -0
- package/src/orchestrator/plan.ts +6 -8
- package/src/orchestrator/plugin-host.ts +87 -63
- package/src/orchestrator/plugin.ts +94 -60
- package/src/orchestrator/prepare.ts +114 -73
- package/src/orchestrator/projects.ts +102 -99
- package/src/orchestrator/remote-prefetch.ts +2 -1
- package/src/orchestrator/run-context.ts +25 -6
- package/src/orchestrator/run-failures.ts +17 -8
- package/src/orchestrator/run-lock.ts +1 -1
- package/src/orchestrator/run-report.ts +9 -9
- package/src/orchestrator/run-settings.ts +48 -0
- package/src/orchestrator/run.ts +127 -88
- package/src/orchestrator/sandbox-fix.ts +39 -20
- package/src/orchestrator/sandbox-request.ts +84 -13
- package/src/orchestrator/signals.ts +1 -1
- package/src/orchestrator/stable-keys.ts +13 -11
- package/src/orchestrator/status-line.ts +48 -6
- package/src/orchestrator/summary.ts +46 -62
- package/src/orchestrator/task-hash.ts +12 -83
- package/src/orchestrator/telemetry.ts +3 -3
- package/src/settings.ts +417 -0
- package/src/util/errors.ts +1 -1
- package/src/util/essential-env.ts +31 -0
- package/src/util/hide-env.ts +107 -0
- package/src/util/index.ts +8 -2
- package/src/util/paths.ts +10 -0
- package/src/util/settle.ts +49 -30
- package/src/util/size.ts +23 -4
- package/src/util/timing.ts +3 -2
- package/src/util/ulid.ts +1 -1
- package/src/util/verbs.ts +0 -15
- package/src/workspace/affected.ts +77 -222
- package/src/workspace/config-eval.ts +15 -20
- package/src/workspace/config-imports.ts +78 -3
- package/src/workspace/config-schema.ts +251 -241
- package/src/workspace/dependency-rules.ts +57 -0
- package/src/workspace/filter.ts +2 -2
- package/src/workspace/fingerprint.ts +11 -121
- package/src/workspace/index.ts +22 -27
- package/src/workspace/load-reads.ts +4 -4
- package/src/workspace/lockfile.ts +96 -140
- package/src/workspace/migration.ts +242 -146
- package/src/workspace/package-graph.ts +30 -216
- package/src/workspace/project-loader.ts +80 -285
- package/src/workspace/repo-id.ts +2 -1
- package/src/workspace/workspace.ts +362 -831
- package/src/cache/config-evals.ts +0 -130
- package/src/workspace/config-cache.ts +0 -661
- package/src/workspace/migrate-scripts.ts +0 -1121
package/src/index.ts
CHANGED
|
@@ -9,19 +9,11 @@
|
|
|
9
9
|
export { VERSION } from './version.js'
|
|
10
10
|
|
|
11
11
|
// Clean error type — user-input failures print a message without a stack.
|
|
12
|
-
|
|
13
|
-
// without it on the façade an integration package writes its own, and that
|
|
14
|
-
// had already happened. A bounds helper whose floor is load-bearing (a
|
|
15
|
-
// fractional SQL LIMIT is a datatype mismatch, not a smaller page) should
|
|
16
|
-
// have one implementation.
|
|
17
|
-
export { clampInt, UserError, isUserError } from './util/index.js'
|
|
12
|
+
export { UserError, isUserError } from './util/index.js'
|
|
18
13
|
// Every hook a plugin may fill, in pipeline order — the one list the
|
|
19
14
|
// loader, the host and `vx info` read; exported so a doc pin outside core
|
|
20
15
|
// (the site's guides) holds its tables to the same list.
|
|
21
16
|
export { PLUGIN_HOOKS, type PluginHook } from './config.js'
|
|
22
|
-
// The workspace doctor's facts (`vx info`), for a host that answers the
|
|
23
|
-
// same question over another surface — `@vzn/vx-mcp`'s `getWorkspaceInfo`.
|
|
24
|
-
export { collectInfo, type CollectInfoOptions, type InfoFacts } from './orchestrator/index.js'
|
|
25
17
|
// The machine as this process may use it — cores and memory capped by the
|
|
26
18
|
// cgroup a container runs under. Core's default worker count reads the
|
|
27
19
|
// first; a policy that budgets memory (`@vzn/vx-schedule-history`) reads
|
|
@@ -31,16 +23,15 @@ export { machineMemoryBytes, machineParallelism } from './util/index.js'
|
|
|
31
23
|
// wildcards (`[` `]` are not; item 667) — for a plugin that turns declared
|
|
32
24
|
// outputs into something else (`@vzn/vx-reapi`'s literal `output_paths`).
|
|
33
25
|
export { isLiteralPattern, normalizeGlob } from './util/index.js'
|
|
34
|
-
// A task's command as vx prints it: values of its `exec.env.secret` names
|
|
35
|
-
// masked. `vx show` and telemetry show this; a plugin that hands a command
|
|
36
|
-
// to someone else (`@vzn/vx-mcp`'s `listTasks`, an AI agent) does too (L-26).
|
|
37
|
-
// `maskedLine` is the same for a line no one task owns: the error `vx mcp`
|
|
38
|
-
// hands an agent (L-11).
|
|
39
|
-
export { maskedCommand, maskedLine } from './util/index.js'
|
|
40
26
|
|
|
41
27
|
// Schema types and helpers (used by user vx.config files and presets).
|
|
42
28
|
export type {
|
|
43
29
|
WorkspaceConfig,
|
|
30
|
+
RunSettings,
|
|
31
|
+
CacheSettings,
|
|
32
|
+
LockSettings,
|
|
33
|
+
WatchSettings,
|
|
34
|
+
Duration,
|
|
44
35
|
ProjectConfig,
|
|
45
36
|
TaskConfig,
|
|
46
37
|
ExecConfig,
|
|
@@ -48,6 +39,7 @@ export type {
|
|
|
48
39
|
CacheConfig,
|
|
49
40
|
CacheInputs,
|
|
50
41
|
CacheOutputs,
|
|
42
|
+
InputStability,
|
|
51
43
|
SandboxConfig,
|
|
52
44
|
SandboxGrants,
|
|
53
45
|
SandboxDenials,
|
|
@@ -64,7 +56,7 @@ export { run, planRun, prepareRun } from './orchestrator/index.js'
|
|
|
64
56
|
// The per-task duration history a `schedule` plugin learns from
|
|
65
57
|
// (`@vzn/vx-schedule-history` does; a plugin package reaches core only
|
|
66
58
|
// through this façade, which is what put these here).
|
|
67
|
-
export { LocalHistoryProvider } from './orchestrator/index.js'
|
|
59
|
+
export { currentBranch, LocalHistoryProvider } from './orchestrator/index.js'
|
|
68
60
|
export type {
|
|
69
61
|
HistoryProvider,
|
|
70
62
|
HistoryTable,
|
|
@@ -81,6 +73,7 @@ export type { AffectedChanges } from './workspace/index.js'
|
|
|
81
73
|
export type { RunPlan, PlannedTask } from './orchestrator/index.js'
|
|
82
74
|
export type { CiContext, GitContext, HostContext, WorkspaceIdentity } from './orchestrator/index.js'
|
|
83
75
|
export type {
|
|
76
|
+
CacheFlags,
|
|
84
77
|
CachePolicy,
|
|
85
78
|
Logger,
|
|
86
79
|
OutputView,
|
|
@@ -95,44 +88,40 @@ export { outputsOverlap, splitTaskId } from './graph/index.js'
|
|
|
95
88
|
export type { TaskNode, TaskOutcome, TaskStatus } from './graph/index.js'
|
|
96
89
|
|
|
97
90
|
// Cache classes + the layer interface (the `cache` capability's currency).
|
|
98
|
-
export { Cache
|
|
91
|
+
export { Cache } from './cache/index.js'
|
|
99
92
|
export type { CacheLayer, RemoteCacheLayer, RunRecord, InvocationRecord } from './cache/index.js'
|
|
100
93
|
|
|
101
94
|
// Workspace discovery + the project/config catalog surface — an
|
|
102
95
|
// out-of-process service/CLI needs these. `loadProjectConfig` is the RAW
|
|
103
96
|
// per-file load (`vx lock` freezes exactly that); the resolved view a run
|
|
104
97
|
// or `vx show` sees — plugin stages applied — is `loadResolvedProjects`
|
|
105
|
-
// below.
|
|
106
|
-
//
|
|
107
|
-
export { findWorkspaceRoot } from './workspace/index.js'
|
|
108
|
-
export {
|
|
109
|
-
loadWorkspace,
|
|
110
|
-
loadProjectConfig,
|
|
111
|
-
listProjects as listProjectMetas,
|
|
112
|
-
} from './workspace/index.js'
|
|
98
|
+
// below. `PROJECT_CONFIG_FILENAMES` are the names a project's config may
|
|
99
|
+
// have, in precedence order, for a tool that finds or writes one.
|
|
100
|
+
export { findWorkspaceRoot, PROJECT_CONFIG_FILENAMES } from './workspace/index.js'
|
|
101
|
+
export { loadProjectConfig } from './workspace/index.js'
|
|
113
102
|
export type { ProjectMeta } from './workspace/index.js'
|
|
114
|
-
// The package graph as a run sees it (workspace deps by manifest), for a tool
|
|
115
|
-
// that needs a project's transitive closure the way `vx run` computes it.
|
|
116
|
-
export { buildPackageGraph } from './workspace/index.js'
|
|
117
103
|
// The run path's RESOLVED view — plugin `config` and `project` stages
|
|
118
|
-
// applied
|
|
119
|
-
//
|
|
104
|
+
// applied — for a reader outside the CLI
|
|
105
|
+
// (`@vzn/vx-schedule-history`, an embedder's task catalog). What `vx show`
|
|
120
106
|
// prints.
|
|
121
107
|
export { loadResolvedProjects } from './orchestrator/index.js'
|
|
122
108
|
export type { ProjectEntry } from './workspace/index.js'
|
|
123
109
|
// The migration seam: how a generated config is planned, rendered, guarded
|
|
124
|
-
// and written.
|
|
125
|
-
//
|
|
110
|
+
// and written. `@vzn/vx-migrate` (package.json scripts, Turbo, Nx) and any
|
|
111
|
+
// other adoption tool use it from here; `taskNameProblem` is why a name
|
|
112
|
+
// cannot be a task's, so a mapper leaves such a script out.
|
|
126
113
|
export {
|
|
127
114
|
applyMigration,
|
|
128
115
|
foldScriptHooks,
|
|
129
116
|
PERSISTENT_TODO,
|
|
130
117
|
pruneOrphanPersistentNotes,
|
|
131
118
|
quoteTsLiteral,
|
|
119
|
+
taskNameProblem,
|
|
132
120
|
} from './workspace/index.js'
|
|
133
121
|
export type {
|
|
134
122
|
ApplyMigrationArgs,
|
|
135
123
|
MigrationFormat,
|
|
124
|
+
MigrationMember,
|
|
136
125
|
GeneratedProject,
|
|
137
126
|
GeneratedTask,
|
|
138
127
|
MigrationPlan,
|
|
@@ -142,7 +131,7 @@ export type {
|
|
|
142
131
|
// Plugin API — the run-level extension points. Behavior capabilities
|
|
143
132
|
// (executor / cache) change WHAT/HOW work runs; the observe-only `telemetry`
|
|
144
133
|
// capability is the canonical data-export path and cannot change behavior.
|
|
145
|
-
// A plugin is declared in vx
|
|
134
|
+
// A plugin is declared in .vx/workspace.ts via defineWorkspace({ plugins }).
|
|
146
135
|
// See docs/design/observability-architecture-2026-06.md.
|
|
147
136
|
// The claimant's shell for a lockfile plugin (`@vzn/vx-lockfile`):
|
|
148
137
|
// the claim, the per-project key, the memo and the `--affected` diff around
|
|
@@ -152,6 +141,7 @@ export {
|
|
|
152
141
|
reachDigests,
|
|
153
142
|
type LockfileClaimHooks,
|
|
154
143
|
type LockfileClaimOptions,
|
|
144
|
+
type LockfileImporter,
|
|
155
145
|
type ReachGraph,
|
|
156
146
|
} from './orchestrator/index.js'
|
|
157
147
|
export type {
|
|
@@ -161,6 +151,7 @@ export type {
|
|
|
161
151
|
PluginOptionKinds,
|
|
162
152
|
CacheContext,
|
|
163
153
|
ExecutorContext,
|
|
154
|
+
OutputContext,
|
|
164
155
|
CommandContext,
|
|
165
156
|
FingerprintChange,
|
|
166
157
|
FingerprintClaim,
|
|
@@ -173,7 +164,7 @@ export type {
|
|
|
173
164
|
AdmitContext,
|
|
174
165
|
WorkspaceHookContext,
|
|
175
166
|
DiscoverContext,
|
|
176
|
-
|
|
167
|
+
DiscoveredProject,
|
|
177
168
|
PluginSetupContext,
|
|
178
169
|
PluginHookName,
|
|
179
170
|
PluginHookHandlers,
|
|
@@ -243,26 +234,3 @@ export type {
|
|
|
243
234
|
|
|
244
235
|
// The serializable run result and its per-task views (what `run()` returns).
|
|
245
236
|
export type { RunResult, TaskView, OutcomeView } from './orchestrator/index.js'
|
|
246
|
-
|
|
247
|
-
// The run-history queries a reader outside the CLI takes today: `vx why`'s
|
|
248
|
-
// answer, a run's failures and a task's log, which `@vzn/vx-mcp` serves. The event bus /
|
|
249
|
-
// wire form and the other history readers (`listRuns`, `getRun`, …) left the
|
|
250
|
-
// façade 2026-09-10 with no consumer; the telemetry seam above is the
|
|
251
|
-
// canonical export path.
|
|
252
|
-
export {
|
|
253
|
-
cacheKeyDiff,
|
|
254
|
-
latestRunId,
|
|
255
|
-
resolveRunId,
|
|
256
|
-
rootCauses,
|
|
257
|
-
runFailures,
|
|
258
|
-
taskLog,
|
|
259
|
-
whyDidThisRerunQuery,
|
|
260
|
-
} from './orchestrator/index.js'
|
|
261
|
-
export type {
|
|
262
|
-
CacheKeyDiff,
|
|
263
|
-
OutputLocation,
|
|
264
|
-
RootCause,
|
|
265
|
-
RunFailures,
|
|
266
|
-
TaskFailure,
|
|
267
|
-
TaskLog,
|
|
268
|
-
} from './orchestrator/index.js'
|
|
@@ -29,7 +29,7 @@ import type { VxPlugin } from './plugin.js'
|
|
|
29
29
|
import { isDefaultBuild } from './projects.js'
|
|
30
30
|
|
|
31
31
|
/** Every file in this set re-keys each of its project's tasks, whatever their inputs. */
|
|
32
|
-
const KEYED_BY_EVERY_TASK = new Set(
|
|
32
|
+
const KEYED_BY_EVERY_TASK: ReadonlySet<string> = new Set(PROJECT_CONFIG_FILENAMES)
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* The projects every task of which the change reaches: the whole ones the
|
|
@@ -41,8 +41,9 @@ const KEYED_BY_EVERY_TASK = new Set(['package.json', ...PROJECT_CONFIG_FILENAMES
|
|
|
41
41
|
function wholeProjects(
|
|
42
42
|
changes: AffectedChanges,
|
|
43
43
|
projects: ReadonlyMap<string, ProjectEntry>,
|
|
44
|
-
):
|
|
45
|
-
|
|
44
|
+
): Map<string, string | undefined> {
|
|
45
|
+
// Each whole project, with the path no cached task claims when one did it.
|
|
46
|
+
const whole = new Map<string, string | undefined>([...changes.whole].map((n) => [n, undefined]))
|
|
46
47
|
for (const [name, rels] of changes.paths) {
|
|
47
48
|
if (whole.has(name)) continue
|
|
48
49
|
const caches = Object.values(projects.get(name)?.config.tasks ?? {}).flatMap((t) =>
|
|
@@ -50,7 +51,8 @@ function wholeProjects(
|
|
|
50
51
|
)
|
|
51
52
|
const unclaimed = (rel: string): boolean =>
|
|
52
53
|
KEYED_BY_EVERY_TASK.has(rel) || !caches.some((c) => declaresInput(c, rel, null))
|
|
53
|
-
|
|
54
|
+
const rel = rels.find(unclaimed)
|
|
55
|
+
if (rel !== undefined) whole.set(name, rel)
|
|
54
56
|
}
|
|
55
57
|
return whole
|
|
56
58
|
}
|
|
@@ -157,7 +159,7 @@ export function affectedRoots(
|
|
|
157
159
|
return hit
|
|
158
160
|
}
|
|
159
161
|
if (whole.has(n.projectName)) {
|
|
160
|
-
seeds?.set(n.id, inProject(n.projectName,
|
|
162
|
+
seeds?.set(n.id, inProject(n.projectName, whole.get(n.projectName)))
|
|
161
163
|
return true
|
|
162
164
|
}
|
|
163
165
|
const rel = rels.find((r) => declaresInput(cache, r, null))
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// When each command of the run ran and where it may write, so
|
|
2
|
+
// `inputStability.strategy: 'mutable'` can tell a task's own identical
|
|
3
|
+
// rewrite from another task's write and restore (STATUS item 28): a file
|
|
4
|
+
// whose bytes match the key after a write is the task's own only if no
|
|
5
|
+
// other command that may write it ran between the describe and that write.
|
|
6
|
+
|
|
7
|
+
import path from 'node:path'
|
|
8
|
+
import type { WriteReach } from './sandbox-request.js'
|
|
9
|
+
|
|
10
|
+
interface Window {
|
|
11
|
+
id: string
|
|
12
|
+
projectDir: string
|
|
13
|
+
reach: WriteReach
|
|
14
|
+
from: number
|
|
15
|
+
to: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CommandWindows {
|
|
19
|
+
/** A command starts; the returned function marks its end. A server never calls it. */
|
|
20
|
+
open(id: string, projectDir: string, reach: WriteReach): () => void
|
|
21
|
+
/** Another command that may write `file` and ran at some point in [from, to]. */
|
|
22
|
+
writerDuring(self: string, file: string, from: number, to: number): string | undefined
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function commandWindows(): CommandWindows {
|
|
26
|
+
const windows: Window[] = []
|
|
27
|
+
return {
|
|
28
|
+
open(id, projectDir, reach) {
|
|
29
|
+
if (reach === 'none') return () => {}
|
|
30
|
+
const w: Window = { id, projectDir, reach, from: Date.now(), to: Infinity }
|
|
31
|
+
windows.push(w)
|
|
32
|
+
return () => {
|
|
33
|
+
w.to = Date.now()
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
writerDuring(self, file, from, to) {
|
|
37
|
+
for (const w of windows) {
|
|
38
|
+
if (w.id === self || w.from > to || w.to < from) continue
|
|
39
|
+
if (w.reach === 'workspace' || file.startsWith(w.projectDir + path.sep)) return w.id
|
|
40
|
+
}
|
|
41
|
+
return undefined
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// The run-scoped registry of tasks whose outputs were left in the remote
|
|
2
|
-
// store (`--download=none`), and the lazy materialisation that fetches
|
|
2
|
+
// store (`--cache-download=none`), and the lazy materialisation that fetches
|
|
3
3
|
// them when a locally-placed task turns out to need them.
|
|
4
4
|
//
|
|
5
5
|
// See docs/design/download-policy-cas-cache-2026-08.md §5. The two
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
// remote store (the executor's own record) is the entry.
|
|
10
10
|
// - Materialisation CONVERGES: after the bytes land, core runs the
|
|
11
11
|
// ordinary `cache.save`, so the machine is indistinguishable from a
|
|
12
|
-
// `--download=all` run and every later reader (get, prune, verify,
|
|
12
|
+
// `--cache-download=all` run and every later reader (get, prune, verify,
|
|
13
13
|
// metrics) sees one entry shape, not two.
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
16
|
cleanOutputs,
|
|
17
|
+
committedFiles,
|
|
17
18
|
resolveOutputs,
|
|
18
19
|
type CacheLayer,
|
|
19
20
|
type GitFilesCache,
|
|
@@ -73,7 +74,7 @@ export class DeferredOutputs {
|
|
|
73
74
|
*/
|
|
74
75
|
async materializeFor(node: TaskNode): Promise<void> {
|
|
75
76
|
// Nothing deferred, nothing to find: the closure walk is the size of
|
|
76
|
-
// the graph, and every task of a run without `--download=none` paid it
|
|
77
|
+
// the graph, and every task of a run without `--cache-download=none` paid it
|
|
77
78
|
// (1.4 s of a 3,270-task cold run's main thread).
|
|
78
79
|
if (this.entries.size === 0) return
|
|
79
80
|
const needed: string[] = []
|
|
@@ -116,7 +117,12 @@ export class DeferredOutputs {
|
|
|
116
117
|
// workspace-anchored can reach this path.
|
|
117
118
|
const outputs = producer.config.cache?.outputs.files ?? []
|
|
118
119
|
const nestedProjectDirs = this.args.nestedDirsByProject.get(producer.projectName) ?? []
|
|
119
|
-
const cleanArgs = {
|
|
120
|
+
const cleanArgs = {
|
|
121
|
+
projectDir: producer.projectDir,
|
|
122
|
+
outputs,
|
|
123
|
+
nestedProjectDirs,
|
|
124
|
+
committed: committedFiles(this.args.gitFilesCache, producer.projectDir),
|
|
125
|
+
}
|
|
120
126
|
|
|
121
127
|
// Mirror `restoreHit`'s sequencing so the two paths cannot drift: wipe
|
|
122
128
|
// the declared outputs, write, then tell the git snapshot what moved.
|
|
@@ -135,14 +141,10 @@ export class DeferredOutputs {
|
|
|
135
141
|
} catch (err) {
|
|
136
142
|
const msg = err instanceof Error ? err.message : String(err)
|
|
137
143
|
throw new Error(
|
|
138
|
-
`could not fetch deferred outputs of ${taskId}: ${msg} — re-run it with --force, or use --download=all`,
|
|
144
|
+
`could not fetch deferred outputs of ${taskId}: ${msg} — re-run it with --force, or use --cache-download=all`,
|
|
139
145
|
)
|
|
140
146
|
}
|
|
141
|
-
const outputFiles = await resolveOutputs(
|
|
142
|
-
projectDir: producer.projectDir,
|
|
143
|
-
outputs,
|
|
144
|
-
nestedProjectDirs,
|
|
145
|
-
})
|
|
147
|
+
const outputFiles = await resolveOutputs(cleanArgs)
|
|
146
148
|
this.args.gitFilesCache?.markOutputsChanged(
|
|
147
149
|
producer.projectDir,
|
|
148
150
|
outputFiles.map((f) => f.slice(producer.projectDir.length + 1)),
|