mirror of
https://github.com/earendil-works/pi.git
synced 2026-06-18 15:54:04 +08:00
fix(coding-agent): resolve captured commands on close closes #3027
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { spawn, spawnSync } from "node:child_process";
|
||||
import { type ChildProcess, type ChildProcessByStdio, spawn, spawnSync } from "node:child_process";
|
||||
import { createHash } from "node:crypto";
|
||||
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
|
||||
import { homedir, tmpdir } from "node:os";
|
||||
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
||||
import type { Readable } from "node:stream";
|
||||
import ignore from "ignore";
|
||||
import { minimatch } from "minimatch";
|
||||
import { CONFIG_DIR_NAME } from "../config.js";
|
||||
@@ -2177,18 +2178,34 @@ export class DefaultPackageManager implements PackageManager {
|
||||
};
|
||||
}
|
||||
|
||||
private spawnCommand(command: string, args: string[], options?: { cwd?: string }): ChildProcess {
|
||||
return spawn(command, args, {
|
||||
cwd: options?.cwd,
|
||||
stdio: isStdoutTakenOver() ? ["ignore", 2, 2] : "inherit",
|
||||
shell: process.platform === "win32",
|
||||
});
|
||||
}
|
||||
|
||||
private spawnCaptureCommand(
|
||||
command: string,
|
||||
args: string[],
|
||||
options?: { cwd?: string; env?: Record<string, string> },
|
||||
): ChildProcessByStdio<null, Readable, Readable> {
|
||||
return spawn(command, args, {
|
||||
cwd: options?.cwd,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
shell: process.platform === "win32",
|
||||
env: options?.env ? { ...process.env, ...options.env } : process.env,
|
||||
});
|
||||
}
|
||||
|
||||
private runCommandCapture(
|
||||
command: string,
|
||||
args: string[],
|
||||
options?: { cwd?: string; timeoutMs?: number; env?: Record<string, string> },
|
||||
): Promise<string> {
|
||||
return new Promise((resolvePromise, reject) => {
|
||||
const child = spawn(command, args, {
|
||||
cwd: options?.cwd,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
shell: process.platform === "win32",
|
||||
env: options?.env ? { ...process.env, ...options.env } : process.env,
|
||||
});
|
||||
const child = this.spawnCaptureCommand(command, args, options);
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
let timedOut = false;
|
||||
@@ -2206,11 +2223,11 @@ export class DefaultPackageManager implements PackageManager {
|
||||
child.stderr?.on("data", (data) => {
|
||||
stderr += data.toString();
|
||||
});
|
||||
child.on("error", (error) => {
|
||||
child.once("error", (error) => {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
reject(error);
|
||||
});
|
||||
child.on("exit", (code) => {
|
||||
child.once("close", (code, signal) => {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
if (timedOut) {
|
||||
reject(new Error(`${command} ${args.join(" ")} timed out after ${options?.timeoutMs}ms`));
|
||||
@@ -2220,18 +2237,15 @@ export class DefaultPackageManager implements PackageManager {
|
||||
resolvePromise(stdout.trim());
|
||||
return;
|
||||
}
|
||||
reject(new Error(`${command} ${args.join(" ")} failed with code ${code}: ${stderr || stdout}`));
|
||||
const exitStatus = code === null ? `signal ${signal ?? "unknown"}` : `code ${code}`;
|
||||
reject(new Error(`${command} ${args.join(" ")} failed with ${exitStatus}: ${stderr || stdout}`));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private runCommand(command: string, args: string[], options?: { cwd?: string }): Promise<void> {
|
||||
return new Promise((resolvePromise, reject) => {
|
||||
const child = spawn(command, args, {
|
||||
cwd: options?.cwd,
|
||||
stdio: isStdoutTakenOver() ? ["ignore", 2, 2] : "inherit",
|
||||
shell: process.platform === "win32",
|
||||
});
|
||||
const child = this.spawnCommand(command, args, options);
|
||||
child.on("error", reject);
|
||||
child.on("exit", (code) => {
|
||||
if (code === 0) {
|
||||
|
||||
Reference in New Issue
Block a user