Merge remote-tracking branch 'origin/main' into garrytan/triage-high-priority-prs

# Conflicts:
#	CHANGELOG.md
#	VERSION
#	package.json
#	test/skill-e2e-bws.test.ts
#	test/skill-e2e-ios.test.ts
This commit is contained in:
Garry Tan
2026-06-21 06:52:06 -07:00
142 changed files with 15021 additions and 502 deletions
+19 -1
View File
@@ -24,6 +24,7 @@
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { hermeticChildEnv, isHermeticEnabled } from './hermetic-env';
/** Strip ANSI escapes for pattern-matching against visible text. */
export function stripAnsi(s: string): string {
@@ -129,6 +130,13 @@ export interface ClaudePtySession {
exited(): boolean;
/** Exit code, if known. */
exitCode(): number | null;
/**
* The hermetic CLAUDE_CONFIG_DIR this session's claude was pointed at, or
* null when EVALS_HERMETIC=0. Forensics: hermetic plan files live under
* `<hermeticConfigDir>/plans/` (extractPlanFilePath still matches them —
* the dir name ends in `/.claude` by contract).
*/
hermeticConfigDir: string | null;
/**
* Send SIGINT, then SIGKILL after 1s. Always safe to call multiple times.
* Awaits process exit before resolving.
@@ -1218,8 +1226,17 @@ export async function launchClaudePty(
if (permissionMode !== null) {
args.push('--permission-mode', permissionMode);
}
// Hermetic children get zero MCP servers; gated on the same call-time
// check as the env scrub so EVALS_HERMETIC=0 restores operator MCP too.
// Before opts.extraArgs so a test could theoretically supply --mcp-config.
const hermetic = isHermeticEnabled();
if (hermetic) args.push('--strict-mcp-config');
if (opts.extraArgs) args.push(...opts.extraArgs);
// Hermetic by default (test/helpers/hermetic-env.ts): operator session
// context never reaches the child; per-test opts.env merges last.
const childEnv = hermeticChildEnv(opts.env);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const proc = (Bun as any).spawn([claudePath, ...args], {
terminal: {
@@ -1230,7 +1247,7 @@ export async function launchClaudePty(
},
},
cwd,
env: { ...process.env, ...(opts.env ?? {}) },
env: childEnv,
});
// Track exit so waitForAny can fail fast if claude crashes.
@@ -1382,6 +1399,7 @@ export async function launchClaudePty(
pid: () => proc.pid as number | undefined,
exited: () => exited,
exitCode: () => exitCodeCaptured,
hermeticConfigDir: hermetic ? childEnv.CLAUDE_CONFIG_DIR ?? null : null,
close,
};
}