@vzn/vx 0.0.560 → 0.0.562

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 (2) hide show
  1. package/package.json +5 -5
  2. package/src/cli/watch.ts +26 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx",
3
- "version": "0.0.560",
3
+ "version": "0.0.562",
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.560",
25
- "@vzn/vx-linux-arm64": "0.0.560",
26
- "@vzn/vx-darwin-x64": "0.0.560",
27
- "@vzn/vx-darwin-arm64": "0.0.560"
24
+ "@vzn/vx-linux-x64": "0.0.562",
25
+ "@vzn/vx-linux-arm64": "0.0.562",
26
+ "@vzn/vx-darwin-x64": "0.0.562",
27
+ "@vzn/vx-darwin-arm64": "0.0.562"
28
28
  },
29
29
  "dependencies": {
30
30
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
package/src/cli/watch.ts CHANGED
@@ -138,11 +138,12 @@ export async function watchCmd(args: readonly string[]): Promise<number> {
138
138
  // closing reaches the loop alone, and the loop passes it on.
139
139
  process.once('SIGHUP', () => stop.abort('SIGHUP'))
140
140
 
141
- // Enumerate projects-in-scope so we know what dirs to watch.
142
- // `opts.projects` is the resolved scope; undefined means "every
143
- // project". The watched set is what a cycle can RUN: the scope plus
144
- // its transitive dependencies (a cycle runs `lib#build` for
145
- // `app#build`'s `^build`, so a `lib` edit is an edit) — the same
141
+ // Enumerate projects-in-scope so we know what dirs to watch: the bare
142
+ // tasks' scope (`opts.projects`; undefined means "every project", or
143
+ // nothing when every task is anchored) and each `pkg#task`'s own
144
+ // project, which no scope reaches. The watched set is what a cycle can
145
+ // RUN: the scope plus its transitive dependencies (a cycle runs
146
+ // `lib#build` for `app#build`'s `^build`, so a `lib` edit is an edit) — the same
146
147
  // closure `--filter 'app...'` walks, computed below once the initial
147
148
  // run has staged the configs. Plus the workspace root, for lockfile
148
149
  // changes.
@@ -150,15 +151,17 @@ export async function watchCmd(args: readonly string[]): Promise<number> {
150
151
  const workspaceRoot = await findWorkspaceRoot(cwd, reads)
151
152
  const workspace = await loadWorkspace(workspaceRoot, reads)
152
153
  const allProjects = await discoverCliProjects(workspace)
154
+ const anchored = opts.tasks.filter((t) => t.includes('#')).map((t) => t.slice(0, t.indexOf('#')))
155
+ const named =
156
+ anchored.length === opts.tasks.length
157
+ ? new Set(anchored)
158
+ : opts.projects === undefined
159
+ ? undefined
160
+ : new Set([...opts.projects, ...anchored])
153
161
  const inScope = (all: readonly ProjectMeta[]): ProjectMeta[] =>
154
- opts.projects === undefined ? [...all] : all.filter((p) => opts.projects!.includes(p.name))
162
+ named === undefined ? [...all] : all.filter((p) => named.has(p.name))
155
163
  const scope = inScope(allProjects)
156
164
 
157
- if (scope.length === 0) {
158
- process.stderr.write(`vx watch: no projects in scope\n`)
159
- return 1
160
- }
161
-
162
165
  // Initial run — same code path as `vx run`.
163
166
  //
164
167
  // Watchers do not exist yet, so an edit made WHILE this run is executing is
@@ -198,6 +201,18 @@ export async function watchCmd(args: readonly string[]): Promise<number> {
198
201
  return 0
199
202
  }
200
203
  if (refusedToStart) return 1
204
+ // After the initial run, so a `pkg#task` naming no project gets the
205
+ // run's own refusal and its "did you mean".
206
+ if (scope.length === 0) {
207
+ await held?.stop()
208
+ process.stderr.write(`vx watch: no projects in scope\n`)
209
+ return 1
210
+ }
211
+ // `--affected`'s diff is the tree at start; judged again, it held every
212
+ // later edit out of the scope it picked. A cycle is an edit, and the
213
+ // cache keys decide what in the scope it re-runs.
214
+ delete opts.affected
215
+ delete opts.selectedOutright
201
216
 
202
217
  const load: CliLoadOptions = {
203
218
  ...(opts.cacheDir !== undefined ? { cacheDir: opts.cacheDir } : {}),