fix(transcript-store): filter startup splash/header lines from cleaned view

TranscriptStore's cleaned transcript view already handled 3 of 4
PM noise classes (orphan cursor fragments, status overlays,
spinner/chrome/TUI). Startup splash/header lines survived cleanup.

Add isStartupSplashLine() filter for:
- Claude Code version headers ("Claude Code v2.1.101")
- Claude model/plan lines ("Opus 4.6 (Claude Max)")
- Codex version headers ("OpenAI Codex (v0.120.0)"), including
  box-drawing-wrapped variants from Codex's TUI banner

Pattern uses ^ anchoring so legitimate sentences mentioning these
strings ("I was running Claude Code v2.1.101 when...") survive.
Box-drawing chars stripped before matching to handle Codex's
bordered startup banner.

Conservative scope per QA directive: does NOT filter generic
"model:" or "directory:" lines that could be legitimate command
output. Only filters clearly-branded startup header patterns.

Tests added (2): startup splash lines removed from both runtimes
+ preservation of legitimate sentences mentioning splash strings.

Product recommendation: rig transcript stays cleaned-by-default;
--raw/--clean split deferred unless forensic workflows request it.

Gates: transcript-store 32/32 (+2); full daemon 1801/1801;
tsc + build clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
This commit is contained in:
mvschwarzandClaude Opus 4.6 committed 2026-04-22 22:55:54 -07:00
1 parent d02ee30f06
commit 84162bd078
2 files changed
+63

No files matched your search

@@ -69,6 +69,19 @@ function stripOrphanCursorFragments(line: string): string {
return line.replace(/\[\d{1,3}[A-Za-z](?=\S)/g, " ");
}
function isStartupSplashLine(line: string): boolean {
// Strip box-drawing wrappers from Codex-style banners before matching
const stripped = line.replace(/[│╭╰╮╯─━]/g, "").trim();
if (!stripped) return false;
// Claude Code version header: "Claude Code v2.1.101"
if (/^Claude Code v[\d.]+/.test(stripped)) return true;
// Claude model/plan line: "Opus 4.6 (Claude Max)", "Sonnet 4.6 (1M context)"
if (/^(?:Opus|Sonnet|Haiku) \d[\d.]+ /.test(stripped)) return true;
// Codex version header: "OpenAI Codex (v0.120.0)", ">_ OpenAI Codex (v0.120.0)"
if (/^>?_?\s*(?:OpenAI )?Codex\b.*v[\d.]+/.test(stripped)) return true;
return false;
}
function isStatusOverlayLine(line: string): boolean {
const trimmed = line.trim();
if (!trimmed) return false;
@@ -248,6 +261,7 @@ export class TranscriptStore {
.filter((line) => line.trim() !== "")
.filter((line) => !isBareShellPrompt(line));
return filtered
.filter((line) => !isStartupSplashLine(line))
.filter((line) => !isStatusOverlayLine(line))
.filter((line) => !isUiChromeLine(line))
.filter((line) => !isSpinnerOnlyLine(line))
@@ -333,6 +333,55 @@ describe("TranscriptStore", () => {
expect(result).toContain("We were discussing the gpt-5.4 xhigh fast footer format yesterday.");
});
it("drops startup splash/header lines from Claude Code and Codex sessions", () => {
const store = new TranscriptStore({ transcriptsRoot: tmpDir });
store.ensureTranscriptDir("my-rig");
const filePath = store.getTranscriptPath("my-rig", "dev@my-rig");
writeFileSync(
filePath,
[
"Claude Code v2.1.101",
"Opus 4.6 (Claude Max)",
"╭───────────────────────────────────────╮",
"│ >_ OpenAI Codex (v0.120.0) │",
"│ │",
"│ model: gpt-5.4 /model to change │",
"│ directory: ~/code/openrig │",
"╰───────────────────────────────────────╯",
"real semantic transcript content should survive",
"and this line too",
].join("\n") + "\n",
);
const result = store.readTail("my-rig", "dev@my-rig", 20);
expect(result).toContain("real semantic transcript content should survive");
expect(result).toContain("and this line too");
expect(result).not.toContain("Claude Code v2.1.101");
expect(result).not.toContain("Opus 4.6");
expect(result).not.toContain("OpenAI Codex");
});
it("preserves legitimate sentences that mention startup splash strings", () => {
const store = new TranscriptStore({ transcriptsRoot: tmpDir });
store.ensureTranscriptDir("my-rig");
const filePath = store.getTranscriptPath("my-rig", "dev@my-rig");
writeFileSync(
filePath,
[
"I was running Claude Code v2.1.101 when the bug appeared.",
"The Opus 4.6 model performed well on the benchmark.",
"We tested against OpenAI Codex (v0.120.0) for comparison.",
].join("\n") + "\n",
);
const result = store.readTail("my-rig", "dev@my-rig", 20);
expect(result).toContain("I was running Claude Code v2.1.101 when the bug appeared.");
expect(result).toContain("The Opus 4.6 model performed well on the benchmark.");
expect(result).toContain("We tested against OpenAI Codex (v0.120.0) for comparison.");
});
it("preserves literal cursor-fragment tokens when they are mentioned as data", () => {
const store = new TranscriptStore({ transcriptsRoot: tmpDir });
store.ensureTranscriptDir("my-rig");