@vzn/vx 0.0.0 → 0.0.12

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.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +332 -1
  3. package/launcher.mjs +84 -0
  4. package/package.json +44 -3
  5. package/src/bin.ts +25 -0
  6. package/src/cache/cache.ts +1832 -0
  7. package/src/cache/cas-backend.ts +97 -0
  8. package/src/cache/digest.ts +47 -0
  9. package/src/cache/index.ts +29 -0
  10. package/src/cache/inputs.ts +833 -0
  11. package/src/cache/layered-cache.ts +335 -0
  12. package/src/cache/remote-cache.ts +251 -0
  13. package/src/cache/tar.ts +343 -0
  14. package/src/cli/backend.ts +23 -0
  15. package/src/cli/cache.ts +101 -0
  16. package/src/cli/format.ts +15 -0
  17. package/src/cli/help.ts +123 -0
  18. package/src/cli/index.ts +85 -0
  19. package/src/cli/info.ts +83 -0
  20. package/src/cli/lock.ts +135 -0
  21. package/src/cli/mcp-rpc.ts +292 -0
  22. package/src/cli/mcp.ts +92 -0
  23. package/src/cli/migrate-nx.ts +450 -0
  24. package/src/cli/migrate-turbo.ts +364 -0
  25. package/src/cli/migrate.ts +219 -0
  26. package/src/cli/plan-format.ts +148 -0
  27. package/src/cli/run.ts +661 -0
  28. package/src/cli/show.ts +201 -0
  29. package/src/cli/upgrade.ts +103 -0
  30. package/src/cli/watch.ts +287 -0
  31. package/src/config.ts +421 -0
  32. package/src/exec/env.ts +74 -0
  33. package/src/exec/index.ts +13 -0
  34. package/src/exec/runner.ts +470 -0
  35. package/src/exec/sandbox-runtime.ts +578 -0
  36. package/src/graph/dependency-spec.ts +69 -0
  37. package/src/graph/index.ts +18 -0
  38. package/src/graph/scheduler.ts +482 -0
  39. package/src/graph/task-graph.ts +325 -0
  40. package/src/index.ts +197 -0
  41. package/src/orchestrator/colors.ts +63 -0
  42. package/src/orchestrator/devframe-surface.ts +74 -0
  43. package/src/orchestrator/events.ts +277 -0
  44. package/src/orchestrator/execute-task.ts +883 -0
  45. package/src/orchestrator/framed-output.ts +461 -0
  46. package/src/orchestrator/history.ts +148 -0
  47. package/src/orchestrator/index.ts +163 -0
  48. package/src/orchestrator/local-shortcircuit.ts +147 -0
  49. package/src/orchestrator/logger.ts +526 -0
  50. package/src/orchestrator/metrics.ts +1576 -0
  51. package/src/orchestrator/options.ts +176 -0
  52. package/src/orchestrator/plan.ts +129 -0
  53. package/src/orchestrator/plugin-host.ts +190 -0
  54. package/src/orchestrator/plugin.ts +283 -0
  55. package/src/orchestrator/predict.ts +106 -0
  56. package/src/orchestrator/prepare.ts +297 -0
  57. package/src/orchestrator/protocol.ts +142 -0
  58. package/src/orchestrator/remote-cache-setup.ts +60 -0
  59. package/src/orchestrator/remote-prefetch.ts +81 -0
  60. package/src/orchestrator/run-artifacts.ts +111 -0
  61. package/src/orchestrator/run-context.ts +205 -0
  62. package/src/orchestrator/run-report.ts +132 -0
  63. package/src/orchestrator/run-state.ts +145 -0
  64. package/src/orchestrator/run.ts +842 -0
  65. package/src/orchestrator/stable-keys.ts +177 -0
  66. package/src/orchestrator/status-line.ts +287 -0
  67. package/src/orchestrator/summary.ts +291 -0
  68. package/src/orchestrator/tally.ts +69 -0
  69. package/src/orchestrator/task-hash.ts +238 -0
  70. package/src/orchestrator/telemetry-host.ts +80 -0
  71. package/src/orchestrator/telemetry.ts +350 -0
  72. package/src/orchestrator/upstream.ts +93 -0
  73. package/src/orchestrator/verify.ts +141 -0
  74. package/src/orchestrator/wire-render.ts +92 -0
  75. package/src/orchestrator/wire.ts +212 -0
  76. package/src/util/errors.ts +11 -0
  77. package/src/util/hash.ts +25 -0
  78. package/src/util/index.ts +7 -0
  79. package/src/util/paths.ts +16 -0
  80. package/src/util/ulid.ts +15 -0
  81. package/src/version.ts +10 -0
  82. package/src/workspace/affected.ts +118 -0
  83. package/src/workspace/filter.ts +155 -0
  84. package/src/workspace/fingerprint.ts +41 -0
  85. package/src/workspace/index.ts +27 -0
  86. package/src/workspace/lockfile.ts +118 -0
  87. package/src/workspace/nested-dirs.ts +34 -0
  88. package/src/workspace/package-graph.ts +148 -0
  89. package/src/workspace/project-loader.ts +470 -0
  90. package/src/workspace/workspace.ts +176 -0
