@vzn/vx 0.0.636 → 0.0.638
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 +246 -213
- package/docs/cli.md +791 -705
- package/docs/execution.md +68 -76
- package/docs/features.md +47 -42
- package/docs/patterns.md +26 -25
- package/docs/schema.md +392 -205
- 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 +4 -4
- package/schemas/show.json +5 -3
- package/schemas/why.json +15 -1
- package/skills/vx/SKILL.md +28 -13
- package/src/bin.ts +30 -9
- package/src/cache/archive.ts +11 -0
- package/src/cache/cache.ts +124 -53
- package/src/cache/chained-cache.ts +4 -0
- package/src/cache/git-inputs.ts +277 -63
- package/src/cache/index.ts +15 -1
- package/src/cache/inputs.ts +102 -36
- package/src/cache/key-fold.ts +8 -7
- package/src/cache/layer.ts +15 -18
- package/src/cache/layered-cache.ts +20 -102
- package/src/cache/plugin-cache.ts +248 -0
- package/src/cache/policy.ts +32 -27
- package/src/cache/run-history.ts +104 -14
- package/src/cache/run-store.ts +77 -0
- package/src/cache/schema.ts +58 -31
- package/src/cache/scoped-cache.ts +237 -0
- package/src/cli/cache.ts +173 -34
- package/src/cli/completions.ts +11 -7
- package/src/cli/core-alias.ts +1 -1
- package/src/cli/foreign-flags.ts +13 -12
- package/src/cli/help.ts +110 -70
- package/src/cli/index.ts +67 -24
- package/src/cli/info.ts +43 -27
- package/src/cli/init.ts +115 -407
- package/src/cli/last.ts +157 -9
- package/src/cli/lock.ts +356 -122
- package/src/cli/plan-format.ts +7 -5
- package/src/cli/plugin-commands.ts +81 -14
- package/src/cli/plugin-templates.ts +11 -11
- package/src/cli/run.ts +116 -160
- package/src/cli/select.ts +50 -47
- package/src/cli/show.ts +83 -59
- package/src/cli/task-verb.ts +6 -13
- package/src/cli/upgrade.ts +415 -149
- package/src/cli/watch-cycle.ts +9 -2
- package/src/cli/watch-filter.ts +39 -61
- package/src/cli/watch-fs.ts +29 -16
- package/src/cli/watch-judge.ts +18 -4
- package/src/cli/watch-set.ts +16 -42
- package/src/cli/watch.ts +227 -230
- package/src/cli/why.ts +38 -18
- package/src/cli/workspace-config.ts +33 -70
- 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 +27 -7
- package/src/graph/task-graph.ts +76 -24
- package/src/handoff.ts +169 -0
- package/src/index.ts +35 -58
- package/src/orchestrator/affected-tasks.ts +15 -8
- 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 +147 -69
- package/src/orchestrator/failure-mode.ts +19 -10
- package/src/orchestrator/fingerprint-watch.ts +18 -15
- package/src/orchestrator/forecast.ts +10 -2
- package/src/orchestrator/framed-output.ts +9 -5
- package/src/orchestrator/graph-stage.ts +5 -5
- package/src/orchestrator/history.ts +126 -30
- package/src/orchestrator/hit-restore.ts +15 -3
- package/src/orchestrator/index.ts +20 -5
- package/src/orchestrator/local-shortcircuit.ts +2 -1
- package/src/orchestrator/lockfile-claim.ts +79 -20
- package/src/orchestrator/logger.ts +80 -41
- package/src/orchestrator/metrics.ts +78 -9
- 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 +100 -66
- package/src/orchestrator/plugin.ts +173 -67
- package/src/orchestrator/prepare.ts +163 -78
- package/src/orchestrator/projects.ts +105 -99
- package/src/orchestrator/remote-prefetch.ts +11 -6
- 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-records.ts +1 -1
- package/src/orchestrator/run-report.ts +9 -9
- package/src/orchestrator/run-settings.ts +48 -0
- package/src/orchestrator/run.ts +244 -119
- 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 +49 -7
- package/src/orchestrator/summary.ts +115 -106
- package/src/orchestrator/task-hash.ts +12 -83
- package/src/orchestrator/telemetry.ts +4 -4
- package/src/settings.ts +428 -0
- package/src/{orchestrator → util}/colors.ts +5 -0
- package/src/util/config-frame.ts +31 -2
- package/src/util/errors.ts +33 -1
- package/src/util/essential-env.ts +31 -0
- package/src/util/hide-env.ts +107 -0
- package/src/util/index.ts +16 -3
- package/src/util/paths.ts +10 -0
- package/src/util/refusal-notice.ts +111 -0
- package/src/util/report.ts +31 -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/ui.ts +186 -0
- package/src/util/ulid.ts +1 -1
- package/src/util/verbs.ts +0 -15
- package/src/workspace/affected.ts +84 -232
- 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 +65 -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 +307 -215
- 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 +363 -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
|
@@ -11,21 +11,28 @@
|
|
|
11
11
|
import { readFileSync } from 'node:fs'
|
|
12
12
|
import path from 'node:path'
|
|
13
13
|
import { fileURLToPath } from 'node:url'
|
|
14
|
-
import
|
|
14
|
+
import {
|
|
15
|
+
absentPluginCache,
|
|
16
|
+
type Cache,
|
|
17
|
+
type PluginCache,
|
|
18
|
+
type RemoteCacheLayer,
|
|
19
|
+
} from '../cache/index.js'
|
|
15
20
|
import { PLUGIN_PACKAGE, type ProjectConfig, type WorkspaceConfig } from '../config.js'
|
|
16
21
|
import type { TaskExecutor } from '../exec/index.js'
|
|
17
|
-
import type { TaskNode, TaskOutcome } from '../graph/index.js'
|
|
22
|
+
import type { TaskNode, TaskOutcome, TaskStatus } from '../graph/index.js'
|
|
18
23
|
import { maskedLine, nearest, UserError } from '../util/index.js'
|
|
19
24
|
import type { ProjectMeta } from '../workspace/index.js'
|
|
20
25
|
import type { EventBus, RunStartInfo } from './events.js'
|
|
26
|
+
import type { CiContext } from './run-context.js'
|
|
21
27
|
import type { TelemetryContext, TelemetrySink } from './telemetry.js'
|
|
28
|
+
import type { Logger } from './logger.js'
|
|
22
29
|
|
|
23
30
|
/**
|
|
24
31
|
* A vx plugin. Contributes any subset of the run-level capabilities —
|
|
25
32
|
* where work runs (executor), which cache is used (cache), who
|
|
26
33
|
* observes the run (telemetry). It never changes WHAT a task is (the
|
|
27
34
|
* command string — principle #3), only where and how that command is
|
|
28
|
-
* executed. Registered explicitly in vx
|
|
35
|
+
* executed. Registered explicitly in .vx/workspace.ts via
|
|
29
36
|
* defineWorkspace({ plugins: [...] }). No auto-discovery.
|
|
30
37
|
*
|
|
31
38
|
* Made by `definePlugin(import.meta, hooks)` only: the loader refuses a
|
|
@@ -59,24 +66,32 @@ export interface VxPlugin {
|
|
|
59
66
|
config?(workspace: WorkspaceConfig, ctx: WorkspaceHookContext): void | Promise<void>
|
|
60
67
|
|
|
61
68
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
+
* Projects beyond the directories holding a vx.config, their names, and
|
|
70
|
+
* edges between projects, as `DiscoveredProject`s (each directory
|
|
71
|
+
* absolute or relative to the workspace root): a lockfile's importers,
|
|
72
|
+
* their package names and the dependencies it records; a runner's root
|
|
73
|
+
* tasks. Runs once per discovery, before any project config loads; each
|
|
74
|
+
* plugin sees the locked projects and the ones earlier plugins added,
|
|
75
|
+
* without their edges. A directory that is not a project becomes one
|
|
76
|
+
* (with no config; named by `name`, else its path). A project named by
|
|
77
|
+
* its path takes `name`; one its config names keeps that name, and a
|
|
78
|
+
* different name from an earlier plugin is refused, as is a directory
|
|
79
|
+
* outside the root. Two projects of one name are refused once the stage
|
|
80
|
+
* ends. `deps` and `reach` from every plugin union then; a target that is
|
|
81
|
+
* no project is refused.
|
|
69
82
|
*/
|
|
70
|
-
discover?(
|
|
83
|
+
discover?(
|
|
84
|
+
ctx: DiscoverContext,
|
|
85
|
+
): readonly DiscoveredProject[] | Promise<readonly DiscoveredProject[]>
|
|
71
86
|
|
|
72
87
|
/**
|
|
73
88
|
* One project's validated config, right after it loaded and before the
|
|
74
89
|
* graph is built. Add, remove or edit tasks. Runs for every loaded project
|
|
75
|
-
* on every run — a config
|
|
76
|
-
*
|
|
77
|
-
* loaded too, as `{ tasks: {} }`, so a
|
|
78
|
-
*
|
|
79
|
-
*
|
|
90
|
+
* on every run — a locked config is the user's file, and the hook is
|
|
91
|
+
* applied on top of it live. A project with NO config file (a
|
|
92
|
+
* `discover` plugin added it) is loaded too, as `{ tasks: {} }`, so a
|
|
93
|
+
* plugin can give it tasks; with no `project` plugin such a project is
|
|
94
|
+
* never visited.
|
|
80
95
|
*/
|
|
81
96
|
project?(config: ProjectConfig, ctx: ProjectHookContext): void | Promise<void>
|
|
82
97
|
|
|
@@ -105,22 +120,14 @@ export interface VxPlugin {
|
|
|
105
120
|
| Promise<Readonly<Record<string, string>> | undefined>
|
|
106
121
|
|
|
107
122
|
/**
|
|
108
|
-
* Workspace-root files this plugin keys on
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
* every project. A file has one claimant.
|
|
117
|
-
*
|
|
118
|
-
* A root file core does NOT fold is claimed the same way when the
|
|
119
|
-
* plugin's stages read it: `turbo()` shapes every task from
|
|
120
|
-
* `turbo.json`, so an edit to it re-keys tasks through their resolved
|
|
121
|
-
* configs while no project owns the path. Nothing is taken out;
|
|
122
|
-
* `--affected` asks `affected` (undefined: every project) and `vx watch`
|
|
123
|
-
* re-runs on an edit (item 961). A claim is a bare name at the root.
|
|
123
|
+
* Workspace-root files this plugin keys on: core folds no root file into
|
|
124
|
+
* any key, so a plugin that reads one (a lockfile it folds per project
|
|
125
|
+
* through `key`, `turbo.json` that shapes every task through its
|
|
126
|
+
* `project` stage) claims it here. `--affected` asks `affected` which
|
|
127
|
+
* projects a change to it touches (undefined: every project), `vx watch`
|
|
128
|
+
* re-runs on an edit (item 961), and a task that rewrites one during the
|
|
129
|
+
* run withholds every later save. A claim is a bare name at the root; a
|
|
130
|
+
* file has one claimant.
|
|
124
131
|
*/
|
|
125
132
|
readonly fingerprint?: FingerprintClaim
|
|
126
133
|
|
|
@@ -167,14 +174,14 @@ export interface VxPlugin {
|
|
|
167
174
|
// --- BEHAVIOR capabilities (change WHAT/HOW work runs — opt-in) -----------
|
|
168
175
|
|
|
169
176
|
/**
|
|
170
|
-
* Contribute a cache
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
177
|
+
* Contribute a remote cache: the wire (`has`, `get`, `put`, optional
|
|
178
|
+
* `hasMany`), or undefined to decline. Consulted ONCE per prepareRun.
|
|
179
|
+
* Core layers each one behind its own local cache and owns the rest:
|
|
180
|
+
* the local store is asked first, then each remote in declaration order;
|
|
181
|
+
* the run's policy and scope gate every remote; a remote's throw is a
|
|
182
|
+
* miss and a warning naming the plugin, never a failed run.
|
|
176
183
|
*/
|
|
177
|
-
cache?(ctx: CacheContext):
|
|
184
|
+
cache?(ctx: CacheContext): RemoteCacheLayer | undefined | Promise<RemoteCacheLayer | undefined>
|
|
178
185
|
|
|
179
186
|
/**
|
|
180
187
|
* Contribute a task executor — WHERE one task's command runs. Consulted
|
|
@@ -206,19 +213,65 @@ export interface VxPlugin {
|
|
|
206
213
|
| undefined
|
|
207
214
|
| Promise<TelemetrySink | TelemetrySink[] | undefined>
|
|
208
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Take the terminal for this run: return the `Logger` that renders it
|
|
218
|
+
* (the contract `run({ log })` takes), or `undefined` to leave core's
|
|
219
|
+
* renderer in place. The first plugin, in declaration order, that
|
|
220
|
+
* returns one renders the run; the rest are not asked. Not consulted
|
|
221
|
+
* when an embedder passed its own `log`. A logger that throws hands the
|
|
222
|
+
* rest of the run back to core's renderer with one warning.
|
|
223
|
+
*/
|
|
224
|
+
output?(ctx: OutputContext): Logger | undefined | Promise<Logger | undefined>
|
|
225
|
+
|
|
209
226
|
/**
|
|
210
227
|
* Optional one-time setup per run (validate the workspace, open a
|
|
211
228
|
* connection, read a token). Throwing aborts the run with a clean
|
|
212
229
|
* UserError naming the plugin. It is not a guard over the pipeline: the
|
|
213
|
-
* config, project, cache, graph
|
|
214
|
-
*
|
|
215
|
-
* precedes the executors, the telemetry sinks,
|
|
216
|
-
* task (tests/plugin-e2e.test.ts).
|
|
230
|
+
* config, project, cache, graph and key stages have run by the time it
|
|
231
|
+
* is called, and a plan (`--dry`, `planRun`) never calls it. It
|
|
232
|
+
* precedes the schedule stage, the executors, the telemetry sinks,
|
|
233
|
+
* admission and the first task (tests/plugin-e2e.test.ts).
|
|
217
234
|
*/
|
|
218
235
|
setup?(ctx: PluginSetupContext): void | Promise<void>
|
|
219
236
|
|
|
220
|
-
/**
|
|
221
|
-
|
|
237
|
+
/**
|
|
238
|
+
* Optional teardown at end-of-run (flush a sink, close a socket). Errors
|
|
239
|
+
* are logged, never thrown. A run that ran to its end passes its
|
|
240
|
+
* `RunReport`; every other exit (a refused setup, a stop) passes none.
|
|
241
|
+
*/
|
|
242
|
+
teardown?(run?: RunReport): void | Promise<void>
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* What a finished run hands each plugin's `teardown`: its facts and every
|
|
247
|
+
* task, with the names core kept the task's bytes under. Core keeps them
|
|
248
|
+
* only when a remote takes the run's writes (CI by default): a failed
|
|
249
|
+
* task's log and the files its outputs left, an uncached task's log. Read
|
|
250
|
+
* them with `ctx.cache.getRun(name)`. Core keeps no manifest of its own; a
|
|
251
|
+
* plugin that wants one writes it from here (`ctx.cache.put`).
|
|
252
|
+
*/
|
|
253
|
+
export interface RunReport {
|
|
254
|
+
/** The `run_id` the run's history rows and telemetry carry. */
|
|
255
|
+
readonly runId: string
|
|
256
|
+
/** `HEAD`'s commit, null outside a git worktree. */
|
|
257
|
+
readonly commit: string | null
|
|
258
|
+
/** What the CI provider says about this run: provider, run URL, pipeline, job, attempt. */
|
|
259
|
+
readonly ciRun: CiContext
|
|
260
|
+
readonly ok: boolean
|
|
261
|
+
/** Every task the run decided, in completion order; group tasks are left out. */
|
|
262
|
+
readonly tasks: readonly RunReportTask[]
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export interface RunReportTask {
|
|
266
|
+
readonly id: string
|
|
267
|
+
readonly status: TaskStatus
|
|
268
|
+
readonly durationMs: number
|
|
269
|
+
/** The task's cache key, when one was computed. */
|
|
270
|
+
readonly key?: string
|
|
271
|
+
/** Its output (both streams, secrets masked), when core kept it: `ctx.cache.getRun(log)`. */
|
|
272
|
+
readonly log?: string
|
|
273
|
+
/** A tar of the files its declared outputs left, when core kept it: `ctx.cache.getRun(outputs)`. */
|
|
274
|
+
readonly outputs?: string
|
|
222
275
|
}
|
|
223
276
|
|
|
224
277
|
/** Shared, read-only context every capability factory receives. */
|
|
@@ -231,6 +284,12 @@ interface BaseContext {
|
|
|
231
284
|
|
|
232
285
|
/** What `setup` receives: the run's lifecycle, observe-only. */
|
|
233
286
|
export interface PluginSetupContext extends BaseContext {
|
|
287
|
+
/** This plugin's entries in the workspace's cache (`PluginCache`). */
|
|
288
|
+
readonly cache: PluginCache
|
|
289
|
+
/** The run is on CI (`CI` set, or a provider core detects). */
|
|
290
|
+
readonly ci: boolean
|
|
291
|
+
/** The run's branch (`currentBranch`): `run.branch`, else git's, else the CI provider's. */
|
|
292
|
+
readonly branch: string | null
|
|
234
293
|
/**
|
|
235
294
|
* Subscribe a lifecycle handler; it leaves with the run. A throw or a
|
|
236
295
|
* rejection warns once and switches the plugin's handlers off for the run.
|
|
@@ -248,7 +307,7 @@ export interface PluginCommand {
|
|
|
248
307
|
export interface CommandContext extends BaseContext {
|
|
249
308
|
/**
|
|
250
309
|
* The worker count a `vx run` here uses unless `--concurrency` says
|
|
251
|
-
* otherwise:
|
|
310
|
+
* otherwise: `.vx/workspace`'s `concurrency`, else what the machine allows.
|
|
252
311
|
* A verb that budgets a run (`vx history`) reads it here; its own
|
|
253
312
|
* `machineParallelism()` said 4 cores beside `concurrency: 1` (item 1068).
|
|
254
313
|
*/
|
|
@@ -256,10 +315,16 @@ export interface CommandContext extends BaseContext {
|
|
|
256
315
|
/**
|
|
257
316
|
* The argv that runs this vx again: the binary alone when compiled, the
|
|
258
317
|
* runtime and its entry script from source. A verb that runs tasks
|
|
259
|
-
*
|
|
318
|
+
* spawns `[...vx, 'run', …]` rather than guess
|
|
260
319
|
* which `vx` a PATH holds.
|
|
261
320
|
*/
|
|
262
321
|
readonly vx: readonly string[]
|
|
322
|
+
/**
|
|
323
|
+
* This plugin's entries in the workspace's cache, as `setup` reaches them
|
|
324
|
+
* (`PluginCache`), read-only: the local store, then each remote the
|
|
325
|
+
* workspace's cache plugins supply, under the run's scope. Opened on first use.
|
|
326
|
+
*/
|
|
327
|
+
readonly cache: PluginCache
|
|
263
328
|
}
|
|
264
329
|
|
|
265
330
|
/** `config` runs before the cache dir is known — it may be what the hook changes. */
|
|
@@ -271,7 +336,7 @@ export interface WorkspaceHookContext {
|
|
|
271
336
|
export interface DiscoverContext extends WorkspaceHookContext {
|
|
272
337
|
/** Where vx's cache lives: a plugin may keep what it read to answer here. */
|
|
273
338
|
readonly cacheDir: string
|
|
274
|
-
/** The projects found so far:
|
|
339
|
+
/** The projects found so far: the lock's, then earlier plugins'. */
|
|
275
340
|
readonly projects: readonly ProjectMeta[]
|
|
276
341
|
/**
|
|
277
342
|
* What `git status` lists in the workspace, workspace-relative: modified,
|
|
@@ -283,30 +348,46 @@ export interface DiscoverContext extends WorkspaceHookContext {
|
|
|
283
348
|
worktreeChanges(): Promise<readonly string[] | null>
|
|
284
349
|
}
|
|
285
350
|
|
|
286
|
-
|
|
351
|
+
/** What a `discover` hook returns per directory — see `VxPlugin.discover`. */
|
|
352
|
+
export interface DiscoveredProject {
|
|
353
|
+
/** Absolute or relative to the workspace root. */
|
|
287
354
|
readonly dir: string
|
|
288
|
-
|
|
355
|
+
/**
|
|
356
|
+
* Its name, when its config names none: replaces a path name, never a
|
|
357
|
+
* config's; a different name from an earlier plugin is refused. Unset on
|
|
358
|
+
* a new directory: its root-relative path.
|
|
359
|
+
*/
|
|
360
|
+
readonly name?: string
|
|
361
|
+
/** Directories this project builds after: `^task` order, and reach for `--filter` and `--affected`. */
|
|
362
|
+
readonly deps?: readonly string[]
|
|
363
|
+
/** Directories a change reaches this project through (`--filter`, `--affected`), with no order. */
|
|
364
|
+
readonly reach?: readonly string[]
|
|
289
365
|
}
|
|
290
366
|
|
|
291
367
|
export interface ProjectHookContext extends BaseContext {
|
|
292
|
-
/** The
|
|
368
|
+
/** The project's name (`ProjectMeta.name`). */
|
|
293
369
|
readonly name: string
|
|
294
370
|
/** The project's directory, absolute. */
|
|
295
371
|
readonly dir: string
|
|
296
|
-
/** The parsed `package.json`, read-only. */
|
|
297
|
-
readonly packageJson: Readonly<Record<string, unknown>>
|
|
298
372
|
/**
|
|
299
|
-
* Every
|
|
300
|
-
* rest of the run's scope and the
|
|
301
|
-
* not — as
|
|
302
|
-
* whole workspace (a `dependsOn` is only valid against every
|
|
303
|
-
* scripts at once) reads it here instead of walking the workspace a
|
|
373
|
+
* Every project the workspace discovered — the one being visited, the
|
|
374
|
+
* rest of the run's scope and the projects outside it, config file or
|
|
375
|
+
* not — as the `discover` stage left them. A plugin whose mapping needs
|
|
376
|
+
* the whole workspace (a `dependsOn` is only valid against every
|
|
377
|
+
* package's scripts at once) reads it here instead of walking the workspace a
|
|
304
378
|
* second time. The same array is handed to every visit of a run and a
|
|
305
379
|
* new one to the next run — a plugin instance outlives a run under `vx
|
|
306
380
|
* watch`, so a per-run memo keys on this array's identity, never on the
|
|
307
381
|
* process.
|
|
308
382
|
*/
|
|
309
383
|
readonly projects: readonly ProjectMeta[]
|
|
384
|
+
/**
|
|
385
|
+
* True when `vx lock` (or `--check`) visits: the one pass that checks the
|
|
386
|
+
* configs, so the place to report what a plugin's mapping could not say.
|
|
387
|
+
* A run checks nothing (the lock model), so such a report there repeats
|
|
388
|
+
* on every run.
|
|
389
|
+
*/
|
|
390
|
+
readonly lock: boolean
|
|
310
391
|
}
|
|
311
392
|
|
|
312
393
|
export interface GraphHookContext extends BaseContext {
|
|
@@ -320,16 +401,16 @@ export interface GraphHookContext extends BaseContext {
|
|
|
320
401
|
|
|
321
402
|
export interface KeyHookContext extends BaseContext {}
|
|
322
403
|
|
|
323
|
-
/** A plugin's claim on workspace
|
|
404
|
+
/** A plugin's claim on workspace-root files — see `VxPlugin.fingerprint`. */
|
|
324
405
|
export interface FingerprintClaim {
|
|
325
|
-
/** Bare names at the workspace root: a lockfile
|
|
406
|
+
/** Bare names at the workspace root the plugin reads: a lockfile (`pnpm-lock.yaml`), a settings file, `turbo.json`. */
|
|
326
407
|
readonly files: readonly string[]
|
|
327
408
|
/**
|
|
328
|
-
* The projects (
|
|
409
|
+
* The projects (by name) a change to a claimed file affects. Called
|
|
329
410
|
* by `--affected` with the file's bytes at the base ref and in the
|
|
330
411
|
* working tree (`null` where it does not exist). Return `undefined` to
|
|
331
412
|
* select every project — the answer a claimant gives when it cannot
|
|
332
|
-
* tell
|
|
413
|
+
* tell.
|
|
333
414
|
*/
|
|
334
415
|
affected(
|
|
335
416
|
change: FingerprintChange,
|
|
@@ -345,7 +426,7 @@ export interface FingerprintChange {
|
|
|
345
426
|
}
|
|
346
427
|
|
|
347
428
|
export interface FingerprintContext extends BaseContext {
|
|
348
|
-
/** Every project in the workspace:
|
|
429
|
+
/** Every project in the workspace: name and absolute directory. */
|
|
349
430
|
readonly projects: ReadonlyArray<{ readonly name: string; readonly dir: string }>
|
|
350
431
|
}
|
|
351
432
|
|
|
@@ -364,13 +445,29 @@ export interface AdmitContext {
|
|
|
364
445
|
export interface ScheduleHookContext extends BaseContext {
|
|
365
446
|
/** The run's local cache handle — its `dbHandle()` holds the run history a policy can learn from. */
|
|
366
447
|
readonly localCache: Cache
|
|
448
|
+
/** The run's branch (`currentBranch`), the timings a forecast reads first: pass it to `LocalHistoryProvider`. */
|
|
449
|
+
readonly branch: string | null
|
|
450
|
+
/** This plugin's entries in the workspace's cache, as `setup` has them. */
|
|
451
|
+
readonly cache: PluginCache
|
|
367
452
|
}
|
|
368
453
|
|
|
454
|
+
/** A `cache` hook's context: the workspace and the run's scope, never the local store or the policy, which core owns. */
|
|
369
455
|
export interface CacheContext extends BaseContext {
|
|
370
|
-
/**
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
456
|
+
/**
|
|
457
|
+
* The run's `cache.scope` (`'pr-123'`), `undefined` when none. Core already keys a scoped run's
|
|
458
|
+
* writes apart; a remote reads it to pick a credential or check a token's
|
|
459
|
+
* claims (an OIDC branch) for every call it makes.
|
|
460
|
+
*/
|
|
461
|
+
readonly scope: string | undefined
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export interface OutputContext extends BaseContext {
|
|
465
|
+
/** Core would write to a terminal: stdout (stderr under `json`) is a TTY. */
|
|
466
|
+
readonly isTTY: boolean
|
|
467
|
+
/** The run is on CI (`CI` set, or a provider core detects). */
|
|
468
|
+
readonly ci: boolean
|
|
469
|
+
/** `--format json`: stdout carries the machine-readable result. */
|
|
470
|
+
readonly json: boolean
|
|
374
471
|
}
|
|
375
472
|
|
|
376
473
|
export interface ExecutorContext extends BaseContext {
|
|
@@ -585,6 +682,12 @@ export interface InstallPluginsArgs {
|
|
|
585
682
|
* `run:status` channel.
|
|
586
683
|
*/
|
|
587
684
|
warn?: (message: string) => void
|
|
685
|
+
/** Each plugin's `ctx.cache`, by plugin name. Default: a cache with no layer. */
|
|
686
|
+
cache?: (plugin: string) => PluginCache
|
|
687
|
+
/** Default false. */
|
|
688
|
+
ci?: boolean
|
|
689
|
+
/** Default null. */
|
|
690
|
+
branch?: string | null
|
|
588
691
|
}
|
|
589
692
|
|
|
590
693
|
/**
|
|
@@ -641,6 +744,9 @@ export async function installPlugins(args: InstallPluginsArgs): Promise<() => vo
|
|
|
641
744
|
workspaceRoot,
|
|
642
745
|
cacheDir,
|
|
643
746
|
warn,
|
|
747
|
+
cache: args.cache?.(plugin.name) ?? absentPluginCache,
|
|
748
|
+
ci: args.ci ?? false,
|
|
749
|
+
branch: args.branch ?? null,
|
|
644
750
|
// A subscription made past the hooks leaves with the run like a
|
|
645
751
|
// hook's does: the bus can outlive the run (`RunOptions.bus`), and
|
|
646
752
|
// one left behind hears every later run on it (item 635).
|