@vzn/vx 0.0.645 → 0.0.648
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 -50
- package/launcher.cjs +9 -2
- package/launcher.sh +2 -2
- package/package.json +5 -5
- package/schemas/cache.json +5 -5
- package/schemas/error.json +1 -1
- package/schemas/info.json +16 -2
- package/schemas/last.json +127 -5
- package/schemas/plan.json +28 -2
- package/schemas/show.json +10 -1
- package/skills/vx/SKILL.md +19 -3
- package/src/bin.ts +54 -13
- package/src/cache/archive.ts +324 -23
- package/src/cache/cache.ts +330 -65
- package/src/cache/git-inputs.ts +274 -97
- package/src/cache/index.ts +7 -2
- package/src/cache/inputs.ts +515 -83
- package/src/cache/key-fold.ts +15 -6
- package/src/cache/layer.ts +74 -11
- package/src/cache/layered-cache.ts +154 -59
- package/src/cache/linked-inputs.ts +1 -1
- package/src/cache/output-index.ts +44 -14
- package/src/cache/plugin-cache.ts +49 -23
- package/src/cache/remote-hits.ts +72 -0
- package/src/cache/remote-lane.ts +100 -15
- package/src/cache/run-history.ts +77 -23
- package/src/cache/run-store.ts +11 -10
- package/src/cache/schema.ts +42 -6
- package/src/cache/tar-stream.ts +5 -0
- package/src/cache/umask.ts +1 -2
- package/src/cli/cache.ts +58 -27
- package/src/cli/completions.ts +12 -5
- package/src/cli/core-alias.ts +5 -2
- package/src/cli/docs.ts +42 -16
- package/src/cli/help.ts +62 -25
- package/src/cli/index.ts +79 -45
- package/src/cli/info.ts +12 -6
- package/src/cli/init.ts +222 -34
- package/src/cli/last.ts +443 -47
- package/src/cli/lock.ts +197 -52
- package/src/cli/plan-format.ts +91 -49
- package/src/cli/plugin-commands.ts +160 -11
- package/src/cli/plugin-templates.ts +13 -13
- package/src/cli/registry.ts +209 -0
- package/src/cli/run.ts +111 -41
- package/src/cli/select.ts +148 -49
- package/src/cli/show.ts +59 -16
- package/src/cli/task-verb.ts +16 -6
- package/src/cli/upgrade.ts +155 -54
- package/src/cli/watch-cycle.ts +10 -5
- package/src/cli/watch-filter.ts +71 -3
- package/src/cli/watch-fs.ts +22 -6
- package/src/cli/watch-judge.ts +48 -6
- package/src/cli/watch.ts +163 -42
- package/src/cli/why.ts +211 -73
- package/src/cli/workspace-config.ts +54 -15
- package/src/config.ts +13 -1
- package/src/exec/env.ts +7 -2
- package/src/exec/executor.ts +262 -15
- package/src/exec/index.ts +8 -2
- package/src/exec/kill-tree.ts +15 -0
- package/src/exec/local-executor.ts +1 -1
- package/src/exec/proc-sample.ts +70 -6
- package/src/exec/runner.ts +256 -53
- package/src/exec/sandbox-binds.ts +7 -3
- package/src/exec/sandbox-paths.ts +1 -1
- package/src/exec/sandbox-runtime.ts +222 -28
- package/src/exec/sandbox-violations.ts +52 -20
- package/src/graph/critical-path.ts +79 -0
- package/src/graph/default-build.ts +19 -0
- package/src/graph/definition.ts +38 -0
- package/src/graph/folds.ts +38 -5
- package/src/graph/index.ts +4 -1
- package/src/graph/priorities.ts +74 -8
- package/src/graph/scheduler.ts +326 -65
- package/src/graph/task-graph.ts +228 -35
- package/src/handoff.ts +97 -9
- package/src/history/failure-mode.ts +6 -3
- package/src/history/history.ts +268 -50
- package/src/history/index.ts +2 -0
- package/src/history/metrics.ts +142 -45
- package/src/index.ts +42 -10
- package/src/orchestrator/admission.ts +10 -6
- package/src/orchestrator/affected-tasks.ts +11 -6
- package/src/orchestrator/deferred-outputs.ts +2 -0
- package/src/orchestrator/doctor.ts +134 -42
- package/src/orchestrator/execute-args.ts +6 -0
- package/src/orchestrator/execute-task.ts +155 -42
- package/src/orchestrator/fingerprint-watch.ts +1 -1
- package/src/orchestrator/graph-memo.ts +140 -0
- package/src/orchestrator/graph-stage.ts +18 -1
- package/src/orchestrator/held-servers.ts +86 -0
- package/src/orchestrator/hit-restore.ts +227 -122
- package/src/orchestrator/index.ts +20 -3
- package/src/orchestrator/local-floor.ts +198 -0
- package/src/orchestrator/local-shortcircuit.ts +51 -8
- package/src/orchestrator/lockfile-claim.ts +96 -16
- package/src/orchestrator/miss-save.ts +52 -12
- package/src/orchestrator/options.ts +8 -6
- package/src/orchestrator/output-host.ts +43 -14
- package/src/orchestrator/output-log.ts +90 -10
- package/src/orchestrator/persistent-task.ts +97 -28
- package/src/orchestrator/persistent.ts +16 -4
- package/src/orchestrator/placement.ts +257 -14
- package/src/orchestrator/plan.ts +64 -7
- package/src/orchestrator/plugin-host.ts +230 -40
- package/src/orchestrator/plugin.ts +150 -37
- package/src/orchestrator/prepare.ts +178 -32
- package/src/orchestrator/projects.ts +65 -40
- package/src/orchestrator/remote-prefetch.ts +119 -25
- package/src/orchestrator/run-artifacts.ts +95 -32
- package/src/orchestrator/run-context.ts +39 -41
- package/src/orchestrator/run-failures.ts +65 -23
- package/src/orchestrator/run-id.ts +6 -3
- package/src/orchestrator/run-keys.ts +300 -0
- package/src/orchestrator/run-live.ts +294 -0
- package/src/orchestrator/run-lock.ts +13 -7
- package/src/orchestrator/run-records.ts +35 -23
- package/src/orchestrator/run-report.ts +3 -3
- package/src/orchestrator/run-steps.ts +58 -22
- package/src/orchestrator/run-stop.ts +22 -5
- package/src/orchestrator/run.ts +409 -79
- package/src/orchestrator/sandbox-fix.ts +7 -5
- package/src/orchestrator/sandbox-request.ts +78 -22
- package/src/orchestrator/shell-verdict.ts +5 -5
- package/src/orchestrator/signals.ts +26 -1
- package/src/orchestrator/stable-keys.ts +92 -8
- package/src/orchestrator/steps.ts +2 -2
- package/src/orchestrator/task-artifacts.ts +206 -0
- package/src/orchestrator/task-hash.ts +89 -14
- package/src/orchestrator/task-log-buffer.ts +72 -36
- package/src/orchestrator/task-process.ts +22 -0
- package/src/orchestrator/telemetry-host.ts +24 -3
- package/src/orchestrator/telemetry.ts +113 -38
- package/src/orchestrator/upstream.ts +15 -0
- package/src/report/events.ts +32 -13
- package/src/report/forecast.ts +36 -35
- package/src/report/framed-output.ts +173 -46
- package/src/report/index.ts +1 -0
- package/src/report/logger.ts +217 -186
- package/src/report/path-links.ts +12 -4
- package/src/report/plain-output.ts +13 -5
- package/src/report/status-line.ts +94 -46
- package/src/report/summary.ts +174 -38
- package/src/report/terminal-signals.ts +13 -2
- package/src/settings.ts +14 -6
- package/src/util/bun-version.ts +4 -1
- package/src/util/colors.ts +20 -3
- package/src/util/config-frame.ts +41 -4
- package/src/{graph → util}/dependency-spec.ts +22 -13
- package/src/util/edit-distance.ts +13 -1
- package/src/util/env-flag.ts +9 -0
- package/src/util/errors.ts +59 -3
- package/src/util/essential-env.ts +57 -0
- package/src/util/git-ignored.ts +1 -1
- package/src/util/hash.ts +35 -0
- package/src/util/hide-env.ts +45 -5
- package/src/util/index.ts +22 -5
- package/src/util/num.ts +8 -0
- package/src/util/paths.ts +121 -21
- package/src/util/report.ts +6 -1
- package/src/util/secret-mask.ts +62 -1
- package/src/util/secrets.ts +7 -2
- package/src/util/size.ts +11 -3
- package/src/util/tail.ts +6 -1
- package/src/util/timing.ts +13 -1
- package/src/util/ui.ts +65 -4
- package/src/util/which.ts +1 -1
- package/src/util/write-file.ts +67 -0
- package/src/workspace/affected.ts +710 -107
- package/src/workspace/bracket-literal.ts +84 -0
- package/src/workspace/canonical-dir.ts +37 -0
- package/src/workspace/config-bytecode.ts +282 -0
- package/src/workspace/config-eval.ts +29 -8
- package/src/workspace/config-imports.ts +199 -58
- package/src/workspace/config-schema.ts +242 -39
- package/src/workspace/filter.ts +37 -8
- package/src/workspace/index.ts +11 -2
- package/src/workspace/json-data.ts +3 -4
- package/src/workspace/lockfile.ts +57 -8
- package/src/workspace/migration.ts +72 -49
- package/src/workspace/package-graph.ts +5 -4
- package/src/workspace/project-loader.ts +314 -47
- package/src/workspace/repo-id.ts +1 -1
- package/src/workspace/workspace.ts +176 -33
- package/src/cli/foreign-flags.ts +0 -727
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
machineMemoryBytes,
|
|
20
20
|
machineParallelism,
|
|
21
21
|
treeBytes,
|
|
22
|
+
ui,
|
|
22
23
|
} from '../util/index.js'
|
|
23
24
|
import { vxPath } from '../handoff.js'
|
|
24
25
|
import { VERSION } from '../version.js'
|
|
@@ -32,10 +33,18 @@ import {
|
|
|
32
33
|
import { flakyTasks, type FlakyTask } from '../history/index.js'
|
|
33
34
|
import type { VxPlugin } from './plugin.js'
|
|
34
35
|
import { discoverProjects, loadProjects, loadWorkspacePlugins, lockReader } from './projects.js'
|
|
35
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
atPath,
|
|
38
|
+
envName,
|
|
39
|
+
parseSettingValue,
|
|
40
|
+
resolveSetting,
|
|
41
|
+
settingRefusal,
|
|
42
|
+
SETTINGS,
|
|
43
|
+
type SettingSource,
|
|
44
|
+
} from '../settings.js'
|
|
36
45
|
|
|
37
46
|
const warnToStderr = (message: string): void => {
|
|
38
|
-
|
|
47
|
+
ui.say('warn', message)
|
|
39
48
|
}
|
|
40
49
|
|
|
41
50
|
/** The doctor's facts, typed: what `--format json` prints and the pretty rows render. */
|
|
@@ -89,6 +98,11 @@ export interface InfoFacts {
|
|
|
89
98
|
schemaVersion: string
|
|
90
99
|
cacheEntries: number
|
|
91
100
|
cacheBytes: number
|
|
101
|
+
/**
|
|
102
|
+
* Why the cache index cannot be read (a file SQLite cannot open, and its
|
|
103
|
+
* fix); null when it reads. While set, the counts it holds read zero.
|
|
104
|
+
*/
|
|
105
|
+
cacheIndexError: string | null
|
|
92
106
|
/**
|
|
93
107
|
* Every setting (src/settings.ts) as a run with no flags takes it: its
|
|
94
108
|
* variable's value, else the workspace's (after the `config` stage),
|
|
@@ -96,7 +110,12 @@ export interface InfoFacts {
|
|
|
96
110
|
*/
|
|
97
111
|
settings: Record<
|
|
98
112
|
string,
|
|
99
|
-
{
|
|
113
|
+
{
|
|
114
|
+
value: string | number | boolean | null
|
|
115
|
+
source: 'env' | 'workspace' | 'default'
|
|
116
|
+
/** Why a run refuses this variable's value; absent when it takes it. */
|
|
117
|
+
refused?: string
|
|
118
|
+
}
|
|
100
119
|
>
|
|
101
120
|
orphans: { artifacts: number; bytes: number }
|
|
102
121
|
runs24h: number
|
|
@@ -106,6 +125,8 @@ export interface InfoFacts {
|
|
|
106
125
|
/** Tasks the retained history shows failing on a key that had passed. */
|
|
107
126
|
flakyTasks: FlakyTask[]
|
|
108
127
|
lockfile: boolean
|
|
128
|
+
/** Why a run refuses the lock that is there; null when it reads it (or there is none). */
|
|
129
|
+
lockError: string | null
|
|
109
130
|
/**
|
|
110
131
|
* Whether this host can run a task's `exec.sandbox`, and how many loaded
|
|
111
132
|
* tasks declare one. A declared sandbox whose runtime cannot start is a
|
|
@@ -127,6 +148,34 @@ export interface CollectInfoOptions {
|
|
|
127
148
|
}
|
|
128
149
|
|
|
129
150
|
export async function collectInfo(cwd: string, opts: CollectInfoOptions = {}): Promise<InfoFacts> {
|
|
151
|
+
// A variable a run refuses is a fact of the report, not a refusal of it:
|
|
152
|
+
// set aside while the workspace loads, so no deep reader throws on it.
|
|
153
|
+
const refused = refusedSettings()
|
|
154
|
+
for (const r of refused.values()) delete process.env[r.name]
|
|
155
|
+
try {
|
|
156
|
+
const facts = await collectInfoChecked(cwd, opts)
|
|
157
|
+
for (const [p, r] of refused)
|
|
158
|
+
facts.settings[p] = { value: r.raw, source: 'env', refused: r.reason }
|
|
159
|
+
return facts
|
|
160
|
+
} finally {
|
|
161
|
+
for (const r of refused.values()) process.env[r.name] = r.raw
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Each set setting variable a run refuses, by path: its name, value and why. */
|
|
166
|
+
function refusedSettings(): Map<string, { name: string; raw: string; reason: string }> {
|
|
167
|
+
const out = new Map<string, { name: string; raw: string; reason: string }>()
|
|
168
|
+
for (const s of SETTINGS) {
|
|
169
|
+
if (s.env === false) continue
|
|
170
|
+
const name = envName(s.path)
|
|
171
|
+
const raw = process.env[name]
|
|
172
|
+
if (raw === undefined || raw === '' || parseSettingValue(s.kind, raw) !== null) continue
|
|
173
|
+
out.set(s.path, { name, raw, reason: settingRefusal(s.path, name, raw) })
|
|
174
|
+
}
|
|
175
|
+
return out
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function collectInfoChecked(cwd: string, opts: CollectInfoOptions): Promise<InfoFacts> {
|
|
130
179
|
const warn = opts.warn ?? warnToStderr
|
|
131
180
|
// Both first: outside a workspace, or under a workspace config that does
|
|
132
181
|
// not load, the doctor refuses at once, with no probe (~180 ms) ahead.
|
|
@@ -162,65 +211,90 @@ async function collectWorkspaceInfo(
|
|
|
162
211
|
// The lock's projects: none without a lock, or with one a run would
|
|
163
212
|
// refuse, which is `vx lock`'s to report.
|
|
164
213
|
const lock = lockReader(root)
|
|
214
|
+
// A lock a run refuses is said, not swallowed: "projects lock yes" with
|
|
215
|
+
// no task hid why every run failed (2026-10-28).
|
|
216
|
+
let refused: string | null = null
|
|
165
217
|
const held = await lock().then(
|
|
166
218
|
() => true,
|
|
167
219
|
(err: unknown) => {
|
|
168
220
|
if (!isUserError(err)) throw err
|
|
221
|
+
refused = err.message
|
|
169
222
|
return false
|
|
170
223
|
},
|
|
171
224
|
)
|
|
172
225
|
const metas = held ? await discoverProjects(root, lock, plugins, cacheDir, warn) : []
|
|
173
226
|
const storeRoot =
|
|
174
227
|
opts.cacheDir === undefined ? await resolveStoreRoot(root, workspaceConfig) : null
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
let
|
|
228
|
+
// The index is read first and alone: one SQLite cannot read is a fact
|
|
229
|
+
// of the report, with its fix, not a refusal of it — the doctor is where
|
|
230
|
+
// a broken setup is diagnosed.
|
|
231
|
+
let stats: ReturnType<Cache['stats']> = {
|
|
232
|
+
entryCount: 0,
|
|
233
|
+
totalBytes: 0,
|
|
234
|
+
runCountLast24h: 0,
|
|
235
|
+
hitCountLast24h: 0,
|
|
236
|
+
restoredCountLast24h: 0,
|
|
237
|
+
}
|
|
238
|
+
let orphans = { orphans: 0, orphanBytes: 0 }
|
|
239
|
+
let flaky: FlakyTask[] = []
|
|
240
|
+
let indexError: string | null = null
|
|
241
|
+
let indexStore: string | undefined
|
|
242
|
+
try {
|
|
243
|
+
const cache = new Cache(cacheDir, undefined, undefined, undefined, 'inspect', storeRoot)
|
|
244
|
+
try {
|
|
245
|
+
indexStore = cache.storeDir
|
|
246
|
+
stats = cache.stats()
|
|
247
|
+
orphans = await cache.orphanStats()
|
|
248
|
+
flaky = flakyTasks(cache.dbHandle())
|
|
249
|
+
} finally {
|
|
250
|
+
cache.close()
|
|
251
|
+
}
|
|
252
|
+
} catch (err) {
|
|
253
|
+
// An index of another schema is refused as by every reading verb: this
|
|
254
|
+
// vx reads nothing in it, and the next run resets it.
|
|
255
|
+
if (!isUserError(err) || err.code === 'VX_E_CACHE_VERSION') throw err
|
|
256
|
+
indexError = err.message
|
|
257
|
+
}
|
|
179
258
|
let taskCount = 0
|
|
180
259
|
let sandboxed = 0
|
|
260
|
+
// The run path's load — the lock, a plugin's `project` stage counted —
|
|
261
|
+
// so the doctor's task count is the number a run would see. No lock, or
|
|
262
|
+
// one a run would refuse, counts zero: broken configs are `vx lock`'s
|
|
263
|
+
// to report.
|
|
181
264
|
try {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
closure: false,
|
|
197
|
-
configs: lock,
|
|
198
|
-
warn,
|
|
199
|
-
})
|
|
200
|
-
for (const p of loaded.projects.values()) {
|
|
201
|
-
const tasks = p.config.tasks ?? {}
|
|
202
|
-
taskCount += Object.keys(tasks).length
|
|
203
|
-
for (const t of Object.values(tasks)) if (t?.exec?.sandbox !== undefined) sandboxed++
|
|
204
|
-
}
|
|
205
|
-
} catch (err) {
|
|
206
|
-
if (!isUserError(err)) throw err
|
|
207
|
-
taskCount = 0
|
|
208
|
-
sandboxed = 0
|
|
265
|
+
const loaded = await loadProjects({
|
|
266
|
+
workspaceRoot: root,
|
|
267
|
+
cacheDir,
|
|
268
|
+
plugins,
|
|
269
|
+
projectMetas: metas,
|
|
270
|
+
seeds: 'all',
|
|
271
|
+
closure: false,
|
|
272
|
+
configs: lock,
|
|
273
|
+
warn,
|
|
274
|
+
})
|
|
275
|
+
for (const p of loaded.projects.values()) {
|
|
276
|
+
const tasks = p.config.tasks ?? {}
|
|
277
|
+
taskCount += Object.keys(tasks).length
|
|
278
|
+
for (const t of Object.values(tasks)) if (t?.exec?.sandbox !== undefined) sandboxed++
|
|
209
279
|
}
|
|
210
|
-
}
|
|
211
|
-
|
|
280
|
+
} catch (err) {
|
|
281
|
+
if (!isUserError(err)) throw err
|
|
282
|
+
taskCount = 0
|
|
283
|
+
sandboxed = 0
|
|
212
284
|
}
|
|
213
285
|
|
|
214
286
|
const lockPresent = await Bun.file(lockfilePath(root)).exists()
|
|
287
|
+
// No lock is its own row, `lockfile`.
|
|
288
|
+
const lockError = lockPresent ? refused : null
|
|
215
289
|
// Asked while the probe runs: each is a synchronous spawn.
|
|
216
290
|
const git = gitVersion()
|
|
217
291
|
const statusCache = gitStatusCache(root)
|
|
218
292
|
const sandbox = { ...(await probing), declared: sandboxed }
|
|
219
|
-
const cacheStore =
|
|
293
|
+
const cacheStore = indexStore ?? storeRoot
|
|
220
294
|
return {
|
|
221
295
|
vx: VERSION,
|
|
222
296
|
vxPath: vxPath(),
|
|
223
|
-
handedOffFrom: process.env['VX_HANDED_OFF']
|
|
297
|
+
handedOffFrom: process.env['VX_HANDED_OFF'] || null,
|
|
224
298
|
// An unsupported Bun does not stop a run, it makes the run's ANSWERS
|
|
225
299
|
// wrong (util/bun-version.ts measures which). The row a reader already
|
|
226
300
|
// consults for "is my setup sane" is where that belongs: a warning on
|
|
@@ -257,6 +331,7 @@ async function collectWorkspaceInfo(
|
|
|
257
331
|
schemaVersion: SCHEMA_VERSION,
|
|
258
332
|
cacheEntries: stats.entryCount,
|
|
259
333
|
cacheBytes: stats.totalBytes,
|
|
334
|
+
cacheIndexError: indexError,
|
|
260
335
|
settings: settingsFact(workspaceConfig),
|
|
261
336
|
// A row-less artifact is indexed again only when its task asks for its
|
|
262
337
|
// key; the rest only `vx cache clean` reclaims (after an upgrade's
|
|
@@ -270,6 +345,7 @@ async function collectWorkspaceInfo(
|
|
|
270
345
|
// this is the workspace's standing list.
|
|
271
346
|
flakyTasks: flaky,
|
|
272
347
|
lockfile: lockPresent,
|
|
348
|
+
lockError,
|
|
273
349
|
sandbox,
|
|
274
350
|
}
|
|
275
351
|
}
|
|
@@ -339,7 +415,7 @@ function memoryFact(): InfoFacts['memory'] {
|
|
|
339
415
|
* the warm run (STATUS, waves 5 and the 2026-09-03 refutations) — the
|
|
340
416
|
* status walk's cost is git's own, and vx already overlaps it.
|
|
341
417
|
*/
|
|
342
|
-
function gitStatusCache(root: string): InfoFacts['gitStatusCache'] {
|
|
418
|
+
export function gitStatusCache(root: string): InfoFacts['gitStatusCache'] {
|
|
343
419
|
try {
|
|
344
420
|
const p = Bun.spawnSync({
|
|
345
421
|
cmd: [executablePath('git'), 'config', '--get-regexp', '^core\\.(fsmonitor|untrackedcache)$'],
|
|
@@ -351,9 +427,25 @@ function gitStatusCache(root: string): InfoFacts['gitStatusCache'] {
|
|
|
351
427
|
// exit 1 is git's "no key matched": both off, still an answer.
|
|
352
428
|
if (p.exitCode !== 0 && p.exitCode !== 1) return null
|
|
353
429
|
const out = p.exitCode === 0 ? new TextDecoder().decode(p.stdout) : ''
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
430
|
+
// The last value set wins, as git reads it (a global `true` under a
|
|
431
|
+
// repo's `false` is off), and a key with no `=` is true.
|
|
432
|
+
const last = new Map<string, string | null>()
|
|
433
|
+
for (const line of out.split('\n')) {
|
|
434
|
+
if (line === '') continue
|
|
435
|
+
const sp = line.indexOf(' ')
|
|
436
|
+
last.set(
|
|
437
|
+
(sp === -1 ? line : line.slice(0, sp)).toLowerCase(),
|
|
438
|
+
sp === -1 ? null : line.slice(sp + 1),
|
|
439
|
+
)
|
|
440
|
+
}
|
|
441
|
+
const on = (key: string, hook: boolean): boolean => {
|
|
442
|
+
const v = last.get(`core.${key}`)
|
|
443
|
+
if (v === undefined) return false
|
|
444
|
+
if (v === null || /^(true|yes|on|1)$/i.test(v)) return true
|
|
445
|
+
// core.fsmonitor may name a hook command instead of a boolean.
|
|
446
|
+
return hook && v !== '' && !/^(false|no|off|0)$/i.test(v)
|
|
447
|
+
}
|
|
448
|
+
return { fsmonitor: on('fsmonitor', true), untrackedCache: on('untrackedcache', false) }
|
|
357
449
|
} catch {
|
|
358
450
|
return null
|
|
359
451
|
}
|
|
@@ -69,6 +69,12 @@ export function executeArgsOf(
|
|
|
69
69
|
if (facts.downloadModeOf.get(id) === 'deferred') a.download = 'deferred'
|
|
70
70
|
if (placements.remoteOnlyNoop.has(id)) a.remoteOnlyNoop = true
|
|
71
71
|
if (placements.remoteOnly.has(id)) a.remoteOnly = true
|
|
72
|
+
if (placements.carried.has(id)) a.carried = true
|
|
73
|
+
const servers = placements.servers.get(id)
|
|
74
|
+
if (servers !== undefined) {
|
|
75
|
+
a.servers = servers
|
|
76
|
+
a.serversNested = servers.map((s) => facts.nestedDirsByProject.get(s.projectName) ?? [])
|
|
77
|
+
}
|
|
72
78
|
if (probe !== undefined) a.preProbed = probe
|
|
73
79
|
if (upfrontKey !== undefined) a.upfrontKey = upfrontKey
|
|
74
80
|
if (upfrontGroupKey !== undefined) a.upfrontGroupKey = upfrontGroupKey
|