export function openCodeArgs(model: string, prompt: string): string[] { return [ "run", "--format", "json", "--auto", "--model", model, prompt, ]; } type ChunkWriter = (chunk: Uint8Array) => void | Promise; export async function collectOpenCodeOutput( stdout: ReadableStream, stderr: ReadableStream, writeStdout: ChunkWriter, writeStderr: ChunkWriter, ): Promise<{ stdout: string; stderr: string }> { const collect = async ( stream: ReadableStream, write: ChunkWriter, ) => { const chunks: Uint8Array[] = []; for await (const chunk of stream) { chunks.push(chunk); await write(chunk); } const length = chunks.reduce((total, chunk) => total + chunk.length, 0); const joined = new Uint8Array(length); let offset = 0; for (const chunk of chunks) { joined.set(chunk, offset); offset += chunk.length; } return new TextDecoder().decode(joined); }; const [output, error] = await Promise.all([ collect(stdout, writeStdout), collect(stderr, writeStderr), ]); return { stdout: output, stderr: error }; } export function parseOpenCodeEvents(output: string): string { let result: string | undefined; for (const line of output.split("\n")) { if (line.trim() === "") continue; const event: unknown = JSON.parse(line); if (typeof event !== "object" || event === null) continue; const { type, part } = event as Record; if (type !== "text" || typeof part !== "object" || part === null) continue; const text = (part as Record).text; if (typeof text === "string" && text.trim() !== "") result = text; } if (result === undefined) throw new Error("OpenCode produced no text output"); return result; }