anomalyco / anomalyco/opencode
fix(core): grep line previews include trailing newlines, emitting phantom blank lines in model output
@kitlangton is already working on this.
Since Aug 28, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Description
rg --json includes the line's trailing newline in data.lines.text (\r\n for CRLF files). packages/core/src/ripgrep.ts passes it through unmodified into Match.text (only applying the 2000-char truncation), so every grep match carries a trailing newline into both the structured tool output and the model-facing text.
In packages/core/src/tool/grep.ts:47, toModelOutput then renders Line ${match.line}: ${match.text} and joins with \n, producing a phantom blank line after every single match — while blank lines are supposed to separate files only (lines 42-44).
Reproduction
printf 'line a\nline b\n' > t.txt
rg --json line t.txt | jq -c 'select(.type=="match") | {line: .data.line_number, text: .data.lines.text}'
# {"line":1,"text":"line a\n"} <- trailing \n
Rendering through toModelOutput:
Found 2 matches
t.txt:
Line 1: line a
<- phantom blank line
Line 2: line b
<- phantom blank line
Expected
Line previews should not include the trailing newline; blank lines should only appear between file groups.
Suggested fix
Strip the trailing newline where the preview is shaped in ripgrep.ts (same place the existing 2000-char truncation and the surrogate-pair fix live), e.g. .replace(/\r?\n$/, "") before truncation.
I have a fix + tests ready and will open a PR referencing this issue.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.