From ec598cb03820266fa7ea18893bc7809c4ff0b33e Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Tue, 15 Sep 2026 01:25:18 +0000 Subject: [PATCH] fix: strip C0/C1 controls from codex thread listings ESC-only sanitizing left CR, backspace, BEL, and other C0/C1 bytes that can still reshape terminal output. Cover them in the regression test. --- .changeset/strip-c0-thread-list.md | 5 +++++ src/cli.js | 5 +++-- test/codex-bridge.test.js | 12 ++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 .changeset/strip-c0-thread-list.md diff --git a/.changeset/strip-c0-thread-list.md b/.changeset/strip-c0-thread-list.md new file mode 100644 index 0000000..be340e4 --- /dev/null +++ b/.changeset/strip-c0-thread-list.md @@ -0,0 +1,5 @@ +--- +"grok-bot-cli": patch +--- + +Strip C0/C1 controls (including CR, backspace, and BEL) from `gbot codex list-threads` text output, not only ESC sequences. diff --git a/src/cli.js b/src/cli.js index bfe084c..4ca4a49 100755 --- a/src/cli.js +++ b/src/cli.js @@ -144,12 +144,13 @@ function takeLeadingGlobals(args) { return { json, gateway, files, dir }; } -/** Strip CSI/OSC so thread names/previews cannot drive the terminal. */ +/** Strip CSI/OSC and other C0/C1 controls so thread fields cannot drive the terminal. */ function stripTerminalControls(text) { return String(text) .replace(/\u001b\[[0-9;?]*[ -/]*[@-~]/g, "") .replace(/\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)/g, "") - .replace(/\u001b./g, ""); + .replace(/\u001b./g, "") + .replace(/[\u0000-\u001F\u007F-\u009F]/g, ""); } function parseOnOff(value, flag) { diff --git a/test/codex-bridge.test.js b/test/codex-bridge.test.js index 9ab2405..6e1c6b1 100644 --- a/test/codex-bridge.test.js +++ b/test/codex-bridge.test.js @@ -289,9 +289,9 @@ test("codex list-threads strips terminal controls from names and previews", asyn { id: "t-evil", status: { type: "idle" }, - name: "Build\u001b[31mRED\u001b[0m", - preview: "hi\u001b]0;owned\u0007 there", - cwd: "/repo", + name: "Build\u001b[31mRED\u001b[0m\rOVERWRITE", + preview: "hi\u001b]0;owned\u0007 there\b\bXX", + cwd: "/repo\u0007", source: "cli", updatedAt: 1, }, @@ -303,9 +303,13 @@ test("codex list-threads strips terminal controls from names and previews", asyn try { const { code, out } = await gbot(fake.home, "codex", "list-threads"); assert.equal(code, 0); - assert.match(out, /BuildRED/); + assert.match(out, /BuildREDOVERWRITE/); assert.doesNotMatch(out, /\u001b/); assert.doesNotMatch(out, /\]0;owned/); + assert.doesNotMatch(out, /\r/); + assert.doesNotMatch(out, /\u0008/); + assert.doesNotMatch(out, /\u0007/); + assert.match(out, /hi thereXX/); } finally { await fake.close(); }