Skip to content

fix: strip ANSI escape sequences before JSONL parsing#24

Open
Mingsicogi wants to merge 3 commits intoopenai:mainfrom
Mingsicogi:fix/strip-ansi-escape-jsonl-parse
Open

fix: strip ANSI escape sequences before JSONL parsing#24
Mingsicogi wants to merge 3 commits intoopenai:mainfrom
Mingsicogi:fix/strip-ansi-escape-jsonl-parse

Conversation

@Mingsicogi
Copy link
Copy Markdown

Summary

  • Strip ANSI escape sequences (e.g. bracketed paste mode \e[?2004h) from JSONL lines before JSON.parse() in both app-server.mjs and app-server-broker.mjs
  • Prevents Failed to parse codex app-server JSONL: Unexpected token errors when the shell environment leaks terminal control characters into the Codex CLI output stream

Problem

When /codex:review runs in environments where the shell (zsh/bash) emits ANSI escape sequences during startup, these control characters appear in the JSONL stream. JSON.parse() then fails because [?2004h is not valid JSON.

Failed to parse codex app-server JSONL: Unexpected token '', "[?2004h" is not valid JSON

This affects both foreground and background execution via Claude Code's Bash tool.

Fix

Added a regex-based ANSI escape sequence stripper before JSON parsing in the two JSONL consumers:

  • plugins/codex/scripts/lib/app-server.mjshandleLine() method
  • plugins/codex/scripts/app-server-broker.mjs — socket data handler

Lines that become empty after stripping are silently skipped (same as the existing blank-line check).

Test plan

  • Verified the regex correctly strips \e[?2004h, \e[0m, \e]0;title\x07 and similar sequences
  • Verified valid JSON lines pass through unchanged
  • Existing test suite passes (1 pre-existing failure unrelated to this change)

Fixes #23

@Mingsicogi Mingsicogi requested a review from a team March 31, 2026 02:55
When the Codex CLI runs in environments where the shell emits terminal
escape sequences (e.g. bracketed paste mode `[?2004h` from zsh), these
control characters leak into the JSONL stream and cause JSON.parse to
fail with: "Failed to parse codex app-server JSONL: Unexpected token"

Extract a shared `stripAnsi()` helper in `app-server.mjs` and use it
in both `app-server.mjs` and `app-server-broker.mjs` to strip ANSI
escape sequences from each line before JSON parsing.

Fixes openai#23
@Mingsicogi Mingsicogi force-pushed the fix/strip-ansi-escape-jsonl-parse branch from 08103c9 to 665a042 Compare March 31, 2026 02:58
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 08103c94e1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Address review feedback: the initial regex missed CSI sequences with
non-letter finals (e.g. `\e[200~` for bracketed paste wrappers) and
OSC sequences terminated by ST (`ESC \`) instead of BEL.

Updated regex covers:
- CSI: ESC [ <params> <final byte 0x40-0x7E> (includes ~, @, etc.)
- OSC: ESC ] ... (BEL | ESC \)
- Simple escapes: ESC <intermediate>* <final>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7554408f21

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Addresses remaining review feedback from chatgpt-codex-connector:

CSI (previously missed):
- Parameter bytes: [0-9;?] → [\x30-\x3f] to include <, =, > (0x3C–0x3E)
  e.g. ESC[>4;2m (modifyOtherKeys), ESC[<1;2M (mouse events)
- Intermediate bytes: added [\x20-\x2f]* between params and final
  e.g. ESC[ q (cursor shape), ESC[!p (soft reset)

String sequences (new):
- DCS (ESC P), SOS (ESC X), PM (ESC ^), APC (ESC _) terminated by BEL or ST
  e.g. ESC P...ESC\ (tmux/Sixel), ESC _G...ESC\ (Kitty graphics protocol)

Simple escapes:
- Final byte range: [\x40-\x7e] → [\x30-\x7e] to include Fp sequences (0x30–0x3F)
  e.g. ESC 7/8 (save/restore cursor), ESC = / ESC > (keypad modes)

Lone ESC fallback:
- Bare \x1b not matched by any complete sequence is now stripped
  prevents JSON.parse failures from truncated/unknown sequences

Add tests/strip-ansi.test.mjs with 27 cases covering all sequence types.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Review fails with JSONL parse error: bracketed paste mode escape sequence in output ([?2004h)

1 participant