@vzn/vx 0.0.603 → 0.0.605
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/package.json +5 -5
- package/src/cli/last.ts +12 -4
- package/src/cli/watch.ts +7 -2
- package/src/orchestrator/metrics.ts +13 -2
- package/src/orchestrator/run-records.ts +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vzn/vx",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.605",
|
|
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.
|
|
25
|
-
"@vzn/vx-linux-arm64": "0.0.
|
|
26
|
-
"@vzn/vx-darwin-x64": "0.0.
|
|
27
|
-
"@vzn/vx-darwin-arm64": "0.0.
|
|
24
|
+
"@vzn/vx-linux-x64": "0.0.605",
|
|
25
|
+
"@vzn/vx-linux-arm64": "0.0.605",
|
|
26
|
+
"@vzn/vx-darwin-x64": "0.0.605",
|
|
27
|
+
"@vzn/vx-darwin-arm64": "0.0.605"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@anthropic-ai/sandbox-runtime": "^0.0.76"
|
package/src/cli/last.ts
CHANGED
|
@@ -354,13 +354,21 @@ export async function lastCmd(args: readonly string[]): Promise<number> {
|
|
|
354
354
|
)
|
|
355
355
|
lines.push(...formatTaskRows(detail?.tasks ?? []))
|
|
356
356
|
// The next command after reading a failed run, with the arguments the
|
|
357
|
-
// run forwarded (a failure under `-- --shard
|
|
357
|
+
// run forwarded to the tasks that got them (a failure under `-- --shard
|
|
358
|
+
// 2` is that shard's); a dependency never got them, so its line has none.
|
|
358
359
|
const failed = (detail?.tasks ?? []).filter((t) => t.status === 'failed')
|
|
359
360
|
if (failed.length > 0) {
|
|
360
361
|
const at = inv.command.indexOf(' -- ')
|
|
361
|
-
const
|
|
362
|
-
const
|
|
363
|
-
|
|
362
|
+
const args = at === -1 ? '' : inv.command.slice(at)
|
|
363
|
+
const rerun: string[] = []
|
|
364
|
+
for (const withArgs of [false, true]) {
|
|
365
|
+
const ids = failed
|
|
366
|
+
.filter((t) => t.forwarded === withArgs)
|
|
367
|
+
.map((t) => `${t.project}#${t.task}`)
|
|
368
|
+
if (ids.length > 0)
|
|
369
|
+
rerun.push(` re-run what failed: vx run ${ids.join(' ')}${withArgs ? args : ''}`)
|
|
370
|
+
}
|
|
371
|
+
lines.push('', ...rerun)
|
|
364
372
|
}
|
|
365
373
|
process.stdout.write(`${lines.join('\n')}\n`)
|
|
366
374
|
return 0
|
package/src/cli/watch.ts
CHANGED
|
@@ -432,6 +432,11 @@ async function runWatchLoop(args: WatchLoopArgs): Promise<void> {
|
|
|
432
432
|
try {
|
|
433
433
|
let label: string | undefined = first
|
|
434
434
|
while (label !== undefined && !stop.aborted) {
|
|
435
|
+
// A member came or went: armed before the run keys it, an edit in a
|
|
436
|
+
// new package while its first cycle runs queues like any other; armed
|
|
437
|
+
// only after, it fell in the gap and ran nothing (X-138). The re-read
|
|
438
|
+
// after the run stays, for what the run itself changed.
|
|
439
|
+
if (reread) await rearm(false)
|
|
435
440
|
process.stdout.write(`\nvx watch: ${label}; re-running...\n\n`)
|
|
436
441
|
try {
|
|
437
442
|
await held?.stop()
|
|
@@ -729,7 +734,7 @@ async function runWatchLoop(args: WatchLoopArgs): Promise<void> {
|
|
|
729
734
|
? 'vx watch: watching the workspace root (workspaceFiles inputs in use)'
|
|
730
735
|
: `vx watch: watching ${count} project(s)`
|
|
731
736
|
|
|
732
|
-
const rearm = async (): Promise<void> => {
|
|
737
|
+
const rearm = async (say = true): Promise<void> => {
|
|
733
738
|
let next: Rediscovered
|
|
734
739
|
try {
|
|
735
740
|
next = await args.rediscover()
|
|
@@ -778,7 +783,7 @@ async function runWatchLoop(args: WatchLoopArgs): Promise<void> {
|
|
|
778
783
|
// A new arm proves delivery like the first ones: an edit in the new
|
|
779
784
|
// package right after this cycle is seen, not lost in the gap.
|
|
780
785
|
await pool.proved()
|
|
781
|
-
process.stdout.write(`${watchingLine(next.projects.length)}\n`)
|
|
786
|
+
if (say) process.stdout.write(`${watchingLine(next.projects.length)}\n`)
|
|
782
787
|
}
|
|
783
788
|
|
|
784
789
|
armMode(projects)
|
|
@@ -48,6 +48,8 @@ export interface RunSummaryRow {
|
|
|
48
48
|
timedOut: boolean | null
|
|
49
49
|
sandboxViolations: number | null
|
|
50
50
|
notReady: 'timeout' | 'exited' | 'spawn' | null
|
|
51
|
+
/** The task ran with the run's forwarded args (`-- …`): a requested one under a run that had some. */
|
|
52
|
+
forwarded: boolean
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
export interface ListRunsArgs {
|
|
@@ -78,8 +80,15 @@ export function listRuns(db: Database, args: ListRunsArgs = {}): RunSummaryRow[]
|
|
|
78
80
|
const clause = where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''
|
|
79
81
|
type RawRow = Omit<
|
|
80
82
|
RunSummaryRow,
|
|
81
|
-
|
|
83
|
+
| 'cacheHit'
|
|
84
|
+
| 'restored'
|
|
85
|
+
| 'cached'
|
|
86
|
+
| 'wallclockStartNs'
|
|
87
|
+
| 'wallclockEndNs'
|
|
88
|
+
| 'timedOut'
|
|
89
|
+
| 'forwarded'
|
|
82
90
|
> & {
|
|
91
|
+
forwarded: number
|
|
83
92
|
cacheHit: number | null
|
|
84
93
|
restored: number | null
|
|
85
94
|
cached: number | null
|
|
@@ -100,7 +109,8 @@ export function listRuns(db: Database, args: ListRunsArgs = {}): RunSummaryRow[]
|
|
|
100
109
|
cpu_ms AS cpuMs, peak_rss_bytes AS peakRssBytes,
|
|
101
110
|
wallclock_start_ns AS wallclockStartNs, wallclock_end_ns AS wallclockEndNs,
|
|
102
111
|
blocked_by AS blockedBy, timed_out AS timedOut,
|
|
103
|
-
sandbox_violations AS sandboxViolations, not_ready AS notReady
|
|
112
|
+
sandbox_violations AS sandboxViolations, not_ready AS notReady,
|
|
113
|
+
forward_args IS NOT NULL AS forwarded
|
|
104
114
|
FROM runs ${clause} ORDER BY id DESC LIMIT ?`,
|
|
105
115
|
)
|
|
106
116
|
.all(...params, limit) as RawRow[]
|
|
@@ -110,6 +120,7 @@ export function listRuns(db: Database, args: ListRunsArgs = {}): RunSummaryRow[]
|
|
|
110
120
|
restored: r.restored === null ? null : Boolean(r.restored),
|
|
111
121
|
cached: r.cached === null ? null : Boolean(r.cached),
|
|
112
122
|
timedOut: r.timedOut === null ? null : Boolean(r.timedOut),
|
|
123
|
+
forwarded: Boolean(r.forwarded),
|
|
113
124
|
wallclockStartNs: r.wallclockStartNs === null ? null : r.wallclockStartNs.toString(),
|
|
114
125
|
wallclockEndNs: r.wallclockEndNs === null ? null : r.wallclockEndNs.toString(),
|
|
115
126
|
}))
|
|
@@ -78,7 +78,11 @@ export function assembleRunRecords(input: RunRecordsInput): RunRecords {
|
|
|
78
78
|
status: o.status,
|
|
79
79
|
exitCode: o.exitCode,
|
|
80
80
|
durationMs: o.durationMs,
|
|
81
|
-
|
|
81
|
+
// A run forwards its args to the tasks it was asked for, never to a
|
|
82
|
+
// dependency: the row says which ran with them.
|
|
83
|
+
...(input.forwardArgs !== undefined && input.forwardArgs.length > 0 && o.node.requested
|
|
84
|
+
? { forwardArgs: input.forwardArgs }
|
|
85
|
+
: {}),
|
|
82
86
|
// Anchor to the REAL per-task wall-clock window: run-start wall time +
|
|
83
87
|
// the task's ns offset (captured for hits and executed tasks alike).
|
|
84
88
|
// The `end - duration` fallback applies to outcomes without an offset —
|