@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.
Files changed (141) hide show
  1. package/README.md +47 -19
  2. package/docs/caching.md +222 -210
  3. package/docs/cli.md +699 -664
  4. package/docs/execution.md +67 -75
  5. package/docs/features.md +44 -40
  6. package/docs/patterns.md +31 -32
  7. package/docs/schema.md +418 -202
  8. package/docs/security.md +76 -39
  9. package/launcher.sh +43 -0
  10. package/package.json +5 -5
  11. package/schemas/cache.json +41 -19
  12. package/schemas/info.json +23 -11
  13. package/schemas/last.json +48 -2
  14. package/schemas/lock.json +1 -1
  15. package/schemas/plan.json +2 -2
  16. package/schemas/show.json +13 -4
  17. package/schemas/why.json +15 -1
  18. package/skills/vx/SKILL.md +16 -12
  19. package/src/bin.ts +17 -2
  20. package/src/cache/archive.ts +11 -0
  21. package/src/cache/cache.ts +105 -53
  22. package/src/cache/git-inputs.ts +277 -63
  23. package/src/cache/index.ts +7 -1
  24. package/src/cache/inputs.ts +125 -35
  25. package/src/cache/key-fold.ts +8 -7
  26. package/src/cache/layer.ts +8 -17
  27. package/src/cache/layered-cache.ts +16 -102
  28. package/src/cache/policy.ts +25 -29
  29. package/src/cache/run-history.ts +36 -14
  30. package/src/cache/schema.ts +21 -23
  31. package/src/cache/scoped-cache.ts +224 -0
  32. package/src/cli/cache.ts +150 -28
  33. package/src/cli/completions.ts +2 -2
  34. package/src/cli/core-alias.ts +1 -1
  35. package/src/cli/foreign-flags.ts +13 -12
  36. package/src/cli/help.ts +94 -61
  37. package/src/cli/index.ts +42 -13
  38. package/src/cli/info.ts +38 -23
  39. package/src/cli/init.ts +115 -406
  40. package/src/cli/last.ts +145 -4
  41. package/src/cli/lock.ts +333 -111
  42. package/src/cli/plan-format.ts +2 -2
  43. package/src/cli/plugin-commands.ts +5 -9
  44. package/src/cli/plugin-templates.ts +10 -10
  45. package/src/cli/run.ts +123 -144
  46. package/src/cli/select.ts +33 -39
  47. package/src/cli/show.ts +17 -19
  48. package/src/cli/task-verb.ts +2 -9
  49. package/src/cli/upgrade.ts +402 -145
  50. package/src/cli/watch-cycle.ts +9 -2
  51. package/src/cli/watch-filter.ts +33 -60
  52. package/src/cli/watch-fs.ts +29 -16
  53. package/src/cli/watch-judge.ts +12 -3
  54. package/src/cli/watch-set.ts +16 -42
  55. package/src/cli/watch.ts +188 -215
  56. package/src/cli/why.ts +28 -17
  57. package/src/cli/workspace-config.ts +31 -68
  58. package/src/config.ts +191 -71
  59. package/src/exec/env.ts +1 -31
  60. package/src/exec/executor.ts +1 -5
  61. package/src/exec/kill-tree.ts +2 -1
  62. package/src/exec/sandbox-runtime.ts +12 -1
  63. package/src/exec/sandbox-violations.ts +9 -1
  64. package/src/graph/dependency-spec.ts +1 -1
  65. package/src/graph/index.ts +1 -0
  66. package/src/graph/priorities.ts +1 -1
  67. package/src/graph/scheduler.ts +19 -7
  68. package/src/graph/task-graph.ts +44 -20
  69. package/src/handoff.ts +169 -0
  70. package/src/index.ts +25 -57
  71. package/src/orchestrator/affected-tasks.ts +7 -5
  72. package/src/orchestrator/command-windows.ts +44 -0
  73. package/src/orchestrator/deferred-outputs.ts +12 -10
  74. package/src/orchestrator/doctor.ts +98 -110
  75. package/src/orchestrator/download-policy.ts +3 -3
  76. package/src/orchestrator/events.ts +19 -3
  77. package/src/orchestrator/excluded-keys.ts +0 -2
  78. package/src/orchestrator/execute-task.ts +192 -70
  79. package/src/orchestrator/fingerprint-watch.ts +18 -15
  80. package/src/orchestrator/forecast.ts +10 -2
  81. package/src/orchestrator/framed-output.ts +8 -3
  82. package/src/orchestrator/graph-stage.ts +5 -5
  83. package/src/orchestrator/history.ts +70 -30
  84. package/src/orchestrator/hit-restore.ts +15 -3
  85. package/src/orchestrator/index.ts +18 -4
  86. package/src/orchestrator/local-shortcircuit.ts +2 -1
  87. package/src/orchestrator/lockfile-claim.ts +79 -20
  88. package/src/orchestrator/logger.ts +71 -39
  89. package/src/orchestrator/metrics.ts +71 -6
  90. package/src/orchestrator/miss-save.ts +3 -0
  91. package/src/orchestrator/options.ts +43 -28
  92. package/src/orchestrator/output-host.ts +72 -0
  93. package/src/orchestrator/plan.ts +6 -8
  94. package/src/orchestrator/plugin-host.ts +87 -63
  95. package/src/orchestrator/plugin.ts +94 -60
  96. package/src/orchestrator/prepare.ts +114 -73
  97. package/src/orchestrator/projects.ts +102 -99
  98. package/src/orchestrator/remote-prefetch.ts +2 -1
  99. package/src/orchestrator/run-context.ts +25 -6
  100. package/src/orchestrator/run-failures.ts +17 -8
  101. package/src/orchestrator/run-lock.ts +1 -1
  102. package/src/orchestrator/run-report.ts +9 -9
  103. package/src/orchestrator/run-settings.ts +48 -0
  104. package/src/orchestrator/run.ts +127 -88
  105. package/src/orchestrator/sandbox-fix.ts +39 -20
  106. package/src/orchestrator/sandbox-request.ts +84 -13
  107. package/src/orchestrator/signals.ts +1 -1
  108. package/src/orchestrator/stable-keys.ts +13 -11
  109. package/src/orchestrator/status-line.ts +48 -6
  110. package/src/orchestrator/summary.ts +46 -62
  111. package/src/orchestrator/task-hash.ts +12 -83
  112. package/src/orchestrator/telemetry.ts +3 -3
  113. package/src/settings.ts +417 -0
  114. package/src/util/errors.ts +1 -1
  115. package/src/util/essential-env.ts +31 -0
  116. package/src/util/hide-env.ts +107 -0
  117. package/src/util/index.ts +8 -2
  118. package/src/util/paths.ts +10 -0
  119. package/src/util/settle.ts +49 -30
  120. package/src/util/size.ts +23 -4
  121. package/src/util/timing.ts +3 -2
  122. package/src/util/ulid.ts +1 -1
  123. package/src/util/verbs.ts +0 -15
  124. package/src/workspace/affected.ts +77 -222
  125. package/src/workspace/config-eval.ts +15 -20
  126. package/src/workspace/config-imports.ts +78 -3
  127. package/src/workspace/config-schema.ts +251 -241
  128. package/src/workspace/dependency-rules.ts +57 -0
  129. package/src/workspace/filter.ts +2 -2
  130. package/src/workspace/fingerprint.ts +11 -121
  131. package/src/workspace/index.ts +22 -27
  132. package/src/workspace/load-reads.ts +4 -4
  133. package/src/workspace/lockfile.ts +96 -140
  134. package/src/workspace/migration.ts +242 -146
  135. package/src/workspace/package-graph.ts +30 -216
  136. package/src/workspace/project-loader.ts +80 -285
  137. package/src/workspace/repo-id.ts +2 -1
  138. package/src/workspace/workspace.ts +362 -831
  139. package/src/cache/config-evals.ts +0 -130
  140. package/src/workspace/config-cache.ts +0 -661
  141. package/src/workspace/migrate-scripts.ts +0 -1121