@@ -0,0 +1,148 @@
1
+ // Formatters for `--dry-run` (human / JSON) and `--graph` (DOT).
2
+
3
+ import type { CacheStatus, RunPlan } from '../orchestrator/index.js'
4
+
5
+ /**
6
+ * Human-readable preview. One line per real task (groups hidden, same
7
+ * as the live runner), tagged with predicted cache outcome.
8
+ *
9
+ * would run:
10
+ * ✓ @vzn/vx#lint cache hit (local) abc12345
11
+ * ↓ @vzn/vx#test cache hit (remote) def67890
12
+ * ▶ @vzn/vx#build cache miss — would exec fedcba98
13
+ *
14
+ * 3 task(s) planned: 2 cache hits (1 local, 1 remote), 1 would run.
15
+ */
16
+ export function formatPlanText(plan: RunPlan): string {
17
+ const real = plan.tasks.filter((t) => t.cacheStatus !== 'group')
18
+ if (real.length === 0) return 'No tasks planned.\n'
19
+
20
+ const idWidth = Math.max(...real.map((t) => t.node.id.length))
21
+ const tagWidth = 24
22
+
23
+ const lines: string[] = ['would run:']
24
+ let local = 0
25
+ let remote = 0
26
+ let miss = 0
27
+ let nocache = 0
28
+ for (const t of real) {
29
+ const sym = symbolFor(t.cacheStatus)
30
+ const desc = describe(t.cacheStatus)
31
+ const shortHash = t.hash ? t.hash.slice(0, 8) : ''
32
+ lines.push(` ${sym} ${t.node.id.padEnd(idWidth)} ${desc.padEnd(tagWidth)} ${shortHash}`)
33
+ // Optional one-line description from the task config, indented
34
+ // under the id so the eye picks up the task → blurb mapping.
35
+ const taskDesc = t.node.config.description
36
+ if (taskDesc) {
37
+ lines.push(` ${' '.repeat(idWidth)} ${taskDesc}`)
38
+ }
39
+ if (t.cacheStatus === 'hit-local') local++
40
+ else if (t.cacheStatus === 'hit-remote') remote++
41
+ else if (t.cacheStatus === 'miss') miss++
42
+ else if (t.cacheStatus === 'no-cache') nocache++
43
+ }
44
+
45
+ const hitParts: string[] = []
46
+ if (local > 0) hitParts.push(`${local} local`)
47
+ if (remote > 0) hitParts.push(`${remote} remote`)
48
+ const hits = local + remote
49
+ const summary: string[] = [`${real.length} task(s) planned`]
50
+ if (hits > 0) summary.push(`${hits} cache hit${hits === 1 ? '' : 's'} (${hitParts.join(', ')})`)
51
+ if (miss > 0) summary.push(`${miss} would run`)
52
+ if (nocache > 0) summary.push(`${nocache} no-cache`)
53
+ lines.push('')
54
+ lines.push(summary.join(', ') + '.')
55
+ return lines.join('\n') + '\n'
56
+ }
57
+
58
+ export function formatPlanJson(plan: RunPlan): string {
59
+ return (
60
+ JSON.stringify(
61
+ {
62
+ tasks: plan.tasks.map((t) => ({
63
+ id: t.node.id,
64
+ project: t.node.projectName,
65
+ task: t.node.taskName,
66
+ hash: t.hash,
67
+ cacheStatus: t.cacheStatus,
68
+ deps: t.deps,
69
+ ...(t.node.config.description !== undefined
70
+ ? { description: t.node.config.description }
71
+ : {}),
72
+ })),
73
+ },
74
+ null,
75
+ 2,
76
+ ) + '\n'
77
+ )
78
+ }
79
+
80
+ /**
81
+ * Render the task graph as a Graphviz DOT document. Includes group
82
+ * nodes — they're real nodes in the graph (just not real units of
83
+ * work), and a `--graph` consumer wants to see the whole structure.
84
+ *
85
+ * Layout: `rankdir=LR`. Node fillcolor varies by predicted cache
86
+ * status so a quick visual scan tells you which boxes get to skip
87
+ * actual work.
88
+ */
89
+ export function formatGraphDot(plan: RunPlan): string {
90
+ const lines: string[] = ['digraph TaskGraph {', ' rankdir=LR;', ' node [shape=box];']
91
+ for (const t of plan.tasks) {
92
+ const label = `${t.node.id}\\n${t.hash.slice(0, 8)}`
93
+ const color = dotColor(t.cacheStatus)
94
+ lines.push(` "${t.node.id}" [label="${label}", style="filled", fillcolor="${color}"];`)
95
+ }
96
+ for (const t of plan.tasks) {
97
+ for (const dep of t.deps) {
98
+ lines.push(` "${dep}" -> "${t.node.id}";`)
99
+ }
100
+ }
101
+ lines.push('}')
102
+ return lines.join('\n') + '\n'
103
+ }
104
+
105
+ function symbolFor(s: CacheStatus): string {
106
+ switch (s) {
107
+ case 'hit-local':
108
+ return '◉'
109
+ case 'hit-remote':
110
+ return '↓'
111
+ case 'miss':
112
+ return '▶'
113
+ case 'no-cache':
114
+ return '·'
115
+ case 'group':
116
+ return '○'
117
+ }
118
+ }
119
+
120
+ function describe(s: CacheStatus): string {
121
+ switch (s) {
122
+ case 'hit-local':
123
+ return 'cache hit (local)'
124
+ case 'hit-remote':
125
+ return 'cache hit (remote)'
126
+ case 'miss':
127
+ return 'cache miss — would exec'
128
+ case 'no-cache':
129
+ return 'no-cache (would exec)'
130
+ case 'group':
131
+ return 'group task'
132
+ }
133
+ }
134
+
135
+ function dotColor(s: CacheStatus): string {
136
+ switch (s) {
137
+ case 'hit-local':
138
+ return '#bbf7d0' // green-200
139
+ case 'hit-remote':
140
+ return '#bae6fd' // sky-200
141
+ case 'miss':
142
+ return '#fed7aa' // orange-200
143
+ case 'no-cache':
144
+ return '#e5e7eb' // gray-200
145
+ case 'group':
146
+ return '#f5d0fe' // fuchsia-200
147
+ }
148
+ }