Skip to content

fix(server): strip terminal escape sequences from opencode CLI output - #7988

Open
Exotic209093 wants to merge 1 commit into
pingdotgg:mainfrom
Exotic209093:fix/opencode-osc-title-leak
Open

fix(server): strip terminal escape sequences from opencode CLI output#7988
Exotic209093 wants to merge 1 commit into
pingdotgg:mainfrom
Exotic209093:fix/opencode-osc-title-leak

Conversation

@Exotic209093

@Exotic209093 Exotic209093 commented Aug 23, 2026

Copy link
Copy Markdown

Problem

opencode <= 1.18 emits an OSC title set (ESC ]0;<cwd>: ready BEL) on stdout even when stdout is a pipe. The escape bytes leak into everything parsed from its CLI output: parseServerUrlFromOutput misses the ready line, model slugs gain a prefix, agent names pick up garbage, and skill JSON fails to decode.

Fix

Add a shared helper, @t3tools/shared/stripTerminalEscapes, that removes OSC sequences (terminated by BEL or ST) and CSI sequences while leaving ordinary text alone (unterminated prefixes are preserved). Apply it in opencodeRuntime.ts before parsing server output, models, agents, and skills. Since JSON.stringify encodes control bytes textually inside JSON values, all three CLI parsers also strip decoded string values via a JSON.parse reviver — model fields at any depth, agent permission rules, and skill metadata — while non-string values and object/array structure pass through untouched.

Tests: direct unit tests for the helper plus parser coverage for raw-byte titles, escapes embedded in decoded model/permission/skill fields, and unterminated-sequence preservation.

Note

Strip terminal escape sequences from opencode CLI output parsers

  • Adds stripTerminalEscapes to @t3tools/shared, which removes OSC and CSI sequences from strings, exported via the new ./stripTerminalEscapes subpath
  • Applies the helper and a stripTerminalEscapesJsonReviver to parseServerUrlFromOutput, parseModelsCliOutput, parseAgentListCliOutput, and parseSkillsCliOutput so CLI output is cleaned before line splitting and JSON decoding
  • parseSkillsCliOutput now uses JSON.parse with the reviver before schema validation (decodeOpenCodeSkillsArrayExit) instead of decoding from JSON text, returning an empty array on parse failure
  • Risk: parseSkillsCliOutput no longer validates raw JSON text via schema; malformed input returns [] instead of throwing, so downstream callers expecting schema errors on bad input will see an empty array

Macroscope summarized 842a0dd.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Aug 23, 2026
Comment thread apps/server/src/provider/opencodeRuntime.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Skipped

Macroscope did not run approvability analysis for this PR. Macroscope could not determine whether this PR modifies its approvability configuration, so the PR was not approved automatically. A PR that may change the rules that govern approval is never approved automatically.

opencode <= 1.18 emits an OSC title set (ESC ]0;<cwd>: ready BEL) on
stdout even when piped, which leaked into the server-ready line match,
model slugs, agent names, and skill payloads parsed from its output.

Add a shared stripTerminalEscapes helper that removes OSC (BEL- and
ST-terminated) and CSI sequences while leaving ordinary text untouched,
apply it to parseServerUrlFromOutput and the models/agents/skills CLI
parsers, and cover both the helper and the parsers with tests.

Escapes embedded inside JSON string values only surface after JSON
decoding, so all three parsers also strip decoded strings via a
JSON.parse reviver; unterminated escape prefixes stay literal text.
@Exotic209093
Exotic209093 force-pushed the fix/opencode-osc-title-leak branch from e6bdd7d to 842a0dd Compare August 23, 2026 10:00
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9a4dd94c-1a3f-4ca4-8d13-5cb758b88c32

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant