qwen-code/packages
秦奇 7ccbfaeb1a fix(cli): address banner re-review (FIFO, mutex schema, display width, regex dedupe)
Addresses the five findings on PR #3710 from the latest re-review:

1. **[Critical] FIFO/pipe at `customAsciiArt.path` no longer hangs
   startup.** The resolver was calling `openSync(path, O_NOFOLLOW)`
   *before* the `fstatSync(...).isFile()` check; on POSIX, opening a
   FIFO read-only blocks until a writer connects, and `O_NOFOLLOW`
   doesn't help — it only refuses symlinks at the final path
   component. `readArtFile` now `lstatSync()`s first and refuses
   non-regular files (FIFO / socket / device / symlink) before the
   open, while keeping the post-open `fstatSync` check for TOCTOU
   safety against a swap between the lstat and the open. New
   POSIX-only regression test `mkfifo`s a named pipe and asserts the
   resolver soft-fails inside 1 s; if the open ever regresses to
   blocking, the test will hang past the timeout and the assertion
   will catch it.

2. **[Suggestion] `{path}` and `{small,large}` are now mutually
   exclusive in both schema and runtime.** The `jsonSchemaOverride`
   on `ui.customAsciiArt` is split into three branches (string,
   `{path}`, `{small?, large?}`); none of them allow `path` and tier
   keys to co-exist. `normalizeTiers()` mirrors that — an object
   carrying both kinds of keys is now soft-rejected with a `[BANNER]`
   warn rather than letting `path` silently win and dropping the
   tier values. New regression test pins the runtime side.

3. **[Suggestion] Column cap and tier-fit selection now measure in
   terminal cells.** `getAsciiArtWidth` (in `textUtils.ts`) and the
   `MAX_ART_COLS` cap in `customBanner.ts` were both using UTF-16
   `.length`, so 200 CJK fullwidth characters would slip the cap and
   render at ~400 cells, and `pickAsciiArtTier`'s width-fit check
   was wrong for any non-ASCII art. Switched both to
   `getCachedStringWidth` (string-width semantics, already in the
   repo); art truncation walks code points until adding another
   would push the cell width past the cap, so we never split a
   fullwidth code point or surrogate pair down the middle. New
   regression test exercises the CJK fullwidth case.

4. **[Suggestion] `collectScopedTiers()` no longer drops a whole
   scope just because it has no `file.path`.** Inline-string tiers
   don't need an owning settings directory; only `{path}` tiers do.
   The path-presence check was moved into the `{path}` branch, so a
   path-less scope (e.g. `systemDefaults`, future SDK-injected
   scopes) can still contribute inline art. `{path}` entries in such
   a scope soft-fail with a tier-specific `[BANNER]` warn rather
   than killing the whole scope. Two regression tests cover both
   sides.

5. **[Suggestion] OSC / CSI / SS2-3 regex are now authored once.**
   Extracted `TERMINAL_OSC_REGEX`, `TERMINAL_CSI_REGEX`,
   `TERMINAL_SHIFT_DCS_REGEX` from `stripTerminalControlSequences`
   in `@qwen-code/qwen-code-core` and re-export them from the
   package index. `customBanner.ts` reuses the constants for
   `sanitizeArt` (which still has to preserve `\n` / `\t`) and
   delegates the title/subtitle pipeline directly to
   `stripTerminalControlSequences`. Also backported the C1 control
   strip (0x80-0x9F) into the core helper so all callers
   (session-title, etc.) benefit from the same coverage; banner
   sanitizer was the only place catching single-byte CSI / DCS / ST.

Banner suite is now 40 + 17 + 6 + 16 = 79 tests, all green. Schema
regen is still byte-for-byte idempotent. `npm run typecheck` and
prettier clean on touched files.
2026-05-06 13:05:24 +08:00
..
channels chore(release): v0.15.6 (#3766) 2026-04-30 15:59:35 +08:00
cli fix(cli): address banner re-review (FIFO, mutex schema, display width, regex dedupe) 2026-05-06 13:05:24 +08:00
core fix(cli): address banner re-review (FIFO, mutex schema, display width, regex dedupe) 2026-05-06 13:05:24 +08:00
sdk-java fix(sdk-java): pass custom env to CLI process (#3543) 2026-04-24 10:37:52 +08:00
sdk-python refactor: extract shared release helper utilities (#3834) 2026-05-05 10:15:17 +08:00
sdk-typescript refactor: extract shared release helper utilities (#3834) 2026-05-05 10:15:17 +08:00
vscode-ide-companion fix(cli): address banner re-review (FIFO, mutex schema, display width, regex dedupe) 2026-05-06 13:05:24 +08:00
web-templates chore(release): v0.15.6 (#3766) 2026-04-30 15:59:35 +08:00
webui fix(core): address post-merge monitor tool and UI routing issues (#3792) 2026-05-04 21:19:41 +08:00
zed-extension chore(zed-extension): update package version to 0.10.0 2026-02-06 14:26:01 +08:00