From d29fc2068133522f02beb1a7e011e06773a1a77c Mon Sep 17 00:00:00 2001 From: mitchell Date: Wed, 15 Apr 2026 15:03:33 -0400 Subject: [PATCH] feat: display stream for half of terminal until finished, then display --- index.ts | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/index.ts b/index.ts index d37a59a..abf4096 100644 --- a/index.ts +++ b/index.ts @@ -13,19 +13,65 @@ const { fullStream, reasoningText, text } = streamText({ prompt: Bun.argv[2]!, }); +const moveCursor = (x: number, y: number) => + new Promise((resolve) => process.stdout.moveCursor(x, y, resolve)); +const clearScreenDown = () => + new Promise((resolve) => process.stdout.clearScreenDown(resolve)); + +let lineCount = 0; +let charsSinceNL = 0; +const [numColumns, numRows] = process.stdout.getWindowSize(); + for await (const part of fullStream) { if (part.type === "reasoning-start") { - process.stdout.write("\u001b[2m\n "); + process.stdout.write("\u001b[2m\n"); } else if (part.type === "reasoning-delta") { - process.stdout.write(part.text.replaceAll('\n', '\n ')); + process.stdout.write(part.text); + + charsSinceNL += part.text.length; + if (part.text.includes("\n")) { + lineCount += part.text.match(/\n/g)?.length ?? 1; + charsSinceNL = 0; + } else if (charsSinceNL >= numColumns) { + lineCount++; + charsSinceNL = charsSinceNL - numColumns; + } + + if (lineCount >= numRows / 2) { + await moveCursor(0, -lineCount); + await clearScreenDown(); + lineCount = 0; + charsSinceNL = 0; + } } else if (part.type === "reasoning-end") { process.stdout.write("\n\u001b[22m"); + await moveCursor(0, -lineCount - 2); + await clearScreenDown(); + lineCount = 0; + charsSinceNL = 0; } else if (part.type === "text-start") { process.stdout.write("\n"); } else if (part.type === "text-delta") { process.stdout.write(part.text); + + charsSinceNL += part.text.length; + if (part.text.includes("\n")) { + lineCount += part.text.match(/\n/g)?.length ?? 1; + charsSinceNL = 0; + } else if (charsSinceNL >= numColumns) { + lineCount++; + charsSinceNL = charsSinceNL - numColumns; + } + + if (lineCount >= numRows / 2) { + await moveCursor(0, -lineCount); + await clearScreenDown(); + lineCount = 0; + charsSinceNL = 0; + } } else if (part.type === "text-end") { - process.stdout.write("\n"); + await moveCursor(0, -lineCount - 1); + await clearScreenDown(); } } @@ -34,3 +80,8 @@ const response = await text; Bun.file("reasoning.md").write(reasoning ?? ""); Bun.file("response.md").write(response); + +Bun.spawnSync({ + cmd: ["glow", "response.md"], + stdio: ["inherit", "inherit", "inherit"], +});