Skip to content
6 changes: 6 additions & 0 deletions changes/concise-search-grep-output.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"githits": patch
"@githits/mcp": patch
---

- **Concise search and grep output** - Use plain outcome counts and shared Read, More results and Follow-up footers, retaining exact native actions, source/preparation provenance and meaningful coverage warnings without repeated header flags. JSON and request behavior are unchanged.
46 changes: 20 additions & 26 deletions docs/implementation/mcp-cli-parity.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,25 +369,17 @@ readiness, trust limits, and action selection; the text renderer owns wording,
wrapping, hit anatomy, and ordering. Callers provide ANSI enablement,
surface-native action syntax, and an optional output width. CLI supplies its
current terminal width; MCP uses the formatter's 80-column default. The order is
an outcome headline carrying count/breakdown, lifecycle, readiness, and
pagination when applicable; shared `Sources:` bullet rows for searched evidence,
one plain outcome sentence counting each returned kind once, without lifecycle,
readiness fractions or pagination; shared `Sources:` rows for searched evidence,
then `Preparing:` rows for actual work before ranked hits. Known repository rows
use an 8-character display SHA, optional independent date and historical ref;
current healthy evidence uses the same shape. Documentation rows retain exact
site scope/corpus and package attribution. Unknown identities retain supplied
labels. Zero-hit searched sources disclose their scope; unsearched/withheld
sources retain target-local readiness/recovery instead. Different full SHAs,
corpora, readiness or coverage remain distinct. Target-local limitations and
global warnings remain visible, followed by at most one final `Next:` action.

`PENDING`, `INDEXING`, and `SEARCHING` remain distinct. Active empty output uses
`No results yet | indexing | 0/1 ready`; an active response without a snapshot
uses `No result snapshot yet | indexing | 0/1 ready`, with corresponding
lower-case lifecycle labels for other active states. Active result counts use
`partial` only when `partialResults` is true; otherwise they say `results`
beside the lifecycle. Terminal
or unknown progress retains lifecycle/readiness in the headline, while completed
output omits them. Target rows keep deterministic `commit`/`using`, `searched`,
use an 8-character display SHA, optional independent date and historical ref.
Target/source limitations remain attributed. Backend partialResults gets a short
full-request warning only when those rows do not explain the missing scope.
Terminal and unknown states retain explicit prose; active work gets a notice
only when otherwise unexplained. Empty active output says `No results available
yet.`; empty continuation pages say `No results on this page.`

Target rows keep deterministic `commit`/`using`, `searched`,
`indexing`, terminal/unavailable, `available`, `indexed`, and constraint segments;
exact terminal reasons remain lane-readable, and a target gets at most one
inline `Fix:` or replayable `Try:` line. Site suggestions and indexed alternatives
Expand All @@ -401,14 +393,16 @@ codes, indexing references, and opaque evidence text stay out of default text.
Reissuing the same search is valid and waits on the same underlying work; text
does not emit negative repeat or poll policy directives.

