Skip to content

Automated code patching system for Rust with byte-span replacement and tree-sitter integration

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

johnzfitch/codex-patcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Codex Patcher

Codex Patcher

Automated code patching system for Rust with byte-span replacement and tree-sitter integration

CI Status Crates.io docs.rs License


Overview

codex-patcher is a robust, compiler-aware patching system designed to apply LLM-generated fixes, refactors, and insertions to Rust source files with high reliability. It preserves comments, formatting, and handles Rust's macro/cfg complexity without silent corruption.

Key Features

Feature Description
Atomic Writes Tempfile + fsync + rename for crash safety
Idempotent Safe to run multiple times without side effects
Tree-sitter CST-based parsing preserves exact source layout
ast-grep Pattern-based code matching and replacement
Workspace Safety Prevents edits outside project boundaries
Multi-format Supports Rust, TOML, and more

Quick Start

Installation

# From crates.io (when published)
cargo install codex-patcher

# From source
git clone https://github.com/your-org/codex-patcher
cd codex-patcher
cargo install --path .

Basic Usage

# Apply all patches in patches/ directory
codex-patcher apply --workspace /path/to/codex-rs

# Dry run with diff output
codex-patcher apply --workspace /path/to/codex-rs --dry-run --diff

# Check status of patches
codex-patcher status --workspace /path/to/codex-rs

# Verify patches are applied correctly
codex-patcher verify --workspace /path/to/codex-rs

Architecture

Core Primitive: Byte-Span Replacement

All edit operations compile down to a single primitive:

pub struct Edit {
    file: PathBuf,
    byte_start: usize,
    byte_end: usize,
    new_text: String,
    expected_before: EditVerification,
}

Why this design?

  • Simplifies verification logic
  • Makes debugging trivial (see exactly what changed)
  • Enables multiple span location strategies
  • Preserves formatting and comments

Verification Strategies

pub enum EditVerification {
    ExactMatch(String),  // For spans < 1KB
    Hash(u64),           // xxh3 for larger spans
}

Automatic selection based on text size ensures both safety and performance.


Documentation

Document Description
Getting Started Installation and first steps
API Reference Library API documentation
Patch Authoring How to write patch definitions
Architecture System design and internals
TOML Patching TOML-specific query syntax

CLI Reference

Commands

Command Description
apply Apply patches to a workspace
status Check which patches are applied
verify Verify patches match expected state
list List available patches

Options

codex-patcher apply [OPTIONS]

Options:
  -w, --workspace <PATH>  Path to workspace root (auto-detected if not specified)
  -p, --patches <FILE>    Specific patch file to apply
  -n, --dry-run           Show what would be changed without modifying files
  -d, --diff              Show unified diff of changes
  -h, --help              Print help
  -V, --version           Print version

Library Usage

Basic Edit

use codex_patcher::{Edit, EditResult, WorkspaceGuard};

// Create workspace guard for safety
let guard = WorkspaceGuard::new("/path/to/workspace")?;

// Validate path is within workspace
let file = guard.validate_path("src/main.rs")?;

// Create and apply edit
let edit = Edit::new(
    file,
    0,              // byte_start
    5,              // byte_end
    "HELLO",        // new_text
    "hello",        // expected_before
);

match edit.apply()? {
    EditResult::Applied { file, bytes_changed } => {
        println!("Applied {} bytes to {}", bytes_changed, file.display());
    }
    EditResult::AlreadyApplied { file } => {
        println!("Already patched: {}", file.display());
    }
}

Batch Edits

use codex_patcher::Edit;

let edits = vec![
    Edit::new("src/main.rs", 0, 5, "HELLO", "hello"),
    Edit::new("src/main.rs", 10, 15, "WORLD", "world"),
    Edit::new("src/lib.rs", 0, 3, "FOO", "foo"),
];

// Applies atomically per file, sorted correctly
let results = Edit::apply_batch(edits)?;

for result in results {
    println!("{:?}", result);
}

Pattern Matching with ast-grep

use codex_patcher::sg::PatternMatcher;

let source = r#"
    fn main() {
        let x = foo.clone();
        let y = bar.clone();
    }
"#;

let matcher = PatternMatcher::new(source);

// Find all .clone() calls
let matches = matcher.find_all("$EXPR.clone()")?;

for m in matches {
    println!("Found clone at bytes {}..{}", m.byte_start, m.byte_end);
}

Safety Guarantees

Hard Rules (Never Violated)

Rule Description
Selector Uniqueness 0 or >1 matches = refuse to edit
Before-text Verification Always verify expected content exists
No External Edits Never modify files outside workspace
Parse Validation Re-parse after edit, rollback on errors
UTF-8 Validation Prevent creation of invalid files

Workspace Boundaries

The WorkspaceGuard prevents edits to:

  • ~/.cargo/registry - Dependency source code
  • ~/.rustup - Toolchain installations
  • target/ - Build artifacts
  • Symlinks escaping workspace

Project Structure

codex-patcher/
├── src/
│   ├── lib.rs           # Library entry point
│   ├── main.rs          # CLI entry point
│   ├── edit.rs          # Core Edit primitive
│   ├── safety.rs        # WorkspaceGuard
│   ├── validate.rs      # Parse/syn validation
│   ├── config/          # Patch configuration
│   │   ├── schema.rs    # Patch definition types
│   │   ├── loader.rs    # TOML config parser
│   │   ├── applicator.rs # Patch application logic
│   │   └── version.rs   # Semver filtering
│   ├── ts/              # Tree-sitter integration
│   │   ├── parser.rs    # Rust parser wrapper
│   │   ├── query.rs     # Query engine
│   │   └── locator.rs   # Structural locators
│   ├── sg/              # ast-grep integration
│   │   ├── matcher.rs   # Pattern matching
│   │   ├── replacer.rs  # Replacement operations
│   │   └── lang.rs      # Language support
│   └── toml/            # TOML editing
│       ├── editor.rs    # TomlEditor
│       ├── query.rs     # Section/key queries
│       └── operations.rs # TOML operations
├── patches/             # Patch definitions
│   ├── privacy.toml     # Telemetry removal
│   └── performance.toml # Build optimizations
├── tests/               # Integration tests
└── docs/                # Documentation

Development

Building

# Debug build
cargo build

# Release build
cargo build --release

# Run tests
cargo test

# Run clippy
cargo clippy --all-targets -- -D warnings

# Format code
cargo fmt

Test Coverage

# Run all tests with output
cargo test --all-targets -- --nocapture

# Run specific test
cargo test test_atomic_write

# Run integration tests only
cargo test --test integration

Status

Component Status
Core Edit Primitive Complete
Atomic File Writes Complete
Workspace Guards Complete
Tree-sitter Integration Complete
ast-grep Integration Complete
TOML Patching Complete
CLI Interface Complete
Patch Definitions Complete
Documentation Complete

Test Results: 117 tests, 100% passing


Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Quick Contribution Guide

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes
  4. Run tests: cargo test && cargo clippy --all-targets -- -D warnings
  5. Commit: git commit -m "feat: add amazing feature"
  6. Push: git push origin feature/amazing-feature
  7. Open a Pull Request

License

Licensed under either of:

at your option.


Acknowledgments

Built with these excellent crates:


Made with care for the Rust community

About

Automated code patching system for Rust with byte-span replacement and tree-sitter integration

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published