A coding agent that ends in a pull request, web tool and interactive agent
Highlights
Released 2026-10-07. 0.4.1 includes the unpublished 0.4.0 line and the changes made since.
Coding agent: every task runs in its own temporary copy-on-write worktree and ends as a proposal commit on refs/greppy/agent/<run-id>, the pull request. No fixed turn cap or tool timeouts.
Production inference uses Metal on macOS and CUDA on Linux; FSKit stays optional acceleration and the ordinary workspace backend provides the same agent behavior.
Web tool (beta):greppy -p and greppy agent can drive a browser (an embedded Servo engine) through greppy web verbs. The verbs may still change.
Built-in agent (beta):greppy agent opens a full-screen terminal session. greppy -p "TASK" stays the headless one-shot mode for scripts.
Every task runs in its own temporary copy-on-write worktree and ends as a proposal commit on refs/greppy/agent/<run-id>, the pull request. Its parent is the user's baseline including uncommitted work, so the proposal contains only the agent's changes. The worktree is removed once the proposal is saved, also when a limit ends the run (exit 5); it is kept only with --keep-worktree or after a failure without a proposal (24 h expiry).
The commit message is the agent's final answer. An explicit Title: line, or else the line before Status:, becomes the subject; the answer is the body.
One prompt source renders the system prompt per mode: one-shot (-p), interactive (TUI), serve and ACP. greppy prompt --mode one-shot|interactive|serve|acp|external [--json] prints each rendering with its SHA-256; greppy prompt --external prints the prompt external agents use.
No fixed limits. There is no default turn cap; --max-turns N is opt-in and followed by one tool-free report turn. Tools have no fixed timeouts: the run deadline bounds them, and calls issued before the deadline get up to 30 s. Large tool output is folded behind expand agent-output-ID instead of cut.
No-match searches and failing tests are normal results, not tool failures, and never trigger stop advice. A leading greppy in tool argv is accepted. Toolchain caches are redirected into the run's scratch directory, so package managers work inside the sandbox.
Long sessions are compacted at complete exchanges into a model-written checkpoint; if a checkpoint cannot be saved, -p stops with an error. --continue and --resume restore the saved proposal into the new worktree, and the TUI refuses a live /resume that would not match the files on disk.
Claude models get explicit prompt-cache breakpoints for system prompt, tools and history; other providers cache implicitly.
The -p gateway check allows 2 s to connect and 15 s to answer and prints the cause when it fails.
ACP mode still edits the client's folder in place; its prompt makes no worktree or pull-request claim.
Prompt for external agents
The prompt for external agents (AGENTS.md, greppy prompt --external) now states that the task is a change to deliver: make the edits with greppy and verify them, do not stop at an analysis. Routing picks one compact command for the next step of the task. Without this, some models answered a bare issue with an analysis instead of a patch.
Added
greppy web verbs open and observe pages, then click, hover, check, extract and find. On the 14-task set greppy-web-tasks-v1 (five runs each), the engine tier and the CLI-chain tier both pass 70/70, up from 78 % and 64 %.
observe returns @N refs tied to the current document; after navigation they expire with STALE_REF. greppy web screenshot --render-complete waits for a complete render.
The public AGENTS.md carries the browser prompt block, so external agents that copy the prompt get the web tool without a second file.
The greppy agent TUI shows a header line, a Markdown transcript with tool rows, a multiline composer and a status footer. Prompts sent while the agent is busy are queued.
TUI slash commands: /help, /clear, /model, /usage, /tools, /copy, /sessions, /name, /compact, /exit. Ctrl+C cancels at a safe boundary and never interrupts an edit in progress.
Sessions are saved as JSONL and restored with --continue or --resume SESSION_ID. Each session has a greppy://sessions/<id> handle.
greppy -p --json streams newline-delimited session, text, tool, turn, error and result events. A cancelled run still ends with a result event (exit 130).
greppy agent sessions list|show|tail|path reads saved transcripts without starting the TUI.
greppy agent serve hosts a headless session on a per-user Unix socket, and greppy agent status|send|attach|interrupt|quit controls it from another shell. Remote control is a collaboration channel inside one user account, not a privilege boundary.
Changed
Agents are told to keep their task while an index builds: reuse the running index job, make one bounded wait using the reported estimate, then continue with full Greppy.
On macOS, FSKit becomes optional acceleration. The ordinary workspace backend gives the same proposal and apply behavior without the extension.
A linked worktree's Base build now reuses the shared inference cache and models. A worktree of 41 012 spans builds in 161 s instead of 1 520 s.
greppy cache gc and each Base build remove abandoned build staging directories after six hours, so leftover staging files do not keep filling the disk.
Store-CoW navigation queries the indexed Base and Delta layers directly: path went from more than 120 s to under 6 s.
Security: the embedded browser honors its HSTS preload list, its TLS stack is locked to rustls 0.23.45 (RUSTSEC-2026-0285), SubtleCrypto is off until a constant-time RSA backend exists (RUSTSEC-2023-0071), and the policy proxy caps connections at 32 per content worker and 128 per process.
The TUI moved to Ratatui 0.30.2, which drops the vulnerable lru 0.12 (GHSA-rhfx-m35p-ff5j).
Fixed
macOS: agent Base stores, Base build staging and retained bash-smart captures no longer need a separate temporary volume. They use the normal per-user locations instead of failing.
replace-text: when OLD matches nowhere, the refusal names the nearest variant (the lines that differ only in whitespace, or else the most similar lines) with its line range, its exact text and the greppy replace-lines alternative. Nothing is written.
bash-smart no longer counts source lines such as warn!(...) in a git diff as warnings.
The TUI prints why --continue or --resume cannot start instead of only "startup stopped".
On macOS, a cold index could drop 16–26 % of embedding batches as transport failures. The inference client now keeps reading after the daemon closes its side.
Rust calls like store::f() resolve to the named module, not to a same-named function in the caller's file.
read returns a temporary failure while the graph is refreshing, so it never pairs current bytes with a stale span.
Since the 0.4.0 line, fixes for the web tool, indexing, the CLI, edits and search have landed on the release branch.
0.4.0
Development line, superseded by 0.4.1
Highlights
The workspace version was set to 0.4.0 on 2026-09-02; the date above is that commit.
Never published: no 0.4.0 tag or GitHub release exists. On 2026-09-28 0.4.1 was chosen as the next release instead.
All of this line ships in 0.4.1, together with the repairs made since. See 0.4.1.
The line brought the beta web tool, the beta interactive agent, persistent and remote-controlled agent sessions, and linked worktrees that reuse the shared inference cache.
Also in the line: security hardening of the embedded browser runtime.
Never tagged or published. The version was prepared on 2026-08-30; development then moved to the 0.4.0 line, and later 0.3.x work was reserved for stability fixes.
greppy -p has one fail-closed workspace path, built for macOS ARM64, Linux x86_64 and Windows x86_64. The Windows provider stays diagnostic: unchanged WinFsp 2.1 has no hard links, which this workspace contract requires.
Linked Git worktrees share one immutable, Git-tree-bound Base index and publish only their own private Delta.
The interactive greppy agent TUI, which the CHANGELOG lists under 0.3.4, reached main with the 0.4.0 web-runtime merge; it is described under 0.4.1.
Added
workspace setup, workspace doctor --json, workspace status --json and workspace gc manage one per-user provider mount: FUSE3 with a systemd user service on Linux, a bundled FSKit app extension on macOS 15+.
greppy agent apply REF applies a proposal made from a dirty checkout: it checks the exact baseline, keeps your Git index and applies only the agent's changes.
Proposal publish and apply are journaled: an interrupted publish or apply is recovered, and apply leaves the Git index byte-identical.
Embedding and summary results are cached user-wide. Linked worktrees and agents reuse identical content; only changed Delta documents cost inference.
Changed
The 0.3.3 snapshot backends, the Git worktree fallback, --workspace-backend and --fresh were removed.
The agent workspace stores files as fixed 1 MiB BLAKE3-addressed chunks, so a partial write replaces only the touched chunks.
Agent Base prewarming fails closed: a graph, embedding, summary or publication failure stops index --agent-worktree and greppy -p before the first model call. --device and --no-gpu are respected.
All heavyweight embedding work goes through one user-scoped daemon per device and model, instead of each client loading EmbeddingGemma.
index status works while an index writer is active and reports phase, span progress and ETA. An active first build reports status=indexing instead of no_index.
Semantic search on an incomplete embedding generation returns exit 75 with an explicit index status --json retry condition.
The first graph query on a large repository starts one background index job, waits at most two seconds and returns retryable exit 75 instead of an unbounded walk.
Structural edges are committed in one transaction, removing a multi-minute tail on large repositories.
A worktree waiting for another Base publisher stops after five seconds with exit 75 and the lock path.
Base publication no longer generates summaries up front; they are generated on demand.
bash-smart prints a heartbeat after 15 s of silence and once a minute after that, applies leading VAR=value tokens, and uses pipefail for quoted pipelines.
Edit verification picks a local checker for the touched language, never downloads one and stops it at a bounded timeout.
Fixed
read-file --all and read-file --lines no longer touch the graph store, so they work during a first index.
Literal-search rows print qualified locators that greppy read accepts.
grep and rg passthrough tolerate delayed pipeline producers; an explicit - stays the unbounded form for slow producers.
path --code explains that path is call-site-only and names the greppy read SYMBOL recovery.
0.3.3
Isolated Filesystem-CoW workspaces for the agent
Highlights
greppy -p creates private Filesystem-CoW workspaces before the model starts.
New --workspace-backend auto|native|cow option. auto (the default) uses copy-on-write only when it is constant-time metadata work, and otherwise falls back to the unchanged 0.3.2 Git-worktree path.
native forces the 0.3.2 path. cow requires exact copy-on-write and fails instead of silently copying files.
Added
Each copy-on-write run gets a real private Git directory. Existing objects are shared read-only; new objects, indexes, refs and commits stay private until finish exports one verified proposal commit.
The snapshot code is greppy-rift-core, a purpose-built MIT-licensed fork of anomalyco/rift pinned to a fixed revision. It keeps only the APFS, Btrfs and Linux reflink mechanics plus capability probing and cleanup.
Btrfs templates are created as read-only subvolumes. On a 300,000-file tree, ten warm creations measured 345.735 ms median and 385.708 ms P95 (limits: 500 ms median, 1,000 ms P95).
Changed
Capability reports distinguish Btrfs subvolume snapshots from copy-on-write trees that walk the namespace. APFS directory clonefile and Linux per-file FICLONE stay available explicitly, but auto does not pick them.
Windows keeps using the native Git-worktree fallback.
If a workspace looks tampered with, it is preserved instead of being deleted or published.
Fixed
Windows agent workspaces and sandbox Cargo paths resolve from LOCALAPPDATA and USERPROFILE instead of a Unix-only HOME assumption. Windows CI now runs the agent workspace suite.
Extended-length Windows paths are converted to ordinary drive or UNC form before they are passed to Git, which rejects \\?\ paths.
0.3.2
Parallel agents share one immutable index
Highlights
Concurrent greppy -p runs share one content-identified, immutable Base index for unchanged code; each agent writes only to its own private Delta.
One leased builder publishes the complete Base — graph, text index, summaries and embeddings — atomically; other agents reuse it read-only.
brief accepts multiple symbols, including newline-separated selectors on stdin.
Concurrency tests gate ten agents and stress fifty isolated Deltas; Base summaries and embeddings are reused across ten agents without duplicate private rows.
Added
greppy index --agent-worktree builds or validates the same shared Base the agent will use.
greppy -p --private-store opts one run out of Base reuse, for diagnosis.
doctor, diagnostics and index-health output report the store mode, identities, completeness, changed paths, cache hits and any fallback reason.
Changed
The Base identity covers the Git tree, store schema, indexer contract and the summary and embedding contracts. Corrupt or incompatible generations are quarantined and rebuilt.
Navigation, search, brief, read, expand, stats and freshness checks all see the Base plus the agent's own edits, deletes and renames; an exact revert removes the agent's contribution.
Shared Bases take part in cache TTL/LRU management and are not evicted while an agent is reading them.
Batched brief keeps the requested order and applies the output budget only at whole results, with a usable retry when the next result does not fit.
The agent's navigation guidance treats one semantic search result as a ranked candidate set and forbids repeated paraphrased searches.
read-file accepts absolute paths outside the repository (for example downloaded artifacts); relative ../ paths stay confined to the repository.
Upgrading from an existing 0.3.1-shaped cache is covered by release-package tests: cache clearing removes managed data and keeps unmanaged legacy files.
Fixed
Automatic CLI option recovery treats -- as a hard boundary. A malformed call is refused once with usage output instead of recursing until a stack overflow.
0.3.1
Interim tag of the 0.3 line: built-in agent and benchmark fixes
Highlights
Tag v0.3.1 (2026-08-11) points to a commit that is an ancestor of v0.3.0. Only two commits separate them: the version renumbering back to 0.3.0 and a CI audit fix. See 0.3.0 for the full contents of the 0.3 line.
The version string read 0.3.1 from 2026-08-08, so that builds of this line would not report greppy 0.3.0.
No GitHub release was published for this tag.
New: greppy -p "TASK" runs a one-shot coding agent over the current repository and delivers its result as one commit on refs/greppy/agent/<run_id>.
Added
The agent's only tool is greppy itself (search, navigate, read, edit, and commands through bash-smart -- CMD); the agent loop is ported from pi v0.80.2 (MIT).
The agent talks to a localhost Anthropic-Messages-compatible gateway (default CLIProxyAPI on 127.0.0.1:8317), configured with GREPPY_ENDPOINT, GREPPY_MODEL and GREPPY_API_KEY.
Tool subprocesses are write-confined with Seatbelt on macOS and Landlock on Linux; --no-sandbox turns this off.
git show <ref> reviews the agent's commit, git cherry-pick -n <ref> applies it, and --apply applies it directly on a clean checkout.
greppy index --agent-worktree prepares and indexes the worktree greppy -p runs in, so the agent does not pay for its first index.
--deadline-secs N / GREPPY_DEADLINE_SECS stops the agent between turns at a wall-clock budget and still delivers the result.
Changed
A stale-index answer leads with the fix, phrased like doctor; index contention names the wait and greppy index status --json.
search-pattern … --fixed names the flag when a regular expression cannot match under --fixed.
Edit receipts echo the landed span with three lines of context, read back from disk, with changed lines marked.
who-calls on a module lists the module's own definitions and names the two commands that answer the question.
Fixed
greppy PATTERN FILE stays grep even when the pattern is close to a command name (greppy greppy FILE was refused).
A mistyped flag such as --jsoon is corrected instead of silently dropped.
index --agent-worktree now writes to the data root the agent actually reads; before, prewarmed agents still paid the full first index.
One invalid parser record no longer discards a whole file, and C++ written in .h headers is re-extracted with the C++ grammar.
A dead embedding-daemon endpoint falls back to in-process embedding instead of failing every semantic query.
0.3.0
Breaking redesign: find, read and edit in one tool, plus greppy -p
Highlights
Breaking release with no aliases or deprecation period: vocabulary that is gone is refused.
One search family on one axis: search "WHAT IT DOES" (meaning), search-symbol NAME (name), search-pattern REGEX [--fixed] (text).
New read and edit commands with receipts, so an agent can change exactly what it read without re-reading the file.
greppy -p "TASK": a built-in one-shot coding agent whose result is one commit on refs/greppy/agent/<run_id>; nothing is edited in place.
Includes everything first tagged as v0.3.1 on 2026-08-11 (see 0.3.1).
Added
where-am-i gives a session overview: languages, file and definition counts, each module's most referenced symbols, entry points and test roots.
read S returns a definition byte-exactly, read-smart S folds nested blocks into one-line descriptions, and read-file PATH pages at 400 lines.
--handle names exactly the printed span, including when output was cut, and replace-span accepts it.
Each edit receipt names every touched span; --dry-run changes nothing; refusals state their reason; patch lands whole or not at all; undo refuses if a later edit touched the same span.
bash-smart -- CMD runs a build or test command unchanged with the same exit code, and returns a verdict line plus the error and warning blocks.
The agent uses a localhost Anthropic-Messages-compatible gateway (default CLIProxyAPI on 127.0.0.1:8317) and write-confines its tool subprocesses with Seatbelt on macOS and Landlock on Linux.
index [PATH] --agent-worktree prepares the agent's worktree index ahead of time; --deadline-secs N stops the agent cleanly at a wall-clock budget.
Changed
who-calls and callees answer for several symbols at once. find-usages is gone: who-calls walks both calls and usages.
brief sketches a body — the signature plus one line per step — and impact and path --from A --to B print trees.
--path, --json, --limit/--offset, --root and --help work on every command. Empty answers exit 0; the search family keeps grep's exit codes.
AGENTS.md is the system prompt, held by twelve guard tests and a 33-case release smoke gate that runs every advertised line against the built binary.
GPU acceleration is the default build: Metal on macOS, CUDA on Linux and Windows; --features cpu-only is the single escape.
A stale-index answer leads with the fix, and index contention names the wait and greppy index status --json.
Known limits: about 13 % of CALLS edges resolve on ambiguous names, and group imports extract only their first name.
Fixed
greppy greppy FILE stays grep, and a mistyped flag such as --jsoon is corrected instead of dropped.
The --max-bytes output budget works again and never shrinks an answer to zero rows.
Prewarmed agents read the store index --agent-worktree wrote; before, they paid the full first index inside the run (9× slower in the benchmark).
Template-heavy C++ headers no longer lose definitions: .h files with C++ syntax are re-extracted with the C++ grammar.
A dead embedding-daemon endpoint falls back to in-process embedding; edit receipts echo the landed span; who-calls on a module lists its definitions.
0.2.1
First public release, with the MSCC paper
Highlights
First public release: the published build passed every automated test, the security scans of code and dependencies, and the quality checks for search and function hints.
The macOS binary is signed and notarized and the release is attested (SBOM and provenance); the direct-download Windows binary is unsigned by design.
Publishes the MSCC paper and the complete four-model evidence (MiniMax-M3, GLM-5.2, Qwen3.6-27B, Kimi-K3).
The CHANGELOG has no separate entries for 0.1.3 and 0.2.0; several items below first appeared in those versions.
Added
Embedded Qwen3.5-0.8B (Q4_K_M, MTP) writes short purpose summaries for brief and semantic-search, with CPU, Metal and CUDA inference.
Versioned JSON output contracts with exact spans, source signatures, summaries and durable expand handles.
greppy doctor --json reports the inference backends, device probing, memory checks, daemon status and model digests.
Managed cache inspection, garbage collection and explicit clearing.
A Windows named-pipe transport for the embedded inference daemons.
Changed
Ordinary grep invocations are byte-exact passthrough to the real grep, with no index, model or cache side effects.
Freshness is fail-closed: greppy does not knowingly print stale source evidence.
EmbeddingGemma and Qwen model assets are mandatory in every binary; only the inference backend and device can be selected.
A model is unloaded after 300 idle seconds; an inference daemon exits after 1800 idle seconds.
Removed: synthetic grep-output augmentation and sidecars, NON_CANONICAL_CODE_HINT, the --vectors switch, public model-disable and model-path controls, installing greppy as grep, and the in-product self-updater.
Source relicensed from MIT to Apache-2.0. Embedded model terms are unchanged: EmbeddingGemma under the Gemma Terms, the in-house Qwen3.5 fine-tune under Apache-2.0.
Model weights are hosted in public, ungated Hugging Face repositories (metricspace/embeddinggemma-300m-q4k, metricspace/greppy-qwen35-mtp-q4km); the build downloads and SHA-256-verifies them before embedding.
Fixed
greppy index publishes the complete graph when embedding inference degrades, instead of discarding all work; embedded vectors are kept and the next semantic query finishes the rest in the background.
0.2.0
More reliable function hints and an index that survives model failures
Highlights
Never tagged or published. Its changes are part of the 0.2.1 release.
Function hints got more reliable: on a fixed test set of 300 functions, anti-helpful hints dropped from 8.6 % to 2.5 % and very helpful hints rose from 34.4 % to 44.1 %, at unchanged format validity (97 %).
The MSCC paper draft (docs/paper/mscc-greppy-paper.pdf) was added and linked from the README.
Changed
The hint decoder runs greedy decoding first and falls back to sampling only when the greedy output is empty.
The hint model receives the definition's repository-relative file path along with its source, matching how it was trained.
The embedded hint model was updated to the checkpoint published as model-qwen35-nano-20260716-0749.
A legal review of redistributing the embedded models was completed; licenses/EMBEDDED-MODEL-TERMS.md states the terms for the model weights.
macOS packages are notarized by Apple. The Windows binary for direct download is unsigned.
Fixed
greppy index no longer throws away the graph when embedding inference fails: it publishes the graph with the vectors that did embed, and the next semantic query retries only the failed documents.
On macOS and BSD, a regular file left at the daemon endpoint path is treated as "no daemon", so the next call replaces it instead of failing until someone deletes it by hand.
Freshness checks treat persisted index skip records as a baseline only while their file identity and policy still match.
Greppy's own global options (--root, --device, --no-gpu, --no-summaries) are consumed before an invocation is forwarded to grep.
0.1.3
Evidence packs, function hints and managed caches
Highlights
Never tagged or published. Its changes are part of the 0.2.1 release.
greppy expand ID prints a prepared evidence pack — the full source of a query's top matches — in one call. who-calls, callees, impact and semantic-search may end with an Expand: greppy expand <id> line.
An embedded Qwen3.5-0.8B model (Q4_K_M with multi-token prediction) adds a short purpose hint under returned function signatures and to each definition printed by brief.
Added
greppy cache status, greppy cache gc and greppy cache clear inspect and reclaim Greppy-managed cache data.
greppy trial runs one mechanically graded A/B observation on your own project: the same who-calls question answered with and without Greppy through Pi.
Speculative multi-token-prediction decoding for the hint model on CPU, Metal and CUDA.
While first-use embeddings are still building, semantic-search returns a retryable status (exit 75) with the backend, progress and an ETA instead of partial results.
Changed
semantic was renamed to semantic-search (the old name stays as an alias) and always uses EmbeddingGemma vector embeddings; --vectors became a hidden no-op.
Ordinary grep invocations run the real system grep byte-for-byte, without opening an index or loading a model. Greppy is installed only as greppy, never as grep.
The placeholder install, uninstall, update and config commands were removed.
Both models (EmbeddingGemma and Qwen3.5) and their tokenizers are embedded in every binary and cannot be disabled.
The embedding and summary engines run as separate local daemons: a model stays loaded for five idle minutes and a daemon exits after 30 idle minutes.
Model files are fetched from pinned GitHub release assets and digest-verified before the build, instead of from Git LFS.
macOS packages are now notarized, and every release is scanned for security issues in its code and dependencies.
Fixed
Indexing no longer stalls on minified files: spans containing a line longer than 2 KB are skipped, and a 306 KB minified file now embeds in about 2.5 s.
A pure Git HEAD move no longer triggers a reindex.
Hung inference daemons are recovered.
Result accounting in semantic-search evidence packs was corrected.
0.1.2
First public commit: grep plus code-navigation commands
Highlights
The first public commit already carried version 0.1.2; there is no tag and no GitHub release.
Any invocation that is not a greppy command runs the real grep and returns its output and exit code unchanged.
A typed symbol graph (CALLS, USES, TYPE_REF, IMPORTS) answers relationship questions with resolved qualified_name file:line results instead of text matches.
Google's EmbeddingGemma is built into the binary for semantic search and runs on CPU, Apple Metal or NVIDIA CUDA, auto-detected.
Added
who-calls, callees, find-usages, impact, path --from A --to B and brief over the graph.
search-symbols NAME finds definitions by name.
semantic finds code by meaning. By default it uses lexical ranking; --vectors switches to EmbeddingGemma vector search.
A warm embedding daemon keeps the model loaded between calls and releases it when idle.
Also included: index, doctor, stats, diagnostics, trace, fan-in, fan-out, graph-locate, search-graph, search-code, plus and context.
Common flags: --code, --all, --json, --root DIR, --kind, and --direction / --depth for impact.
The README lists 107 supported languages; tree-sitter parsers and SQLite are compiled in.