@vzn/vx 0.0.564 → 0.0.565

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.564",
3
+ "version": "0.0.565",
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.564",
25
- "@vzn/vx-linux-arm64": "0.0.564",
26
- "@vzn/vx-darwin-x64": "0.0.564",
27
- "@vzn/vx-darwin-arm64": "0.0.564"
24
+ "@vzn/vx-linux-x64": "0.0.565",
25
+ "@vzn/vx-linux-arm64": "0.0.565",
26
+ "@vzn/vx-darwin-x64": "0.0.565",
27
+ "@vzn/vx-darwin-arm64": "0.0.565"
28
28
  },
29
29
  "dependencies": {
30
30
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -25,6 +25,7 @@
25
25
  // price is no live progress within a task. This matches Turbo's
26
26
  // `--ui=stream` mode.
27
27
 
28
+ import { withForwardArgs } from '../exec/index.js'
28
29
  import { isGroupTask, type TaskNode, type TaskOutcome } from '../graph/index.js'
29
30
  import { maskedCommand } from '../util/index.js'
30
31
  import { paint, type ColorSupport } from './colors.js'
@@ -82,6 +83,7 @@ export function formatTaskBlock(
82
83
  // tasks set this so a requested task's frame is identical whether it
83
84
  // ran or was cached — you asked for it, you see what it would run.
84
85
  forceCommand = false,
86
+ forwardArgs: readonly string[] = [],
85
87
  ): string {
86
88
  // Group tasks (no `exec`) do no work and have no body — they're
87
89
  // organizational nodes the user wrote so a `vx run ci` invocation
@@ -105,11 +107,7 @@ export function formatTaskBlock(
105
107
  if (forceCommand || outcome.status === 'success' || outcome.status === 'failed') {
106
108
  // No section label for the command (owner cut it) — the dim `$ `
107
109
  // line under the header reads as the command on its own.
108
- lines.push(
109
- '',
110
- corner(`$ ${maskedCommand(node.config.exec?.command ?? '', node.config.exec?.env)}`),
111
- '',
112
- )
110
+ lines.push('', corner(`$ ${shownCommand(node, forwardArgs)}`), '')
113
111
  }
114
112
 
115
113
  pushStreamSection(lines, stdout, 'STDOUT', SUCCESS, body.droppedStdout ?? 0, colors)
@@ -444,9 +442,13 @@ export function formatTaskAbortedLine(
444
442
  * formatTaskBlock, but emitted in real time around the live stream
445
443
  * instead of buffered.
446
444
  */
447
- export function formatFrameOpen(node: TaskNode, colors: ColorSupport = NO_COLOR): string {
445
+ export function formatFrameOpen(
446
+ node: TaskNode,
447
+ colors: ColorSupport = NO_COLOR,
448
+ forwardArgs: readonly string[] = [],
449
+ ): string {
448
450
  const corner = (t: string) => paint('', t, colors, { dim: true })
449
- const cmd = maskedCommand(node.config.exec?.command ?? '', node.config.exec?.env)
451
+ const cmd = shownCommand(node, forwardArgs)
450
452
  const mark = isPersistentNode(node) ? `${paint(ACCENT, '▸', colors)} ` : ''
451
453
  return `${corner('┌─')} ${mark}${paintTaskId(node, colors, { bold: true })} ${corner('>')} $ ${cmd}`
452
454
  }
@@ -492,6 +494,15 @@ export function formatFrameClose(
492
494
  return violations.length === 0 ? close : `${violations.join('\n')}\n${close}`
493
495
  }
494
496
 
497
+ /** What ran: a requested task gets the args after `--`, as execute-task.ts appends them. */
498
+ function shownCommand(node: TaskNode, forwardArgs: readonly string[]): string {
499
+ const exec = node.config.exec
500
+ return maskedCommand(
501
+ withForwardArgs(exec?.command ?? '', node.requested ? forwardArgs : []),
502
+ exec?.env,
503
+ )
504
+ }
505
+
495
506
  function isPersistentNode(node: TaskNode): boolean {
496
507
  return node.config.exec?.persistent !== undefined
497
508
  }
@@ -512,11 +523,12 @@ export function formatPersistentTailBlock(
512
523
  body: TaskBlockBody,
513
524
  dropped: { stdout?: number; stderr?: number } = {},
514
525
  colors: ColorSupport = NO_COLOR,
526
+ forwardArgs: readonly string[] = [],
515
527
  ): string {
516
528
  const stdout = body.stdout ?? ''
517
529
  const stderr = body.stderr ?? ''
518
530
  if (stdout.trim().length === 0 && stderr.trim().length === 0) return ''
519
- const lines: string[] = [formatFrameOpen(node, colors)]
531
+ const lines: string[] = [formatFrameOpen(node, colors, forwardArgs)]
520
532
  pushStreamSection(lines, stdout, 'STDOUT (since ready)', SUCCESS, dropped.stdout ?? 0, colors)
521
533
  pushStreamSection(lines, stderr, 'STDERR (since ready)', ERROR, dropped.stderr ?? 0, colors)
522
534
  lines.push(formatFrameClose(node, outcome, colors))
@@ -166,8 +166,15 @@ export function defaultLogger(
166
166
  colors: ColorSupport = detectColors(),
167
167
  view: OutputView = { mode: 'full' },
168
168
  out: StatusStream = process.stdout,
169
- opts: { forceFloorMs?: number; coalesce?: boolean; tty?: boolean } = {},
169
+ opts: {
170
+ forceFloorMs?: number
171
+ coalesce?: boolean
172
+ tty?: boolean
173
+ /** The args after `--`: a requested task's `$ <command>` line shows them, as it ran. */
174
+ forwardArgs?: readonly string[]
175
+ } = {},
170
176
  ): DefaultLogger {
177
+ const forwardArgs = opts.forwardArgs ?? []
171
178
  // Per-task buffers, split by stream. Splitting lets the framed-output
172
179
  // renderer put stdout under `├─ stdout` and stderr under `├─ stderr`.
173
180
  // The price: chunks that interleaved at runtime get re-ordered (all
@@ -478,7 +485,7 @@ export function defaultLogger(
478
485
  killStatus()
479
486
  // Open the live frame: full task info even when the command
480
487
  // streams nothing (or the hit replays nothing).
481
- emitLine(formatFrameOpen(node, colors))
488
+ emitLine(formatFrameOpen(node, colors, forwardArgs))
482
489
  return
483
490
  }
484
491
  // Bound a persistent task's output from its FIRST chunk. Waiting for
@@ -520,6 +527,7 @@ export function defaultLogger(
520
527
  { stdout: tailText(t.out), stderr: tailText(t.err) },
521
528
  { stdout: t.out.dropped, stderr: t.err.dropped },
522
529
  colors,
530
+ forwardArgs,
523
531
  ),
524
532
  ),
525
533
  )
@@ -619,7 +627,16 @@ export function defaultLogger(
619
627
  return
620
628
  }
621
629
  if (framed && (stdout.length > 0 || stderr.length > 0)) {
622
- emitBlock(formatTaskBlock(node, outcome, { stdout, stderr, ...dropped }, colors, true))
630
+ emitBlock(
631
+ formatTaskBlock(
632
+ node,
633
+ outcome,
634
+ { stdout, stderr, ...dropped },
635
+ colors,
636
+ true,
637
+ forwardArgs,
638
+ ),
639
+ )
623
640
  return
624
641
  }
625
642
  // Otherwise a row in the task list, in every view that lists a
@@ -709,7 +726,14 @@ export function defaultLogger(
709
726
  if (outcome.status !== 'failed') return
710
727
  emitLine(failureRow(node, outcome))
711
728
  deferredFailures.push(
712
- formatTaskBlock(node, outcome, { stdout, stderr, ...dropped }, colors),
729
+ formatTaskBlock(
730
+ node,
731
+ outcome,
732
+ { stdout, stderr, ...dropped },
733
+ colors,
734
+ false,
735
+ forwardArgs,
736
+ ),
713
737
  )
714
738
  return
715
739
  case 'broad':
@@ -721,7 +745,14 @@ export function defaultLogger(
721
745
  // ◼ row now; the full frame replays at runEnd.
722
746
  emitLine(failureRow(node, outcome))
723
747
  deferredFailures.push(
724
- formatTaskBlock(node, outcome, { stdout, stderr, ...dropped }, colors),
748
+ formatTaskBlock(
749
+ node,
750
+ outcome,
751
+ { stdout, stderr, ...dropped },
752
+ colors,
753
+ false,
754
+ forwardArgs,
755
+ ),
725
756
  )
726
757
  } else if (outcome.status === 'success') {
727
758
  emitLine(formatTaskExecutedLine(node, outcome, colors))
@@ -758,13 +789,29 @@ export function defaultLogger(
758
789
  if (outcome.status === 'failed') {
759
790
  emitLine(failureRow(node, outcome))
760
791
  deferredFailures.push(
761
- formatTaskBlock(node, outcome, { stdout, stderr, ...dropped }, colors),
792
+ formatTaskBlock(
793
+ node,
794
+ outcome,
795
+ { stdout, stderr, ...dropped },
796
+ colors,
797
+ false,
798
+ forwardArgs,
799
+ ),
762
800
  )
763
801
  return
764
802
  }
765
803
  // forceCommand: a requested task's frame shows `$ cmd`
766
804
  // whether it ran or was cached — same frame every run.
767
- emitBlock(formatTaskBlock(node, outcome, { stdout, stderr, ...dropped }, colors, true))
805
+ emitBlock(
806
+ formatTaskBlock(
807
+ node,
808
+ outcome,
809
+ { stdout, stderr, ...dropped },
810
+ colors,
811
+ true,
812
+ forwardArgs,
813
+ ),
814
+ )
768
815
  return
769
816
  }
770
817
  // Dependency-pulled nodes: silent on success; a skip gets its
@@ -774,7 +821,14 @@ export function defaultLogger(
774
821
  } else if (outcome.status === 'failed') {
775
822
  emitLine(failureRow(node, outcome))
776
823
  deferredFailures.push(
777
- formatTaskBlock(node, outcome, { stdout, stderr, ...dropped }, colors),
824
+ formatTaskBlock(
825
+ node,
826
+ outcome,
827
+ { stdout, stderr, ...dropped },
828
+ colors,
829
+ false,
830
+ forwardArgs,
831
+ ),
778
832
  )
779
833
  }
780
834
  return
@@ -793,7 +847,14 @@ export function defaultLogger(
793
847
  emitLine(formatTaskSkippedLine(node, colors, outcome.blockedBy))
794
848
  return
795
849
  }
796
- const block = formatTaskBlock(node, outcome, { stdout, stderr, ...dropped }, colors)
850
+ const block = formatTaskBlock(
851
+ node,
852
+ outcome,
853
+ { stdout, stderr, ...dropped },
854
+ colors,
855
+ false,
856
+ forwardArgs,
857
+ )
797
858
  if (block.length === 0) return
798
859
  if (view.gha) {
799
860
  // The block is the task's own output — fenced, so a task that
@@ -297,6 +297,7 @@ export async function run(options: RunOptions): Promise<RunSummary> {
297
297
  ? defaultLogger(colors, resolveOutputView(options), process.stdout, {
298
298
  coalesce: true,
299
299
  ...(options.tty === true ? { tty: true } : {}),
300
+ ...(options.forwardArgs !== undefined ? { forwardArgs: options.forwardArgs } : {}),
300
301
  })
301
302
  : null
302
303
  const sink = options.log ?? terminal!