@vzn/vx 0.0.454 → 0.0.455

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.454",
3
+ "version": "0.0.455",
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.454",
25
- "@vzn/vx-linux-arm64": "0.0.454",
26
- "@vzn/vx-darwin-x64": "0.0.454",
27
- "@vzn/vx-darwin-arm64": "0.0.454"
24
+ "@vzn/vx-linux-x64": "0.0.455",
25
+ "@vzn/vx-linux-arm64": "0.0.455",
26
+ "@vzn/vx-darwin-x64": "0.0.455",
27
+ "@vzn/vx-darwin-arm64": "0.0.455"
28
28
  },
29
29
  "dependencies": {
30
30
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -536,7 +536,7 @@ export function validateProjectConfig(config: ProjectConfig, configPath: string)
536
536
  if (typeof g !== 'string' || g.length === 0) {
537
537
  throw new UserError(`${where}.cache.outputs.files must be an array of non-empty strings`)
538
538
  }
539
- if (g.startsWith('/') || g.startsWith('!/')) {
539
+ if (isAbsoluteGlob(g)) {
540
540
  throw new UserError(
541
541
  `${where}.cache.outputs.files: absolute paths are not allowed (got "${g}") — ` +
542
542
  `outputs must be project-relative globs`,
@@ -574,7 +574,7 @@ export function validateProjectConfig(config: ProjectConfig, configPath: string)
574
574
  if (typeof g !== 'string' || g.length === 0) {
575
575
  throw new UserError(`${where}.cache.inputs.files must be an array of non-empty strings`)
576
576
  }
577
- if (g.startsWith('/')) {
577
+ if (!g.startsWith('!/') && isAbsoluteGlob(g)) {
578
578
  throw new UserError(
579
579
  `${where}.cache.inputs.files: absolute paths are not allowed (got "${g}") — ` +
580
580
  `inputs must be project-relative globs`,
@@ -1025,7 +1025,19 @@ function namesDirItself(glob: string): boolean {
1025
1025
  */
1026
1026
  function hasParentSegment(glob: string): boolean {
1027
1027
  const g = glob.startsWith('!') ? glob.slice(1) : glob
1028
- return g.split('/').some((seg) => seg === '..')
1028
+ // A brace alternative is a segment too: `{../shared,src}/**` splits on `/`
1029
+ // into `{..`, so it passed, and its `..` arm matched nothing — an input
1030
+ // that silently left the key (M-64).
1031
+ return g.split(/[/{},]/).some((seg) => seg === '..')
1032
+ }
1033
+
1034
+ /**
1035
+ * True when a glob is absolute, or a brace alternative in it is:
1036
+ * `{/etc,dist}/*` matched nothing outside and said so nowhere (M-64).
1037
+ */
1038
+ function isAbsoluteGlob(glob: string): boolean {
1039
+ const g = glob.startsWith('!') ? glob.slice(1) : glob
1040
+ return g.startsWith('/') || (g.includes('{') && /[{,]\//.test(g))
1029
1041
  }
1030
1042
 
1031
1043
  /**
@@ -1203,7 +1215,7 @@ function validateWorkspaceGlobs(v: unknown, where: string, negation: boolean): v
1203
1215
  if (typeof g !== 'string' || g.length === 0) {
1204
1216
  throw new UserError(`${where} must be an array of non-empty strings`)
1205
1217
  }
1206
- if (g.startsWith('/') || g.startsWith('!/')) {
1218
+ if (isAbsoluteGlob(g)) {
1207
1219
  throw new UserError(
1208
1220
  `${where}: absolute paths are not allowed (got "${g}") — ` +
1209
1221
  `entries are workspace-root-relative globs`,