# Stitch: Deterministic File Edits for AI Agents
[](https://github.com/Summykai/stitch-core/actions)
[](https://crates.io/crates/stitch-core)
[](https://badge.fury.io/py/stitch-core)
[](https://github.com/Summykai/stitch-core/stargazers)
[](https://github.com/Summykai/stitch-core/issues)
[](https://www.rust-lang.org/)
[](https://www.python.org/downloads/)
**Stitch is a small CLI that sits between your AI agent and the filesystem.**
Agents send a structured “patch” (`@stitch` block); Stitch verifies the expected context, corrects for line drift, and applies the change atomically, returning a JSON report the agent can use to self-correct.
It’s meant to replace fragile `sed`, `awk`, or ad-hoc `write_file` commands in agentic workflows.
---
## Why Agents Fail at Editing Code
Most LLM agents treat file editing as simple text replacement:
- **The Drift Problem** – The agent reads a file, then other changes move lines around. Its line-number-based edit corrupts the file.
- **The Context Problem** – There’s no verification that the surrounding code matches the agent’s assumption before writing.
- **The Tooling Problem** – Shell-based edits (`sed`, `awk`, escaping hell) often break in surprising ways, leading to loops of failed commands.
Stitch treats this as a **search + reconciliation** problem instead of “dumb replace”:
1. You specify what content you **expect** to see.
2. Stitch searches near an optional line anchor, tolerating small shifts and indentation differences.
3. If it finds the expected context, it applies the change atomically; if not, it tells you exactly what it found instead.
---
## Key Features
- **Context-aware editing**
Edits are anchored on expected content, not just line numbers. If the context doesn’t match, Stitch refuses to touch the file.
- **Drift correction**
When line numbers are wrong, Stitch searches a configurable window around the anchor to find the right place.
- **Atomic writes**
Changes are written via a temp file + atomic replace, reducing the risk of partial or corrupted writes.
- **Structured feedback (JSON)**
Every operation returns a machine-readable JSON report (`success` / `context_not_found` / `file_not_found` with metadata) that agents can feed back into their reasoning loop.
- **Core verbs**
Supports `CREATE`, `UPDATE`, `APPEND`, and `DELETE`.
- **Simple CLI integration**
Reads from `stdin` or a file, so it plugs into any language, framework, or agent runtime.
---
## Quickstart
### Install
**Rust (Crates.io, recommended)**
```bash
cargo install stitch-corePrebuilt binaries (GitHub Releases)
Download the latest release for your platform:
- Linux x86_64
https://github.com/Summykai/stitch-core/releases/latest/download/stitch-v0.1.0-x86_64-unknown-linux-gnu.tar.gz - macOS x86_64
https://github.com/Summykai/stitch-core/releases/latest/download/stitch-v0.1.0-x86_64-apple-darwin.tar.gz - Windows x86_64
https://github.com/Summykai/stitch-core/releases/latest/download/stitch-v0.1.0-x86_64-pc-windows-msvc.zip
From source
git clone https://github.com/Summykai/stitch-core.git
cd stitch-core
cargo install --path .Python (bindings + installer)
pip install stitch-coreCreate a file:
echo "@stitch CREATE hello.txt
+ Hello World
@end" | stitchUpdate a line in place:
echo "@stitch UPDATE hello.txt:1
- Hello World
+ Hello Stitch
@end" | stitchStitch is designed to be driven by an LLM or agent. A typical pattern is:
-
Add this to your system or tool prompt:
You have access to a `stitch` tool. Do not use sed, awk, or cat. To edit a file, output a valid stitch block: @stitch <VERB> <filepath>[:<line_anchor>] - <expected_content (for UPDATE/DELETE)> + <new_content (for CREATE/UPDATE/APPEND)> @end -
Capture the
@stitchblock from the model’s response. -
Pipe it into the CLI:
echo "$STITCH_BLOCK" | stitch --verbose
-
Parse the JSON from
stdoutand decide whether to:- Mark the step as successful, or
- Show the
context_not_founddiagnostics to the model and retry.
You can wrap this loop in any framework (OpenAI tools, LangGraph, MCP servers, etc.) using the JSON protocol described below.
Stitch uses a simple, token-efficient text format that works well inside Markdown blocks and model outputs.
@stitch <VERB> <filepath>[:<line_anchor>]
- <expected_content (for UPDATE/DELETE)>
+ <new_content (for CREATE/UPDATE/APPEND)>
@end
VERB∈{CREATE, UPDATE, APPEND, DELETE}filepathis a path on diskline_anchor(optional) is a 1-based line number hint-lines describe what you expect to see (forUPDATE/DELETE)+lines describe what you want to write
Stitch finds the expected line near line 10, even if it has moved a bit, then updates it:
@stitch UPDATE src/server.py:10
- app.run(host='0.0.0.0', port=80)
+ app.run(host='0.0.0.0', port=8080)
@end
@stitch CREATE /etc/nginx/sites-available/my-app
+ server {
+ listen 80;
+ server_name my-app.com;
+ }
@end
@stitch APPEND /home/user/.bashrc
+ export DATABASE_URL="postgres://user:pass@host/db"
@end
@stitch DELETE config.yaml:25
- - deprecated_feature_flag
@end
Stitch reports every operation as JSON on stdout. This is meant to be consumed by agents.
{
"status": "success",
"file": "src/server.py",
"action": "update",
"meta": {
"requested_line": 10,
"actual_line": 12,
"drift_strategy": "search_window_hit",
"drift_offset": 2
}
}If the expected context isn’t found, Stitch returns what it did see so the agent can adjust:
{
"status": "error",
"reason": "context_not_found",
"file": "src/server.py",
"action": "update",
"meta": {
"requested_line": 10,
"search_window": 5,
"actual_content": "app.run(host='127.0.0.1', port=80)"
}
}Agents can feed actual_content back into the model and ask it to regenerate a corrected @stitch block.
Stitch can read a block from a file or from stdin.
From a file:
stitch stitch.inFrom stdin:
cat stitch.in | stitchor inline:
echo "@stitch CREATE hello.txt
+ Hello World
@end" | stitchUse --dry-run to validate without writing:
echo "$BLOCK" | stitch --dry-runThis project is built with Rust.
cargo build --releaseThe binary is produced at:
target/release/stitch
Note: The crate is named
stitch-core, but the installed binary is namedstitchto leave room for higher-level wrappers.
cargo testIntegration tests cover all core verbs, drift correction, indentation handling, and dry-run behavior.
The core engine is complete and tested. Planned features include:
-
Syntax safety layer Integrate
tree-sitterto parse the modified file’s AST. If a syntax error is introduced, reject the edit instead of writing broken code. -
Expanded native bindings Ship first-class bindings and installers for Python and Node.js to make Stitch trivial to drop into existing agent frameworks.
-
Fuzzy matching for context For
UPDATE/DELETE, if an exact match forexpected_contentisn’t found, use a diff algorithm (e.g., Myers diff) to find the closest match and apply the change when above a confidence threshold.
Contributions, integrations, and feedback from real agent workloads are very welcome!