@vzn/vx 0.0.516 → 0.0.518

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 CHANGED
@@ -145,7 +145,7 @@ Declared in `vx.workspace.ts`; without any, vx runs and caches locally.
145
145
  | [`@vzn/vx-reapi`](packages/vx-reapi) | Remote cache and remote execution over Bazel's REAPI (NativeLink, BuildBuddy) |
146
146
  | [`@vzn/vx-lockfile`](packages/vx-lockfile) | Key each project on its own lockfile slice: pnpm, bun, npm, yarn |
147
147
  | [`@vzn/vx-otel`](packages/vx-otel) | OpenTelemetry traces, metrics and logs, no SDK |
148
- | [`@vzn/vx-github`](packages/vx-github) | GitHub Actions job summary and Checks API |
148
+ | [`@vzn/vx-ci`](packages/vx-ci) | GitHub Actions job summary and Checks API |
149
149
  | [`@vzn/vx-mcp`](packages/vx-mcp) | `vx mcp`: a read-only MCP server for AI coding agents |
150
150
  | [`@vzn/vx-schedule-history`](packages/vx-schedule-history) | Schedule by the critical path learned from past runs |
151
151
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx",
3
- "version": "0.0.516",
3
+ "version": "0.0.518",
4
4
  "description": "The fastest task runner and build cache for JavaScript monorepos.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -21,10 +21,10 @@
21
21
  "node": ">=18"
22
22
  },
23
23
  "optionalDependencies": {
24
- "@vzn/vx-linux-x64": "0.0.516",
25
- "@vzn/vx-linux-arm64": "0.0.516",
26
- "@vzn/vx-darwin-x64": "0.0.516",
27
- "@vzn/vx-darwin-arm64": "0.0.516"
24
+ "@vzn/vx-linux-x64": "0.0.518",
25
+ "@vzn/vx-linux-arm64": "0.0.518",
26
+ "@vzn/vx-darwin-x64": "0.0.518",
27
+ "@vzn/vx-darwin-arm64": "0.0.518"
28
28
  },
