Skip to main content

Selection-based mutable output buffer for LLM tools

Project description

editbuffer

editbuffer is a small Python runtime for editing an LLM's pending text output before it is committed.

The public abstraction is selection-based editing, not file patches:

  • select exact, contextual, fuzzy, block, or character-range targets;
  • replace, insert before/after, or delete the selection;
  • reject missing, ambiguous, invalid, and stale selections;
  • inspect the current buffer and its audit history;
  • commit the final artifact.

Install

pip install editbuffer

For local development:

python -m pip install -e .

Python 3.11+ is required. The core library has no runtime dependencies.

Quickstart

from editbuffer import EditBuffer, Selection

buf = EditBuffer()
buf.append('find . -name "*.py" -exec grep -n "TODO" {} ;')
buf.replace(Selection.exact("{} ;"), "{} \\;")

final = buf.commit()

Selections can also be dictionaries:

buf.replace(
    {
        "type": "context",
        "before": 'grep -n "TODO" ',
        "text": "{} ;",
        "after": "",
    },
    "{} \\;",
)

LLM tool-call format

{
  "op": "replace",
  "target": {
    "type": "context",
    "before": "grep -n \"TODO\" ",
    "text": "{} ;",
    "after": ""
  },
  "text": "{} \\;"
}

Pass the decoded object to buffer.apply(operation). Supported operations are append, replace, insert_before, insert_after, and delete.

Range selections use half-open character offsets and can reject stale edits:

{
  "op": "delete",
  "target": {
    "type": "range",
    "start": 10,
    "end": 20,
    "expected_version": 3
  }
}

Failure behavior

  • no match raises TargetNotFoundError;
  • multiple matches raise AmbiguousTargetError with candidate ranges;
  • occurrence can explicitly choose a zero-based match;
  • invalid ranges or operations raise InvalidOperationError;
  • a mismatched expected_version raises StaleVersionError;
  • validator failures do not mutate text or history;
  • fuzzy matching is opt-in and rejects low-confidence or competing candidates.

Fuzzy and block selections

Fuzzy selection uses the standard library and records the accepted confidence:

buf.replace(
    Selection.fuzzy(
        "run integrtion tests",
        threshold=0.85,
        ambiguity_margin=0.05,
    ),
    "run unit tests",
)

It never runs as a fallback for exact/context selection. If no candidate meets the threshold, or two candidates are too close, FuzzyMatchError includes candidate ranges and scores.

Block selection requires an explicit ID. Fenced code blocks use:

```python editbuffer:id=setup
print("old")
```

Markdown regions use:

<!-- editbuffer:block summary -->
old content
<!-- /editbuffer:block -->

Selection.block("setup") selects the content inside the markers, preserving the fence or comments. Duplicate IDs are rejected as ambiguous.

Snapshots and rollback

Every successful edit stores an in-memory snapshot:

buf.append("draft")
version = buf.version
buf.replace(Selection.exact("draft"), "final")
buf.rollback(version)

Rollback restores the snapshot as a new audited version. Snapshots live only for the lifetime of the EditBuffer process.

Optional validators

from editbuffer import EditBuffer
from editbuffer.validators import valid_json, valid_shell

json_buffer = EditBuffer('{"ok": true}', validators=(valid_json,))
shell_buffer = EditBuffer("echo ok", validators=(valid_shell,))

valid_shell invokes the local POSIX sh -n parser without executing the command.

CLI

The CLI stores an operation log in a JSON state file:

editbuffer new /tmp/output.json --text "hello world"
editbuffer replace /tmp/output.json '{"type":"exact","text":"world"}' "there"
editbuffer view /tmp/output.json
editbuffer history /tmp/output.json
editbuffer rollback /tmp/output.json 1
editbuffer commit /tmp/output.json

Use editbuffer apply STATE OPERATION_JSON for the complete operation schema.

MCP / agent integration

Install the optional server:

pipx install 'editbuffer[mcp]'

Until a PyPI release exists, install directly from GitHub:

pipx install 'editbuffer[mcp] @ git+https://github.com/averagedigital/editbuffer.git'

Connect it to Codex:

codex mcp add editbuffer -- editbuffer-mcp

Codex supports local STDIO MCP servers configured with codex mcp add; use /mcp in the Codex terminal UI to confirm the server is active.

Claude Desktop and generic MCP client examples are in docs/mcp.md.

The server exposes:

  • buffer_create
  • buffer_list
  • buffer_view
  • buffer_edit
  • buffer_history
  • buffer_rollback
  • buffer_commit
  • command_history
  • command_select

Buffers are in-memory and live for the MCP server process. The MCP layer calls the same core API and does not implement separate edit semantics.

buffer_commit remembers non-empty committed output as a reusable command. command_history returns the last 10 commands, newest first. command_select creates a new pending buffer from a previous command so the model can reuse it instead of regenerating it.

Examples

Scope

This project is not:

  • an agent framework;
  • a retrieval system or repo indexer;
  • a full IDE;
  • a replacement for coding agents;
  • a generic output quality evaluator.

Persistent storage, atomic operation batches, TypeScript bindings, and syntax-aware block parsing are future work.

Development

PYTHONPATH=src python -m unittest discover -s tests -v

License

MIT

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

editbuffer-0.2.1.tar.gz (19.6 kB view details)

Uploaded Source

Built Distribution

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

editbuffer-0.2.1-py3-none-any.whl (16.1 kB view details)

Uploaded Python 3

File details

Details for the file editbuffer-0.2.1.tar.gz.

File metadata

  • Download URL: editbuffer-0.2.1.tar.gz
  • Upload date:
  • Size: 19.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for editbuffer-0.2.1.tar.gz
Algorithm Hash digest
SHA256 edaaff95b00596ef4f78d771835149f7a5cd5c6edc6b1436e373c46d87d7c4ff
MD5 df4e298aaa1ec7e91f708866141f04f3
BLAKE2b-256 7650639045ed3d6526c465726674aa88734a828231b5620b21f57ab5caf298c8

See more details on using hashes here.

File details

Details for the file editbuffer-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: editbuffer-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 16.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for editbuffer-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3d4a481b483a5aaecc969f2b1f225b73cad4926140e6cadfcccba941ec370693
MD5 f085ce44d13fc0842da623095e434173
BLAKE2b-256 f0c6170d2497a08d371e1a40b5dd3ff20f3b33c529e8a7a54f787809ff37270c

See more details on using hashes here.

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