fix(cli): ASCII glyph fallback for Windows console mojibake (#168) (#178)

The shimmer progress renderer writes from a worker thread via
`fs.writeSync(1, ...)` to keep the animation smooth while the main
thread is busy in SQLite. That path bypasses Node's TTY-aware
UTF-8->codepage conversion on Windows, so glyphs like `|`/`<>`/`-`
were emitted as raw UTF-8 bytes and reinterpreted by the console's
OEM codepage (CP437, CP936, ...), producing strings like
`鋍?[0m 鉒?[0m Scanning files 鈥?N found`.

Add `src/ui/glyphs.ts` with `supportsUnicode()` detection plus
matched Unicode + ASCII glyph sets, and route all CLI/shimmer
output through `getGlyphs()`. Defaults: ASCII on Windows and on
Linux kernel consoles (`TERM=linux`), Unicode everywhere else.
`CODEGRAPH_UNICODE=1` and `CODEGRAPH_ASCII=1` are escape hatches.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Colby Mchenry
2026-05-19 10:45:20 -05:00
committed by GitHub
co-authored by Claude Opus 4.7
parent 36c8dbc404
commit e176062c56
7 changed files with 322 additions and 34 deletions
+2 -1
View File
@@ -21,6 +21,7 @@ import {
resolveTargetFlag,
} from './targets/registry';
import type { AgentTarget, Location, WriteResult } from './targets/types';
import { getGlyphs } from '../ui/glyphs';
// Backwards-compat: keep these named exports — downstream code may
// import them. The shim in `config-writer.ts` continues to re-export
@@ -331,7 +332,7 @@ async function initializeLocalProject(clack: typeof import('@clack/prompts')): P
// Index the project with shimmer progress (worker thread for smooth animation)
const { createShimmerProgress } = await import('../ui/shimmer-progress');
process.stdout.write(`\x1b[2m\x1b[0m\n`);
process.stdout.write(`\x1b[2m${getGlyphs().rail}\x1b[0m\n`);
const progress = createShimmerProgress();
const result = await cg.indexAll({