@vzn/vx 0.0.536 → 0.0.538

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.536",
3
+ "version": "0.0.538",
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.536",
25
- "@vzn/vx-linux-arm64": "0.0.536",
26
- "@vzn/vx-darwin-x64": "0.0.536",
27
- "@vzn/vx-darwin-arm64": "0.0.536"
24
+ "@vzn/vx-linux-x64": "0.0.538",
25
+ "@vzn/vx-linux-arm64": "0.0.538",
26
+ "@vzn/vx-darwin-x64": "0.0.538",
27
+ "@vzn/vx-darwin-arm64": "0.0.538"
28
28
  },
29
29
  "dependencies": {
30
30
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
package/src/cli/run.ts CHANGED
@@ -160,7 +160,8 @@ export function parseRunArgs(rawArgs: readonly string[], verb: 'run' | 'watch' =
160
160
  const a = before[i]
161
161
  if (a === '--filter' || a?.startsWith('--filter=')) {
162
162
  const v = a === '--filter' ? before[++i] : a.slice('--filter='.length)
163
- if (v === undefined || v === '')
163
+ // `--filter --dry` took `--dry` as the pattern (X-13); no filter opens with `--`.
164
+ if (v === undefined || v === '' || (a === '--filter' && v.startsWith('--')))
164
165
  return {
165
166
  ...out,
166
167
  error: `--filter requires a value (a project name, glob or path, e.g. --filter app)`,
package/src/cli/select.ts CHANGED
@@ -524,6 +524,10 @@ function didYouMeanProject(
524
524
  }
525
525
  for (const pattern of unmatched) {
526
526
  const typed = pattern.replace(/^!|\.\.\.$|^\.\.\.|\^/g, '')
527
+ // Two edits from any two-letter name: `--filter //` hinted `ui` (X-13).
528
+ if (typed === '//') {
529
+ return ". `//` is Turbo's root package, but the workspace root is no project here: give it a package.json name and a vx.config"
530
+ }
527
531
  const best = nearest(typed, names)
528
532
  if (best !== undefined) return `. Did you mean ${best}?`
529
533
  const bare = byBare.has(typed) ? typed : nearest(typed, byBare.keys())
@@ -155,6 +155,22 @@ function trailingCommentStart(command: string): number {
155
155
  return comment
156
156
  }
157
157
 
158
+ /** Per line: is it a heredoc's body or terminator (`<<X` / `<<-'X'` … `X`)? */
159
+ function heredocLines(lines: readonly string[]): boolean[] {
160
+ const pending: Array<{ delim: string; tabs: boolean }> = []
161
+ return lines.map((line) => {
162
+ const open = pending[0]
163
+ if (open !== undefined) {
164
+ if ((open.tabs ? line.replace(/^\t+/, '') : line) === open.delim) pending.shift()
165
+ return true
166
+ }
167
+ for (const m of line.matchAll(/(?<!<)<<(?!<)(-?)\s*(['"]?)([A-Za-z_]\w*)\2/g)) {
168
+ pending.push({ delim: m[3]!, tabs: m[1] === '-' })
169
+ }
170
+ return false
171
+ })
172
+ }
173
+
158
174
  /**
159
175
  * The command a task runs with the args after `--` appended, shell-quoted.
160
176
  * They go before a trailing comment: appended after it, `echo args: # show`
@@ -162,6 +178,17 @@ function trailingCommentStart(command: string): number {
162
178
  */
163
179
  export function withForwardArgs(command: string, args: readonly string[] | undefined): string {
164
180
  if (!args || args.length === 0) return command
181
+ // A command that ends in a heredoc's body: appended to its terminator,
182
+ // `X FWD` closed nothing and the args never reached the command (X-12).
183
+ // They go on the last line that is a command, where `cat <<X FWD` is
184
+ // still `cat FWD` reading the heredoc.
185
+ const lines = command.trimEnd().split('\n')
186
+ const body = heredocLines(lines)
187
+ if (body[lines.length - 1] === true) {
188
+ const last = body.lastIndexOf(false)
189
+ const tail = lines.slice(last + 1).join('\n')
190
+ return `${withForwardArgs(lines.slice(0, last + 1).join('\n'), args)}\n${tail}`
191
+ }
165
192
  const quoted = args.map(shellQuote).join(' ')
166
193
  let comment = trailingCommentStart(command)
167
194
  if (comment < 0) {
@@ -33,6 +33,7 @@ import {
33
33
  parseSize,
34
34
  printTimings,
35
35
  ulid,
36
+ isLiteralPattern,
36
37
  listed,
37
38
  nearest,
38
39
  UserError,
@@ -1577,6 +1578,21 @@ function didYouMean(
1577
1578
  continue
1578
1579
  }
1579
1580
  const [proj, task] = [spec.slice(0, at), spec.slice(at + 1)]
1581
+ // `//` is two edits from any two-letter name: it hinted `ui#build` (X-13).
1582
+ if (proj === '//') {
1583
+ lists.add(
1584
+ "`//` is Turbo's root package, but the workspace root is no project here: give it a package.json name and a vx.config with that task.",
1585
+ )
1586
+ continue
1587
+ }
1588
+ // `*` is one edit from any one-letter name and two from `ui`: `*#lint`
1589
+ // hinted `ui#lint`, though the user meant every project.
1590
+ if (!isLiteralPattern(proj) && !projects.has(proj)) {
1591
+ lists.add(
1592
+ `\`${spec}\` names one project, not a pattern: run \`${task}\` with --filter '${proj}' instead.`,
1593
+ )
1594
+ continue
1595
+ }
1580
1596
  if (!projects.has(proj)) {
1581
1597
  const p = projectNamed(proj, projects) ?? nearest(proj, projects.keys())
1582
1598
  if (p !== undefined && tasksOf(projects.get(p)).includes(task)) hints.add(`${p}#${task}`)