Skip to main content

AXM Edit — Atomic batch file editing for AI agents.

Project description

axm-edit

Atomic batch file editing for AI agents.

axm-audit axm-init Coverage Python 3.12+


Overview

IDE agents edit files one-at-a-time. A refactor touching 30 files = 30 tool calls. The agent spends 70% of its budget on mechanics.

axm-edit replaces all of that with 1 call.

Features

  • 🔧 batch_edit — Replace, create, and delete files in a single atomic operation
  • 📖 read_file — Read file content with optional line-range support
  • 🔍 search_files — Grep-like search across project files (literal or regex)
  • 📂 list_dir — List files and directories with metadata (recursive, depth-limited)
  • ✏️ write_file — Write or overwrite file content
  • ▶️ run_command — Execute shell commands with timeout and output truncation
  • batch_rollback — Restore the exact paths a batch touched from a targeted snapshot
  • 🛡️ Atomic — All-or-nothing: validation runs before any file is touched
  • 📐 Bottom-to-top — Line edits applied in reverse order to avoid line-shift problems
  • 🔒 Safe — Path traversal blocked, old content validated, targeted path snapshot before writes

Installation

uv add axm-edit

Or as a workspace dependency in pyproject.toml:

[project]
dependencies = ["axm-edit"]

[tool.uv.sources]
axm-edit = { workspace = true }

Quick Start

from axm_edit.core.engine import batch_apply
from axm_edit.models.operations import Edit, ReplaceOp, CreateOp
from pathlib import Path

result = batch_apply(
    root=Path("/my/project"),
    operations=[
        ReplaceOp(file="src/core.py", edits=[
            Edit(line=5, old="class OldName:", new="class NewName:"),
        ]),
        CreateOp(file="src/new.py", content='"""New module."""\n'),
    ],
)
print(result.summary)  # {"modified": 1, "created": 1, "deleted": 0}

MCP Tools

batch_edit

Atomic batch file operations.

Param Type Default Description
path str "." Project root directory
operations list[Op] List of replace/create/delete operations
lint bool True Run ruff --fix on changed Python files after apply
lint_diff bool True Surface per-file lint_diffs hunks of post-lint mutations
lint_diff_max_ratio float 0.5 Fallback to file_reread_recommended when len(diff) > ratio * len(post)

When lint_diff=True and ruff/harness_fix mutates any Python file, ToolResult.data["lint_diffs"] lists one entry per file: {"file", "rules": [ruff codes], "diff": "@L<n>\n-old\n+new..."}. On large rewrites the entry drops diff and carries "diff_skipped": "file_reread_recommended".

3 operation types:

replace — modify lines in an existing file

{
    "op": "replace",
    "file": "src/foo.py",
    "edits": [
        {"line": 3,  "old": "import bar",  "new": "import baz"},
        {"line": 17, "old": "x = bar()",   "new": "x = baz()"}
    ]
}

All line numbers reference the original file. The engine sorts edits bottom-to-top.

create — create a new file

{"op": "create", "file": "src/new.py", "content": "\"\"\"New module.\"\"\"\n"}

Fails if file exists (unless "overwrite": true).

delete — remove a file

{"op": "delete", "file": "src/old.py"}

read_file

Read file content with optional line-range support.

Param Type Description
path str Project root directory
file str Relative path to the file
start_line int? Optional 1-indexed start line (inclusive)
end_line int? Optional 1-indexed end line (inclusive)

search_files

Grep-like search across project files.

Param Type Description
path str Project root directory
pattern str Search string or regex (required)
is_regex bool? Treat pattern as regex (default false)
include list[str]? Glob patterns to filter files (e.g. ["*.py"])

list_dir

List files and directories with metadata.

Param Type Description
path str Root directory to list (default ".")
max_depth int? Recursion depth — 1 for immediate children only (default 1)

run_command

Execute shell commands with timeout and output truncation.

Param Type Description
path str Project root directory
command str Shell command string (required)
cwd str? Working directory, relative to root
timeout int? Timeout in seconds (default 30)

batch_rollback

Restore the exact paths a batch touched from its snapshot.

Param Type Description
path str Project root directory
checkpoint str Snapshot payload from the batch_edit response

Development

This package is part of the axm-forge workspace.

git clone https://github.com/axm-protocols/axm-forge.git
cd axm-forge
uv sync --all-groups

# Run tests for this package
uv run pytest --package axm-edit

📖 Full documentation

License

Apache-2.0 — © 2026 Gabriel Jarry

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

axm_edit-0.2.0.tar.gz (73.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

axm_edit-0.2.0-py3-none-any.whl (47.5 kB view details)

Uploaded Python 3

File details

Details for the file axm_edit-0.2.0.tar.gz.

File metadata

  • Download URL: axm_edit-0.2.0.tar.gz
  • Upload date:
  • Size: 73.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for axm_edit-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a3803cee5211a7908402a0a9a85acbe1fbd25b3a0ef72d1eecf7d24c23719bf0
MD5 531515535823ad5fff639fb38d64f7d9
BLAKE2b-256 6a29d271cd9ef446b2c6ae5c7f9248a4c74ffebf5d61ce0f8e03d4c64ea84ce4

See more details on using hashes here.

Provenance

The following attestation bundles were made for axm_edit-0.2.0.tar.gz:

Publisher: publish.yml on axm-protocols/axm-forge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file axm_edit-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: axm_edit-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 47.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for axm_edit-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 848f8f29610da3183eaa3a981706ecc07e740e3935738baef3c5a9c042b7c774
MD5 b90d0712a5ca170e0c394a6cc800b6e5
BLAKE2b-256 f61c6f5be93622467351662b7708b446c8586fd8e17ac8744d7f36656f4337fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for axm_edit-0.2.0-py3-none-any.whl:

Publisher: publish.yml on axm-protocols/axm-forge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page