import { afterEach, expect, test } from "vitest" ;
import { markBackgrounded, resetProcessRegistryForTests } from "./bash-process-registry.js" ;
import { runExecProcess } from "./bash-tools.exec-runtime.js" ;
import { createProcessTool } from "./bash-tools.process.js" ;
afterEach(() => {
resetProcessRegistryForTests();
});
function currentEnv(): Record<string, string> {
const env: Record<string, string> = {};
for (const [key, value] of Object.entries(process.env)) {
if (typeof value === "string" ) {
env[key] = value;
}
}
return env;
}
async function startPtySession(command: string) {
const processTool = createProcessTool();
const run = await runExecProcess({
command,
workdir: process.cwd(),
env: currentEnv(),
usePty: true ,
warnings: [],
maxOutput: 20 _000 ,
pendingMaxOutput: 20 _000 ,
notifyOnExit: false ,
timeoutSec: 5 ,
});
markBackgrounded(run.session);
return { processTool, sessionId: run.session.id };
}
async function waitForSessionCompletion(params: {
processTool: ReturnType<typeof createProcessTool>;
sessionId: string;
expectedText: string;
}) {
await expect
.poll(
async () => {
const poll = await params.processTool.execute("toolcall" , {
action: "poll" ,
sessionId: params.sessionId,
});
const details = poll.details as { status?: string; aggregated?: string };
if (details.status === "running" ) {
return false ;
}
expect(details.status).toBe("completed" );
expect(details.aggregated ?? "" ).toContain(params.expectedText);
return true ;
},
{
timeout: process.platform === "win32" ? 12 _000 : 8 _000 ,
interval: 30 ,
},
)
.toBe(true );
}
test("process send-keys encodes Enter for pty sessions" , async () => {
const { processTool, sessionId } = await startPtySession(
'node -e "const dataEvent=String.fromCharCode(100,97,116,97);process.stdin.on(dataEvent,d=>{process.stdout.write(d);if(d.includes(10)||d.includes(13))process.exit(0);});"' ,
);
await processTool.execute("toolcall" , {
action: "send-keys" ,
sessionId,
keys: ["h" , "i" , "Enter" ],
});
await waitForSessionCompletion({ processTool, sessionId, expectedText: "hi" });
});
test("process submit sends Enter for pty sessions" , async () => {
const { processTool, sessionId } = await startPtySession(
'node -e "const dataEvent=String.fromCharCode(100,97,116,97);const submitted=String.fromCharCode(115,117,98,109,105,116,116,101,100);process.stdin.on(dataEvent,d=>{if(d.includes(10)||d.includes(13)){process.stdout.write(submitted);process.exit(0);}});"' ,
);
await processTool.execute("toolcall" , {
action: "submit" ,
sessionId,
});
await waitForSessionCompletion({ processTool, sessionId, expectedText: "submitted" });
});
Messung V0.5 in Prozent C=100 H=94 G=96
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-05-26)
¤
*© Formatika GbR, Deutschland