mirror of
https://github.com/vectorize-io/hindsight.git
synced 2026-09-14 19:31:49 +08:00
fix(coding-agents): hide Windows child processes (#3736)
This commit is contained in:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user