mirror of
https://github.com/Narcooo/inkos.git
synced 2026-08-31 01:42:58 +08:00
fix(tui): buffer stdout writes for Terminal.app to prevent CJK crash
Terminal.app crashes (SIGSEGV in CGFontStrikeGetValue) when it sees partial CJK UTF-8 bytes across multiple write() calls — the font glyph cache gets corrupted with text bytes in pointer fields. Buffer all stdout.write() calls within a single event-loop tick and flush them as one atomic write via process.nextTick. This mirrors Claude Code's single-write buffering approach (writeDiffToTerminal) and ensures Terminal.app always receives complete frames. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -110,11 +110,30 @@ export async function launchTui(
|
||||
projectRoot: string,
|
||||
toolsOverride?: InteractionRuntimeTools,
|
||||
): Promise<void> {
|
||||
// Terminal.app has a CoreGraphics bug where UTF-8 bytes (e.g. CJK, em dash)
|
||||
// end up in color space pointers during ANSI color rendering, causing SIGSEGV.
|
||||
// Disable all color output to avoid triggering the crash.
|
||||
// Terminal.app has a CoreGraphics bug: when it sees partial CJK UTF-8 bytes
|
||||
// across multiple write() calls, the font glyph cache gets corrupted (text bytes
|
||||
// end up in pointer fields → SIGSEGV in CGFontStrikeGetValue).
|
||||
// Fix: buffer all writes within a single event-loop tick and flush once,
|
||||
// so Terminal.app always sees complete frames. Same approach as Claude Code's
|
||||
// single-write buffering in writeDiffToTerminal().
|
||||
if (isAppleTerminal) {
|
||||
process.env.FORCE_COLOR = "0";
|
||||
let buffer = "";
|
||||
const originalWrite = process.stdout.write.bind(process.stdout);
|
||||
let scheduled = false;
|
||||
|
||||
process.stdout.write = ((chunk: string | Uint8Array): boolean => {
|
||||
buffer += typeof chunk === "string" ? chunk : Buffer.from(chunk).toString();
|
||||
if (!scheduled) {
|
||||
scheduled = true;
|
||||
process.nextTick(() => {
|
||||
scheduled = false;
|
||||
const content = buffer;
|
||||
buffer = "";
|
||||
originalWrite(content);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}) as typeof process.stdout.write;
|
||||
}
|
||||
|
||||
projectRoot = await resolveProjectRoot(projectRoot);
|
||||
|
||||
Reference in New Issue
Block a user