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 project state to a checkpoint via git stash
  • 🛡️ 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, git checkpoint 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/claude_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 state to a checkpoint.

Param Type Description
path str Project root directory
checkpoint str SHA from batch_edit response

Development

This package is part of the axm-draft workspace.

git clone https://github.com/axm-protocols/axm-draft-workspace.git
cd axm-draft
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.1.0.tar.gz (61.0 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.1.0-py3-none-any.whl (40.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: axm_edit-0.1.0.tar.gz
  • Upload date:
  • Size: 61.0 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.1.0.tar.gz
Algorithm Hash digest
SHA256 df3a6915139a29fadf36ae79d98b6ab0282d9b1500be6de9039ca526e5a71785
MD5 2e11919dd6f1950b12ea9bdd4200afb4
BLAKE2b-256 bd0f249ea7e4250acafc3819e1b2ceb1b9a6d56f43c5ca5e8e3d5c4ed9f00ddf

See more details on using hashes here.

Provenance

The following attestation bundles were made for axm_edit-0.1.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.1.0-py3-none-any.whl.

File metadata

  • Download URL: axm_edit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 40.3 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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9906b71663da1093aeadb7796eff4b572448058465af6929b2c9d4a1b63801b1
MD5 04a6f3e827df2579e8931361e7637371
BLAKE2b-256 2377b6fc195e841b09f53fba55af86ec3ce0291a794e3cfcfc4923f5ae984b24

See more details on using hashes here.

Provenance

The following attestation bundles were made for axm_edit-0.1.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