Skip to content

[Bug]: grep content parser still breaks on CRLF / path parsing; #2962 appears incomplete #3439

@EnochLi15

Description

@EnochLi15

Summary

The custom grep tool provided by oh-my-openagent still has a parser bug in output_mode: "content" (and potentially count) because it parses CLI stdout using regexes that assume Unix line endings and colon-delimited paths.

This appears to be the same issue family as #2962, but #2962 seems to have been closed before CRLF handling was fully fixed.

Open PR #3321 looks like the correct fix:

What is happening

When OmO is enabled, the active grep tool is the plugin implementation in src/tools/grep/*, not OpenCode's native grep tool.

For output_mode: "content", OmO eventually does this in src/tools/grep/cli.ts:

const lines = output.split("\n")
const match = line.match(/^(.+?):(\d+):(.*)$/)

This is fragile for two reasons:

  1. split("\n") leaves a trailing \r on CRLF output.
  2. ^(.+?):(\d+):(.*)$ breaks on Windows drive-letter paths like C:\path\file.ts:42:text.

If either case happens, the line is silently dropped and the tool reports No matches found even though ripgrep did return a match.

Why this matters

This is easy to miss because:

  • files_with_matches often still works
  • count may appear to work in some environments
  • the bug is in the parser layer, not in the search itself

So the end user sees "content mode can't find a match" even though the file/path/pattern are valid.

Reproduction

Tool call:

{"name":"grep","input":{"pattern":"ContBindIF","path":"VSM_mim.xml","output_mode":"content"}}

Example XML line:

<class opright="add|del|modify|query" type="CFG" name="ContBindIF">

The | characters in the XML are not the root cause.
The real issue is the parser in parseOutput() / parseCountOutput().

Root cause

Current parser logic in src/tools/grep/cli.ts depends on raw stdout looking exactly like path:line:text.
That assumption is not stable across environments.

Suggested fix

The change in PR #3321 looks correct and low-risk:

  • strip trailing \r from each line before matching
  • update the regex to support Windows drive-letter paths

Suggested regexes from the PR:

line = line.replace(/\r$/, "")
const match = line.match(/^([A-Za-z]:[\\/].*?|.+?):(\d+):(.*)$/)
const countMatch = line.match(/^([A-Za-z]:[\\/].*?|.+?):(\d+)$/)

Longer-term improvement

A more robust fix would be to stop parsing plain-text ripgrep output for content / count and use structured rg --json output instead.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions