@vzn/vx 0.0.485 → 0.0.487

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/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- // Root entry shim. Bun 1.4.0's `--compile` binaries resolve an on-disk
1
+ // Root entry shim. Bun 1.4.0's `--compile` binaries built without
2
+ // `--compile-autoload-package-json` (vx 0.0.484 and older) resolve an on-disk
2
3
  // package by directory convention (`<pkg>/index.ts`, `<pkg>/<subpath>/index.ts`)
3
4
  // and ignore package.json `exports` / `main` (measured 2026-09-03: an
4
5
  // entry of `./src/index.ts` resolved to the root `index.ts` regardless of the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx",
3
- "version": "0.0.485",
3
+ "version": "0.0.487",
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.485",
25
- "@vzn/vx-linux-arm64": "0.0.485",
26
- "@vzn/vx-darwin-x64": "0.0.485",
27
- "@vzn/vx-darwin-arm64": "0.0.485"
24
+ "@vzn/vx-linux-x64": "0.0.487",
25
+ "@vzn/vx-linux-arm64": "0.0.487",
26
+ "@vzn/vx-darwin-x64": "0.0.487",
27
+ "@vzn/vx-darwin-arm64": "0.0.487"
28
28
  },
29
29
  "dependencies": {
30
30
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
package/src/cli/help.ts CHANGED
@@ -1,7 +1,72 @@
1
- import { nearest } from '../util/index.js'
1
+ import type { ColorSupport, paint as Paint } from '../orchestrator/index.js'
2
+ import { CORE_VERBS, nearest } from '../util/index.js'
2
3
 
3
- export function printHelp(pluginCommands: readonly string[] = [], verb?: string): void {
4
- process.stdout.write(verb === undefined ? helpText(pluginCommands) : verbHelpText(verb))
4
+ export async function printHelp(
5
+ pluginCommands: readonly string[] = [],
6
+ verb?: string,
7
+ ): Promise<void> {
8
+ const text = verb === undefined ? helpText(pluginCommands) : verbHelpText(verb)
9
+ // The orchestrator is already loaded by the plugin-verb lookup every
10
+ // caller awaits first, so this import costs `vx --version` nothing.
11
+ const { detectColors, paint } = await import('../orchestrator/index.js')
12
+ process.stdout.write(paintHelp(text, helpColors(process.stdout, detectColors), paint))
13
+ }
14
+
15
+ /**
16
+ * Help paints on a terminal only. `FORCE_COLOR=1` set for a run's log in
17
+ * CI does not paint it: a script that greps `vx help` (or reads the flag
18
+ * list from it) gets plain text whatever forces colour elsewhere.
19
+ */
20
+ export function helpColors(
21
+ stream: { isTTY?: boolean },
22
+ detect: (s: NodeJS.WriteStream) => ColorSupport,
23
+ ): ColorSupport {
24
+ return { enabled: stream.isTTY === true && detect(stream as NodeJS.WriteStream).enabled }
25
+ }
26
+
27
+ const VERB = '#06b6d4' // cyan-500 — the orchestrator's accent
28
+ const TERM = '#22d3ee' // cyan-400 — a flag, a selector, an example
29
+
30
+ /**
31
+ * The reference with ANSI accents, line by line and never reflowed, so the
32
+ * painted text strips back to `text` exactly: section headings bold (their
33
+ * `(for <verb>)` dim), `vx <verb>` bold cyan, and the term an option or
34
+ * example line opens with cyan. Prose and continuation lines stay plain.
35
+ */
36
+ export function paintHelp(text: string, colors: ColorSupport, paint: typeof Paint): string {
37
+ if (!colors.enabled) return text
38
+ const lines = text.split('\n')
39
+ return lines
40
+ .map((line, i) => {
41
+ if (line === '') return line
42
+ if (i === 0) {
43
+ const [name, ...rest] = line.split(' ')
44
+ return [paint(VERB, name!, colors, { bold: true }), ...rest].join(' ')
45
+ }
46
+ const heading = /^([A-Z][^:]*?)( \(for [^)]*\))?:$/.exec(line)
47
+ if (heading !== null) {
48
+ const qualifier =
49
+ heading[2] === undefined ? '' : paint('', heading[2], colors, { dim: true })
50
+ return `${paint('', heading[1]!, colors, { bold: true })}${qualifier}${paint('', ':', colors, { bold: true })}`
51
+ }
52
+ // ` term description`: a term is a flag, a `vx` form, a selector.
53
+ const row = /^(\s+)(\S(?:.*?\S)?)(\s{2,}\S.*)?$/.exec(line)
54
+ if (row === null) return line
55
+ const [, indent, term, description = ''] = row
56
+ if (/^vx \S/.test(term!)) {
57
+ const verb = term!.split(' ')[1]!
58
+ // Prose that opens with `vx` (`vx core runs tasks…`) is not a form.
59
+ if (description === '' && !(CORE_VERBS as readonly string[]).includes(verb)) return line
60
+ const head = `vx ${verb}`
61
+ const tail = term!.slice(head.length)
62
+ return `${indent}${paint(VERB, head, colors, { bold: true })}${tail === '' ? '' : paint(TERM, tail, colors)}${description}`
63
+ }
64
+ if (description === '') return line
65
+ if (/^(-|\(|[\w-]+#)/.test(term!))
66
+ return `${indent}${paint(TERM, term!, colors)}${description}`
67
+ return line
68
+ })
69
+ .join('\n')
5
70
  }
6
71
 
7
72
  /**
@@ -96,11 +161,11 @@ export function helpText(pluginCommands: readonly string[] = []): string {
96
161
  ' --graph[=<path>] Emit Graphviz DOT (stdout if no path).',
97
162
  '',
98
163
  'Artifacts (for run):',
99
- ' --summarize[=<path>] Write per-run JSON to <cacheDir>/runs/<run_id>.json.',
100
- ' --profile[=<path>] Write Chrome-trace JSON (default profile.json).',
101
- ' --report[=markdown] Print a markdown run report to stdout after the run.',
102
- ' --report-file <path> Append that report to <path> (for $GITHUB_STEP_SUMMARY).',
103
- ' --tag <k=v> Label this invocation (repeatable); recorded on its history row.',
164
+ ' --summarize[=<path>] Write per-run JSON to <cacheDir>/runs/<run_id>.json.',
165
+ ' --profile[=<path>] Write Chrome-trace JSON (default profile.json).',
166
+ ' --report[=markdown] Print a markdown run report to stdout after the run.',
167
+ ' --report-file <path> Append that report to <path> (for $GITHUB_STEP_SUMMARY).',
168
+ ' --tag <k=v> Label this invocation (repeatable); recorded on its history row.',
104
169
  '',
105
170
  'Extensions (plugins):',
106
171
  ' vx core runs tasks in-process and nothing else. A dashboard, remote',
package/src/cli/index.ts CHANGED
@@ -23,7 +23,7 @@ export async function run(argv: readonly string[]): Promise<number> {
23
23
  // which is the one place `--help` is not being asked of vx. Core verbs
24
24
  // only — a plugin verb owns its own arguments, `--help` included.
25
25
  if (command !== undefined && wantsHelp(command, rest)) {
26
- printHelp(await (await plugins()).pluginCommandHelp(), command)
26
+ await printHelp(await (await plugins()).pluginCommandHelp(), command)
27
27
  return 0
28
28
  }
29
29
 
@@ -39,12 +39,12 @@ export async function run(argv: readonly string[]): Promise<number> {
39
39
  process.stderr.write(`vx: ${err.message}; \`vx help\` lists the verbs\n`)
40
40
  return 1
41
41
  }
42
- printHelp(await (await plugins()).pluginCommandHelp())
42
+ await printHelp(await (await plugins()).pluginCommandHelp())
43
43
  return 0
44
44
  }
45
45
  case '--help':
46
46
  case '-h':
47
- printHelp(await (await plugins()).pluginCommandHelp())
47
+ await printHelp(await (await plugins()).pluginCommandHelp())
48
48
  return 0
49
49
  case 'help': {
50
50
  // `vx help run` is the same question as `vx run --help`. A plugin verb
@@ -76,7 +76,7 @@ export async function run(argv: readonly string[]): Promise<number> {
76
76
  return 1
77
77
  }
78
78
  }
79
- printHelp(await (await plugins()).pluginCommandHelp(), core ? verb : undefined)
79
+ await printHelp(await (await plugins()).pluginCommandHelp(), core ? verb : undefined)
80
80
  return 0
81
81
  }
82
82
  case '--version':
@@ -25,6 +25,7 @@ export { forwardedSignal } from './signals.js'
25
25
  // `vx cache prune` waits for a run on the workspace before it evicts.
26
26
  export { acquireRunLock } from './run-lock.js'
27
27
  export { defaultLogger, resolveOutputView } from './logger.js'
28
+ export { detectColors, paint, type ColorSupport } from './colors.js'
28
29
  export type { Logger, OutputView } from './logger.js'
29
30
  export type { RunPlan, PlannedTask, PlanPrediction, CacheStatus } from './plan.js'
30
31
  export { formatDuration } from './summary.js'