mirror of
https://github.com/mvschwarz/openrig.git
synced 2026-11-09 17:32:41 -10:00
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:
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");
|
||||
|
||||
Reference in new issue
Block a user