@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx",
3
- "version": "0.0.603",
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.603",
25
- "@vzn/vx-linux-arm64": "0.0.603",
26
- "@vzn/vx-darwin-x64": "0.0.603",
27
- "@vzn/vx-darwin-arm64": "0.0.603"
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 2` is that shard's).
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 forwarded = at === -1 ? '' : inv.command.slice(at)
362
- const ids = failed.map((t) => `${t.project}#${t.task}`).join(' ')
363
- lines.push('', ` re-run what failed: vx run ${ids}${forwarded}`)
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
- 'cacheHit' | 'restored' | 'cached' | 'wallclockStartNs' | 'wallclockEndNs' | 'timedOut'
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
- ...(input.forwardArgs !== undefined ? { forwardArgs: input.forwardArgs } : {}),
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 —