Output
Terminal output lists matching and uncertain files as path, a tab, then the outcome. A search of part of a file prints path:N-M instead, or path:N for one line. Counts and errors go to stderr. Nonmatches are omitted.
| Outcome | Meaning |
|---|---|
match | The model judges that the file supports the query |
no_match | The model judges that the file provides enough evidence to reject the query |
uncertain | The model reports insufficient context, or its confidence is below 0.8 |
The default confidence threshold is 0.8. Set --min-confidence 0.9 to retain answers below 0.9 as uncertain. Values range from 0 to 1; even 0 keeps an explicit uncertain answer. The threshold is a routing policy, not an accuracy guarantee. A failed request is an execution error, never a semantic outcome.
JSON retains the raw choice, confidence, and probabilities even when the threshold changes the outcome. Confidence describes the model's answer, not the completeness of a code review.
JSON Lines
ev-grep 'Performs database operations' src/ --json > results.jsonlEach line has schema_version, type, and data. This summary from a dry run selecting one text file is expanded for readability. The actual record occupies one line:
{
"schema_version": 1,
"type": "summary",
"data": {
"dry_run": true,
"errors": 0,
"evaluated": 0,
"matches": 0,
"no_match": 0,
"selected": 1,
"skipped": 0,
"uncertain": 0
}
}Extract matching paths:
jq -r 'select(.type == "result" and .data.assessment.outcome == "match") | .data.path' results.jsonlThat filter does not check for errors or uncertainty. Check the command's exit status and final summary before treating results as complete.
Exit codes
When several conditions apply, the first matching row wins:
| Code | Meaning |
|---|---|
2 | An execution or argument error occurred, possibly after partial results |
3 | Evaluation completed with at least one uncertain file |
0 | At least one match, with no errors or uncertainty |
1 | No matches, with no errors or uncertainty; includes empty selections |
Dry runs return 0 when at least one text file is selected, 1 when none are eligible, and 2 for errors. They do not evaluate files.
Record types
JSONL schema version 1 includes:
| Type | Data |
|---|---|
begin | provider, requested_model, min_confidence, dry_run, jobs |
selected | Dry run only: path, bytes |
result | path, assessment |
skipped | path, reason: "binary" |
error | path (null for run-wide errors), message |
summary | selected, evaluated, matches, no_match, uncertain, skipped, errors, dry_run |
Records for part of a file add start_line and end_line, counted from 1. path stays the plain file path, so the range never has to be parsed back out of it. Errors about the argument itself, such as a malformed range or a range on a directory, report the argument as typed in path. A range past the end of a file reports the plain path with start_line and end_line. The summary counts each file and each range as one selection.
An assessment contains outcome, raw choice, confidence, probabilities keyed by the three outcome names, actual model, input_tokens, and output_tokens. Uncertain assessments also include reason: insufficient_context or low_confidence.
Records arrive in completion order. JSONL includes every successful assessment, including nonmatches. Completed runs end with one summary; interrupted runs may not. Argument parsing errors print usage to stderr and exit 2 without starting a JSONL stream.
Object key order and human-readable messages are not stable interfaces. Version 1 may gain fields. Source contents, credentials, and human diagnostics are never written to JSON stdout.
SARIF
ev-grep 'Catches a database failure and returns an empty result' src/ --sarif > ev-grep.sarif--sarif writes one SARIF 2.1.0 log to stdout when the search ends, for code scanning tools such as GitHub's. It cannot be combined with --json. Counts and errors still go to stderr, and the exit codes above still apply.
| ev-grep | SARIF |
|---|---|
| The query | One rule, whose ID, such as query/9884e336a13bc935, is a hash of the query text; the same query keeps the same ID |
match | A result with level warning |
uncertain | A result with level note |
no_match | Left out, as in terminal output |
| An error | A notification with level error in invocations, which then reports executionSuccessful: false |
| A skipped binary file | A notification with level note |
| A dry run | No results; the selected files are listed as artifacts |
A result's message starts with the first line of the query, followed by the outcome and confidence. Its properties.assessment holds the same assessment as JSON output. A line range becomes the result's startLine and endLine; a whole-file result points at line 1. Relative paths stay relative to %SRCROOT%, the directory ev-grep ran in, and absolute paths become file:// URIs. Run ev-grep from the repository root so code scanning can find the files.
The log is written once, when the search ends, so an interrupted search writes none. Argument errors print usage and write no log.