Files
Alex Newman 3415d97500 fix(context): BMP-only injected context to stop astral-surrogate 400s (closes #2787) (#2802)
* fix(context): BMP-only injected context to stop astral-surrogate 400s (closes #2787)

Claude Code can truncate auto-loaded context (CLAUDE.md / AGENTS.md / .mdc)
at a UTF-16 code-unit boundary; if the cut splits an astral emoji's surrogate
pair it emits a lone surrogate and the Anthropic API rejects the request with
'400 no low surrogate in string' — bricking the session in a way that survives
/clear (the bytes live in the always-reloaded context file).

- Add src/utils/bmp-safe.ts: toBmpSafe() guarantees every emitted code point is
  <= U+FFFF (known type markers -> distinct BMP glyphs, other astral -> bullet,
  lone surrogates dropped).
- Apply it at every context-injection write boundary: injectContextIntoMarkdownFile,
  writeClaudeMdToFolder, and the cursor .mdc writer — so ANY mode (incl. custom)
  is safe, not just the default markers.
- Switch the default 'code' mode (plugin/modes/code.json) and TYPE_ICONS to BMP
  markers so the source of truth is already clean.
- Tests in tests/bmp-safe.test.ts assert output is surrogate-free.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: cursor context now sanitizes astral emoji to BMP (#2787)

Update the unicode test to assert the post-#2787 contract: BMP scripts
(日本語, العربية) survive untouched while astral emoji are stripped and the
output contains no UTF-16 surrogate code units.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 20:49:12 -07:00
..
2026-04-08 17:31:19 -07:00