29
29
  "dependencies": {
30
30
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -25,7 +25,6 @@ import {
25
25
  type TaskOutcome,
26
26
  } from '../graph/index.js'
27
27
  import {
28
- formatBytes,
29
28
  mark,
30
29
  killGraceMs,
31
30
  MAX_TIMEOUT_MS,
@@ -52,7 +51,7 @@ import { buildAdmission, executorLabel, resolveExecutors, teardownPlugins } from
52
51
  import { subscribeTelemetry, type TelemetryHandle } from './telemetry-host.js'
53
52
  import { assembleRunSummary, isPassStatus } from './telemetry.js'
54
53
  import type { RunContextRecord } from './telemetry.js'
55
- import { defaultLogger, resolveOutputView, type Logger } from './logger.js'
54
+ import { defaultLogger, resolveOutputView } from './logger.js'
56
55
  import { detectColors, type ColorSupport } from './colors.js'
57
56
  import { plainOutput } from './plain-output.js'
58
57
  import { formatPersistentList } from './framed-output.js'
@@ -1150,10 +1149,6 @@ async function runOnBus(
1150
1149
  log.status(`vx: failed to write profile: ${msg}`)
1151
1150
  }
1152
1151
  }
1153
- // The footer is the run's last word: every line above, nothing below
1154
- // (owner, 2026-10-06). A task's own facts (flaky, blocked) ride its row.
1155
- for (const line of formatRunSummary(list, totalMs, colors, runContext)) log.status(line)
1156
-
1157
1152
  // Record each task to the run history in a single SQLite transaction
1158
1153
  // (one fsync instead of N), with the invocation header row alongside,
1159
1154
  // atomically via recordRunBundle. The Tier-3 input-fingerprint rows
@@ -1264,7 +1259,7 @@ async function runOnBus(
1264
1259
  mark('output dir snapshots')
1265
1260
  // Not on a stopped run: one stopped while it waited on another run's
1266
1261
  // lock never held it, and its prune evicted under that run (item 858).
1267
- if (!stopRun.signal.aborted) await applyCacheRetention(prepared, log)
1262
+ if (!stopRun.signal.aborted) await applyCacheRetention(prepared)
1268
1263
  // A plugin hears the run until its teardown and nothing after: released
1269
1264
  // only in the finally, its handlers heard a kept server through the
1270
1265
  // whole keep-alive wait below (C-66). Idempotent; the finally's stay.
@@ -1288,6 +1283,13 @@ async function runOnBus(
1288
1283
  }
1289
1284
  }
1290
1285
 
1286
+ // The footer is the run's last word (owner, 2026-10-06): it prints once
1287
+ // the run's own work is done, history, uploads, plugin teardown and the
1288
+ // sandbox reset included, so any warning they raise lands above it. A
1289
+ // task's own facts (flaky, blocked) ride its row. Only a kept server's
1290
+ // own output follows.
1291
+ for (const line of formatRunSummary(list, totalMs, colors, runContext)) log.status(line)
1292
+
1291
1293
  // Edge case the summary already reported: the user requested a
1292
1294
  // persistent task (dev server / watcher). The run is "done" in every
1293
1295
  // bookkeeping sense — summary printed, history recorded — but the
@@ -1392,10 +1394,10 @@ async function runOnBus(
1392
1394
  /**
1393
1395
  * The workspace's `cacheRetention`, after every save and upload of this run
1394
1396
  * has landed (so nothing this run wrote is mid-flight) and before the cache
1395
- * closes. Housekeeping, not the run's work: a failure is one warning, never
1397
+ * closes. Housekeeping, not the run's work: silent, and a failure is never
1396
1398
  * a failed run. Declared nowhere → one property read.
1397
1399
  */
1398
- async function applyCacheRetention(prepared: PreparedRun, log: Logger): Promise<void> {
1400
+ async function applyCacheRetention(prepared: PreparedRun): Promise<void> {
1399
1401
  const retention = prepared.workspaceConfig?.cacheRetention
1400
1402
  if (retention === undefined) return
1401
1403
  // Validated at load (`validateRetention`), so both parse.
@@ -1403,26 +1405,12 @@ async function applyCacheRetention(prepared: PreparedRun, log: Logger): Promise<
1403
1405
  retention.olderThan === undefined ? undefined : parseDuration(retention.olderThan)!
1404
1406
  const maxBytes = retention.maxSize === undefined ? undefined : parseSize(retention.maxSize)!
1405
1407
  try {
1406
- const result = await prepared.localCache.evictIfDue({
1408
+ await prepared.localCache.evictIfDue({
1407
1409
  ...(maxAgeMs !== undefined ? { maxAgeMs } : {}),
1408
1410
  ...(maxBytes !== undefined ? { maxBytes } : {}),
1409
1411
  })
1410
- if (result !== null && (result.evicted > 0 || result.orphans > 0)) {
1411
- const said: string[] = []
1412
- if (result.evicted > 0) {
1413
- said.push(
1414
- `evicted ${result.evicted} entr${result.evicted === 1 ? 'y' : 'ies'} (${formatBytes(result.bytesFreed)})`,
1415
- )
1416
- }
1417
- if (result.orphans > 0) {
1418
- said.push(
1419
- `reaped ${result.orphans} orphaned artifact${result.orphans === 1 ? '' : 's'} (${formatBytes(result.orphanBytes)})`,
1420
- )
1421
- }
1422
- log.status(`vx: cache retention ${said.join(', ')}`)
1423
- }
1424
- } catch (err) {
1425
- log.status(`vx: cache retention skipped: ${err instanceof Error ? err.message : String(err)}`)
1412
+ } catch {
1413
+ // Housekeeping says nothing (owner): the next due run tries again.
1426
1414
  }
1427
1415
  }
1428
1416