MCP renders `Next: search_status search_ref=... wait_timeout_ms=...`; CLI renders
`Next: githits search-status ... --wait ...`. An active continuation reference
appears exactly once, in that surface-native final `Next:` action; stopped terminal
references are not rendered. Raw diagnostic fields are never rendered.
Search results omit per-hit read commands from both text surfaces. ANSI-stripped
CLI output shares the same hierarchy and wording as no-color MCP text; line
breaks can differ because CLI uses the terminal width while MCP uses the
80-column default.
Search and grep share optional `Read:`, `More results:` and `Follow-up:` footers
in that order. Search offers one exact read example, including healthy completed
results; grep offers file/page templates after matches. MCP actions use native
`read`, `search_status` and argument syntax; CLI actions use `githits` commands.
A status reference appears once under Follow-up. With usable hits, reading is
first and waiting conditional; stopped references never poll. Pagination repeats
the original search with its exact offset or grep with its opaque cursor,
preserving original controls. Search status cannot paginate. ANSI changes only
emphasis; widths can differ. See [snapshot presentation](search-snapshot-presentation.md#concise-search-and-grep-headers-and-footers)
for zero-page, limitation and continuation rules. JSON remains unchanged.

Documentation JSON retains `docsReadTarget`, compatible `pageId`, and provenance
`sourceUrl`. Search/status JSON follow-ups consume the backend `ReadTarget`
Expand Down
89 changes: 84 additions & 5 deletions docs/implementation/search-snapshot-presentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,16 @@ stored and could not obtain later evidence.
With returned hits, an active search now leads with:

```text
Next: use these hits now; read for details:
read target="github:anomalyco/opencode@bbd72fb8" path="..." start_line=480 end_line=490
For a specific ref, search github:anomalyco/opencode@<ref>.
If you need current HEAD, wait (hits and order may change):
search_status search_ref="..." wait_timeout_ms=120000
Found 1 code result.

Read:
Use these results now; example read:
read target="github:anomalyco/opencode@bbd72fb8" path="..." start_line=480 end_line=490
For a specific ref, search github:anomalyco/opencode@<ref>.

Follow-up:
If you need current HEAD, wait (hits and order may change):
search_status search_ref="..." wait_timeout_ms=120000
```

The specific-ref advice and HEAD-specific conditional appear only for proved
Expand Down Expand Up @@ -502,3 +507,77 @@ guideline against default-true agent booleans, preserving the existing
flag. Compact query echo omits true as a default; false remains explicit. The
parameter/status description changes are in this same user-directed increment;
qualitative eval authentication limits above remain unchanged.


## Concise search and grep headers and footers

The shared `search-grep-output-text.ts` owns only the fixed footer order and
indentation: optional **Read**, **More results**, then **Follow-up**. Each tool
renderer owns its outcome, limitations, lifecycle and exact native operands.
There is no command reconstruction or new service/state layer. Initial search
and search status continue to share their semantic projection and renderer.

Search counts each returned result once by kind, for example `Found 2 code
results and 1 documentation result.` Grep counts page occurrences, distinct
physical lines and exact file/page identities: `Found 4 matches on 3 lines in
2 files.` Headlines omit pipe separators, readiness fractions, pagination and
abstract partial/interim labels. Sources/Preparing and attributed coverage notes
explain available evidence and missing scope. Only otherwise unexplained facts
get a short notice: `These results do not cover the full request.` for backend
partialResults, or explicit running/terminal/unknown lifecycle prose. The private
availability projection retains partialResults, including completed empty
snapshots; public JSON is unchanged. Dates do not drive these decisions.

Healthy searches offer one exact read example without use-now prose. When a wait
is offered beside usable hits, the read comes first with short use-now advice;
the wait remains conditional. Readless usable results put `Use these results now.`
first in Follow-up. Grep templates follow all matches; CLI templates include
`githits`. Standalone read, pagination and status actions remain unwrapped;
grep omitted-target retry remains wrapped guidance, as in the approved copy.
ANSI changes only emphasis. Empty outputs omit read advice.

Pagination always lives in More results, independently of lifecycle. Search/status
instruct repeating the original search with the exact next offset, preserving
its target/query/filter controls; status itself cannot paginate. A missing offset
gets a truthful availability hint with no invented value. Active search pages
warn that results can change. Grep preserves the opaque cursor for the original
ordered targets and controls. Follow-up retains seconds for CLI search-status
and milliseconds for MCP status and grep retries. Ended references never poll.
Counted alternatives say `(+N more)`; unknown `+more` remains unknown.

For grep, CURRENT+RESUMABLE_LIMIT and UNSPECIFIED+RESUMABLE_LIMIT are ordinary
pagination absent independent errors/skips. The strict exhaustive predicate
still controls source-level `no results` claims. Retryable-only omitted targets
use `No matches available yet.` (adding `on this page` beside a cursor), even
when omission accounting yields NON_RESUMABLE_PARTIAL overall. Preparing/Omitted
already explains that limit. Independent failed traversal, stale readiness,
errors/skips/issues and expired cursors retain attributed warnings. Unspecified
readiness outside unvisited pagination is explicitly unknown. Search/grep empty
continuation pages say `No results on this page.` / `No matches on this page.`


Follow-up verification (2026-10-07): full `bun test` passes 5,624 tests across
235 files, zero failures and 22,404 assertions. Typecheck, both builds, source
and built CLI/MCP smoke checks, and packed public-package validation pass. Smoke
business cohorts skipped AUTH_REQUIRED; authenticated dev calls separately
prove output. Pending CLI search/grep used registry-confirmed Express 2.3.12;
MCP grep used 2.4.0 and fresh pending MCP search/status used 2.4.1. Both pending
search surfaces returned one hosted-doc result with actual repository Preparing,
indexed alternatives, native read, offset1 and conditional status. Immediate
MCP status returned byte-identical text. Once indexed, healthy CLI/MCP search
returned code with Sources, Read and More results, without a wait. Initial MCP
search's transient Keychain error was retried successfully; no auth code changed.

The same fixed renderer fixtures measure ready search 89 -> 163 bytes (+74),
preparing search 459 -> 553 (+94) and mixed paged grep 6992 -> 6985 (-7). Search
adds actionable read/pagination footers the baseline omitted. These are output
bytes, not tokens, latency or proof of agent quality. Targeted Claude agent:e2e
search-investigation and grep-mixed-docs remained blocked by `Not logged in`:
zero tool calls, no final/isolation artifacts, unknown usage. No comprehension
claim follows. The revised cursor/coverage closure passes 354 focused tests,
zero failures and 1,353 assertions; the final headline-assertion closure passes
19 tests, zero failures and 118 assertions. Typecheck, both builds and
source/built CLI/MCP smoke checks pass after the production correction.
Internal review and fresh Claude Opus 5.5 review, including its final
fresh-context check, are clean for implementation commit 384e9c2. No major
deferred item or new infrastructure was introduced.
Loading
Loading