fix(coding-agents): hide Windows child processes (#3736)

This commit is contained in:
Parafee41
2026-08-24 17:55:29 +08:00
committed by GitHub
parent 1cbd77d2b8
commit 0429060be9
12 changed files with 28 additions and 8 deletions
@@ -51,7 +51,13 @@ export function getProjectRootFromGit(directory: string): string | null {
const commonDir = execFileSync(
"git",
["rev-parse", "--path-format=absolute", "--git-common-dir"],
{ cwd: directory, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"], timeout: 1000 }
{
cwd: directory,
encoding: "utf-8",
stdio: ["ignore", "pipe", "ignore"],
timeout: 1000,
windowsHide: true,
}
).trim();
if (!commonDir) return null;
// clones + `git worktree add`: common-dir is `<main root>/.git`; bare repos: the dir itself.
@@ -180,12 +180,13 @@ describe("startDaemonDetached", () => {
const [cmd, args, opts] = spawn.mock.calls[0] as unknown as [
string,
string[],
{ detached: boolean; stdio: string },
{ detached: boolean; stdio: string; windowsHide: boolean },
];
expect(cmd).toBe("node");
expect(args[0]).toMatch(/daemon-start\.js$/);
expect(opts.detached).toBe(true);
expect(opts.stdio).toBe("ignore");
expect(opts.windowsHide).toBe(true);
// An async spawn 'error' event would otherwise crash the hook process.
expect(child.on).toHaveBeenCalledWith("error", expect.any(Function));
expect(child.unref).toHaveBeenCalled();
@@ -195,6 +195,7 @@ export function startDaemonDetached(
const child = spawnFn("node", [starter, "--harness", harness], {
detached: true,
stdio: "ignore",
windowsHide: true,
});
// spawn() failures often surface ASYNCHRONOUSLY as an 'error' event; unhandled, that would
// crash the hook.
@@ -16,7 +16,11 @@ const US = "\x1f";
const RS = "\x1e"; // record separator between commits in gitLogText
function git(repo: string, ...args: string[]): string {
return execFileSync("git", ["-C", repo, ...args], { encoding: "utf8", maxBuffer: 1 << 28 });
return execFileSync("git", ["-C", repo, ...args], {
encoding: "utf8",
maxBuffer: 1 << 28,
windowsHide: true,
});
}
/** The bank-facing name for a repo — WORKTREE-AWARE (all worktrees produce the main checkout's
@@ -13,7 +13,7 @@ describe("startBackgroundSeed", () => {
expect(spawn).toHaveBeenCalledWith(
"node",
["/dist/deepen.js", "--repo", "/some/repo", "--gitlog-limit", String(DEFAULT_SEED_LIMIT)],
{ detached: true, stdio: expect.anything() }
{ detached: true, stdio: expect.anything(), windowsHide: true }
);
expect(spawn.mock.results[0].value.unref).toHaveBeenCalled();
});
@@ -38,7 +38,7 @@ describe("startBackgroundSeed", () => {
expect(spawn).toHaveBeenCalledWith(
"node",
["/dist/deepen.js", "--repo", "/some/repo", "--gitlog-limit", "50"],
{ detached: true, stdio: expect.anything() }
{ detached: true, stdio: expect.anything(), windowsHide: true }
);
});
@@ -60,7 +60,7 @@ describe("startBackgroundSeed", () => {
"--harness",
"antigravity-cli",
],
{ detached: true, stdio: expect.anything() }
{ detached: true, stdio: expect.anything(), windowsHide: true }
);
});
@@ -42,6 +42,7 @@ export function startBackgroundSeed(
{
detached: true,
stdio: "ignore",
windowsHide: true,
}
);
// spawn() failures (ENOENT/EACCES/fd exhaustion/sandboxed environments) often arrive
@@ -98,7 +98,10 @@ async function gitSyncNote(args: {
try {
const { execFileSync } = await import("node:child_process");
const n = Number(
execFileSync("git", ["-C", cwd, "rev-list", "--count", "HEAD"], { encoding: "utf8" }).trim()
execFileSync("git", ["-C", cwd, "rev-list", "--count", "HEAD"], {
encoding: "utf8",
windowsHide: true,
}).trim()
);
if (n > 0) target = Math.min(DEEPEN_DIFF_TARGET, n);
} catch {
@@ -48,6 +48,7 @@ function commitCount(repoDir: string): number | null {
try {
const out = execFileSync("git", ["-C", repoDir, "rev-list", "--count", "HEAD"], {
encoding: "utf8",
windowsHide: true,
});
return Number(out.trim()) || 0;
} catch {
@@ -83,6 +83,7 @@ describe("startCodebaseSurvey", () => {
expect(options.cwd).toBe("/repo");
expect(options.detached).toBe(true);
expect(options.stdio).toBe("ignore");
expect(options.windowsHide).toBe(true);
expect(options.env.HINDSIGHT_DISABLE_HOOKS).toBe("1");
const child = spawn.mock.results[0].value;
@@ -338,6 +338,7 @@ export function startCodebaseSurvey(
cwd: repoDir,
detached: true,
stdio: "ignore",
windowsHide: true,
env: plan.env,
});
// spawn() failures (binary not found, EACCES, sandboxed environments) often arrive
@@ -19,6 +19,7 @@ function gitTry(repo: string, ...args: string[]): string | null {
return execFileSync("git", ["-C", repo, ...args], {
encoding: "utf8",
maxBuffer: 1 << 28,
windowsHide: true,
}).trim();
} catch {
return null;
@@ -228,7 +228,7 @@ async function main() {
const shas = execFileSync(
"git",
["-C", REPO!, "rev-list", `-n`, String(DEEPEN_DIFF_TARGET), "HEAD"],
{ encoding: "utf8" }
{ encoding: "utf8", windowsHide: true }
)
.trim()
.split("\n")