@vzn/vx 0.0.553 → 0.0.555
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 +5 -5
- package/src/cache/layer.ts +2 -1
- package/src/workspace/config-schema.ts +39 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vzn/vx",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.555",
|
|
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.
|
|
25
|
-
"@vzn/vx-linux-arm64": "0.0.
|
|
26
|
-
"@vzn/vx-darwin-x64": "0.0.
|
|
27
|
-
"@vzn/vx-darwin-arm64": "0.0.
|
|
24
|
+
"@vzn/vx-linux-x64": "0.0.555",
|
|
25
|
+
"@vzn/vx-linux-arm64": "0.0.555",
|
|
26
|
+
"@vzn/vx-darwin-x64": "0.0.555",
|
|
27
|
+
"@vzn/vx-darwin-arm64": "0.0.555"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@anthropic-ai/sandbox-runtime": "^0.0.76"
|
package/src/cache/layer.ts
CHANGED
|
@@ -329,7 +329,8 @@ export interface PruneResult {
|
|
|
329
329
|
* the full `workspace-outputs/<rel-to-root>` tar entry name as the
|
|
330
330
|
* discriminator — least-invasive row format, no schema change. A
|
|
331
331
|
* project output dir literally named `workspace-outputs/` would
|
|
332
|
-
* collide with the namespace; the name is reserved
|
|
332
|
+
* collide with the namespace; the name is reserved, and a project
|
|
333
|
+
* output glob under it is refused at load (config-schema.ts).
|
|
333
334
|
*/
|
|
334
335
|
export const WORKSPACE_OUTPUT_PREFIX = 'workspace-outputs/'
|
|
335
336
|
|
|
@@ -24,6 +24,9 @@ import {
|
|
|
24
24
|
UserError,
|
|
25
25
|
BUN_GLOB_WILDCARDS,
|
|
26
26
|
EXTGLOB,
|
|
27
|
+
anyTaskGlob,
|
|
28
|
+
asTrees,
|
|
29
|
+
isLiteralPattern,
|
|
27
30
|
} from '../util/index.js'
|
|
28
31
|
import { nonJsonMessage, nonJsonPaths } from './json-data.js'
|
|
29
32
|
|
|
@@ -650,6 +653,15 @@ export function validateProjectConfig(config: ProjectConfig, configPath: string)
|
|
|
650
653
|
`name the directory the task writes, such as "dist/**"`,
|
|
651
654
|
)
|
|
652
655
|
}
|
|
656
|
+
// An artifact stores workspace outputs under `workspace-outputs/`,
|
|
657
|
+
// and its index read a project output there as one: every hit was
|
|
658
|
+
// a "corrupt artifact", dropped and run again.
|
|
659
|
+
if (!g.startsWith('!') && normalizeGlob(g).split('/')[0] === 'workspace-outputs') {
|
|
660
|
+
throw new UserError(
|
|
661
|
+
`${where}.cache.outputs.files: "${g}" is under workspace-outputs/, a name vx's ` +
|
|
662
|
+
`artifacts reserve for outputs.workspaceFiles — write the task's files to another directory`,
|
|
663
|
+
)
|
|
664
|
+
}
|
|
653
665
|
// A `!` entry takes a path back from the outputs (A-44): it is not
|
|
654
666
|
// cleaned, saved or restored, and it stays an input.
|
|
655
667
|
assertNotDoubleNegated(g, `${where}.cache.outputs.files`)
|
|
@@ -713,6 +725,7 @@ export function validateProjectConfig(config: ProjectConfig, configPath: string)
|
|
|
713
725
|
// error for the same reason. Refusing costs nothing: such a config was
|
|
714
726
|
// already silently broken, so no working key changes.
|
|
715
727
|
assertNotNegationOnly((inputs as { files: string[] }).files, `${where}.cache.inputs.files`)
|
|
728
|
+
assertNoLiteralTakenBack((inputs as { files: string[] }).files, `${where}.cache.inputs.files`)
|
|
716
729
|
// The only CacheInputs field that reached the run unvalidated: a
|
|
717
730
|
// non-string entry crashes deep in `filterUpstreamHashes` /
|
|
718
731
|
// `parseDependencySpec` with a raw TypeError naming neither the task
|
|
@@ -1329,6 +1342,28 @@ function assertNotNegationOnly(globs: readonly string[], where: string): void {
|
|
|
1329
1342
|
)
|
|
1330
1343
|
}
|
|
1331
1344
|
|
|
1345
|
+
/**
|
|
1346
|
+
* A `!` entry subtracts wherever it sits in the list, so a file named
|
|
1347
|
+
* outright after it (`['src/**', '!src/gen/**', 'src/gen/keep.ts']`) never
|
|
1348
|
+
* entered the key, and an edit to it replayed the old output. Refusing is
|
|
1349
|
+
* free: the literal already selected nothing.
|
|
1350
|
+
*/
|
|
1351
|
+
function assertNoLiteralTakenBack(globs: readonly string[], where: string): void {
|
|
1352
|
+
const negative = globs.filter((g) => g.startsWith('!')).map((g) => g.slice(1))
|
|
1353
|
+
if (negative.length === 0) return
|
|
1354
|
+
const taken = anyTaskGlob(asTrees(negative))
|
|
1355
|
+
for (const g of globs) {
|
|
1356
|
+
if (g.startsWith('!')) continue
|
|
1357
|
+
const lit = normalizeGlob(g).replace(/\/+$/, '')
|
|
1358
|
+
if (!isLiteralPattern(lit) || !taken(lit)) continue
|
|
1359
|
+
const by = negative.find((n) => anyTaskGlob(asTrees([n]))(lit))
|
|
1360
|
+
throw new UserError(
|
|
1361
|
+
`${where}: "${g}" is taken back by "!${by}" — a \`!\` entry subtracts wherever it sits in ` +
|
|
1362
|
+
`the list, so the file never enters the key. Narrow the negation so it leaves "${g}".`,
|
|
1363
|
+
)
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1332
1367
|
/**
|
|
1333
1368
|
* `negation: false` for OUTPUT globs: a `!` entry takes a path back (A-44),
|
|
1334
1369
|
* and a list of only negations selects nothing and is refused.
|
|
@@ -1361,8 +1396,10 @@ function validateWorkspaceGlobs(v: unknown, where: string, negation: boolean): v
|
|
|
1361
1396
|
}
|
|
1362
1397
|
assertNotDoubleNegated(g, where)
|
|
1363
1398
|
}
|
|
1364
|
-
if (negation)
|
|
1365
|
-
|
|
1399
|
+
if (negation) {
|
|
1400
|
+
assertNotNegationOnly(v as string[], where)
|
|
1401
|
+
assertNoLiteralTakenBack(v as string[], where)
|
|
1402
|
+
} else assertOutputsNotNegationOnly(v as string[], where)
|
|
1366
1403
|
}
|
|
1367
1404
|
|
|
1368
1405
|
/**
|