@@ -0,0 +1,107 @@
1
+ import { ESSENTIAL_ENV } from './essential-env.js'
2
+
3
+ const PR_SET_DUMPABLE = 4
4
+
5
+ /**
6
+ * Hide vx's environment from a same-user task. A task gets only declared
7
+ * variables, but vx itself holds the rest. Not a boundary (`exec.sandbox`
8
+ * is): it hides the environment, not files. On every verb (owner,
9
+ * 2026-10-13).
10
+ *
11
+ * Linux: make vx non-dumpable, so its `/proc/<pid>/environ` (and ptrace)
12
+ * close to the task. A child is dumpable again after `exec`, so tasks are
13
+ * unaffected. Loading `bun:ffi` costs ~0.8 ms. `VX_DEBUG_DUMPABLE` keeps vx
14
+ * observable: strace cannot read a non-dumpable tracee's memory, nor a
15
+ * debugger `/proc/<pid>/fd`.
16
+ *
17
+ * macOS: `ps eww` reads the env strings the kernel copied above the
18
+ * stack, and no flag closes that to the same user, so vx zeroes the
19
+ * values there (owner, 2026-10-13: "Do the override then on macOS").
20
+ * Bun copied the env at startup, so `process.env`, and every task built
21
+ * from it, keeps them.
22
+ */
23
+ export async function hideEnvFromTasks(): Promise<boolean> {
24
+ if (process.platform === 'darwin') return wipeStartupEnv()
25
+ if (process.platform !== 'linux' || process.env['VX_DEBUG_DUMPABLE']) return false
26
+ try {
27
+ const { dlopen, FFIType } = await import('bun:ffi')
28
+ const libc = dlopen('libc.so.6', {
29
+ prctl: {
30
+ args: [FFIType.i32, FFIType.u64, FFIType.u64, FFIType.u64, FFIType.u64],
31
+ returns: FFIType.i32,
32
+ },
33
+ })
34
+ const ok = libc.symbols.prctl(PR_SET_DUMPABLE, 0n, 0n, 0n, 0n) === 0
35
+ libc.close()
36
+ return ok
37
+ } catch {
38
+ // No glibc (musl names it otherwise): the env stays as readable as
39
+ // any process's, as it was.
40
+ return false
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Zero the value of every startup variable a task does not see by
46
+ * default (`ESSENTIAL_ENV` stays: every task gets it anyway). The
47
+ * original `envp` array follows `argv`'s NULL on the stack and is never
48
+ * moved, unlike `environ`, which `setenv` may reallocate. libc's
49
+ * `getenv` reads that block, so it answers `''` for a wiped name; vx
50
+ * reads `process.env`.
51
+ */
52
+ async function wipeStartupEnv(): Promise<boolean> {
53
+ try {
54
+ const { dlopen, FFIType, read, toArrayBuffer, CString } = await import('bun:ffi')
55
+ const sys = dlopen('/usr/lib/libSystem.B.dylib', {
56
+ _NSGetArgv: { args: [], returns: FFIType.ptr },
57
+ _NSGetArgc: { args: [], returns: FFIType.ptr },
58
+ })
59
+ const argv = read.ptr(sys.symbols._NSGetArgv()!, 0)
60
+ const argc = read.i32(sys.symbols._NSGetArgc()!, 0)
61
+ sys.close()
62
+ const keep = new Set(ESSENTIAL_ENV)
63
+ for (let i = argc + 1; ; i++) {
64
+ const p = read.ptr(argv, i * 8)
65
+ if (!p) break
66
+ const entry = new CString(p as never).toString()
67
+ const eq = entry.indexOf('=')
68
+ if (eq < 0 || keep.has(entry.slice(0, eq))) continue
69
+ new Uint8Array(toArrayBuffer(p as never, 0, Buffer.byteLength(entry))).fill(0, eq + 1)
70
+ }
71
+ return true
72
+ } catch {
73
+ return false
74
+ }
75
+ }
76
+
77
+ /**
78
+ * The env for a helper vx keeps running beside its tasks (the group
79
+ * guard, a port bridge): PATH alone. Without an `env`, a spawn hands the
80
+ * child vx's startup env, and that child, dumpable after its `exec`,
81
+ * would show a task what `hideEnvFromTasks` hid.
82
+ */
83
+ export function helperEnv(): Record<string, string> {
84
+ return { PATH: process.env['PATH'] ?? '' }
85
+ }
86
+
87
+ /**
88
+ * The env for a `git` vx runs: what git reads (`GIT_*`, the locale,
89
+ * `XDG_CONFIG_HOME`, the essentials: `HOME`, `PATH`) and nothing else.
90
+ * A git child is readable after its `exec` like any helper, and `vx
91
+ * watch` runs git while its tasks run.
92
+ */
93
+ export function gitEnv(): Record<string, string> {
94
+ const env: Record<string, string> = {}
95
+ for (const [name, value] of Object.entries(process.env)) {
96
+ if (value === undefined) continue
97
+ if (
98
+ name.startsWith('GIT_') ||
99
+ name.startsWith('LC_') ||
100
+ name === 'XDG_CONFIG_HOME' ||
101
+ name === 'LANGUAGE' ||
102
+ ESSENTIAL_ENV.includes(name)
103
+ )
104
+ env[name] = value
105
+ }
106
+ return env
107
+ }
package/src/util/index.ts CHANGED
@@ -45,6 +45,8 @@ export {
45
45
  outputMatcher,
46
46
  printable,
47
47
  relPosix,
48
+ DOT_VX_GITATTRIBUTES,
49
+ DOT_VX_GITIGNORE,
48
50
  splitNegations,
49
51
  staticPrefix,
50
52
  stripTrailingSlash,
@@ -58,10 +60,12 @@ export {
58
60
  claimExitForSignal,
59
61
  exitClaimedBySignal,
60
62
  killGraceMs,
63
+ setSettleBounds,
64
+ type SettleBound,
61
65
  settleWithin,
62
66
  teardownTimeoutMs,
63
67
  } from './settle.js'
64
- export { formatBytes, parseDuration, parseSize } from './size.js'
68
+ export { formatBytes, parseDuration, parseSize, treeBytes } from './size.js'
65
69
  export {
66
70
  cgroupCpuQuota,
67
71
  cgroupMemoryLimitBytes,
@@ -73,11 +77,13 @@ export { appendTail, createTail, resetTail, tailText, type Tail } from './tail.j
73
77
  export { ulid } from './ulid.js'
74
78
  export { splitTaskId } from './task-id.js'
75
79
  export { editDistance, listed, nearMatches, nearest } from './edit-distance.js'
76
- export { CORE_VERBS, MOVED_VERBS } from './verbs.js'
80
+ export { CORE_VERBS } from './verbs.js'
77
81
  export { isUnsupportedBun, MIN_BUN, unsupportedBunMessage } from './bun-version.js'
78
82
  export { executablePath, shellArgv, taskShell } from './which.js'
79
83
  export { procfsIsOwn } from './procfs.js'
80
84
  export { hangupIgnored } from './hangup.js'
85
+ export { ESSENTIAL_ENV } from './essential-env.js'
86
+ export { gitEnv, helperEnv, hideEnvFromTasks } from './hide-env.js'
81
87
  export { realPath, realpathOf } from './real-path.js'
82
88
  export {
83
89
  maskedCommand,
package/src/util/paths.ts CHANGED
@@ -11,6 +11,16 @@ export function toPosix(p: string): string {
11
11
  return IS_POSIX ? p : p.split(path.sep).join('/')
12
12
  }
13
13
 
14
+ /**
15
+ * `.vx/.gitignore`: git ignores the machine-local `.vx/cache` and nothing
16
+ * else in `.vx`, so the workspace config and the lock beside it are
17
+ * committed. `vx init` and the cache write it when missing.
18
+ */
19
+ export const DOT_VX_GITIGNORE = '/cache\n'
20
+
21
+ /** `.vx/.gitattributes`' text: GitHub collapses the machine lock in a diff. */
22
+ export const DOT_VX_GITATTRIBUTES = 'projects.lock.json linguist-generated=true\n'
23
+
14
24
  export function relPosix(from: string, to: string): string {
15
25
  return toPosix(path.relative(from, to))
16
26
  }
@@ -2,49 +2,68 @@
2
2
  // wrote; it must not hold the run's exit hostage.
3
3
 
4
4
  import { MAX_TIMEOUT_MS } from './num.js'
5
+ import { parseDuration } from './size.js'
5
6
 
6
7
  /** Default upper bound on one end-of-run flush/teardown await. */
7
8
  const DEFAULT_TIMEOUT_MS = 3000
8
9
 
10
+ /** A bound the run resolved from its flag or `.vx/workspace`. */
11
+ export interface SettleBound {
12
+ readonly ms: number
13
+ readonly from: 'flag' | 'workspace'
14
+ }
15
+
16
+ let teardownSet: SettleBound | undefined
17
+ let killGraceSet: SettleBound | undefined
18
+
9
19
  /**
10
- * The bound to apply, read per call so a test can drive the deadline
11
- * instead of waiting it out.
20
+ * The run's `run.teardownTimeout` and `run.killGrace` from its flag or
21
+ * workspace (the orchestrator resolves them; util sits below settings).
22
+ * The variable, read per call, sits between the two, so a test drives the
23
+ * deadline instead of waiting it out.
12
24
  */
13
- export function teardownTimeoutMs(): number {
14
- const raw = process.env['VX_TEARDOWN_TIMEOUT_MS']
15
- // Out-of-range falls back to the DEFAULT rather than clamping to
16
- // MAX_TIMEOUT_MS, and the distinction matters. This value is a BOUND, not a
17
- // duration: there is no "no limit" option here, because the whole reason the
18
- // deadline exists is that a plugin's flush must not hold the run's exit
19
- // hostage. Clamping would honour "wait ~24.8 days", which defeats it — the
20
- // run would hang. Unbounded is worse still (the delay becomes 1 ms, so every
21
- // flush times out and every buffered record is dropped). Falling back keeps
22
- // the bound real in both directions.
23
- if (raw !== undefined && /^[0-9]+$/.test(raw)) {
24
- const n = Number(raw)
25
- if (n <= MAX_TIMEOUT_MS) return n
25
+ export function setSettleBounds(b: { teardown?: SettleBound; killGrace?: SettleBound }): void {
26
+ teardownSet = b.teardown
27
+ killGraceSet = b.killGrace
28
+ }
29
+
30
+ /**
31
+ * A flag's bound, else the variable's (a positive duration inside the
32
+ * timer's range: the CLI refuses any other before a run, and an embedder's
33
+ * falls back), else the workspace's.
34
+ */
35
+ function bound(name: string, set: SettleBound | undefined, zero = false): number | undefined {
36
+ if (set?.from === 'flag') return set.ms
37
+ const raw = process.env[name]
38
+ if (raw !== undefined && raw !== '') {
39
+ const n = parseDuration(raw)
40
+ if (n !== null && (n > 0 || zero) && n <= MAX_TIMEOUT_MS) return n
26
41
  }
27
- return DEFAULT_TIMEOUT_MS
42
+ return set?.ms
28
43
  }
29
44
 
30
45
  /**
31
- * The SIGTERM→SIGKILL grace a run grants a child that ignores SIGTERM: the
32
- * one-shot timeout escalation (`exec/runner.ts`), the signal teardown
33
- * (`orchestrator/signals.ts`) and the end-of-run persistent shutdown
34
- * (`orchestrator/persistent.ts`) share it. Two seconds
46
+ * The bound on one end-of-run flush or teardown (`run.teardownTimeout`).
47
+ * There is no "no limit": the deadline exists so a plugin's flush cannot
48
+ * hold the run's exit hostage, so a timer past the platform's range (which
49
+ * would fire at once and drop every buffered record) is no value.
50
+ */
51
+ export function teardownTimeoutMs(): number {
52
+ return bound('VX_RUN_TEARDOWN_TIMEOUT', teardownSet, true) ?? DEFAULT_TIMEOUT_MS
53
+ }
54
+
55
+ /**
56
+ * The SIGTERM→SIGKILL grace a run grants a child that ignores SIGTERM
57
+ * (`run.killGrace`): the one-shot timeout escalation (`exec/runner.ts`),
58
+ * the signal teardown (`orchestrator/signals.ts`) and the end-of-run
59
+ * persistent shutdown (`orchestrator/persistent.ts`) share it. Two seconds
35
60
  * is generous for a real server's cleanup and is what every run waits when
36
- * a child wedges. `VX_KILL_GRACE_MS` overrides it, read per call and bounded
37
- * like the teardown deadline (out of range falls back to the default): the
38
- * tests that prove the escalation used to wait the full two seconds each,
39
- * a third of the suite's wall time for a claim a 200 ms grace proves too.
61
+ * a child wedges; the tests that prove the escalation used to wait the
62
+ * full two seconds each, a third of the suite's wall time for a claim a
63
+ * 200 ms grace proves too.
40
64
  */
41
65
  export function killGraceMs(defaultMs: number): number {
42
- const raw = process.env['VX_KILL_GRACE_MS']
43
- if (raw !== undefined && /^[0-9]+$/.test(raw)) {
44
- const n = Number(raw)
45
- if (n > 0 && n <= MAX_TIMEOUT_MS) return n
46
- }
47
- return defaultMs
66
+ return bound('VX_RUN_KILL_GRACE', killGraceSet) ?? defaultMs
48
67
  }
49
68
 
50
69
  /**
package/src/util/size.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { lstatSync, readdirSync } from 'node:fs'
2
+ import path from 'node:path'
1
3
  import { parseDecimalInt } from './num.js'
2
4
 
3
5
  /**
@@ -20,25 +22,34 @@ export function parseSize(input: string): number | null {
20
22
  }
21
23
 
22
24
  /**
23
- * Parse `<n><unit>` where unit is s/m/h/d, case-insensitively (`parseSize`
25
+ * Parse `<n><unit>` where unit is ms/s/m/h/d, case-insensitively (`parseSize`
24
26
  * has always been case-insensitive; this matched only lowercase, so `30D`
25
27
  * was rejected while `1GB` and `1gb` both worked).
26
28
  */
27
29
  export function parseDuration(input: string): number | null {
28
- const m = input.match(/^(\d+)([smhd])$/i)
30
+ const m = input.match(/^(\d+)(ms|[smhd])$/i)
29
31
  if (!m) return null
30
32
  const n = parseDecimalInt(m[1]!)
31
33
  if (n === null) return null
32
34
  // Lowercase before the switch: with the /i flag an uppercase `M` would
33
35
  // otherwise fall through to the days branch.
34
36
  const unit = m[2]!.toLowerCase()
35
- const mult = unit === 's' ? 1000 : unit === 'm' ? 60_000 : unit === 'h' ? 3_600_000 : 86_400_000
37
+ const mult =
38
+ unit === 'ms'
39
+ ? 1
40
+ : unit === 's'
41
+ ? 1000
42
+ : unit === 'm'
43
+ ? 60_000
44
+ : unit === 'h'
45
+ ? 3_600_000
46
+ : 86_400_000
36
47
  return n * mult
37
48
  }
38
49
 
39
50
  /**
40
51
  * Human-readable byte size with KB/MB/GB/TB/PB suffixes and one
41
- * decimal of precision below 10 of any unit. Used by `vx info`, `vx cache prune` and the
52
+ * decimal of precision below 10 of any unit. Used by `vx info`, `vx cache clean` and the
42
53
  * run's `cacheRetention` line.
43
54
  */
44
55
  export function formatBytes(n: number): string {
@@ -51,3 +62,11 @@ export function formatBytes(n: number): string {
51
62
  }
52
63
  return `${v.toFixed(0)} PB`
53
64
  }
65
+
66
+ /** Bytes under `p` on disk, links not followed; 0 when it is missing. */
67
+ export function treeBytes(p: string): number {
68
+ const st = lstatSync(p, { throwIfNoEntry: false })
69
+ if (st === undefined) return 0
70
+ if (!st.isDirectory()) return st.size
71
+ return readdirSync(p).reduce((n, e) => n + treeBytes(path.join(p, e)), 0)
72
+ }
@@ -1,4 +1,5 @@
1
- // Stage timing for the run path, printed to stderr when `VX_TIMING` is set.
1
+ // Stage timing for the run path, printed to stderr when `VX_DEBUG_TIMING` is
2
+ // true (`debug.timing`; util reads it itself, below src/settings.ts).
2
3
  //
3
4
  // The CPU profiler attributes a tight loop's cost unreliably and hides
4
5
  // where an `await` waited; a stage table answers "where did the warm run
@@ -8,7 +9,7 @@
8
9
  // prints (a push per stage, ~15 a run): a telemetry sink draws them as
9
10
  // spans (`stageTimes`). The per-call `span`s stay off unless enabled.
10
11
 
11
- const enabled = process.env.VX_TIMING !== undefined && process.env.VX_TIMING !== ''
12
+ const enabled = process.env.VX_DEBUG_TIMING === 'true' || process.env.VX_DEBUG_TIMING === '1'
12
13
  let t0 = Bun.nanoseconds()
13
14
  // The wall clock at t0, read then: `performance.timeOrigin` plus the
14
15
  // monotonic clock drifted 34 ms from `Date.now()` on macOS CI, so stages
package/src/util/ulid.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Run-id generator. Thin wrapper over `Bun.randomUUIDv7()` so the
2
2
  // `runId` column on `runs` carries a timestamp-ordered identifier —
3
- // `vx stats --since` queries can range-scan without an index on the
3
+ // time-range queries can range-scan without an index on the
4
4
  // time column, and the IDs lexicographically sort by creation time
5
5
  // for grouping.
6
6
  //
package/src/util/verbs.ts CHANGED
@@ -19,18 +19,3 @@ export const CORE_VERBS = [
19
19
  'help',
20
20
  'version',
21
21
  ] as const
22
-
23
- /**
24
- * Verbs core owned once and a package owns now. Not core verbs: a plugin
25
- * may declare them, and the dispatcher prints the
26
- * pointer only when no declared plugin claimed the name.
27
- */
28
- export const MOVED_VERBS: Readonly<Record<string, string>> = {
29
- migrate:
30
- 'vx migrate moved to @vzn/vx-migrate: run `bunx @vzn/vx-migrate` (turbo.json or an Nx ' +
31
- 'project graph → vx.config.ts); `vx init` reads package.json scripts',
32
- prune:
33
- 'vx prune comes from @vzn/vx-lockfile: declare pnpm(), bun(), npm() or yarn() in ' +
34
- 'vx.workspace.ts',
35
- stats: 'vx stats was removed (H-19): run `vx info`, which prints the same report',
36
- }