@vzn/vx 0.0.342 → 0.0.343
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.
|
|
3
|
+
"version": "0.0.343",
|
|
4
4
|
"description": "A fast, correct 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.343",
|
|
25
|
+
"@vzn/vx-linux-arm64": "0.0.343",
|
|
26
|
+
"@vzn/vx-darwin-x64": "0.0.343",
|
|
27
|
+
"@vzn/vx-darwin-arm64": "0.0.343"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@anthropic-ai/sandbox-runtime": "^0.0.76"
|
package/src/cache/inputs.ts
CHANGED
|
@@ -1223,6 +1223,7 @@ async function scanUnion(
|
|
|
1223
1223
|
// `/`: `{dist,lib/esm}/**` saved an empty artifact, and a hit restored
|
|
1224
1224
|
// nothing over a cleaned tree (A-10). Expanded here, as discovery does.
|
|
1225
1225
|
for (const pattern of positive.flatMap(slashBraceExpansions)) {
|
|
1226
|
+
if (absentPrefix(cwd, pattern)) continue
|
|
1226
1227
|
const glob = globFor(pattern)
|
|
1227
1228
|
for (const rel of glob.scanSync({ cwd, onlyFiles: false, followSymlinks: false, dot: true })) {
|
|
1228
1229
|
if (nested(rel) || excludeGlobs.some((g) => g.match(rel))) continue
|
|
@@ -1235,6 +1236,23 @@ async function scanUnion(
|
|
|
1235
1236
|
return matches
|
|
1236
1237
|
}
|
|
1237
1238
|
|
|
1239
|
+
/**
|
|
1240
|
+
* True when `pattern`'s static directory is not on disk, so nothing can
|
|
1241
|
+
* match under it. A restore into a tree without its outputs scans each
|
|
1242
|
+
* glob twice (the check, then the clean), and a scan of a missing `dist`
|
|
1243
|
+
* cost ~58 µs where the lstat costs a few. Anything this cannot read
|
|
1244
|
+
* plainly (no prefix, an escape, an absolute path, a refused stat) scans.
|
|
1245
|
+
*/
|
|
1246
|
+
function absentPrefix(cwd: string, pattern: string): boolean {
|
|
1247
|
+
const prefix = staticPrefix(pattern)
|
|
1248
|
+
if (prefix === '.' || prefix.includes('\\') || path.isAbsolute(prefix)) return false
|
|
1249
|
+
try {
|
|
1250
|
+
return lstatSync(path.join(cwd, prefix), { throwIfNoEntry: false }) === undefined
|
|
1251
|
+
} catch {
|
|
1252
|
+
return false
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1238
1256
|
// Compiled once per pattern string for the life of the process: a `Bun.Glob`
|
|
1239
1257
|
// is immutable, and the same handful of declared globs are compiled again
|
|
1240
1258
|
// for every task otherwise (three sites, up to thousands of times per run).
|
|
@@ -1012,7 +1012,7 @@ export async function wrapSandboxedCommand(
|
|
|
1012
1012
|
let wrapped = await wrapForTask(
|
|
1013
1013
|
SandboxManager,
|
|
1014
1014
|
inner,
|
|
1015
|
-
customConfig,
|
|
1015
|
+
process.platform === 'linux' ? literalReadPaths(customConfig) : customConfig,
|
|
1016
1016
|
ports.length > 0 || asksUnixSockets(args.config),
|
|
1017
1017
|
args.config.gitConfig === true,
|
|
1018
1018
|
)
|
|
@@ -1148,6 +1148,30 @@ function asksUnixSockets(c: Pick<ResolvedSandboxConfig, 'unixSockets'>): boolean
|
|
|
1148
1148
|
return c.unixSockets === true || (c.unixSockets !== undefined && c.unixSockets.length > 0)
|
|
1149
1149
|
}
|
|
1150
1150
|
|
|
1151
|
+
/**
|
|
1152
|
+
* Linux: the read paths as SRT must be handed them to take each as the
|
|
1153
|
+
* name it is. vx has expanded every grant by then, so each is a path,
|
|
1154
|
+
* but SRT reads any holding `[` as a glob, where a bracket opens a class:
|
|
1155
|
+
* a route granted as `pages/\[id\].tsx` was never mounted (its denial
|
|
1156
|
+
* unreported, a listed grant), and a workspace under `[ws]/` was never
|
|
1157
|
+
* walled. `[[]` is a class of one `[`; a lone `]` is plain text to it.
|
|
1158
|
+
*/
|
|
1159
|
+
function literalReadPaths(
|
|
1160
|
+
config: Parameters<SrtModule['SandboxManager']['wrapWithSandbox']>[2],
|
|
1161
|
+
): Parameters<SrtModule['SandboxManager']['wrapWithSandbox']>[2] {
|
|
1162
|
+
const fs = config?.filesystem
|
|
1163
|
+
if (fs === undefined) return config
|
|
1164
|
+
const escape = (paths: readonly string[]): string[] => paths.map((p) => p.replaceAll('[', '[[]'))
|
|
1165
|
+
return {
|
|
1166
|
+
...config,
|
|
1167
|
+
filesystem: {
|
|
1168
|
+
...fs,
|
|
1169
|
+
denyRead: escape(fs.denyRead),
|
|
1170
|
+
...(fs.allowRead !== undefined ? { allowRead: escape(fs.allowRead) } : {}),
|
|
1171
|
+
},
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1151
1175
|
/** SRT's wrap, with the socket lift and the git-config grant this task asked for, or none (L-6, B-41). */
|
|
1152
1176
|
function wrapForTask(
|
|
1153
1177
|
SandboxManager: SrtModule['SandboxManager'],
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { readFileSync, statSync } from 'node:fs'
|
|
13
13
|
import path from 'node:path'
|
|
14
|
-
import { FILE_HASH_RACY_MS } from '../cache/index.js'
|
|
14
|
+
import { FILE_HASH_RACY_MS, racyWindowMs } from '../cache/index.js'
|
|
15
15
|
import { WORKSPACE_FINGERPRINT_FILES, type WorkspaceFingerprints } from '../workspace/index.js'
|
|
16
16
|
import type { Logger } from './logger.js'
|
|
17
17
|
|
|
@@ -56,7 +56,10 @@ export class FingerprintWatch {
|
|
|
56
56
|
if (before !== undefined) moved.push(f)
|
|
57
57
|
continue
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
// A whole-second stamp widens the window by that second (A-2): a
|
|
60
|
+
// rewrite 400 ms after the read was stamped before it (C-59).
|
|
61
|
+
if (before !== undefined && ctimeMs < this.at - racyWindowMs(ctimeMs, FILE_HASH_RACY_MS))
|
|
62
|
+
continue
|
|
60
63
|
let now: Uint8Array | undefined
|
|
61
64
|
try {
|
|
62
65
|
now = readFileSync(abs)
|