@vibe-agent-toolkit/utils 0.2.0-rc.1 → 0.2.0-rc.10
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 +69 -23
- package/dist/asset-reference.js +3 -11
- package/dist/asset-reference.js.map +1 -1
- package/dist/compare-code-units.d.ts +28 -0
- package/dist/compare-code-units.d.ts.map +1 -0
- package/dist/compare-code-units.js +33 -0
- package/dist/compare-code-units.js.map +1 -0
- package/dist/crawl-timing.d.ts +657 -0
- package/dist/crawl-timing.d.ts.map +1 -0
- package/dist/crawl-timing.js +765 -0
- package/dist/crawl-timing.js.map +1 -0
- package/dist/crawl.d.ts +2 -4
- package/dist/crawl.d.ts.map +1 -1
- package/dist/crawl.js +2 -4
- package/dist/crawl.js.map +1 -1
- 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/entrypoint.d.ts +54 -0
- package/dist/entrypoint.d.ts.map +1 -0
- package/dist/entrypoint.js +71 -0
- package/dist/entrypoint.js.map +1 -0
- package/dist/env-flag.d.ts +51 -0
- package/dist/env-flag.d.ts.map +1 -0
- package/dist/env-flag.js +62 -0
- package/dist/env-flag.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.d.ts +60 -0
- package/dist/file-crawler.d.ts.map +1 -1
- package/dist/file-crawler.js +133 -29
- 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 +422 -191
- package/dist/fs-utils.d.ts.map +1 -1
- package/dist/fs-utils.js +534 -204
- package/dist/fs-utils.js.map +1 -1
- package/dist/fs.d.ts +5 -2
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +9 -7
- package/dist/fs.js.map +1 -1
- package/dist/git-run.d.ts +167 -0
- package/dist/git-run.d.ts.map +1 -0
- package/dist/git-run.js +154 -0
- package/dist/git-run.js.map +1 -0
- package/dist/git-snapshot.d.ts +199 -0
- package/dist/git-snapshot.d.ts.map +1 -0
- package/dist/git-snapshot.js +250 -0
- package/dist/git-snapshot.js.map +1 -0
- package/dist/git-tracker.d.ts +166 -3
- package/dist/git-tracker.d.ts.map +1 -1
- package/dist/git-tracker.js +250 -22
- package/dist/git-tracker.js.map +1 -1
- package/dist/git-utils.d.ts +84 -1
- package/dist/git-utils.d.ts.map +1 -1
- package/dist/git-utils.js +208 -82
- package/dist/git-utils.js.map +1 -1
- package/dist/git.d.ts +13 -4
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +12 -4
- package/dist/git.js.map +1 -1
- package/dist/gitignore-checker.d.ts.map +1 -1
- package/dist/gitignore-checker.js +15 -6
- package/dist/gitignore-checker.js.map +1 -1
- package/dist/glob/glob-pattern.js +5 -5
- package/dist/glob/glob-pattern.js.map +1 -1
- package/dist/index.d.ts +32 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +95 -50
- package/dist/index.js.map +1 -1
- package/dist/listing-refusal.d.ts +112 -0
- package/dist/listing-refusal.d.ts.map +1 -0
- package/dist/listing-refusal.js +105 -0
- package/dist/listing-refusal.js.map +1 -0
- 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 +113 -18
- package/dist/path-core.d.ts.map +1 -1
- package/dist/path-core.js +139 -23
- 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/process.d.ts +7 -0
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +7 -0
- package/dist/process.js.map +1 -1
- package/dist/project-utils.d.ts.map +1 -1
- package/dist/project-utils.js +15 -9
- package/dist/project-utils.js.map +1 -1
- package/dist/project.d.ts +7 -5
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +7 -5
- package/dist/project.js.map +1 -1
- package/dist/safe-exec.d.ts +40 -11
- package/dist/safe-exec.d.ts.map +1 -1
- package/dist/safe-exec.js +111 -25
- 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/index.d.ts +1 -1
- package/dist/skill-test/index.d.ts.map +1 -1
- package/dist/skill-test/index.js +1 -1
- package/dist/skill-test/index.js.map +1 -1
- package/dist/skill-test/spawn-claude.d.ts +30 -1
- package/dist/skill-test/spawn-claude.d.ts.map +1 -1
- package/dist/skill-test/spawn-claude.js +71 -5
- package/dist/skill-test/spawn-claude.js.map +1 -1
- package/dist/skill-test/transcript.d.ts +41 -2
- package/dist/skill-test/transcript.d.ts.map +1 -1
- package/dist/skill-test/transcript.js +55 -10
- package/dist/skill-test/transcript.js.map +1 -1
- package/dist/spawn-hardened.js +0 -1
- package/dist/spawn-hardened.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 +135 -100
- package/dist/test-helpers.d.ts.map +1 -1
- package/dist/test-helpers.js +224 -146
- 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 +94 -3
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +119 -3
- package/dist/testing.js.map +1 -1
- package/dist/text-content.d.ts +197 -0
- package/dist/text-content.d.ts.map +1 -0
- package/dist/text-content.js +354 -0
- package/dist/text-content.js.map +1 -0
- package/dist/text-file.d.ts +45 -0
- package/dist/text-file.d.ts.map +1 -0
- package/dist/text-file.js +51 -0
- package/dist/text-file.js.map +1 -0
- package/dist/text.d.ts +16 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +16 -0
- package/dist/text.js.map +1 -0
- package/dist/timing-dump.d.ts +136 -0
- package/dist/timing-dump.d.ts.map +1 -0
- package/dist/timing-dump.js +229 -0
- package/dist/timing-dump.js.map +1 -0
- 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 +223 -49
- package/eslint/index.cjs +111 -97
- package/eslint/index.d.cts +16 -6
- 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 +2 -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 +213 -0
- 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 +217 -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 +228 -0
- 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 +29 -18
- package/eslint/rules/no-io-in-unit-tier.cjs +129 -0
- package/eslint/rules/no-literal-process-exit.cjs +129 -0
- package/eslint/rules/no-manual-path-normalize.cjs +136 -107
- 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 +127 -0
- package/eslint/rules/no-raw-node-path.cjs +563 -0
- package/eslint/rules/no-raw-text-decode.cjs +305 -0
- package/eslint/rules/no-registry-count-pin.cjs +255 -0
- package/eslint/rules/no-self-package-import.cjs +168 -0
- 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 +16 -16
- package/dist/link-auth/build-headers.d.ts +0 -34
- package/dist/link-auth/build-headers.d.ts.map +0 -1
- package/dist/link-auth/build-headers.js +0 -58
- package/dist/link-auth/build-headers.js.map +0 -1
- package/dist/link-auth/expand-macro.d.ts +0 -38
- package/dist/link-auth/expand-macro.d.ts.map +0 -1
- package/dist/link-auth/expand-macro.js +0 -133
- package/dist/link-auth/expand-macro.js.map +0 -1
- package/dist/link-auth/macros.yaml +0 -50
- package/dist/link-auth/resolve-token.d.ts +0 -83
- package/dist/link-auth/resolve-token.d.ts.map +0 -1
- package/dist/link-auth/resolve-token.js +0 -101
- package/dist/link-auth/resolve-token.js.map +0 -1
- package/dist/link-auth/resolve.d.ts +0 -102
- package/dist/link-auth/resolve.d.ts.map +0 -1
- package/dist/link-auth/resolve.js +0 -66
- package/dist/link-auth/resolve.js.map +0 -1
- package/dist/link-auth/rewrite.d.ts +0 -52
- package/dist/link-auth/rewrite.d.ts.map +0 -1
- package/dist/link-auth/rewrite.js +0 -102
- package/dist/link-auth/rewrite.js.map +0 -1
- package/dist/link-auth/select-provider.d.ts +0 -30
- package/dist/link-auth/select-provider.d.ts.map +0 -1
- package/dist/link-auth/select-provider.js +0 -55
- package/dist/link-auth/select-provider.js.map +0 -1
- package/dist/link-auth/template.d.ts +0 -40
- package/dist/link-auth/template.d.ts.map +0 -1
- package/dist/link-auth/template.js +0 -89
- package/dist/link-auth/template.js.map +0 -1
- package/dist/link-auth/transforms.d.ts +0 -46
- package/dist/link-auth/transforms.d.ts.map +0 -1
- package/dist/link-auth/transforms.js +0 -52
- package/dist/link-auth/transforms.js.map +0 -1
- package/dist/template-entry.d.ts +0 -10
- package/dist/template-entry.d.ts.map +0 -1
- package/dist/template-entry.js +0 -10
- package/dist/template-entry.js.map +0 -1
- package/dist/template.d.ts +0 -7
- package/dist/template.d.ts.map +0 -1
- package/dist/template.js +0 -18
- package/dist/template.js.map +0 -1
- 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,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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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { applyDeclaredEnv, buildForwardedEnv, formatForwardedEnvLine, protectedEnvNames, type DeclaredEnvInput, type DeclaredEnvResult, type ForwardEnvOptions, } from './env-scrub.js';
|
|
1
|
+
export { applyDeclaredEnv, buildForwardedEnv, formatForwardedEnvLine, isProtectedName, protectedEnvNames, type DeclaredEnvInput, type DeclaredEnvResult, type ForwardEnvOptions, } from './env-scrub.js';
|
|
2
2
|
export { AuthPreflightError, probeAuthStatus, resolveAuth, type AuthMechanism, type AuthMode, type AuthStatusProbe, type AuthStatusResult, type ResolveAuthOptions, type ResolvedAuth, } from './auth-resolver.js';
|
|
3
3
|
export { assembleClaudeArgs, killAllActiveClaudeChildren, spawnHeadlessClaude, type ClaudeSpawnArgs, type SpawnHeadlessOptions, type SpawnResult, } from './spawn-claude.js';
|
|
4
4
|
export { detectInvocationFromTranscript, parseStreamJsonTranscript, type ParsedTranscript, } from './transcript.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skill-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,WAAW,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skill-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,WAAW,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC"}
|
package/dist/skill-test/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { applyDeclaredEnv, buildForwardedEnv, formatForwardedEnvLine, protectedEnvNames, } from './env-scrub.js';
|
|
1
|
+
export { applyDeclaredEnv, buildForwardedEnv, formatForwardedEnvLine, isProtectedName, protectedEnvNames, } from './env-scrub.js';
|
|
2
2
|
export { AuthPreflightError, probeAuthStatus, resolveAuth, } from './auth-resolver.js';
|
|
3
3
|
export { assembleClaudeArgs, killAllActiveClaudeChildren, spawnHeadlessClaude, } from './spawn-claude.js';
|
|
4
4
|
export { detectInvocationFromTranscript, parseStreamJsonTranscript, } from './transcript.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skill-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,GAIlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,WAAW,GAOZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,GAIpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,GAE1B,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skill-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,EACf,iBAAiB,GAIlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,WAAW,GAOZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,GAIpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,GAE1B,MAAM,iBAAiB,CAAC"}
|
|
@@ -11,6 +11,34 @@ export interface ClaudeSpawnArgs {
|
|
|
11
11
|
* `--prompt-file` flag — the prompt is fed to the child's stdin by
|
|
12
12
|
* {@link spawnHeadlessClaude} instead. `--setting-sources ""` suppresses
|
|
13
13
|
* user/project settings; built-in skills remain (§5).
|
|
14
|
+
*
|
|
15
|
+
* `--no-session-persistence` is load-bearing for the harness's integrity model,
|
|
16
|
+
* not a tidiness flag. Claude Code otherwise writes every headless session to
|
|
17
|
+
* `$CLAUDE_CONFIG_DIR/projects/<cwd-slug>/<uuid>.jsonl` — plaintext, mode 0600,
|
|
18
|
+
* retained indefinitely — and `CLAUDE_CONFIG_DIR` and `HOME` are both forwarded
|
|
19
|
+
* to the child (they have to be: that is where auth lives). That file falsifies
|
|
20
|
+
* three of the harness's stated guarantees at once:
|
|
21
|
+
*
|
|
22
|
+
* - the per-run grading NONCE, which {@link SpawnHeadlessOptions.prompt} keeps
|
|
23
|
+
* off disk precisely so untrusted skill code cannot read it back and forge a
|
|
24
|
+
* passing grading.json — the grader's own session file contains it verbatim;
|
|
25
|
+
* - the eval ANSWER KEY (`expected_output`), which `eval-suite-isolation.ts`
|
|
26
|
+
* exists solely to keep off the executor's filesystem;
|
|
27
|
+
* - the `--baseline` control, which could read the treatment arm's entire
|
|
28
|
+
* session by listing `projects/` for its slug.
|
|
29
|
+
*
|
|
30
|
+
* And it leaks ACROSS runs: a transcript from one run is still readable weeks
|
|
31
|
+
* later by the next run's executor, so no per-run randomness helps.
|
|
32
|
+
*
|
|
33
|
+
* VERIFIED on macOS with claude 2.x, both directions: without the flag one
|
|
34
|
+
* `.jsonl` lands under the config dir per spawn; with it, zero, and the session
|
|
35
|
+
* still authenticates. It is `--print`-only, which is exactly this spawn's shape.
|
|
36
|
+
*
|
|
37
|
+
* 🪤 An ephemeral per-spawn `CLAUDE_CONFIG_DIR` — the obvious alternative — does
|
|
38
|
+
* NOT work: on macOS the subscription credential is a Keychain item whose service
|
|
39
|
+
* name is derived from the config-dir PATH, so a fresh dir reports "Not logged
|
|
40
|
+
* in" even with the real `.claude.json` copied in (verified). Materializing the
|
|
41
|
+
* token into a dir the executor can read would be strictly worse than the leak.
|
|
14
42
|
*/
|
|
15
43
|
export declare function assembleClaudeArgs(opts: ClaudeSpawnArgs): string[];
|
|
16
44
|
export interface SpawnResult {
|
|
@@ -25,7 +53,8 @@ export interface SpawnResult {
|
|
|
25
53
|
* orphaned MCP subprocesses that a direct `child.kill()` would leave running.
|
|
26
54
|
*
|
|
27
55
|
* - Guards an undefined pid (child never spawned — nothing to kill).
|
|
28
|
-
* -
|
|
56
|
+
* - Absorbs the throw that means the group is already gone (see
|
|
57
|
+
* {@link isProcessGroupGone}); anything else stays loud.
|
|
29
58
|
* - Windows has no POSIX process groups: fall back to `taskkill /T /F`, which
|
|
30
59
|
* terminates the whole process tree.
|
|
31
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
|
|
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"}
|
|
@@ -7,6 +7,34 @@ import { spawnHardened } from '../spawn-hardened.js';
|
|
|
7
7
|
* `--prompt-file` flag — the prompt is fed to the child's stdin by
|
|
8
8
|
* {@link spawnHeadlessClaude} instead. `--setting-sources ""` suppresses
|
|
9
9
|
* user/project settings; built-in skills remain (§5).
|
|
10
|
+
*
|
|
11
|
+
* `--no-session-persistence` is load-bearing for the harness's integrity model,
|
|
12
|
+
* not a tidiness flag. Claude Code otherwise writes every headless session to
|
|
13
|
+
* `$CLAUDE_CONFIG_DIR/projects/<cwd-slug>/<uuid>.jsonl` — plaintext, mode 0600,
|
|
14
|
+
* retained indefinitely — and `CLAUDE_CONFIG_DIR` and `HOME` are both forwarded
|
|
15
|
+
* to the child (they have to be: that is where auth lives). That file falsifies
|
|
16
|
+
* three of the harness's stated guarantees at once:
|
|
17
|
+
*
|
|
18
|
+
* - the per-run grading NONCE, which {@link SpawnHeadlessOptions.prompt} keeps
|
|
19
|
+
* off disk precisely so untrusted skill code cannot read it back and forge a
|
|
20
|
+
* passing grading.json — the grader's own session file contains it verbatim;
|
|
21
|
+
* - the eval ANSWER KEY (`expected_output`), which `eval-suite-isolation.ts`
|
|
22
|
+
* exists solely to keep off the executor's filesystem;
|
|
23
|
+
* - the `--baseline` control, which could read the treatment arm's entire
|
|
24
|
+
* session by listing `projects/` for its slug.
|
|
25
|
+
*
|
|
26
|
+
* And it leaks ACROSS runs: a transcript from one run is still readable weeks
|
|
27
|
+
* later by the next run's executor, so no per-run randomness helps.
|
|
28
|
+
*
|
|
29
|
+
* VERIFIED on macOS with claude 2.x, both directions: without the flag one
|
|
30
|
+
* `.jsonl` lands under the config dir per spawn; with it, zero, and the session
|
|
31
|
+
* still authenticates. It is `--print`-only, which is exactly this spawn's shape.
|
|
32
|
+
*
|
|
33
|
+
* 🪤 An ephemeral per-spawn `CLAUDE_CONFIG_DIR` — the obvious alternative — does
|
|
34
|
+
* NOT work: on macOS the subscription credential is a Keychain item whose service
|
|
35
|
+
* name is derived from the config-dir PATH, so a fresh dir reports "Not logged
|
|
36
|
+
* in" even with the real `.claude.json` copied in (verified). Materializing the
|
|
37
|
+
* token into a dir the executor can read would be strictly worse than the leak.
|
|
10
38
|
*/
|
|
11
39
|
export function assembleClaudeArgs(opts) {
|
|
12
40
|
const args = [
|
|
@@ -17,6 +45,7 @@ export function assembleClaudeArgs(opts) {
|
|
|
17
45
|
'--output-format', 'stream-json',
|
|
18
46
|
'--verbose',
|
|
19
47
|
'--setting-sources', '',
|
|
48
|
+
'--no-session-persistence',
|
|
20
49
|
'--permission-mode', 'bypassPermissions',
|
|
21
50
|
'--add-dir', opts.sandboxDir,
|
|
22
51
|
];
|
|
@@ -38,7 +67,8 @@ export function assembleClaudeArgs(opts) {
|
|
|
38
67
|
* orphaned MCP subprocesses that a direct `child.kill()` would leave running.
|
|
39
68
|
*
|
|
40
69
|
* - Guards an undefined pid (child never spawned — nothing to kill).
|
|
41
|
-
* -
|
|
70
|
+
* - Absorbs the throw that means the group is already gone (see
|
|
71
|
+
* {@link isProcessGroupGone}); anything else stays loud.
|
|
42
72
|
* - Windows has no POSIX process groups: fall back to `taskkill /T /F`, which
|
|
43
73
|
* terminates the whole process tree.
|
|
44
74
|
*/
|
|
@@ -56,10 +86,26 @@ export function killProcessTree(child) {
|
|
|
56
86
|
process.kill(-pid, 'SIGKILL');
|
|
57
87
|
}
|
|
58
88
|
}
|
|
59
|
-
catch {
|
|
60
|
-
//
|
|
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;
|
|
61
96
|
}
|
|
62
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
|
+
}
|
|
63
109
|
/**
|
|
64
110
|
* Registry of currently in-flight `claude` child processes, keyed by the
|
|
65
111
|
* `ChildProcess` object itself. A child is registered immediately after
|
|
@@ -119,6 +165,24 @@ export async function spawnHeadlessClaude(opts) {
|
|
|
119
165
|
// Register immediately after spawn so the child is reapable by
|
|
120
166
|
// killAllActiveClaudeChildren() for the entire time it can be in flight.
|
|
121
167
|
activeClaudeChildren.add(child);
|
|
168
|
+
// Decode BOTH output streams as UTF-8 at the stream, not per chunk.
|
|
169
|
+
//
|
|
170
|
+
// A pipe hands the reader whatever bytes have arrived (typically capped at
|
|
171
|
+
// 64 KiB) with no regard for character boundaries, so `chunk.toString()` on
|
|
172
|
+
// each Buffer independently mangles any multi-byte character that straddles a
|
|
173
|
+
// boundary into replacement characters on both sides of the split. That
|
|
174
|
+
// corruption lands INSIDE a stream-json line, and it costs the harness
|
|
175
|
+
// evidence two ways: the line can stop parsing, silently deleting the tool
|
|
176
|
+
// call in it (see ParsedTranscript.malformedLineCount), or — worse, because
|
|
177
|
+
// nothing reports it — the line still parses with a mangled VALUE, so a
|
|
178
|
+
// contamination needle no longer matches the path the arm actually reached.
|
|
179
|
+
//
|
|
180
|
+
// `setEncoding` runs the stream's own StringDecoder, which holds a partial
|
|
181
|
+
// sequence back until the rest arrives AND flushes whatever is left at EOF, so
|
|
182
|
+
// a genuinely truncated tail still surfaces (as U+FFFD) rather than vanishing.
|
|
183
|
+
// Set before any listener is attached, so no chunk is ever seen undecoded.
|
|
184
|
+
child.stdout.setEncoding('utf8');
|
|
185
|
+
child.stderr.setEncoding('utf8');
|
|
122
186
|
let timedOut = false;
|
|
123
187
|
let stalled = false;
|
|
124
188
|
// Feed the prompt to the child via stdin (claude 2.x has no --prompt-file).
|
|
@@ -170,8 +234,10 @@ export async function spawnHeadlessClaude(opts) {
|
|
|
170
234
|
// child's real exit status).
|
|
171
235
|
child.stdin.on('error', () => { });
|
|
172
236
|
promptStream.pipe(child.stdin);
|
|
173
|
-
|
|
174
|
-
|
|
237
|
+
// `d` is already a string: setEncoding('utf8') above put the stream's
|
|
238
|
+
// StringDecoder in front of these listeners. Never call `.toString()` here.
|
|
239
|
+
child.stdout.on('data', (d) => { opts.onStdout?.(d); });
|
|
240
|
+
child.stderr.on('data', (d) => { opts.onStderr?.(d); });
|
|
175
241
|
// Reap on 'error' too: clearAllTimers() unregisters the child, so if 'error'
|
|
176
242
|
// ever fires while the process is actually alive we would otherwise drop it
|
|
177
243
|
// from the reap set without killing it (the exact orphan this file guards
|
|
@@ -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
|
|
1
|
+
{"version":3,"file":"spawn-claude.js","sourceRoot":"","sources":["../../src/skill-test/spawn-claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
*
|
|
6
6
|
* The stream-json schema is informally documented and may shift between
|
|
7
7
|
* Claude Code releases. This parser is intentionally tolerant of unknown
|
|
8
|
-
* event kinds —
|
|
8
|
+
* event kinds — an event whose `type` we do not recognise is simply not
|
|
9
|
+
* consumed. Tolerance stops at unknown SHAPES: a line that is not JSON at all is
|
|
10
|
+
* counted into {@link ParsedTranscript.malformedLineCount}, because that is data
|
|
11
|
+
* loss, not forward compatibility.
|
|
9
12
|
*
|
|
10
13
|
* Shape notes (empirically verified):
|
|
11
14
|
* - `tool_use` content blocks carry `input.command` for Bash calls.
|
|
@@ -23,11 +26,40 @@ export interface ParsedTranscript {
|
|
|
23
26
|
inputSummary: string;
|
|
24
27
|
}>;
|
|
25
28
|
errors: string[];
|
|
26
|
-
|
|
29
|
+
/**
|
|
30
|
+
* How many non-empty lines failed `JSON.parse` and were therefore NOT consumed.
|
|
31
|
+
*
|
|
32
|
+
* This is the only thing that distinguishes "parsed fine, nothing found" from
|
|
33
|
+
* "we lost the evidence". A corrupted line drops its whole event — the tool call
|
|
34
|
+
* in it, and any contamination it proves — while every other line, including the
|
|
35
|
+
* terminal `result`, still parses. Every downstream "did this transcript decode?"
|
|
36
|
+
* test is an any-of over the populated fields, so the surviving `result` line on
|
|
37
|
+
* its own certifies the transcript as decoded and the loss goes unremarked.
|
|
38
|
+
*
|
|
39
|
+
* Non-zero means the scan that consumed this transcript ran on less than the
|
|
40
|
+
* whole transcript and its verdict must be reported as DEGRADED, never clean.
|
|
41
|
+
* Zero is a positive statement, not an absence: every line was accounted for.
|
|
42
|
+
*/
|
|
43
|
+
malformedLineCount: number;
|
|
27
44
|
toolUses: Array<{
|
|
28
45
|
id: string | null;
|
|
29
46
|
name: string;
|
|
30
47
|
command?: string;
|
|
48
|
+
/**
|
|
49
|
+
* The FULL, unsummarized tool input.
|
|
50
|
+
*
|
|
51
|
+
* `inputSummary` beside it is truncated to 200 characters by
|
|
52
|
+
* {@link summarizeValue}, which is fine for an observation record a human
|
|
53
|
+
* skims and useless for anything that has to REASON about what the call did
|
|
54
|
+
* — a path 200 characters into a `Read` input simply is not there. The
|
|
55
|
+
* baseline-integrity detector walks tool inputs to decide whether the
|
|
56
|
+
* skill-absent arm reached the skill, so it needs the whole value; the
|
|
57
|
+
* summary stays for the consumers that only ever display it.
|
|
58
|
+
*
|
|
59
|
+
* `unknown` because the shape is per-tool and informally documented — every
|
|
60
|
+
* consumer narrows it itself rather than trusting a type we invented.
|
|
61
|
+
*/
|
|
62
|
+
input: unknown;
|
|
31
63
|
inputSummary: string;
|
|
32
64
|
parentToolUseId: string | null;
|
|
33
65
|
}>;
|
|
@@ -35,6 +67,13 @@ export interface ParsedTranscript {
|
|
|
35
67
|
toolUseId: string | null;
|
|
36
68
|
isError: boolean;
|
|
37
69
|
contentSummary: string;
|
|
70
|
+
/**
|
|
71
|
+
* The FULL tool result, flattened to text. Same reason as `input` above:
|
|
72
|
+
* `contentSummary` is truncated to 200 characters, so scanning a tool RESULT
|
|
73
|
+
* for evidence (a file's contents echoed back, a grep hit line) cannot be
|
|
74
|
+
* done through it. Never truncated — the caller bounds what it keeps.
|
|
75
|
+
*/
|
|
76
|
+
content: string;
|
|
38
77
|
}>;
|
|
39
78
|
result?: {
|
|
40
79
|
subtype?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.d.ts","sourceRoot":"","sources":["../../src/skill-test/transcript.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
*
|
|
6
6
|
* The stream-json schema is informally documented and may shift between
|
|
7
7
|
* Claude Code releases. This parser is intentionally tolerant of unknown
|
|
8
|
-
* event kinds —
|
|
8
|
+
* event kinds — an event whose `type` we do not recognise is simply not
|
|
9
|
+
* consumed. Tolerance stops at unknown SHAPES: a line that is not JSON at all is
|
|
10
|
+
* counted into {@link ParsedTranscript.malformedLineCount}, because that is data
|
|
11
|
+
* loss, not forward compatibility.
|
|
9
12
|
*
|
|
10
13
|
* Shape notes (empirically verified):
|
|
11
14
|
* - `tool_use` content blocks carry `input.command` for Bash calls.
|
|
@@ -16,14 +19,48 @@
|
|
|
16
19
|
* - The terminal `result` event carries `subtype`, `is_error`, `num_turns`,
|
|
17
20
|
* and `total_cost_usd`.
|
|
18
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
|
+
*/
|
|
19
30
|
function summarizeValue(value) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
const json = stringifyValue(value);
|
|
32
|
+
return json.length > 200 ? `${json.slice(0, 197)}...` : json;
|
|
33
|
+
}
|
|
34
|
+
function stringifyValue(value) {
|
|
35
|
+
return JSON.stringify(value) ?? '';
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Flatten a `tool_result` `content` field to plain text, WITHOUT truncating.
|
|
39
|
+
*
|
|
40
|
+
* Three shapes occur in practice: a bare string (most Bash results), an array of
|
|
41
|
+
* content blocks (`{type:'text',text}` and friends), and — for a tool that
|
|
42
|
+
* returns structured data — an arbitrary object. The array case is the one that
|
|
43
|
+
* matters: `JSON.stringify` of it would bury the text behind escaped quotes, and
|
|
44
|
+
* a consumer scanning for a verbatim sentence would never find it.
|
|
45
|
+
*/
|
|
46
|
+
function contentToText(value) {
|
|
47
|
+
if (typeof value === 'string')
|
|
48
|
+
return value;
|
|
49
|
+
if (Array.isArray(value))
|
|
50
|
+
return value.map((block) => contentBlockToText(block)).join('\n');
|
|
51
|
+
if (value === undefined || value === null)
|
|
52
|
+
return '';
|
|
53
|
+
return stringifyValue(value);
|
|
54
|
+
}
|
|
55
|
+
function contentBlockToText(block) {
|
|
56
|
+
if (typeof block === 'string')
|
|
57
|
+
return block;
|
|
58
|
+
if (block !== null && typeof block === 'object') {
|
|
59
|
+
const { text } = block;
|
|
60
|
+
if (typeof text === 'string')
|
|
61
|
+
return text;
|
|
26
62
|
}
|
|
63
|
+
return stringifyValue(block);
|
|
27
64
|
}
|
|
28
65
|
function extractCommand(input) {
|
|
29
66
|
if (input !== null && typeof input === 'object' && typeof input.command === 'string') {
|
|
@@ -44,6 +81,7 @@ function consumeAssistantBlocks(blocks, parentToolUseId, out) {
|
|
|
44
81
|
id: typeof block.id === 'string' ? block.id : null,
|
|
45
82
|
name: block.name,
|
|
46
83
|
...(command === undefined ? {} : { command }),
|
|
84
|
+
input: block.input,
|
|
47
85
|
inputSummary,
|
|
48
86
|
parentToolUseId,
|
|
49
87
|
});
|
|
@@ -57,6 +95,7 @@ function consumeUserBlocks(blocks, out) {
|
|
|
57
95
|
toolUseId: typeof block.tool_use_id === 'string' ? block.tool_use_id : null,
|
|
58
96
|
isError: block.is_error === true,
|
|
59
97
|
contentSummary: summarizeValue(block.content),
|
|
98
|
+
content: contentToText(block.content),
|
|
60
99
|
});
|
|
61
100
|
}
|
|
62
101
|
}
|
|
@@ -114,22 +153,28 @@ export function parseStreamJsonTranscript(streamText) {
|
|
|
114
153
|
text: '',
|
|
115
154
|
toolUseEvents: [],
|
|
116
155
|
errors: [],
|
|
117
|
-
raw: [],
|
|
118
156
|
toolUses: [],
|
|
119
157
|
toolResults: [],
|
|
120
158
|
rateLimited: false,
|
|
159
|
+
malformedLineCount: 0,
|
|
121
160
|
};
|
|
122
161
|
const lines = streamText.split('\n');
|
|
123
162
|
for (const line of lines) {
|
|
124
163
|
const trimmed = line.trim();
|
|
125
164
|
if (trimmed.length === 0)
|
|
126
165
|
continue;
|
|
127
|
-
out.raw.push(trimmed);
|
|
128
166
|
let parsed;
|
|
129
167
|
try {
|
|
130
168
|
parsed = JSON.parse(trimmed);
|
|
131
169
|
}
|
|
132
|
-
catch {
|
|
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;
|
|
177
|
+
out.malformedLineCount += 1;
|
|
133
178
|
continue;
|
|
134
179
|
}
|
|
135
180
|
applyEvent(parsed, out);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/skill-test/transcript.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/skill-test/transcript.ts"],"names":[],"mappings":"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"}
|
package/dist/spawn-hardened.js
CHANGED
|
@@ -28,7 +28,6 @@ export function spawnHardened(command, args, options = {}) {
|
|
|
28
28
|
// Windows shell path (.cmd/.bat/.ps1). Token selection is shared with the sync
|
|
29
29
|
// `safeExecSync` path so the two cannot drift — see `resolveShellCommandToken`.
|
|
30
30
|
const shellLine = buildWindowsShellLine(resolveShellCommandToken(command, resolved), args);
|
|
31
|
-
// eslint-disable-next-line sonarjs/os-command -- Windows DEP0190 workaround: command is a PATH-resolved bare name or an explicit path; args are per-arg shell-quoted via windowsShellQuote()
|
|
32
31
|
return spawn(shellLine, { ...options, shell: true });
|
|
33
32
|
}
|
|
34
33
|
//# sourceMappingURL=spawn-hardened.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn-hardened.js","sourceRoot":"","sources":["../src/spawn-hardened.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAwC,MAAM,oBAAoB,CAAC;AAEjF,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,wBAAwB,EACxB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,IAAc,EACd,UAAwB,EAAE;IAE1B,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAErE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,+EAA+E;IAC/E,gFAAgF;IAChF,MAAM,SAAS,GAAG,qBAAqB,CAAC,wBAAwB,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"spawn-hardened.js","sourceRoot":"","sources":["../src/spawn-hardened.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAwC,MAAM,oBAAoB,CAAC;AAEjF,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,wBAAwB,EACxB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,IAAc,EACd,UAAwB,EAAE;IAE1B,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAErE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,+EAA+E;IAC/E,gFAAgF;IAChF,MAAM,SAAS,GAAG,qBAAqB,CAAC,wBAAwB,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;IAE3F,OAAO,KAAK,CAAC,SAAS,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC"}
|
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"}
|