@vzn/vx 0.0.133 → 0.0.135

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.133",
3
+ "version": "0.0.135",
4
4
  "description": "A fast, correct task runner and build cache for JavaScript monorepos.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -17,10 +17,10 @@
17
17
  "node": ">=18"
18
18
  },
19
19
  "optionalDependencies": {
20
- "@vzn/vx-linux-x64": "0.0.133",
21
- "@vzn/vx-linux-arm64": "0.0.133",
22
- "@vzn/vx-darwin-x64": "0.0.133",
23
- "@vzn/vx-darwin-arm64": "0.0.133"
20
+ "@vzn/vx-linux-x64": "0.0.135",
21
+ "@vzn/vx-linux-arm64": "0.0.135",
22
+ "@vzn/vx-darwin-x64": "0.0.135",
23
+ "@vzn/vx-darwin-arm64": "0.0.135"
24
24
  },
25
25
  "dependencies": {
26
26
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -96,11 +96,25 @@ export function formatPlanText(plan: RunPlan): string {
96
96
  return lines.join('\n') + '\n'
97
97
  }
98
98
 
99
+ /** One task of `vx run --dry=json`: the wire, stated by `schemas/plan.json`. */
100
+ export interface PlanTaskJson {
101
+ id: string
102
+ project: string
103
+ task: string
104
+ hash: string
105
+ cacheStatus: CacheStatus
106
+ deps: readonly string[]
107
+ p50Ms?: number
108
+ executor?: string
109
+ download?: 'deferred'
110
+ description?: string
111
+ }
112
+
99
113
  export function formatPlanJson(plan: RunPlan): string {
100
114
  return (
101
115
  JSON.stringify(
102
116
  {
103
- tasks: plan.tasks.map((t) => ({
117
+ tasks: plan.tasks.map((t): PlanTaskJson => ({
104
118
  id: t.node.id,
105
119
  project: t.node.projectName,
106
120
  task: t.node.taskName,
@@ -180,6 +180,22 @@ function npmEnv(
180
180
  return { define, unset, readsManifest }
181
181
  }
182
182
 
183
+ /**
184
+ * A script that never exits by design (D-40): a `watch` segment in its
185
+ * name (`build:watch`, `watch-css`), a `--watch` flag, `tsc -w` /
186
+ * `rollup -w`, or nodemon. Run as a plain task it held its dependents
187
+ * forever. A bare `-w` elsewhere is not read: `npm run x -w pkg` is a
188
+ * workspace.
189
+ */
190
+ function isWatcher(name: string, command: string): boolean {
191
+ if (name.split(/[:\-_.]/).includes('watch')) return true
192
+ return (
193
+ /(?:^|\s)--watch(?:All)?(?:[=\s]|$)/.test(command) ||
194
+ /\b(?:tsc|rollup)\b[^&|;]*\s-w(?:\s|$)/.test(command) ||
195
+ /(?:^|[\s&|;])nodemon\b/.test(command)
196
+ )
197
+ }
198
+
183
199
  function scriptsOf(meta: ProjectMeta): Record<string, unknown> {
184
200
  // package.json is a boundary: `scripts` is whatever the file holds. A
185
201
  // string or an array would enumerate its indices as script names.
@@ -298,7 +314,7 @@ export function migrateScripts(metas: readonly ProjectMeta[]): MigrationPlan {
298
314
  )
299
315
  }
300
316
  const task: Record<string, unknown> = { exec }
301
- if (PERSISTENT_TASK_NAMES.has(name)) {
317
+ if (PERSISTENT_TASK_NAMES.has(name) || isWatcher(name, own)) {
302
318
  exec['persistent'] = {}
303
319
  todos.push(PERSISTENT_TODO)
304
320
  }