Back to Discover

formpatch

plugin

mikewong23571

View on GitHub
0 starsEPL-1.0Synced Aug 5, 2026

Install to Claude Code

/plugin marketplace add mikewong23571/formpatch

README

formpatch

Top-level object editor for Clojure source files.

The tool is designed for AI agents. It exposes each file as an ordered list of top-level objects and supports two mutations:

  • insert: insert zero or more top-level objects before or after an existing object, or at the head/tail of the file
  • replace: replace one or more contiguous top-level objects with zero or more new objects

The runtime path is babashka, so normal CLI usage does not pay JVM startup cost. rewrite-clj is used for parsing and validation.

Handle Model

Each top-level object has:

  • oid: stable file-local object identity encoded as a 6-character base62 token
  • rev: short hash of the current full object text
  • file_rev: short hash of the whole file

The default workflow is:

  • use oid to address an object
  • optionally add @rev to guard against overwriting a changed object
  • optionally pass --file-rev for strict whole-file optimistic locking

This means one list can usually support multiple follow-up edits without re-listing, as long as the target object itself has not changed.

Install As A bb Tool

The project is packaged as a bbin-installable Babashka tool via bb.edn.

Install from a local checkout:

bbin install . --as formpatch

After publishing the repository, install from git:

bbin install io.github.mikewong23571/formpatch --as formpatch

The tool entrypoint is declared in :bbin/bin and resolves to:

bb -m formpatch.cli/-main

Commands

Show usage:

./bin/formpatch --help

List top-level objects in a file:

./bin/formpatch list --file src/formpatch.clj

Fetch one or more full objects by handle:

./bin/formpatch get \
  --file src/formpatch.clj \
  --objects 00000a,00000b@19ab7def

Insert objects after an anchor:

./bin/formpatch insert \
  --file src/formpatch.clj \
  --after 00000a@19ab7def <<'EOF'
(defn helper-a
  []
  :a)

(defn helper-b
  []
  :b)
EOF

Insert at the head of the file (no anchor needed):

./bin/formpatch insert \
  --file src/formpatch.clj \
  --head <<'EOF'
(ns foo.core)
EOF

Use --tail to append at the end of the file. Both work on empty files.

Replace one object with multiple objects:

./bin/formpatch replace \
  --file src/formpatch.clj \
  --targets 00000a@19ab7def <<'EOF'
(defn helper
  [x]
  (inc x))

(defn updated
  [x]
  (helper x))
EOF

Delete objects without stdin:

./bin/formpatch replace \
  --file src/formpatch.clj \
  --targets 00000a@19ab7def \
  --empty

Preview a mutation without writing:

./bin/formpatch replace \
  --file src/formpatch.clj \
  --targets 00000a@19ab7def \
  --dry-run \
  --diff <<'EOF'
(defn preview []
  :ok)
EOF

Enable strict whole-file locking when needed:

./bin/formpatch replace \
  --file src/formpatch.clj \
  --file-rev abc12345 \
  --targets 00000a@19ab7def \
  --empty

Output

list emits JSON on stdout, but each object's text is truncated by default to reduce token usage.

get emits JSON on stdout with the full object text for one or more objects.

insert and replace emit a minimal mutation delta JSON on stdout. The response includes:

  • file_rev: the new file version
  • touched: the objects created or updated by the mutation
  • deleted: removed oids
  • before / after: stable neighbor anchors around the changed span

Use --diff when you also want a unified diff string embedded in the same JSON response.

Identity Store

formpatch persists object identities in a small EDN sidecar store. By default it lives under:

~/.cache/formpatch/state

You can override it with:

  • env var FORMPATCH_STATE_DIR
  • JVM property formpatch.state-dir

Formatting Rules

The wrapper applies a small deterministic formatting policy:

  • top-level objects are joined with exactly two blank lines
  • the file ends with exactly one trailing newline
  • object-internal formatting is preserved exactly as provided

Development

Run the JVM test suite:

clojure -T:build test

Run the Babashka task wrapper:

bb formpatch --help

Run the tool entrypoint exactly as bbin will invoke it:

bb -m formpatch.cli/-main --help

Design Notes

The design document is in rewrite-clj-object-editing-design.md.

Rendered live from mikewong23571/formpatch's GitHub README — not stored, always reflects the source repo.

1 Plugin

NameDescriptionCategorySource
formpatchInspect and edit Clojure source files with the formpatch CLI./

0 Comments

Login required
Log in to post a comment or update on this repo.

No comments yet — be the first to share an update.