fix: Monkey-patch stdout.write to force UTF-8 Buffer encoding

Explicitly convert string chunks to Buffer.from(chunk, 'utf8') before
writing to process.stdout. This fixes UTF-8 mojibake (â instead of ◆/│)
seen in some Bun + terminal combinations (e.g. Ghostty on macOS) where
process.stdout.write(string) doesn't encode as UTF-8 by default.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sprite 2026-02-10 09:25:58 +00:00
parent 553626e902
commit 67051bfc48
3 changed files with 137 additions and 6 deletions

118
cli/cli.js Executable file

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{
"name": "@openrouter/spawn",
"version": "0.2.9",
"version": "0.2.10",
"type": "module",
"bin": {
"spawn": "cli.js"

View file

@ -45,12 +45,25 @@ if (process.env.SPAWN_DEBUG === "1") {
if (forceAscii) {
process.env.TERM = "linux";
} else {
// Explicitly ensure UTF-8 encoding for Unicode output
// Ensure LANG includes UTF-8
if (!process.env.LANG || !process.env.LANG.includes("UTF-8")) {
process.env.LANG = "en_US.UTF-8";
}
// Set stdout encoding to UTF-8 if possible
if (process.stdout.setEncoding) {
process.stdout.setEncoding("utf8");
}
// Monkey-patch stdout.write to explicitly encode strings as UTF-8 Buffer.
// This fixes mojibake (â instead of ◆) seen in some Bun + terminal combos
// where process.stdout.write(string) doesn't use UTF-8 by default.
const originalStdoutWrite = process.stdout.write.bind(process.stdout);
(process.stdout as any).write = function (
chunk: any,
encodingOrCb?: BufferEncoding | ((err?: Error) => void),
cb?: (err?: Error) => void
): boolean {
if (typeof chunk === "string") {
const encoding =
typeof encodingOrCb === "string" ? encodingOrCb : "utf8";
return originalStdoutWrite(Buffer.from(chunk, encoding), cb ?? (typeof encodingOrCb === "function" ? encodingOrCb : undefined));
}
return originalStdoutWrite(chunk, encodingOrCb as any, cb);
};
}