@vibe-agent-toolkit/utils 0.2.0-rc.7 → 0.2.0-rc.8
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/README.md +22 -3
- package/dist/asset-reference.js +3 -11
- package/dist/asset-reference.js.map +1 -1
- package/dist/crawl-timing.d.ts +3 -3
- package/dist/crawl-timing.js +3 -3
- package/dist/dirent-kind.d.ts +83 -0
- package/dist/dirent-kind.d.ts.map +1 -0
- package/dist/dirent-kind.js +129 -0
- package/dist/dirent-kind.js.map +1 -0
- package/dist/errors/errno.d.ts +51 -0
- package/dist/errors/errno.d.ts.map +1 -0
- package/dist/errors/errno.js +112 -0
- package/dist/errors/errno.js.map +1 -0
- package/dist/errors/vat-error.d.ts +60 -0
- package/dist/errors/vat-error.d.ts.map +1 -0
- package/dist/errors/vat-error.js +86 -0
- package/dist/errors/vat-error.js.map +1 -0
- package/dist/file-crawler.js +9 -9
- package/dist/file-crawler.js.map +1 -1
- package/dist/fs/file-hash.d.ts.map +1 -1
- package/dist/fs/file-hash.js +0 -1
- package/dist/fs/file-hash.js.map +1 -1
- package/dist/fs-utils.d.ts +16 -18
- package/dist/fs-utils.d.ts.map +1 -1
- package/dist/fs-utils.js +56 -80
- package/dist/fs-utils.js.map +1 -1
- package/dist/fs.d.ts +2 -1
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +2 -1
- package/dist/fs.js.map +1 -1
- package/dist/git-run.d.ts +1 -1
- package/dist/git-run.js +1 -1
- package/dist/git-tracker.d.ts +1 -1
- package/dist/git-tracker.d.ts.map +1 -1
- package/dist/git-tracker.js +1 -2
- package/dist/git-tracker.js.map +1 -1
- package/dist/git-utils.d.ts.map +1 -1
- package/dist/git-utils.js +0 -1
- package/dist/git-utils.js.map +1 -1
- package/dist/gitignore-checker.d.ts.map +1 -1
- package/dist/gitignore-checker.js +9 -3
- package/dist/gitignore-checker.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -4
- package/dist/index.js.map +1 -1
- package/dist/listing-refusal.d.ts +2 -1
- package/dist/listing-refusal.d.ts.map +1 -1
- package/dist/listing-refusal.js +3 -3
- package/dist/listing-refusal.js.map +1 -1
- package/dist/path-containment.d.ts +64 -0
- package/dist/path-containment.d.ts.map +1 -0
- package/dist/path-containment.js +111 -0
- package/dist/path-containment.js.map +1 -0
- package/dist/path-core.d.ts +77 -3
- package/dist/path-core.d.ts.map +1 -1
- package/dist/path-core.js +96 -6
- package/dist/path-core.js.map +1 -1
- package/dist/path-utils.d.ts.map +1 -1
- package/dist/path-utils.js +42 -47
- package/dist/path-utils.js.map +1 -1
- package/dist/path.d.ts +1 -1
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +1 -1
- package/dist/path.js.map +1 -1
- package/dist/project-utils.d.ts.map +1 -1
- package/dist/project-utils.js +9 -6
- package/dist/project-utils.js.map +1 -1
- package/dist/safe-exec.d.ts +2 -1
- package/dist/safe-exec.d.ts.map +1 -1
- package/dist/safe-exec.js +25 -7
- package/dist/safe-exec.js.map +1 -1
- package/dist/skill-targets.d.ts +2 -2
- package/dist/skill-targets.js +2 -2
- package/dist/skill-test/auth-resolver.d.ts +10 -2
- package/dist/skill-test/auth-resolver.d.ts.map +1 -1
- package/dist/skill-test/auth-resolver.js +26 -11
- package/dist/skill-test/auth-resolver.js.map +1 -1
- package/dist/skill-test/spawn-claude.d.ts +2 -1
- package/dist/skill-test/spawn-claude.d.ts.map +1 -1
- package/dist/skill-test/spawn-claude.js +20 -3
- package/dist/skill-test/spawn-claude.js.map +1 -1
- package/dist/skill-test/transcript.d.ts.map +1 -1
- package/dist/skill-test/transcript.js +18 -17
- package/dist/skill-test/transcript.js.map +1 -1
- package/dist/stdio-blocking.js +13 -14
- package/dist/stdio-blocking.js.map +1 -1
- package/dist/test-helpers.d.ts +47 -204
- package/dist/test-helpers.d.ts.map +1 -1
- package/dist/test-helpers.js +105 -310
- package/dist/test-helpers.js.map +1 -1
- package/dist/testing/executables.d.ts +32 -0
- package/dist/testing/executables.d.ts.map +1 -0
- package/dist/testing/executables.js +70 -0
- package/dist/testing/executables.js.map +1 -0
- package/dist/testing/hostile-tree.d.ts +79 -0
- package/dist/testing/hostile-tree.d.ts.map +1 -0
- package/dist/testing/hostile-tree.js +164 -0
- package/dist/testing/hostile-tree.js.map +1 -0
- package/dist/testing/platform-gates.d.ts +31 -0
- package/dist/testing/platform-gates.d.ts.map +1 -0
- package/dist/testing/platform-gates.js +31 -0
- package/dist/testing/platform-gates.js.map +1 -0
- package/dist/testing/temp-dir.d.ts +255 -0
- package/dist/testing/temp-dir.d.ts.map +1 -0
- package/dist/testing/temp-dir.js +363 -0
- package/dist/testing/temp-dir.js.map +1 -0
- package/dist/testing.d.ts +5 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +10 -1
- package/dist/testing.js.map +1 -1
- package/dist/text-content.d.ts.map +1 -1
- package/dist/text-content.js +7 -1
- package/dist/text-content.js.map +1 -1
- package/dist/text-file.d.ts.map +1 -1
- package/dist/text-file.js +0 -2
- package/dist/text-file.js.map +1 -1
- package/dist/timing-dump.d.ts +1 -1
- package/dist/timing-dump.d.ts.map +1 -1
- package/dist/timing-dump.js +1 -2
- package/dist/timing-dump.js.map +1 -1
- package/dist/windows-shell.d.ts +0 -1
- package/dist/windows-shell.d.ts.map +1 -1
- package/dist/windows-shell.js +0 -1
- package/dist/windows-shell.js.map +1 -1
- package/dist/zod-introspection.js +2 -2
- package/dist/zod-introspection.js.map +1 -1
- package/eslint/README.md +125 -67
- package/eslint/index.cjs +111 -162
- package/eslint/index.d.cts +14 -17
- package/eslint/rules/callee-name.cjs +23 -0
- package/eslint/rules/commands-import-boundary.cjs +148 -0
- package/eslint/rules/dead-import.cjs +1 -1
- package/eslint/rules/dirent-type-needs-symlink-check.cjs +282 -0
- package/eslint/rules/eslint-rule-factory.cjs +5 -2
- package/eslint/rules/exempt-path-matcher.cjs +1 -1
- package/eslint/rules/explicit-zod-strictness.cjs +120 -0
- package/eslint/rules/no-bare-dynamic-import-path.cjs +5 -1
- package/eslint/rules/no-bare-executable-spawn.cjs +70 -0
- package/eslint/rules/no-bare-symlink-in-tests.cjs +16 -3
- package/eslint/rules/no-blind-catch.cjs +171 -0
- package/eslint/rules/no-child-process-execSync.cjs +8 -0
- package/eslint/rules/no-decaying-referent.cjs +216 -0
- package/eslint/rules/no-dotdot-containment.cjs +160 -0
- package/eslint/rules/no-file-url-string-concat.cjs +4 -1
- package/eslint/rules/no-fragile-entrypoint-guard.cjs +14 -1
- package/eslint/rules/no-fs-mkdirSync.cjs +8 -0
- package/eslint/rules/no-fs-promises-cp.cjs +7 -0
- package/eslint/rules/no-fs-realpathSync.cjs +8 -0
- package/eslint/rules/no-hardcoded-path-split.cjs +7 -2
- package/eslint/rules/no-io-in-unit-tier.cjs +128 -0
- package/eslint/rules/no-literal-process-exit.cjs +129 -0
- package/eslint/rules/no-manual-path-normalize.cjs +7 -2
- package/eslint/rules/no-os-tmpdir.cjs +8 -0
- package/eslint/rules/no-path-operations-in-comparisons.cjs +7 -2
- package/eslint/rules/no-path-sep-in-strings.cjs +7 -2
- package/eslint/rules/no-path-startswith.cjs +7 -2
- package/eslint/rules/no-process-exit-in-phase.cjs +12 -2
- package/eslint/rules/no-raw-node-path.cjs +563 -0
- package/eslint/rules/no-raw-text-decode.cjs +10 -1
- package/eslint/rules/no-registry-count-pin.cjs +255 -0
- package/eslint/rules/no-self-package-import.cjs +13 -2
- package/eslint/rules/no-test-scoped-functions.cjs +10 -3
- package/eslint/rules/no-unix-shell-commands.cjs +6 -2
- package/eslint/rules/no-unsafe-root-join.cjs +23 -2
- package/eslint/rules/no-url-pathname-for-fs.cjs +5 -1
- package/eslint/rules/no-version-literal.cjs +151 -0
- package/eslint/rules/prefer-startswith-over-regex.cjs +9 -0
- package/eslint/rules/require-justified-skip.cjs +8 -2
- package/eslint/rules/safe-import.cjs +1 -1
- package/package.json +4 -9
- package/eslint/rules/no-path-join.cjs +0 -14
- package/eslint/rules/no-path-relative.cjs +0 -14
- package/eslint/rules/no-path-resolve.cjs +0 -14
- package/eslint/rules/path-function-rule-factory.cjs +0 -496
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-resolver.d.ts","sourceRoot":"","sources":["../../src/skill-test/auth-resolver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth-resolver.d.ts","sourceRoot":"","sources":["../../src/skill-test/auth-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAKlD,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,GAAG,MAAM,CAAC;AACvE,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,SAAS,CAAC;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,gBAAgB,GAAG,IAAI,CAAC;AAElF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC;IAC7B,uEAAuE;IACvE,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,kBAAkB,EAAE,aAAa,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,sDAAsD;AACtD,qBAAa,kBAAmB,SAAQ,QAAQ;IAC9C,QAAQ,CAAC,MAAM,EAAG,WAAW,CAAU;gBAC3B,OAAO,EAAE,MAAM;CAG5B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,gBAAgB,GAAG,IAAI,CAI/E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAevE;AAgBD,wBAAgB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,YAAY,CA+BlE"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { VatError } from '../errors/vat-error.js';
|
|
1
2
|
import { safeExecResult } from '../safe-exec.js';
|
|
2
3
|
import { buildForwardedEnv } from './env-scrub.js';
|
|
3
4
|
/** A preflight auth failure — maps to exit code 2. */
|
|
4
|
-
export class AuthPreflightError extends
|
|
5
|
-
|
|
5
|
+
export class AuthPreflightError extends VatError {
|
|
6
|
+
reason = 'preflight';
|
|
6
7
|
constructor(message) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = 'AuthPreflightError';
|
|
8
|
+
super('AUTH_PREFLIGHT', message);
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
@@ -16,17 +16,32 @@ export function probeAuthStatus(env) {
|
|
|
16
16
|
const res = safeExecResult('claude', ['auth', 'status', '--json'], { env, encoding: 'utf8', stdio: 'pipe' });
|
|
17
17
|
if (!res.success)
|
|
18
18
|
return null;
|
|
19
|
+
return parseAuthStatus(res.stdout.toString());
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Read what `claude auth status --json` printed. `null` means "not the JSON
|
|
23
|
+
* object the flag promises" — an older CLI answering in prose, or a bare
|
|
24
|
+
* literal — and only that: a failure inside this reader is a bug, not "not
|
|
25
|
+
* logged in", and `resolveAuth` would otherwise turn it into a preflight exit.
|
|
26
|
+
*/
|
|
27
|
+
export function parseAuthStatus(stdout) {
|
|
28
|
+
let parsed;
|
|
19
29
|
try {
|
|
20
|
-
|
|
21
|
-
return {
|
|
22
|
-
loggedIn: parsed['loggedIn'] === true,
|
|
23
|
-
...(typeof parsed['authMethod'] === 'string' ? { authMethod: parsed['authMethod'] } : {}),
|
|
24
|
-
...(typeof parsed['apiKeySource'] === 'string' ? { apiKeySource: parsed['apiKeySource'] } : {}),
|
|
25
|
-
};
|
|
30
|
+
parsed = JSON.parse(stdout);
|
|
26
31
|
}
|
|
27
|
-
catch {
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (!(error instanceof SyntaxError))
|
|
34
|
+
throw error;
|
|
28
35
|
return null;
|
|
29
36
|
}
|
|
37
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
38
|
+
return null;
|
|
39
|
+
const record = parsed;
|
|
40
|
+
return {
|
|
41
|
+
loggedIn: record['loggedIn'] === true,
|
|
42
|
+
...(typeof record['authMethod'] === 'string' ? { authMethod: record['authMethod'] } : {}),
|
|
43
|
+
...(typeof record['apiKeySource'] === 'string' ? { apiKeySource: record['apiKeySource'] } : {}),
|
|
44
|
+
};
|
|
30
45
|
}
|
|
31
46
|
function hasInferenceKey(env) {
|
|
32
47
|
return Boolean(env['ANTHROPIC_API_KEY'] ?? env['ANTHROPIC_AUTH_TOKEN']);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-resolver.js","sourceRoot":"","sources":["../../src/skill-test/auth-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA6BnD,sDAAsD;AACtD,MAAM,OAAO,kBAAmB,SAAQ,
|
|
1
|
+
{"version":3,"file":"auth-resolver.js","sourceRoot":"","sources":["../../src/skill-test/auth-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -53,7 +53,8 @@ export interface SpawnResult {
|
|
|
53
53
|
* orphaned MCP subprocesses that a direct `child.kill()` would leave running.
|
|
54
54
|
*
|
|
55
55
|
* - Guards an undefined pid (child never spawned — nothing to kill).
|
|
56
|
-
* -
|
|
56
|
+
* - Absorbs the throw that means the group is already gone (see
|
|
57
|
+
* {@link isProcessGroupGone}); anything else stays loud.
|
|
57
58
|
* - Windows has no POSIX process groups: fall back to `taskkill /T /F`, which
|
|
58
59
|
* terminates the whole process tree.
|
|
59
60
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn-claude.d.ts","sourceRoot":"","sources":["../../src/skill-test/spawn-claude.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAoBlE;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED
|
|
1
|
+
{"version":3,"file":"spawn-claude.d.ts","sourceRoot":"","sources":["../../src/skill-test/spawn-claude.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAoBlE;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,IAAI,CAkBzE;AAgCD;;;;;GAKG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAKlD;AAED,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D;;;;;;;;;OASG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CA8G1F"}
|
|
@@ -67,7 +67,8 @@ export function assembleClaudeArgs(opts) {
|
|
|
67
67
|
* orphaned MCP subprocesses that a direct `child.kill()` would leave running.
|
|
68
68
|
*
|
|
69
69
|
* - Guards an undefined pid (child never spawned — nothing to kill).
|
|
70
|
-
* -
|
|
70
|
+
* - Absorbs the throw that means the group is already gone (see
|
|
71
|
+
* {@link isProcessGroupGone}); anything else stays loud.
|
|
71
72
|
* - Windows has no POSIX process groups: fall back to `taskkill /T /F`, which
|
|
72
73
|
* terminates the whole process tree.
|
|
73
74
|
*/
|
|
@@ -85,10 +86,26 @@ export function killProcessTree(child) {
|
|
|
85
86
|
process.kill(-pid, 'SIGKILL');
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
|
-
catch {
|
|
89
|
-
//
|
|
89
|
+
catch (error) {
|
|
90
|
+
// A reaper that says nothing about a tree it did not reap is the
|
|
91
|
+
// orphan-billing defect the registry exists to prevent, so only "already
|
|
92
|
+
// gone" is absorbed. A bug here — the one other thing `process.kill` on our
|
|
93
|
+
// own child's group can throw — stays loud.
|
|
94
|
+
if (!isProcessGroupGone(error))
|
|
95
|
+
throw error;
|
|
90
96
|
}
|
|
91
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Whether `process.kill(-pid)` failed because the group is already gone.
|
|
100
|
+
*
|
|
101
|
+
* `ESRCH`: no such process group. `EPERM`: the group id has been recycled to a
|
|
102
|
+
* process this uid may not signal — which, for a group WE created and would
|
|
103
|
+
* have permission over, also means every process of ours in it has exited.
|
|
104
|
+
* Both are the outcome the kill was after.
|
|
105
|
+
*/
|
|
106
|
+
function isProcessGroupGone(error) {
|
|
107
|
+
return error instanceof Error && 'code' in error && (error.code === 'ESRCH' || error.code === 'EPERM');
|
|
108
|
+
}
|
|
92
109
|
/**
|
|
93
110
|
* Registry of currently in-flight `claude` child processes, keyed by the
|
|
94
111
|
* `ChildProcess` object itself. A child is registered immediately after
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn-claude.js","sourceRoot":"","sources":["../../src/skill-test/spawn-claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA+C,MAAM,oBAAoB,CAAC;AAC5F,OAAO,EAAE,QAAQ,EAAiB,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAUrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAqB;IACtD,MAAM,IAAI,GAAa;QACrB,IAAI;QACJ,0EAA0E;QAC1E,sEAAsE;QACtE,4DAA4D;QAC5D,iBAAiB,EAAE,aAAa;QAChC,WAAW;QACX,mBAAmB,EAAE,EAAE;QACvB,0BAA0B;QAC1B,mBAAmB,EAAE,mBAAmB;QACxC,WAAW,EAAE,IAAI,CAAC,UAAU;KAC7B,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/D,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjF,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAC9F,OAAO,IAAI,CAAC;AACd,CAAC;AAQD
|
|
1
|
+
{"version":3,"file":"spawn-claude.js","sourceRoot":"","sources":["../../src/skill-test/spawn-claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/skill-test/transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;;;;;;;;;;;;OAaG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB;;;;;;;;;;;;;WAaG;QACH,KAAK,EAAE,OAAO,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;KAChC,CAAC,CAAC;IACH,WAAW,EAAE,KAAK,CAAC;QACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB;;;;;WAKG;QACH,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1F,WAAW,EAAE,OAAO,CAAC;CACtB;AA+JD,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/skill-test/transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;;;;;;;;;;;;OAaG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB;;;;;;;;;;;;;WAaG;QACH,KAAK,EAAE,OAAO,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;KAChC,CAAC,CAAC;IACH,WAAW,EAAE,KAAK,CAAC;QACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB;;;;;WAKG;QACH,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1F,WAAW,EAAE,OAAO,CAAC;CACtB;AA+JD,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,CAiC9E;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,gBAAgB,EACxB,iBAAiB,EAAE,SAAS,MAAM,EAAE,GACnC,OAAO,CAOT"}
|
|
@@ -19,22 +19,20 @@
|
|
|
19
19
|
* - The terminal `result` event carries `subtype`, `is_error`, `num_turns`,
|
|
20
20
|
* and `total_cost_usd`.
|
|
21
21
|
*/
|
|
22
|
+
/**
|
|
23
|
+
* Every value these two see is a fragment of a `JSON.parse` result — plain
|
|
24
|
+
* data, no cycles, no BigInt, no `toJSON` — so `JSON.stringify` cannot fail on
|
|
25
|
+
* it, and neither wraps it in a catch. The one thing it CAN answer with is
|
|
26
|
+
* `undefined`, for an absent field (a `tool_use` with no `input`); that used
|
|
27
|
+
* to trip a `.length` inside a blind catch and surface as `<unserializable>`,
|
|
28
|
+
* a parser accident reported as a property of the event.
|
|
29
|
+
*/
|
|
22
30
|
function summarizeValue(value) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return json.length > 200 ? `${json.slice(0, 197)}...` : json;
|
|
26
|
-
}
|
|
27
|
-
catch {
|
|
28
|
-
return '<unserializable>';
|
|
29
|
-
}
|
|
31
|
+
const json = stringifyValue(value);
|
|
32
|
+
return json.length > 200 ? `${json.slice(0, 197)}...` : json;
|
|
30
33
|
}
|
|
31
34
|
function stringifyValue(value) {
|
|
32
|
-
|
|
33
|
-
return JSON.stringify(value) ?? '';
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
return '<unserializable>';
|
|
37
|
-
}
|
|
35
|
+
return JSON.stringify(value) ?? '';
|
|
38
36
|
}
|
|
39
37
|
/**
|
|
40
38
|
* Flatten a `tool_result` `content` field to plain text, WITHOUT truncating.
|
|
@@ -169,10 +167,13 @@ export function parseStreamJsonTranscript(streamText) {
|
|
|
169
167
|
try {
|
|
170
168
|
parsed = JSON.parse(trimmed);
|
|
171
169
|
}
|
|
172
|
-
catch {
|
|
173
|
-
//
|
|
174
|
-
// what the AGENT hit, this reports what
|
|
175
|
-
// would make a harness defect look like
|
|
170
|
+
catch (error) {
|
|
171
|
+
// A line that is not JSON is counted, not thrown on, and never pushed
|
|
172
|
+
// into `errors`: `errors` reports what the AGENT hit, this reports what
|
|
173
|
+
// the PARSER lost. Conflating them would make a harness defect look like
|
|
174
|
+
// a run failure and vice versa. Only a parse failure is a lost line.
|
|
175
|
+
if (!(error instanceof SyntaxError))
|
|
176
|
+
throw error;
|
|
176
177
|
out.malformedLineCount += 1;
|
|
177
178
|
continue;
|
|
178
179
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/skill-test/transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA2DH,SAAS,cAAc,CAAC,KAAc;IACpC,
|
|
1
|
+
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/skill-test/transcript.ts"],"names":[],"mappings":"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"}
|
package/dist/stdio-blocking.js
CHANGED
|
@@ -10,23 +10,22 @@
|
|
|
10
10
|
/**
|
|
11
11
|
* Switch one stream's underlying handle into blocking mode.
|
|
12
12
|
*
|
|
13
|
-
* @returns `true` only if `setBlocking` was present AND
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* @returns `true` only if `setBlocking` was present AND reported success. Both
|
|
14
|
+
* failure modes are real: a handle can be absent (stdio replaced, or a shape
|
|
15
|
+
* libuv does not wrap), and libuv can refuse the switch for a handle type that
|
|
16
|
+
* does not support it. It reports that refusal as a negative errno RETURN VALUE
|
|
17
|
+
* — `LibuvStreamWrap::SetBlocking` hands back `uv_stream_set_blocking`'s int,
|
|
18
|
+
* and a Windows TTY answers `UV_EINVAL` — never as a throw. This used to sit in
|
|
19
|
+
* a `try` that read a throw as the failure and the return value as nothing, so
|
|
20
|
+
* a refused switch reported `true` and the debug line said truncation could
|
|
21
|
+
* not happen on a stream it could happen on. A throw from in here would be a
|
|
22
|
+
* bug in Node's internals, and stays loud.
|
|
17
23
|
*/
|
|
18
24
|
function setStreamBlocking(stream) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (typeof handle?.setBlocking !== 'function')
|
|
22
|
-
return false;
|
|
23
|
-
handle.setBlocking(true);
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
catch {
|
|
27
|
-
// Best-effort: never let a startup nicety take down the process.
|
|
25
|
+
const handle = stream._handle;
|
|
26
|
+
if (typeof handle?.setBlocking !== 'function')
|
|
28
27
|
return false;
|
|
29
|
-
|
|
28
|
+
return handle.setBlocking(true) === 0;
|
|
30
29
|
}
|
|
31
30
|
/**
|
|
32
31
|
* Make stdout/stderr BLOCKING, so that `process.exit()` can never discard output.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio-blocking.js","sourceRoot":"","sources":["../src/stdio-blocking.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH
|
|
1
|
+
{"version":3,"file":"stdio-blocking.js","sourceRoot":"","sources":["../src/stdio-blocking.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH;;;;;;;;;;;;;GAaG;AACH,SAAS,iBAAiB,CAAC,MAA0B;IACpD,MAAM,MAAM,GACX,MACA,CAAC,OAAO,CAAC;IACV,IAAI,OAAO,MAAM,EAAE,WAAW,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,iBAAiB;IAChC,OAAO;QACN,MAAM,EAAE,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC;QACzC,MAAM,EAAE,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC;KACzC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAA2B;IAChE,MAAM,MAAM,GAAI,CAAC,QAAQ,EAAE,QAAQ,CAAW,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,4EAA4E,CAAC;IACrF,CAAC;IACD,OAAO,yBAAyB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,yBAAyB,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,yDAAyD,CAAC;AAC7L,CAAC"}
|
package/dist/test-helpers.d.ts
CHANGED
|
@@ -1,191 +1,3 @@
|
|
|
1
|
-
/** Knobs for {@link removeScratchDir}; all three exist so the behaviour is testable. */
|
|
2
|
-
export interface RemoveScratchDirOptions {
|
|
3
|
-
/** Deadline before the removal is abandoned. Default {@link SCRATCH_REMOVAL_BUDGET_MS}. */
|
|
4
|
-
readonly budgetMs?: number;
|
|
5
|
-
/** Where the give-up notice goes. Default `console.warn`. */
|
|
6
|
-
readonly onWarn?: (message: string) => void;
|
|
7
|
-
/**
|
|
8
|
-
* The removal itself. Defaults to `fs.rm` with recursive/force/retries.
|
|
9
|
-
*
|
|
10
|
-
* Injectable because the *contract* — a removal that fails must warn rather
|
|
11
|
-
* than throw — cannot otherwise be tested on every platform. Driving a real
|
|
12
|
-
* `fs.rm` failure needs a path the OS refuses, and those diverge: a path
|
|
13
|
-
* whose parent component is a regular file yields `ENOTDIR` on POSIX, and
|
|
14
|
-
* resolves silently on Windows. A test written against the POSIX shape
|
|
15
|
-
* passes locally and fails in CI, which is exactly what it did once.
|
|
16
|
-
*/
|
|
17
|
-
readonly remove?: (dir: string) => Promise<void>;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Delete a scratch directory as *best effort* — never failing the suite that
|
|
21
|
-
* created it, and never taking longer than its own budget to say so.
|
|
22
|
-
*
|
|
23
|
-
* ## Why this is not just `await rm(dir, { recursive: true, force: true })`
|
|
24
|
-
*
|
|
25
|
-
* A teardown hook that can redden a suite whose every assertion passed is a
|
|
26
|
-
* defect in the harness, not a flake. `packages/lab/test/instrument.test.ts`
|
|
27
|
-
* timed out here on two consecutive Windows runs with all 655 assertions
|
|
28
|
-
* green — only the cleanup lost.
|
|
29
|
-
*
|
|
30
|
-
* The measurement is what rules out the obvious fixes: that scratch dir holds
|
|
31
|
-
* 490 files / 378 KiB across 14 fixture git repos, and deletes in **59 ms**
|
|
32
|
-
* idle. Against vitest's 10,000 ms unit-hook budget that is 170x of headroom,
|
|
33
|
-
* and Windows blew through it anyway. No quantity of real work explains that,
|
|
34
|
-
* so the cause is scheduling — contention from a fully parallel `validate`,
|
|
35
|
-
* plus per-unlink antivirus on Windows — which is unbounded by nature. Hence:
|
|
36
|
-
*
|
|
37
|
-
* - **Raising `hookTimeout` cannot be argued.** You would be picking a number
|
|
38
|
-
* to beat an unbounded quantity, when 10s of 170x headroom already lost. It
|
|
39
|
-
* also punches a hole in the deliberate policy in `vitest.shared.ts` ("no
|
|
40
|
-
* hookTimeout override here on purpose") for every unit hook, to fix one.
|
|
41
|
-
* - **`try`/`catch` around the `rm` cannot work.** A vitest hook timeout is a
|
|
42
|
-
* race decided on the *timer* side; the hook's own catch never sees it. It
|
|
43
|
-
* addresses a failure mode we did not observe and leaves the one we did.
|
|
44
|
-
* - **`maxRetries` alone makes it worse.** Retries target transient
|
|
45
|
-
* `EPERM`/`EBUSY`, which fail *fast*; our failure was *slow*, and retry
|
|
46
|
-
* backoff only adds to it. Kept below as a cheap inner win, not as the fix.
|
|
47
|
-
*
|
|
48
|
-
* So the deadline is taken away from vitest: the removal races a timer of our
|
|
49
|
-
* own, well inside the hook budget, and expiry is a warning rather than a
|
|
50
|
-
* failure. The hook therefore always resolves in time, which makes it
|
|
51
|
-
* *structurally* incapable of reddening a green suite on any machine at any
|
|
52
|
-
* load — rather than merely unlikely to.
|
|
53
|
-
*
|
|
54
|
-
* The cost, stated plainly: under pathological contention the directory
|
|
55
|
-
* survives in the OS temp dir, which the OS reclaims, and the warning names
|
|
56
|
-
* the path. It can never surface as an unhandled rejection, because the only
|
|
57
|
-
* rejection handler is installed before the race.
|
|
58
|
-
*
|
|
59
|
-
* ⚠️ **Abandoning the removal does not stop it, and does not free the worker.**
|
|
60
|
-
* A pending libuv `fs` request is an active handle, so the `rm` runs to
|
|
61
|
-
* completion regardless — measured at 2,407 ms on an 8,000-file tree after the
|
|
62
|
-
* race was decided at 5 ms — and the process cannot exit until it does.
|
|
63
|
-
* `timer.unref()` below unrefs the *timer*, not the removal. So what this buys
|
|
64
|
-
* is bounded: the **hook** always resolves in time, which is what stops a green
|
|
65
|
-
* suite going red. It does **not** shed the work, and under the contention it
|
|
66
|
-
* targets the abandoned removal competes for disk with whatever runs next in
|
|
67
|
-
* the same worker. That is the trade, and it is why the budget wants to be as
|
|
68
|
-
* large as the tier's hook allows rather than as small as possible.
|
|
69
|
-
*
|
|
70
|
-
* @param dir - Directory to remove. An empty string is a no-op, so a suite
|
|
71
|
-
* whose `beforeAll` never ran can call this unconditionally.
|
|
72
|
-
* @param options - Deadline and warning sink
|
|
73
|
-
*
|
|
74
|
-
* @example
|
|
75
|
-
* ```typescript
|
|
76
|
-
* afterAll(async () => {
|
|
77
|
-
* await removeScratchDir(scratch);
|
|
78
|
-
* });
|
|
79
|
-
* ```
|
|
80
|
-
*/
|
|
81
|
-
export declare function removeScratchDir(dir: string, options?: RemoveScratchDirOptions): Promise<void>;
|
|
82
|
-
/**
|
|
83
|
-
* Get isolated test output directory for current test run
|
|
84
|
-
*
|
|
85
|
-
* Creates a unique directory under `packages/{packageName}/.test-output/{testType}/{runId}`
|
|
86
|
-
* where runId is `{timestamp}-{randomId}` to ensure isolation across parallel test runs.
|
|
87
|
-
*
|
|
88
|
-
* @param packageName - Name of package (e.g., 'rag-lancedb')
|
|
89
|
-
* @param testType - Type of test ('unit', 'integration', 'system')
|
|
90
|
-
* @param subdirs - Optional subdirectories to create within the test output directory
|
|
91
|
-
* @returns Absolute path to the created directory
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* ```typescript
|
|
95
|
-
* // Create isolated database directory for system tests
|
|
96
|
-
* const dbPath = getTestOutputDir('rag-lancedb', 'system', 'databases', 'test-db');
|
|
97
|
-
* // Result: packages/rag-lancedb/.test-output/system/20260105-143022-abc123/databases/test-db
|
|
98
|
-
*
|
|
99
|
-
* // Create temporary file directory for integration tests
|
|
100
|
-
* const tempDir = getTestOutputDir('agent-skills', 'integration', 'temp-files');
|
|
101
|
-
* // Result: packages/agent-skills/.test-output/integration/20260105-143022-def456/temp-files
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
export declare function getTestOutputDir(packageName: string, testType: 'unit' | 'integration' | 'system', ...subdirs: string[]): string;
|
|
105
|
-
/**
|
|
106
|
-
* Get the base test output directory for a package
|
|
107
|
-
* Useful for cleanup operations that need to remove all test output
|
|
108
|
-
*
|
|
109
|
-
* @param packageName - Name of package (e.g., 'rag-lancedb')
|
|
110
|
-
* @returns Absolute path to packages/{packageName}/.test-output
|
|
111
|
-
*
|
|
112
|
-
* @example
|
|
113
|
-
* ```typescript
|
|
114
|
-
* const baseDir = getTestOutputBase('rag-lancedb');
|
|
115
|
-
* // Result: packages/rag-lancedb/.test-output
|
|
116
|
-
* ```
|
|
117
|
-
*/
|
|
118
|
-
export declare function getTestOutputBase(packageName: string): string;
|
|
119
|
-
/**
|
|
120
|
-
* Per-suite temp directory pattern (async version)
|
|
121
|
-
* Creates a single temp directory for the entire test suite,
|
|
122
|
-
* with subdirectories for each test. This is 3-5x faster on Windows
|
|
123
|
-
* than creating a new mkdtemp for each test.
|
|
124
|
-
*
|
|
125
|
-
* @param prefix - Prefix for the suite temp directory name
|
|
126
|
-
* @param teardown - Forwarded to {@link removeScratchDir}. Raise `budgetMs` for a
|
|
127
|
-
* suite whose fixture tree is heavy or whose tier allows a longer hook than the
|
|
128
|
-
* unit tier this default is sized against — see {@link SCRATCH_REMOVAL_BUDGET_MS}.
|
|
129
|
-
* @returns Suite helper with beforeAll, afterAll, beforeEach, afterEach, and getTempDir
|
|
130
|
-
*
|
|
131
|
-
* @example
|
|
132
|
-
* ```typescript
|
|
133
|
-
* const suite = setupAsyncTempDirSuite('my-test');
|
|
134
|
-
*
|
|
135
|
-
* describe('my tests', () => {
|
|
136
|
-
* beforeAll(suite.beforeAll);
|
|
137
|
-
* afterAll(suite.afterAll);
|
|
138
|
-
* beforeEach(suite.beforeEach);
|
|
139
|
-
*
|
|
140
|
-
* it('test 1', async () => {
|
|
141
|
-
* const tempDir = suite.getTempDir();
|
|
142
|
-
* // Use tempDir...
|
|
143
|
-
* });
|
|
144
|
-
* });
|
|
145
|
-
* ```
|
|
146
|
-
*/
|
|
147
|
-
export declare function setupAsyncTempDirSuite(prefix: string, teardown?: RemoveScratchDirOptions): {
|
|
148
|
-
beforeAll: () => Promise<void>;
|
|
149
|
-
afterAll: () => Promise<void>;
|
|
150
|
-
beforeEach: () => Promise<void>;
|
|
151
|
-
afterEach: () => Promise<void>;
|
|
152
|
-
getTempDir: () => string;
|
|
153
|
-
};
|
|
154
|
-
/**
|
|
155
|
-
* Per-suite temp directory pattern (sync version)
|
|
156
|
-
* Creates a single temp directory for the entire test suite,
|
|
157
|
-
* with subdirectories for each test. This is 3-5x faster on Windows
|
|
158
|
-
* than creating a new mkdtemp for each test.
|
|
159
|
-
*
|
|
160
|
-
* @param prefix - Prefix for the suite temp directory name
|
|
161
|
-
* @param teardown - Forwarded to {@link removeScratchDir}. Raise `budgetMs` for a
|
|
162
|
-
* suite whose fixture tree is heavy or whose tier allows a longer hook than the
|
|
163
|
-
* unit tier this default is sized against — see {@link SCRATCH_REMOVAL_BUDGET_MS}.
|
|
164
|
-
* @returns Suite helper with beforeAll, afterAll, beforeEach, afterEach, and getTempDir
|
|
165
|
-
*
|
|
166
|
-
* @example
|
|
167
|
-
* ```typescript
|
|
168
|
-
* const suite = setupSyncTempDirSuite('my-test');
|
|
169
|
-
*
|
|
170
|
-
* describe('my tests', () => {
|
|
171
|
-
* beforeAll(suite.beforeAll);
|
|
172
|
-
* afterAll(suite.afterAll);
|
|
173
|
-
* beforeEach(suite.beforeEach);
|
|
174
|
-
*
|
|
175
|
-
* it('test 1', () => {
|
|
176
|
-
* const tempDir = suite.getTempDir();
|
|
177
|
-
* // Use tempDir...
|
|
178
|
-
* });
|
|
179
|
-
* });
|
|
180
|
-
* ```
|
|
181
|
-
*/
|
|
182
|
-
export declare function setupSyncTempDirSuite(prefix: string, teardown?: RemoveScratchDirOptions): {
|
|
183
|
-
beforeAll: () => void;
|
|
184
|
-
afterAll: () => Promise<void>;
|
|
185
|
-
beforeEach: () => void;
|
|
186
|
-
afterEach: () => void;
|
|
187
|
-
getTempDir: () => string;
|
|
188
|
-
};
|
|
189
1
|
declare const symlinkCapabilityBrand: unique symbol;
|
|
190
2
|
/**
|
|
191
3
|
* Proof that this process can create filesystem symlinks.
|
|
@@ -207,11 +19,17 @@ export type SymlinkCapability = {
|
|
|
207
19
|
* `SeCreateSymbolicLinkPrivilege`. That privilege lives on the process's
|
|
208
20
|
* security token, not on any one directory: it cannot change between calls
|
|
209
21
|
* within a single run, so probing it once and reusing the result is a
|
|
210
|
-
* memoization, not a shortcut that risks a stale answer. (
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
22
|
+
* memoization, not a shortcut that risks a stale answer. (A filesystem that
|
|
23
|
+
* itself has no symlinks — some network shares, some FAT variants — answers
|
|
24
|
+
* `ENOTSUP` and is read as the same "no"; every fixture in this repo creates
|
|
25
|
+
* its roots under {@link normalizedTmpdir}, so it never arises here.)
|
|
26
|
+
*
|
|
27
|
+
* Because the answer is memoized for the whole process, what reads as "no"
|
|
28
|
+
* matters more than usual: a `null` here silently `skip()`s every symlink test
|
|
29
|
+
* for the rest of the run. So ONLY {@link SYMLINK_UNSUPPORTED_ERRNOS} is a
|
|
30
|
+
* no. A tmpdir that is unwritable or missing, or a bug, is not an answer about
|
|
31
|
+
* symlinks at all and stays loud rather than becoming a process-wide skip for
|
|
32
|
+
* a reason nothing reported.
|
|
215
33
|
*
|
|
216
34
|
* Fixtures that depend on symlinks must ask rather than assume — and, having
|
|
217
35
|
* asked, must SAY they skipped. A symlink case that silently no-ops reads as
|
|
@@ -286,19 +104,44 @@ export declare const INHERITED_GIT_ENV: readonly ["GIT_ALTERNATE_OBJECT_DIRECTOR
|
|
|
286
104
|
* ```
|
|
287
105
|
*/
|
|
288
106
|
export declare function detachGitEnv(): () => void;
|
|
107
|
+
/**
|
|
108
|
+
* The errno-shaped error a refused `fs` call throws: a message, the `code`,
|
|
109
|
+
* and the `syscall`, exactly as Node shapes one.
|
|
110
|
+
*/
|
|
111
|
+
export declare function errnoError(code: string, syscall: string, target: string): NodeJS.ErrnoException;
|
|
112
|
+
/** The sync `node:fs` calls a refusal can be injected into. */
|
|
113
|
+
export type RefusableSyncFsMethod = 'readdirSync' | 'readFileSync' | 'statSync' | 'lstatSync' | 'realpathSync' | 'renameSync' | 'rmSync' | 'unlinkSync';
|
|
114
|
+
/** The `node:fs/promises` calls a refusal can be injected into. */
|
|
115
|
+
export type RefusableAsyncFsMethod = 'readdir' | 'readFile' | 'stat' | 'lstat' | 'access';
|
|
116
|
+
/**
|
|
117
|
+
* Make `fs[method]` throw `code` for exactly `targetPath` until the returned
|
|
118
|
+
* restore is called; every other path, and every other method, stays real.
|
|
119
|
+
*
|
|
120
|
+
* A patch rather than a `chmod`: `chmod` reaches one errno (`EACCES`), only
|
|
121
|
+
* where POSIX modes bind, and not as root — and the property under test is
|
|
122
|
+
* "any refusal that is not an absence", so `EACCES`, `ELOOP`, `EMFILE` must all
|
|
123
|
+
* be reachable. What a walk under test meets is ONE refused call inside an
|
|
124
|
+
* otherwise ordinary tree; a walk that gave up entirely would pass a test where
|
|
125
|
+
* everything was refused.
|
|
126
|
+
*
|
|
127
|
+
* Lives in the shipped helpers because consumers in five packages each need to
|
|
128
|
+
* refuse a call, and the duplication gate refuses five copies.
|
|
129
|
+
*/
|
|
130
|
+
export declare function refuseSyncFs(method: RefusableSyncFsMethod, targetPath: string, code: string): () => void;
|
|
131
|
+
/**
|
|
132
|
+
* `fs/promises[method]` rejects with `code` for exactly `targetPath` until the
|
|
133
|
+
* returned restore is called; every other path, and every other method, is real.
|
|
134
|
+
*/
|
|
135
|
+
export declare function refuseAsyncFs(method: RefusableAsyncFsMethod, targetPath: string, code: string): () => void;
|
|
136
|
+
/**
|
|
137
|
+
* Run `body` while `fs[method]` throws `code` for exactly `targetPath`; the
|
|
138
|
+
* patch is lifted however `body` exits. See {@link refuseSyncFs}.
|
|
139
|
+
*/
|
|
140
|
+
export declare function withSyncFsRefused<T>(method: RefusableSyncFsMethod, targetPath: string, code: string, body: () => T | Promise<T>): Promise<T>;
|
|
289
141
|
/**
|
|
290
142
|
* Run `body` with `fs.readdirSync` of exactly `directory` throwing an error
|
|
291
|
-
* carrying errno `code`.
|
|
292
|
-
*
|
|
293
|
-
* a walk that gave up entirely would pass a test where everything was refused.
|
|
294
|
-
*
|
|
295
|
-
* A patch rather than a `chmod`, for the reason the promise-API twin in
|
|
296
|
-
* `resources/test/helpers/refused-listing.ts` gives: `chmod` reaches one errno
|
|
297
|
-
* (`EACCES`), only where POSIX modes bind, and not as root. The mapping under
|
|
298
|
-
* test is "anything that is not an absence errno", and `EMFILE` / `ENFILE` /
|
|
299
|
-
* `ELOOP` are just as reachable in ordinary operation. This one lives in the
|
|
300
|
-
* shipped helpers because the sync crawler has consumers in three packages that
|
|
301
|
-
* each need to refuse a listing, and the duplication gate refuses three copies.
|
|
143
|
+
* carrying errno `code`. The listing case of {@link withSyncFsRefused}, named
|
|
144
|
+
* because refusing a LISTING is the question the crawler's consumers ask.
|
|
302
145
|
*
|
|
303
146
|
* @param directory - Absolute path of the one directory to refuse
|
|
304
147
|
* @param code - The errno to reject with
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../src/test-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../src/test-helpers.ts"],"names":[],"mappings":"AAQA,OAAO,CAAC,MAAM,sBAAsB,EAAE,OAAO,MAAM,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,CAAC,CAAC,sBAAsB,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAe5E;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,IAAI,iBAAiB,GAAG,IAAI,CAwB5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,UAAU,GACjC,IAAI,CAEN;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,UAAU,GACjC,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,yUAgBpB,CAAC;AAEX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,IAAI,MAAM,IAAI,CAoBzC;AAGD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,cAAc,CAE/F;AAED,+DAA+D;AAC/D,MAAM,MAAM,qBAAqB,GAC7B,aAAa,GACb,cAAc,GACd,UAAU,GACV,WAAW,GACX,cAAc,GACd,YAAY,GACZ,QAAQ,GACR,YAAY,CAAC;AAEjB,mEAAmE;AACnE,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAiB1F;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,IAAI,CAQxG;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,IAAI,CAQ1G;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,MAAM,EAAE,qBAAqB,EAC7B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAOZ;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAEZ"}
|