feat: separate plain output flags for stdout and stderr

This commit is contained in:
mitchell 2026-04-17 16:49:45 -04:00
parent 9d599d98bf
commit cdfafc9d5f
2 changed files with 23 additions and 9 deletions

View file

@ -15,7 +15,8 @@ const { values: args, positionals } = parseArgs({
save: { type: "boolean" }, save: { type: "boolean" },
s: { type: "boolean" }, s: { type: "boolean" },
plain: { type: "boolean" }, plain: { type: "boolean" },
p: { type: "boolean" }, plainOut: { type: "boolean" },
plainErr: { type: "boolean" },
}, },
strict: true, strict: true,
allowPositionals: true, allowPositionals: true,
@ -27,7 +28,8 @@ const configFile = Bun.file(`${home}/.aicl_config.json`);
async function main() { async function main() {
const newConvo = args.new ?? args.n; const newConvo = args.new ?? args.n;
const plain = args.plain ?? args.p ?? !process.stdout.isTTY; const plainOut = args.plainOut ?? args.plain ?? !process.stdout.isTTY;
const plainErr = args.plainErr ?? args.plain ?? !process.stderr.isTTY;
let saveConfig = args.save ?? args.s; let saveConfig = args.save ?? args.s;
let config: { model?: string }; let config: { model?: string };
@ -47,9 +49,10 @@ async function main() {
if (saveConfig) { if (saveConfig) {
await configFile.write(JSON.stringify(config, null, " ")); await configFile.write(JSON.stringify(config, null, " "));
return;
} }
const renderer = new Renderer(plain); const renderer = new Renderer(plainOut, plainErr);
const provider = createOpenAICompatible({ const provider = createOpenAICompatible({
name: "llama.cpp", name: "llama.cpp",
@ -88,7 +91,7 @@ async function main() {
convo.messages.push({ role: "assistant", content: await text }); convo.messages.push({ role: "assistant", content: await text });
await convoFile.write(JSON.stringify(convo)); await convoFile.write(JSON.stringify(convo));
if (!plain) { if (!plainOut) {
const [width] = process.stdout.getWindowSize(); const [width] = process.stdout.getWindowSize();
await Bun.spawn({ await Bun.spawn({
cmd: ["glow", "-w", `${width}`, "-"], cmd: ["glow", "-w", `${width}`, "-"],

View file

@ -18,7 +18,10 @@ export default class Renderer {
private charsSinceNL = 0; private charsSinceNL = 0;
private memOk = true; private memOk = true;
constructor(private isPlain = false) { constructor(
private isPlain = false,
private isPlainErr = false,
) {
process.stdout.addListener("drain", () => { process.stdout.addListener("drain", () => {
this.memOk = true; this.memOk = true;
}); });
@ -73,25 +76,33 @@ export default class Renderer {
`${styles.dim.open}${styles.italic.open}`, `${styles.dim.open}${styles.italic.open}`,
process.stderr, process.stderr,
); );
this.write("\n", process.stderr); this.write("\n", process.stderr);
reasoningFile.write(""); reasoningFile.write("");
break; break;
} }
case "reasoning-delta": { case "reasoning-delta": {
this.write(part.text, process.stderr); this.write(part.text, process.stderr);
if (!this.isPlainErr)
this.checkContainment(part.text, process.stderr); this.checkContainment(part.text, process.stderr);
reasoningWriter.write(part.text); reasoningWriter.write(part.text);
break; break;
} }
case "reasoning-end": { case "reasoning-end": {
if (!this.isPlainErr) {
this.moveCursor(-this.lineCount - 1, process.stderr);
this.clearScreenDown(process.stderr);
this.resetCounts();
} else {
this.write("\n--- Done Thinking ---\n", process.stderr);
}
if (supportsColorStderr) if (supportsColorStderr)
this.write( this.write(
`${styles.italic.close}${styles.dim.close}`, `${styles.italic.close}${styles.dim.close}`,
process.stderr, process.stderr,
); );
this.moveCursor(-this.lineCount - 1, process.stderr);
this.clearScreenDown(process.stderr);
this.resetCounts();
reasoningWriter.end(); reasoningWriter.end();
break; break;
} }