@vzn/vx 0.0.0 → 0.0.14
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/LICENSE +21 -0
- package/README.md +349 -1
- package/launcher.mjs +92 -0
- package/package.json +44 -3
- package/src/bin.ts +25 -0
- package/src/cache/cache.ts +1832 -0
- package/src/cache/cas-backend.ts +97 -0
- package/src/cache/digest.ts +47 -0
- package/src/cache/index.ts +28 -0
- package/src/cache/inputs.ts +839 -0
- package/src/cache/layered-cache.ts +355 -0
- package/src/cache/tar.ts +343 -0
- package/src/cli/backend.ts +23 -0
- package/src/cli/cache.ts +96 -0
- package/src/cli/format.ts +15 -0
- package/src/cli/help.ts +129 -0
- package/src/cli/index.ts +85 -0
- package/src/cli/info.ts +80 -0
- package/src/cli/lock.ts +135 -0
- package/src/cli/mcp-rpc.ts +292 -0
- package/src/cli/mcp.ts +92 -0
- package/src/cli/migrate-nx.ts +450 -0
- package/src/cli/migrate-turbo.ts +364 -0
- package/src/cli/migrate.ts +219 -0
- package/src/cli/plan-format.ts +148 -0
- package/src/cli/run.ts +683 -0
- package/src/cli/show.ts +201 -0
- package/src/cli/upgrade.ts +103 -0
- package/src/cli/watch.ts +287 -0
- package/src/config.ts +460 -0
- package/src/exec/env.ts +74 -0
- package/src/exec/index.ts +13 -0
- package/src/exec/runner.ts +470 -0
- package/src/exec/sandbox-runtime.ts +578 -0
- package/src/graph/dependency-spec.ts +85 -0
- package/src/graph/index.ts +27 -0
- package/src/graph/scheduler.ts +677 -0
- package/src/graph/task-graph.ts +377 -0
- package/src/index.ts +222 -0
- package/src/orchestrator/colors.ts +63 -0
- package/src/orchestrator/devframe-surface.ts +74 -0
- package/src/orchestrator/events.ts +277 -0
- package/src/orchestrator/execute-task.ts +939 -0
- package/src/orchestrator/framed-output.ts +461 -0
- package/src/orchestrator/history.ts +148 -0
- package/src/orchestrator/index.ts +174 -0
- package/src/orchestrator/local-shortcircuit.ts +147 -0
- package/src/orchestrator/logger.ts +526 -0
- package/src/orchestrator/metrics.ts +1927 -0
- package/src/orchestrator/options.ts +197 -0
- package/src/orchestrator/plan.ts +129 -0
- package/src/orchestrator/plugin-host.ts +185 -0
- package/src/orchestrator/plugin.ts +283 -0
- package/src/orchestrator/predict.ts +106 -0
- package/src/orchestrator/prepare.ts +306 -0
- package/src/orchestrator/protocol.ts +156 -0
- package/src/orchestrator/remote-prefetch.ts +81 -0
- package/src/orchestrator/resources.ts +59 -0
- package/src/orchestrator/run-artifacts.ts +111 -0
- package/src/orchestrator/run-context.ts +205 -0
- package/src/orchestrator/run-report.ts +132 -0
- package/src/orchestrator/run-state.ts +145 -0
- package/src/orchestrator/run.ts +887 -0
- package/src/orchestrator/stable-keys.ts +177 -0
- package/src/orchestrator/status-line.ts +287 -0
- package/src/orchestrator/summary.ts +315 -0
- package/src/orchestrator/tally.ts +69 -0
- package/src/orchestrator/task-hash.ts +253 -0
- package/src/orchestrator/telemetry-host.ts +80 -0
- package/src/orchestrator/telemetry.ts +358 -0
- package/src/orchestrator/upstream.ts +121 -0
- package/src/orchestrator/verify.ts +164 -0
- package/src/orchestrator/wire-render.ts +92 -0
- package/src/orchestrator/wire.ts +212 -0
- package/src/util/errors.ts +11 -0
- package/src/util/hash.ts +25 -0
- package/src/util/index.ts +8 -0
- package/src/util/paths.ts +16 -0
- package/src/util/size.ts +16 -0
- package/src/util/ulid.ts +15 -0
- package/src/version.ts +10 -0
- package/src/workspace/affected.ts +118 -0
- package/src/workspace/filter.ts +155 -0
- package/src/workspace/fingerprint.ts +41 -0
- package/src/workspace/index.ts +27 -0
- package/src/workspace/lockfile.ts +118 -0
- package/src/workspace/nested-dirs.ts +34 -0
- package/src/workspace/package-graph.ts +148 -0
- package/src/workspace/project-loader.ts +512 -0
- package/src/workspace/workspace.ts +176 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// Module contract for `orchestrator`. Cross-module imports must come
|
|
2
|
+
// through here (enforced by tests/module-boundaries.test.ts).
|
|
3
|
+
|
|
4
|
+
export { run, planRun } from './run.js'
|
|
5
|
+
export { prepareRun, type PreparedRun } from './prepare.js'
|
|
6
|
+
export { computeTaskHash, createHashCache, type HashCache } from './task-hash.js'
|
|
7
|
+
export type { RunOptions, RunSummary } from './options.js'
|
|
8
|
+
// Re-surface the cache policy contract (defined in the cache module) so
|
|
9
|
+
// embedders constructing RunOptions.cache and the package façade can
|
|
10
|
+
// reach it without importing the cache module directly.
|
|
11
|
+
export { type CachePolicy, FULL_CACHE_POLICY, parseCachePolicy } from '../cache/index.js'
|
|
12
|
+
export { defaultLogger, resolveOutputView } from './logger.js'
|
|
13
|
+
export type { Logger, OutputView } from './logger.js'
|
|
14
|
+
export type { RunPlan, PlannedTask, CacheStatus } from './plan.js'
|
|
15
|
+
export {
|
|
16
|
+
createEventBus,
|
|
17
|
+
wireForwarder,
|
|
18
|
+
toWireEvent,
|
|
19
|
+
projectNode,
|
|
20
|
+
projectOutcome,
|
|
21
|
+
} from './events.js'
|
|
22
|
+
export type {
|
|
23
|
+
EventBus,
|
|
24
|
+
RunEvent,
|
|
25
|
+
RunEventSubscriber,
|
|
26
|
+
WireEvent,
|
|
27
|
+
TaskView,
|
|
28
|
+
OutcomeView,
|
|
29
|
+
} from './events.js'
|
|
30
|
+
export { createVxSurface } from './devframe-surface.js'
|
|
31
|
+
export { createWireRenderer } from './wire-render.js'
|
|
32
|
+
export { optionsToRequest, requestToOptions } from './protocol.js'
|
|
33
|
+
export type { ClientMessage, RunBackend, RunRequest, RunResult, ServerMessage } from './protocol.js'
|
|
34
|
+
export { formatRunReportMarkdown } from './run-report.js'
|
|
35
|
+
export {
|
|
36
|
+
clientMessageToEnvelope,
|
|
37
|
+
decodeEnvelope,
|
|
38
|
+
encodeForNDJSON,
|
|
39
|
+
encodeForSSE,
|
|
40
|
+
encodeForWS,
|
|
41
|
+
ENVELOPE_ERRORS,
|
|
42
|
+
envelopeToClientMessage,
|
|
43
|
+
envelopeToServerMessage,
|
|
44
|
+
isEnvelope,
|
|
45
|
+
isNotification,
|
|
46
|
+
isRequest,
|
|
47
|
+
makeError,
|
|
48
|
+
makeNotification,
|
|
49
|
+
makeRequest,
|
|
50
|
+
makeResponse,
|
|
51
|
+
serverMessageToEnvelope,
|
|
52
|
+
WIRE_CHANNELS,
|
|
53
|
+
WIRE_PROTOCOL_VERSION,
|
|
54
|
+
} from './wire.js'
|
|
55
|
+
export type {
|
|
56
|
+
Envelope,
|
|
57
|
+
ErrorResponse,
|
|
58
|
+
Notification,
|
|
59
|
+
Request as WireRequest,
|
|
60
|
+
Response as WireResponse,
|
|
61
|
+
WireChannel,
|
|
62
|
+
} from './wire.js'
|
|
63
|
+
export {
|
|
64
|
+
EmptyHistoryProvider,
|
|
65
|
+
type HistoryProvider,
|
|
66
|
+
type HistoryTable,
|
|
67
|
+
LocalHistoryProvider,
|
|
68
|
+
type TaskHistory,
|
|
69
|
+
} from './history.js'
|
|
70
|
+
export { computePredictedPriorities } from './predict.js'
|
|
71
|
+
export {
|
|
72
|
+
installPlugins,
|
|
73
|
+
type BackendContext,
|
|
74
|
+
type CacheContext,
|
|
75
|
+
type EventSink,
|
|
76
|
+
type EventSinkContext,
|
|
77
|
+
type InstallPluginsArgs,
|
|
78
|
+
type Plugin,
|
|
79
|
+
type PluginContext,
|
|
80
|
+
type PluginHookHandlers,
|
|
81
|
+
type PluginHookName,
|
|
82
|
+
type PluginSetupContext,
|
|
83
|
+
type VxPlugin,
|
|
84
|
+
} from './plugin.js'
|
|
85
|
+
export { resolveBackend, resolveCache, subscribeEventSinks } from './plugin-host.js'
|
|
86
|
+
export { subscribeTelemetry, type TelemetryHandle } from './telemetry-host.js'
|
|
87
|
+
export { createTelemetrySource, deriveCacheSource, TELEMETRY_SCHEMA_VERSION } from './telemetry.js'
|
|
88
|
+
export type {
|
|
89
|
+
CacheSource,
|
|
90
|
+
RunContextRecord,
|
|
91
|
+
RunSummaryRecord,
|
|
92
|
+
TaskTelemetry,
|
|
93
|
+
TelemetryContext,
|
|
94
|
+
TelemetryRecord,
|
|
95
|
+
TelemetrySink,
|
|
96
|
+
TelemetrySource,
|
|
97
|
+
} from './telemetry.js'
|
|
98
|
+
// `diffOutputTrees` is the ONE tree-diff implementation — the verify verdict
|
|
99
|
+
// and a serve's cross-machine fingerprint diff must never drift on it.
|
|
100
|
+
export { diffOutputTrees } from './verify.js'
|
|
101
|
+
export { deriveStableKeys } from './stable-keys.js'
|
|
102
|
+
export type { DeriveStableKeysArgs, StableKey } from './stable-keys.js'
|
|
103
|
+
export { captureGitContext, captureWorkspaceIdentity, resolveCacheScope } from './run-context.js'
|
|
104
|
+
export type { GitContext, WorkspaceIdentity } from './run-context.js'
|
|
105
|
+
export {
|
|
106
|
+
cacheKeyDiff,
|
|
107
|
+
compareRuns,
|
|
108
|
+
explainCacheKey as explainCacheKeyQuery,
|
|
109
|
+
getBottlenecks,
|
|
110
|
+
getCacheBreakdown,
|
|
111
|
+
getCacheSavings,
|
|
112
|
+
getCacheStatsSql,
|
|
113
|
+
getFlakiestTasks,
|
|
114
|
+
getHistory,
|
|
115
|
+
getHitRateSplit,
|
|
116
|
+
getInvocation,
|
|
117
|
+
getParallelismHistory,
|
|
118
|
+
getPeriodComparison,
|
|
119
|
+
getPrunableEntries,
|
|
120
|
+
getRecentFailures,
|
|
121
|
+
getRegressions,
|
|
122
|
+
getRun,
|
|
123
|
+
getRunHeatmap,
|
|
124
|
+
getRunTrends,
|
|
125
|
+
getStorageGrowth,
|
|
126
|
+
getTaskDetail,
|
|
127
|
+
getTopTimeBurners,
|
|
128
|
+
listCacheEntries,
|
|
129
|
+
listInvocations,
|
|
130
|
+
listProjects,
|
|
131
|
+
listRuns,
|
|
132
|
+
whyDidThisRerun as whyDidThisRerunQuery,
|
|
133
|
+
} from './metrics.js'
|
|
134
|
+
export type {
|
|
135
|
+
BottleneckRow,
|
|
136
|
+
CacheEntryRow,
|
|
137
|
+
CacheKeyDiff,
|
|
138
|
+
CacheKeyExplanation,
|
|
139
|
+
CacheProjectRow,
|
|
140
|
+
CacheSavings,
|
|
141
|
+
CacheStatsResult,
|
|
142
|
+
CompareRuns,
|
|
143
|
+
CompareTaskRow,
|
|
144
|
+
CompareTaskSide,
|
|
145
|
+
FailureRow,
|
|
146
|
+
FlakyTask,
|
|
147
|
+
GetHistoryArgs,
|
|
148
|
+
HeatmapCell,
|
|
149
|
+
HitRateSplit,
|
|
150
|
+
InputDiffEntry,
|
|
151
|
+
InvocationDetail,
|
|
152
|
+
InvocationRow,
|
|
153
|
+
ListCacheEntriesArgs,
|
|
154
|
+
ListInvocationsArgs,
|
|
155
|
+
ListRunsArgs,
|
|
156
|
+
ParallelismPoint,
|
|
157
|
+
PeriodComparison,
|
|
158
|
+
PeriodComparisonArgs,
|
|
159
|
+
PeriodStats,
|
|
160
|
+
PrunableEntry,
|
|
161
|
+
ProjectRollup,
|
|
162
|
+
RegressedTask,
|
|
163
|
+
RegressionArgs,
|
|
164
|
+
TaskMover,
|
|
165
|
+
RunDetail,
|
|
166
|
+
RunSummaryRow,
|
|
167
|
+
StoragePoint,
|
|
168
|
+
TaskDetail,
|
|
169
|
+
TaskHistoryRow,
|
|
170
|
+
TopTaskRow,
|
|
171
|
+
TrendBucket,
|
|
172
|
+
TrendPoint,
|
|
173
|
+
WhyDidThisRerun,
|
|
174
|
+
} from './metrics.js'
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// Local cache short-circuit (default-on) — the classify phase. The
|
|
2
|
+
// owner's scheduling policy: "prioritize running cache MISSES; only if
|
|
3
|
+
// required, or if there are free workers, add cache restores." So a
|
|
4
|
+
// confirmed stable-key LOCAL cache HIT should not have to wait for its
|
|
5
|
+
// dependencies to finish RUNNING — its bytes are derivable now and its
|
|
6
|
+
// restore needs none of its deps' output — but it must NOT preempt a
|
|
7
|
+
// real cache MISS for a worker slot.
|
|
8
|
+
//
|
|
9
|
+
// This module owns the UP-FRONT CLASSIFY: for every STABLE-key,
|
|
10
|
+
// cacheable, local-read task it derives the key (reusing the run's
|
|
11
|
+
// hashCache memo) and probes `cache.get` ONCE, building a `preProbed`
|
|
12
|
+
// map that covers stable HITS and stable MISSES alike. The scheduler
|
|
13
|
+
// (two-tier) and execute-task (probe reuse) consume it:
|
|
14
|
+
//
|
|
15
|
+
// - hit → RESTORE-TIER: scheduler makes it ready immediately (LOW
|
|
16
|
+
// priority), execute reuses the probed entry → restoreHit
|
|
17
|
+
// (no second cache.get).
|
|
18
|
+
// - miss → EXEC-TIER (stable): scheduler runs it dep-gated at normal
|
|
19
|
+
// priority; execute skips the first cache.get (it's a known
|
|
20
|
+
// miss) and goes to the run path.
|
|
21
|
+
// - unstable / not-probed → EXEC-TIER: execute probes lazily, exactly
|
|
22
|
+
// as today (a codegen-consumer's key isn't computable until
|
|
23
|
+
// its upstream runs — see dependsOnSiblingOutputs).
|
|
24
|
+
//
|
|
25
|
+
// Because EVERY task still runs through execute(), the logger emits the
|
|
26
|
+
// same taskStart + stdout replay + taskComplete it always did — the
|
|
27
|
+
// focused live frame is preserved with zero special-casing — and the
|
|
28
|
+
// up-front probes are just the probes execute() would have done,
|
|
29
|
+
// hoisted (no double work — the warm path stays free).
|
|
30
|
+
//
|
|
31
|
+
// SCOPE / safety:
|
|
32
|
+
// - Only STABLE-key, cacheable, local-read tasks are classified. A
|
|
33
|
+
// stable miss stays in the normal (dep-gated) schedule; an unstable
|
|
34
|
+
// task is never probed here.
|
|
35
|
+
// - If ANY task in the graph declares `cache.outputs.workspaceFiles`,
|
|
36
|
+
// no task is restore-tiered (the boundary-ignoring escape hatch
|
|
37
|
+
// could let a task write where a restore touches — a blanket
|
|
38
|
+
// conservative exclusion). Those tasks still get an exec-tier probe
|
|
39
|
+
// reuse entry so there's no double work.
|
|
40
|
+
|
|
41
|
+
import type { CacheEntry, CacheLayer, GitFilesCache } from '../cache/index.js'
|
|
42
|
+
import type { TaskNode } from '../graph/index.js'
|
|
43
|
+
import { deriveStableKeys } from './stable-keys.js'
|
|
44
|
+
import type { HashCache } from './task-hash.js'
|
|
45
|
+
|
|
46
|
+
export interface ShortCircuitArgs {
|
|
47
|
+
nodes: Map<string, TaskNode>
|
|
48
|
+
cache: CacheLayer
|
|
49
|
+
workspaceRoot: string
|
|
50
|
+
workspaceFingerprint: string
|
|
51
|
+
forwardArgs?: readonly string[] | undefined
|
|
52
|
+
nestedDirsByProject: Map<string, string[]>
|
|
53
|
+
gitFilesCache: GitFilesCache
|
|
54
|
+
hashCache: HashCache
|
|
55
|
+
/** Cap on concurrent probes — the run's concurrency. */
|
|
56
|
+
concurrency: number
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Per-task result of the up-front probe. `hit` null = a confirmed
|
|
60
|
+
* stable miss (skips the lazy probe in execute, goes to the run path).
|
|
61
|
+
* `hash` is the up-front-derived stable key (reused so a restore-tier
|
|
62
|
+
* task that runs before its deps doesn't recompute against an
|
|
63
|
+
* incomplete upstream). */
|
|
64
|
+
export interface ProbedEntry {
|
|
65
|
+
hash: string
|
|
66
|
+
hit: CacheEntry | null
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface ShortCircuit {
|
|
70
|
+
/**
|
|
71
|
+
* Every stable, cacheable, local-read task → its up-front probe.
|
|
72
|
+
* Threaded into executeCachedTask so it reuses the probe (no second
|
|
73
|
+
* cache.get). Covers hits AND stable misses.
|
|
74
|
+
*/
|
|
75
|
+
preProbed: Map<string, ProbedEntry>
|
|
76
|
+
/**
|
|
77
|
+
* Task ids that are confirmed stable LOCAL hits — the restore-tier.
|
|
78
|
+
* The scheduler makes these ready immediately (dep-independent) and
|
|
79
|
+
* LOW priority (backfill only). A subset of `preProbed` keys (those
|
|
80
|
+
* with a non-null hit, minus the workspace-outputs exclusion).
|
|
81
|
+
*/
|
|
82
|
+
restoreTier: Set<string>
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const EMPTY: ShortCircuit = { preProbed: new Map(), restoreTier: new Set() }
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Classify the graph's stable tasks: derive keys + probe local ONCE,
|
|
89
|
+
* returning the `preProbed` map (probe reuse) and the `restoreTier` set
|
|
90
|
+
* (confirmed hits the scheduler may run ahead of their deps).
|
|
91
|
+
*
|
|
92
|
+
* Never throws — any error in derivation / probing degrades to "no
|
|
93
|
+
* short-circuit" (an empty result), so every task falls back to the
|
|
94
|
+
* normal lazy-probe schedule, identical to today.
|
|
95
|
+
*/
|
|
96
|
+
export async function startLocalShortCircuit(args: ShortCircuitArgs): Promise<ShortCircuit> {
|
|
97
|
+
let stableKeys
|
|
98
|
+
try {
|
|
99
|
+
stableKeys = await deriveStableKeys(args)
|
|
100
|
+
} catch {
|
|
101
|
+
return EMPTY
|
|
102
|
+
}
|
|
103
|
+
const candidates = stableKeys.filter(({ node }) => node.config.cache !== undefined)
|
|
104
|
+
if (candidates.length === 0) return EMPTY
|
|
105
|
+
|
|
106
|
+
// Belt-and-suspenders for the boundary-ignoring escape hatch: a
|
|
107
|
+
// root-anchored output can land anywhere, so if ANY task declares
|
|
108
|
+
// workspace outputs a task could in principle write where a
|
|
109
|
+
// restore-tier task restores. Disable the RESTORE tier graph-wide —
|
|
110
|
+
// workspace outputs are rare bad-practice. (Probe reuse still applies,
|
|
111
|
+
// so there's no double work; those tasks just stay dep-gated.)
|
|
112
|
+
let anyWorkspaceOutputs = false
|
|
113
|
+
for (const node of args.nodes.values()) {
|
|
114
|
+
if ((node.config.cache?.outputs.workspaceFiles?.length ?? 0) > 0) {
|
|
115
|
+
anyWorkspaceOutputs = true
|
|
116
|
+
break
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const preProbed = new Map<string, ProbedEntry>()
|
|
121
|
+
const restoreTier = new Set<string>()
|
|
122
|
+
|
|
123
|
+
// Bounded pool over the stable candidates: probe local ONCE each. A
|
|
124
|
+
// confirmed hit becomes restore-tier (unless workspace outputs disable
|
|
125
|
+
// it); a miss stays exec-tier with a known-miss reuse entry. The pool
|
|
126
|
+
// keeps the up-front pass from being a serial pre-phase on a wide warm
|
|
127
|
+
// graph — the probes parallelize at the run's concurrency.
|
|
128
|
+
let next = 0
|
|
129
|
+
const workers = Math.max(1, Math.min(args.concurrency, candidates.length))
|
|
130
|
+
const pump = async (): Promise<void> => {
|
|
131
|
+
while (next < candidates.length) {
|
|
132
|
+
const { hash, node } = candidates[next++]!
|
|
133
|
+
try {
|
|
134
|
+
const command = node.config.exec?.command ?? ''
|
|
135
|
+
const hit = await args.cache.get(hash, { taskId: node.id, command })
|
|
136
|
+
preProbed.set(node.id, { hash, hit })
|
|
137
|
+
if (hit !== null && !anyWorkspaceOutputs) restoreTier.add(node.id)
|
|
138
|
+
} catch {
|
|
139
|
+
// Leave this task out of preProbed → it probes lazily in
|
|
140
|
+
// execute(), exactly as today.
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
await Promise.all(Array.from({ length: workers }, () => pump()))
|
|
145
|
+
|
|
146
|
+
return { preProbed, restoreTier }
|
|
147
|
+
}
|