Skip to content

Summykai/stitch-core

Repository files navigation

# Stitch: Deterministic File Edits for AI Agents

[![Build Status](https://img.shields.io/github/actions/workflow/status/Summykai/stitch-core/rust.yml?branch=main)](https://github.com/Summykai/stitch-core/actions)
[![Crates.io](https://img.shields.io/crates/v/stitch-core.svg)](https://crates.io/crates/stitch-core)
[![PyPI version](https://badge.fury.io/py/stitch-core.svg)](https://badge.fury.io/py/stitch-core)
[![GitHub stars](https://img.shields.io/github/stars/Summykai/stitch-core.svg)](https://github.com/Summykai/stitch-core/stargazers)
[![GitHub issues](https://img.shields.io/github/issues/Summykai/stitch-core.svg)](https://github.com/Summykai/stitch-core/issues)
[![Rust](https://img.shields.io/badge/rust-stable-orange.svg)](https://www.rust-lang.org/)
[![Python](https://img.shields.io/badge/python-3.8+-blue.svg)](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-core

Prebuilt 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-core

Minimal CLI Example

Create a file:

echo "@stitch CREATE hello.txt
+ Hello World
@end" | stitch

Update a line in place:

echo "@stitch UPDATE hello.txt:1
- Hello World
+ Hello Stitch
@end" | stitch

Using Stitch with AI Agents

Stitch is designed to be driven by an LLM or agent. A typical pattern is:

  1. 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
    
  2. Capture the @stitch block from the model’s response.

  3. Pipe it into the CLI:

    echo "$STITCH_BLOCK" | stitch --verbose
  4. Parse the JSON from stdout and decide whether to:

    • Mark the step as successful, or
    • Show the context_not_found diagnostics 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.


The Stitch Block Format

Stitch uses a simple, token-efficient text format that works well inside Markdown blocks and model outputs.

Grammar

@stitch <VERB> <filepath>[:<line_anchor>]
- <expected_content (for UPDATE/DELETE)>
+ <new_content (for CREATE/UPDATE/APPEND)>
@end
  • VERB{CREATE, UPDATE, APPEND, DELETE}
  • filepath is a path on disk
  • line_anchor (optional) is a 1-based line number hint
  • - lines describe what you expect to see (for UPDATE/DELETE)
  • + lines describe what you want to write

Examples

Robust update

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

Create a file

@stitch CREATE /etc/nginx/sites-available/my-app
+ server {
+   listen 80;
+   server_name my-app.com;
+ }
@end

Append to a file

@stitch APPEND /home/user/.bashrc
+ export DATABASE_URL="postgres://user:pass@host/db"
@end

Delete content

@stitch DELETE config.yaml:25
-   - deprecated_feature_flag
@end

JSON Protocol

Stitch reports every operation as JSON on stdout. This is meant to be consumed by agents.

Success

{
  "status": "success",
  "file": "src/server.py",
  "action": "update",
  "meta": {
    "requested_line": 10,
    "actual_line": 12,
    "drift_strategy": "search_window_hit",
    "drift_offset": 2
  }
}

Failure (for self-healing)

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.


CLI Usage

Stitch can read a block from a file or from stdin.

From a file:

stitch stitch.in

From stdin:

cat stitch.in | stitch

or inline:

echo "@stitch CREATE hello.txt
+ Hello World
@end" | stitch

Use --dry-run to validate without writing:

echo "$BLOCK" | stitch --dry-run

Development

This project is built with Rust.

Build from source

cargo build --release

The binary is produced at:

target/release/stitch

Note: The crate is named stitch-core, but the installed binary is named stitch to leave room for higher-level wrappers.

Run tests

cargo test

Integration tests cover all core verbs, drift correction, indentation handling, and dry-run behavior.


Roadmap

The core engine is complete and tested. Planned features include:

  • Syntax safety layer Integrate tree-sitter to 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 for expected_content isn’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!

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published