feat: streaming output for bash commands (#516)

Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
Charles Packer
2026-01-11 15:49:38 -08:00
committed by GitHub
parent c07a5edd88
commit 163e34b04b
10 changed files with 439 additions and 17 deletions

View File

@@ -37,6 +37,7 @@ function spawnWithLauncher(
env: NodeJS.ProcessEnv;
timeout: number;
signal?: AbortSignal;
onOutput?: (chunk: string, stream: "stdout" | "stderr") => void;
},
): Promise<{ stdout: string; stderr: string; exitCode: number | null }> {
return new Promise((resolve, reject) => {
@@ -71,10 +72,12 @@ function spawnWithLauncher(
childProcess.stdout?.on("data", (chunk: Buffer) => {
stdoutChunks.push(chunk);
options.onOutput?.(chunk.toString("utf8"), "stdout");
});
childProcess.stderr?.on("data", (chunk: Buffer) => {
stderrChunks.push(chunk);
options.onOutput?.(chunk.toString("utf8"), "stderr");
});
childProcess.on("error", (err) => {
@@ -137,6 +140,7 @@ export async function spawnCommand(
env: NodeJS.ProcessEnv;
timeout: number;
signal?: AbortSignal;
onOutput?: (chunk: string, stream: "stdout" | "stderr") => void;
},
): Promise<{ stdout: string; stderr: string; exitCode: number | null }> {
// On Unix (Linux/macOS), use simple bash -c approach (original behavior)
@@ -200,6 +204,7 @@ interface BashArgs {
description?: string;
run_in_background?: boolean;
signal?: AbortSignal;
onOutput?: (chunk: string, stream: "stdout" | "stderr") => void;
}
interface BashResult {
@@ -218,6 +223,7 @@ export async function bash(args: BashArgs): Promise<BashResult> {
description: _description,
run_in_background = false,
signal,
onOutput,
} = args;
const userCwd = process.env.USER_CWD || process.cwd();
@@ -314,6 +320,7 @@ export async function bash(args: BashArgs): Promise<BashResult> {
env: getShellEnv(),
timeout: effectiveTimeout,
signal,
onOutput,
});
let output = stdout;

View File

@@ -87,5 +87,15 @@ export function getShellEnv(): NodeJS.ProcessEnv {
: nodeModulesDir;
}
// Disable interactive pagers (fixes git log, man, etc. hanging)
env.PAGER = "cat";
env.GIT_PAGER = "cat";
env.MANPAGER = "cat";
// Ensure TERM is set for proper color support
if (!env.TERM) {
env.TERM = "xterm-256color";
}
return env;
}