pdalinis/incise
Make small AI models reliable at editing Markdown. Incise provides safe, semantic, byte-preserving edits for AI agents.
Incise is a CLI and agent-tool backend designed for precise, semantic updates to Markdown files. It enables targeted modifications to tables, lists, sections, and YAML frontmatter by addressing content rather than line numbers, ensuring unrelated bytes remain unchanged.
- Performs byte-preserving edits to specific Markdown structural ranges.
- Provides deterministic tools for AI agents to modify documentation.
- Supports semantic addressing for headings, rows, items, and keys.
full readme from github
Incise — semantic Markdown editing for AI agents
Safe, semantic, byte-preserving Markdown edits for AI agents and automation.
Incise is a CLI and agent-tool backend for precise updates to Markdown tables, lists, sections, and YAML frontmatter. The caller expresses what should change; deterministic code handles formatting, boundaries, and the smallest possible splice.
Model intent: In the Projects table, set Launch to done.
Incise: Address the table, row, and column by content.
Result: One targeted edit; unrelated bytes stay unchanged.
Documentation · Install · Benchmarks · Releases
Why Incise?
Language models can identify the change a document needs but are less reliable at reproducing surrounding Markdown exactly. A one-cell table update can require pipe escaping, alignment arithmetic, line-ending preservation, and a byte-perfect rewrite of unrelated content.
Incise separates intent from mechanics:
- Semantic addresses: select headings, rows, items, and keys by content rather than line number.
- Minimal edits: change only the targeted structural range.
- Actionable refusals: ambiguous or unsafe requests fail loudly instead of choosing a plausible target.
It is built for AI-maintained documentation, Obsidian vaults, Markdown knowledge bases, and local models with limited context. Incise is not a WYSIWYG editor, knowledge graph, or vault index; it is the deterministic mutation layer used after an agent decides which file and fact to change.
Quick start
Install from crates.io
Install incise-cli from crates.io:
cargo install incise-cli --locked
incise --version
Prebuilt Linux and macOS archives are available from GitHub Releases.
Build from source
git clone https://github.com/pdalinis/incise.git
cd incise
cargo install --locked --path crates/incise-cli
Inspect a Markdown file
Before modifying a document, inspect only the structure the agent needs:
incise tables vault/Projects.md
incise outline vault/Projects.md
Make a semantic edit
incise table-update-cell vault/Projects.md \
--table Projects \
--where Note=Launch \
--column Status \
--value done
The row is selected by content, not by a line number.
If the new value requires the table to widen, Incise re-pads the table correctly while leaving the rest of the file untouched.
What Incise can edit
| Markdown structure | Operations |
|---|---|
| Tables | Add rows, update cells, delete rows, realign columns, query rows |
| Lists & tasks | Add/remove items, toggle checkboxes |
| Sections | Append, replace, insert, delete, rename, change heading levels |
| YAML frontmatter | Read, set, and delete nested keys |
| Structure | Discover headings, tables, lists, frontmatter, rows, keys, and hashes |
Use Incise with an AI agent
Incise publishes the function schemas an agent should receive:
incise schema
Or inspect an individual tool:
incise schema --tool table_edit
These schemas are measured artifacts rather than handwritten approximations. A function-calling harness can pass the model's argument object to the corresponding Incise command and return stdout or stderr directly.
Hermes Agent
Incise includes a Hermes adapter under plugins/hermes/.
For Markdown structures represented by Incise, give the agent an explicit preference for structured editing:
## Editing Markdown
For Markdown tables, lists, sections, and frontmatter, prefer Incise tools over
generic patch, write, or shell tools.
Inspect structure first with `md_tables`, `md_lists`, or `md_outline`. Use
`table_get` when current table rows are needed. Make changes with `table_edit`,
`list_edit`, `section_edit`, or `frontmatter_edit`.
If Incise refuses an operation, follow the remedy in its response rather than
rewriting the document. Use raw editing only for prose changes that Incise does
not represent.
The Hermes adapter exposes the measured edit and table-read schemas together with structural reads. See plugins/hermes/README.md for installation and safety details.
Incise is deliberately scoped to Markdown structures it understands. Generic editing remains appropriate for ordinary prose and for creating the initial contents of a new document.
Use with Pi
Install the published pi-incise package from npm:
pi install npm:pi-incise
pi
The package provides native binaries for macOS arm64/x64 and glibc Linux arm64/x64. It registers the three structural readers, table_get, and all four structured edit tools. Run /incise-doctor inside Pi to inspect the selected binary and schema status.
Safety model
Incise is designed around five guarantees:
- Semantic addressing: targets use heading paths, cell values, item text, keys, and ordinals—never line numbers.
- Byte-preserving splices: unrelated document bytes remain identical.
- Loud ambiguity: malformed, unsupported, or non-unique targets produce an actionable refusal.
- Safe writes: the CLI supports dry runs, atomic replacement, no-op detection, and content-hash preconditions.
- Token-frugal results: successful writes describe the change instead of returning the whole document.
Measured with small models
The recorded benchmark compares direct patch calls with Incise operations on the same tasks, model, seeds, and grader.
| Operation | Direct patch |
Incise | Mean Incise output |
|---|---|---|---|
| Tables | 60.0% (36/60) | 100% (60/60) | 66 tokens |
| Lists | 63.0% (63/100) | 91.0% (91/100) | 58 tokens |
| Sections | 19.0% (19/100) | 74.0% (74/100) | 60 tokens |
These results describe one small local model under recorded conditions, not every model. The useful result is the class of failure removed: character arithmetic, structural-boundary mistakes, and byte-for-byte reconstruction.
Read the benchmark summary, the complete bench/FINDINGS.md, or jump to the source findings for tables, lists, sections, and frontmatter.
The dependency-free Rust core is checked byte-for-byte against an independent Python oracle across 110,406 generated cases over 54 fixtures. Property invariants and 212 injected mutations provide additional evidence that preservation failures are detected.
Frequently asked questions
What is byte-preserving Markdown editing?
Incise changes the smallest structural range required by an operation. Bytes outside that range remain identical, so an agent does not have to reproduce the rest of the document.
Can Incise edit an Obsidian vault?
Yes. Incise works directly on Markdown files and leaves unrelated wikilinks, callouts, block IDs, embeds, comments, and prose untouched. It does not index or search the vault; another tool chooses the file to edit.
How does an AI agent use Incise?
The agent first inspects document structure, then calls a semantic editor with a content-based address. Use incise schema for the function definitions or install the Hermes or Pi integration.
How do I update YAML frontmatter without reformatting?
Inspect keys with incise keys FILE, then call incise frontmatter-set FILE --key PATH --value VALUE. Incise preserves unrelated key order, comments, scalar formatting, and document content. See the frontmatter guide.
Documentation
The Incise documentation site covers installation and the core workflow, with focused guides for Markdown tables, YAML frontmatter, and Obsidian vaults.
Run incise --help for every command or incise <command> --help for its arguments. Integration details live in the Hermes guide and Pi package guide.
Project status
Incise uses 0.x versioning and is under active development. It currently supports tables, lists, sections, YAML frontmatter, structural reads, semantic addressing, dry runs, atomic writes, stale-read protection, and agent-tool schemas.
Linux and macOS are supported. Windows is not currently supported or tested. Scoped search and replace and multi-operation transactions remain planned.
Behavioral claims stay tied to the model, prompts, schemas, tasks, and executor that produced them. A tool-description or refusal change may require remeasurement even when deterministic tests still pass.
Development
Run the deterministic test suite before submitting a code change:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test --workspace --locked
python3 bench/test_incise_ops.py
python3 bench/difftest.py
python3 bench/schematest.py
python3 bench/replaycheck.py
python3 plugins/hermes/test_plugin.py
The benchmark corpus is frozen because published findings refer to its exact bytes.
Purpose-built coverage inputs belong under:
bench/synthetic/
Experiments should run on copies of the corpus.
See CONTRIBUTING.md for the benchmark-impact policy and pull-request expectations.
Release maintainers should also see RELEASING.md for crate-publication order, tag checks, and post-release smoke tests.
Contributing and security
Contributions are welcome.
Read CONTRIBUTING.md before changing measured behavior or benchmark artifacts.
Report ordinary bugs and feature ideas through GitHub issues.
Report potential vulnerabilities through GitHub private vulnerability reporting as described in SECURITY.md.
License
Incise is available under the MIT License. See LICENSE.