@vzn/vx 0.0.636 → 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 +39 -11
- package/docs/caching.md +213 -207
- package/docs/cli.md +699 -655
- package/docs/execution.md +67 -75
- package/docs/features.md +44 -40
- package/docs/patterns.md +26 -25
- package/docs/schema.md +376 -198
- 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 +5 -3
- 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 -63
- 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 +103 -149
- 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 +169 -70
- 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 +24 -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 +158 -63
- 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 +42 -29
- 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 +113 -72
- 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 +121 -95
- 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 +209 -268
- 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 +20 -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,
|
|
@@ -65,7 +56,7 @@ export { run, planRun, prepareRun } from './orchestrator/index.js'
|
|
|
65
56
|
// The per-task duration history a `schedule` plugin learns from
|
|
66
57
|
// (`@vzn/vx-schedule-history` does; a plugin package reaches core only
|
|
67
58
|
// through this façade, which is what put these here).
|
|
68
|
-
export { LocalHistoryProvider } from './orchestrator/index.js'
|
|
59
|
+
export { currentBranch, LocalHistoryProvider } from './orchestrator/index.js'
|
|
69
60
|
export type {
|
|
70
61
|
HistoryProvider,
|
|
71
62
|
HistoryTable,
|
|
@@ -82,6 +73,7 @@ export type { AffectedChanges } from './workspace/index.js'
|
|
|
82
73
|
export type { RunPlan, PlannedTask } from './orchestrator/index.js'
|
|
83
74
|
export type { CiContext, GitContext, HostContext, WorkspaceIdentity } from './orchestrator/index.js'
|
|
84
75
|
export type {
|
|
76
|
+
CacheFlags,
|
|
85
77
|
CachePolicy,
|
|
86
78
|
Logger,
|
|
87
79
|
OutputView,
|
|
@@ -96,44 +88,40 @@ export { outputsOverlap, splitTaskId } from './graph/index.js'
|
|
|
96
88
|
export type { TaskNode, TaskOutcome, TaskStatus } from './graph/index.js'
|
|
97
89
|
|
|
98
90
|
// Cache classes + the layer interface (the `cache` capability's currency).
|
|
99
|
-
export { Cache
|
|
91
|
+
export { Cache } from './cache/index.js'
|
|
100
92
|
export type { CacheLayer, RemoteCacheLayer, RunRecord, InvocationRecord } from './cache/index.js'
|
|
101
93
|
|
|
102
94
|
// Workspace discovery + the project/config catalog surface — an
|
|
103
95
|
// out-of-process service/CLI needs these. `loadProjectConfig` is the RAW
|
|
104
96
|
// per-file load (`vx lock` freezes exactly that); the resolved view a run
|
|
105
97
|
// or `vx show` sees — plugin stages applied — is `loadResolvedProjects`
|
|
106
|
-
// below.
|
|
107
|
-
//
|
|
108
|
-
export { findWorkspaceRoot } from './workspace/index.js'
|
|
109
|
-
export {
|
|
110
|
-
loadWorkspace,
|
|
111
|
-
loadProjectConfig,
|
|
112
|
-
listProjects as listProjectMetas,
|
|
113
|
-
} 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'
|
|
114
102
|
export type { ProjectMeta } from './workspace/index.js'
|
|
115
|
-
// The package graph as a run sees it (workspace deps by manifest), for a tool
|
|
116
|
-
// that needs a project's transitive closure the way `vx run` computes it.
|
|
117
|
-
export { buildPackageGraph } from './workspace/index.js'
|
|
118
103
|
// The run path's RESOLVED view — plugin `config` and `project` stages
|
|
119
|
-
// applied
|
|
120
|
-
//
|
|
104
|
+
// applied — for a reader outside the CLI
|
|
105
|
+
// (`@vzn/vx-schedule-history`, an embedder's task catalog). What `vx show`
|
|
121
106
|
// prints.
|
|
122
107
|
export { loadResolvedProjects } from './orchestrator/index.js'
|
|
123
108
|
export type { ProjectEntry } from './workspace/index.js'
|
|
124
109
|
// The migration seam: how a generated config is planned, rendered, guarded
|
|
125
|
-
// and written.
|
|
126
|
-
//
|
|
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.
|
|
127
113
|
export {
|
|
128
114
|
applyMigration,
|
|
129
115
|
foldScriptHooks,
|
|
130
116
|
PERSISTENT_TODO,
|
|
131
117
|
pruneOrphanPersistentNotes,
|
|
132
118
|
quoteTsLiteral,
|
|
119
|
+
taskNameProblem,
|
|
133
120
|
} from './workspace/index.js'
|
|
134
121
|
export type {
|
|
135
122
|
ApplyMigrationArgs,
|
|
136
123
|
MigrationFormat,
|
|
124
|
+
MigrationMember,
|
|
137
125
|
GeneratedProject,
|
|
138
126
|
GeneratedTask,
|
|
139
127
|
MigrationPlan,
|
|
@@ -143,7 +131,7 @@ export type {
|
|
|
143
131
|
// Plugin API — the run-level extension points. Behavior capabilities
|
|
144
132
|
// (executor / cache) change WHAT/HOW work runs; the observe-only `telemetry`
|
|
145
133
|
// capability is the canonical data-export path and cannot change behavior.
|
|
146
|
-
// A plugin is declared in vx
|
|
134
|
+
// A plugin is declared in .vx/workspace.ts via defineWorkspace({ plugins }).
|
|
147
135
|
// See docs/design/observability-architecture-2026-06.md.
|
|
148
136
|
// The claimant's shell for a lockfile plugin (`@vzn/vx-lockfile`):
|
|
149
137
|
// the claim, the per-project key, the memo and the `--affected` diff around
|
|
@@ -153,6 +141,7 @@ export {
|
|
|
153
141
|
reachDigests,
|
|
154
142
|
type LockfileClaimHooks,
|
|
155
143
|
type LockfileClaimOptions,
|
|
144
|
+
type LockfileImporter,
|
|
156
145
|
type ReachGraph,
|
|
157
146
|
} from './orchestrator/index.js'
|
|
158
147
|
export type {
|
|
@@ -162,6 +151,7 @@ export type {
|
|
|
162
151
|
PluginOptionKinds,
|
|
163
152
|
CacheContext,
|
|
164
153
|
ExecutorContext,
|
|
154
|
+
OutputContext,
|
|
165
155
|
CommandContext,
|
|
166
156
|
FingerprintChange,
|
|
167
157
|
FingerprintClaim,
|
|
@@ -174,7 +164,7 @@ export type {
|
|
|
174
164
|
AdmitContext,
|
|
175
165
|
WorkspaceHookContext,
|
|
176
166
|
DiscoverContext,
|
|
177
|
-
|
|
167
|
+
DiscoveredProject,
|
|
178
168
|
PluginSetupContext,
|
|
179
169
|
PluginHookName,
|
|
180
170
|
PluginHookHandlers,
|
|
@@ -244,26 +234,3 @@ export type {
|
|
|
244
234
|
|
|
245
235
|
// The serializable run result and its per-task views (what `run()` returns).
|
|
246
236
|
export type { RunResult, TaskView, OutcomeView } from './orchestrator/index.js'
|
|
247
|
-
|
|
248
|
-
// The run-history queries a reader outside the CLI takes today: `vx why`'s
|
|
249
|
-
// answer, a run's failures and a task's log, which `@vzn/vx-mcp` serves. The event bus /
|
|
250
|
-
// wire form and the other history readers (`listRuns`, `getRun`, …) left the
|
|
251
|
-
// façade 2026-09-10 with no consumer; the telemetry seam above is the
|
|
252
|
-
// canonical export path.
|
|
253
|
-
export {
|
|
254
|
-
cacheKeyDiff,
|
|
255
|
-
latestRunId,
|
|
256
|
-
resolveRunId,
|
|
257
|
-
rootCauses,
|
|
258
|
-
runFailures,
|
|
259
|
-
taskLog,
|
|
260
|
-
whyDidThisRerunQuery,
|
|
261
|
-
} from './orchestrator/index.js'
|
|
262
|
-
export type {
|
|
263
|
-
CacheKeyDiff,
|
|
264
|
-
OutputLocation,
|
|
265
|
-
RootCause,
|
|
266
|
-
RunFailures,
|
|
267
|
-
TaskFailure,
|
|
268
|
-
TaskLog,
|
|
269
|
-
} 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)),
|