Installation

Prefer channels we control. They track each GitHub Release within minutes: Homebrew, Scoop, crates.io, npm, and GitHub Release binaries/installers. On Windows, Scoop is still the recommended path. Community catalogs (winget, Chocolatey) remain useful for discovery and are fine when they match the version you need; see the winget/Chocolatey section for how each lags after a new GitHub Release.

brew install patchloom/tap/patchloom

This installs patchloom with all commands, including the MCP server.

After a new GitHub Release, formula metadata can show the new version while your linked cellar is still the previous one until you upgrade:

brew update
brew upgrade patchloom
patchloom --version
scoop bucket add patchloom https://github.com/patchloom/scoop-bucket
scoop install patchloom/patchloom

Each GitHub Release updates bucket/patchloom.json in patchloom/scoop-bucket with the new version and SHA256 hashes (same idea as the Homebrew tap). Then:

scoop update
scoop update patchloom
# One-shot (downloads the platform binary on first run)
npx patchloom --version

# Global install
npm install -g patchloom

The unscoped package is on npmjs.com/package/patchloom. It is generated by cargo-dist and downloads the matching prebuilt binary from GitHub Releases (not a Node rewrite of the CLI). Release CI publishes each new version via npm Trusted Publishing (OIDC from GitHub Actions; no long-lived write token required).

cargo install patchloom

Verify which binary and crate you have

Channels can disagree until you upgrade each one. Embedder hosts that pin patchloom in Cargo.toml / Cargo.lock often ship a library version ahead of the operator's shell PATH binary (Homebrew, Scoop, older cargo install).

SurfaceHow to check
CLI on PATHpatchloom --version
Homebrew formula / cellarbrew info patchloom/tap/patchloom then brew upgrade patchloom if linked is behind
Scoopscoop update patchloom then re-check --version
crates.io installcargo install patchloom (or cargo install-update -a if you use cargo-update)
Embedder library pinCargo.lock entry for name = "patchloom"

Before filing "CLI behavior differs from 0.x" bugs, compare patchloom --version to the version your host embeds. Dual-path dogfood (library + brew CLI) is expected to split until the shell binary is upgraded.

Release CI installs a fresh Homebrew formula and checks patchloom --version against the tag. That does not upgrade machines that already have an older cellar linked; run brew upgrade patchloom there.

Pre-built binaries for Linux (x64, ARM64, musl), macOS (x64, ARM64), and Windows (x64, ARM64) are available on the Releases page. Download the archive for your platform, extract, and place patchloom (or patchloom.exe on Windows) on your PATH.

Shell and PowerShell installer scripts are also available:

# Unix (Linux/macOS)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/patchloom/patchloom/releases/latest/download/patchloom-installer.sh | sh

# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://github.com/patchloom/patchloom/releases/latest/download/patchloom-installer.ps1 | iex"

Pre-built binaries include all commands, including the MCP server.

Portable zip (Windows)

Each release ships flat zips (no nested folder). Common asset names:

  • patchloom-x86_64-pc-windows-msvc.zip (x64)
  • patchloom-aarch64-pc-windows-msvc.zip (ARM64)

Tag form is patchloom-vX.Y.Z (for example patchloom-v0.33.0).

$ver = "0.33.0"   # x-release-please-version (or pin an older release)
$tag = "patchloom-v$ver"
$url = "https://github.com/patchloom/patchloom/releases/download/$tag/patchloom-x86_64-pc-windows-msvc.zip"
$dir = "$env:TEMP\patchloom-portable"
New-Item -ItemType Directory -Force -Path $dir | Out-Null
$zip = Join-Path $dir "pl.zip"
Invoke-WebRequest -Uri $url -OutFile $zip
Expand-Archive -Path $zip -DestinationPath $dir -Force
# Layout: patchloom.exe, LICENSE, README.md, CHANGELOG.md at $dir root
& "$dir\patchloom.exe" --version
& "$dir\patchloom.exe" --help
# Optional: copy patchloom.exe to a directory already on PATH

winget and Chocolatey (Windows)

Prefer Scoop or a GitHub Release installer when you want the channel we operate. Use winget or Chocolatey when that is what your environment already allows. Both are published from Release CI; currency differs after each tag.

# winget (package id is Patchloom.Patchloom)
winget source update
winget install Patchloom.Patchloom
# or upgrade an existing install
winget upgrade Patchloom.Patchloom

# Chocolatey (community feed; may trail GitHub latest)
choco install patchloom
CatalogId / packageCurrency after a GitHub Release
wingetPatchloom.PatchloomRelease CI opens a microsoft/winget-pkgs PR. After Microsoft merge and publish, refresh with winget source update. Can lag by days while the PR waits; once published it is usually current.
ChocolateypatchloomEach nupkg is pushed automatically, then community moderation must approve it before it is installable as latest. Often trails GitHub longer than winget.

If winget show / choco list only offers an older build, that is expected until the community queue clears. Use Scoop or GitHub Releases for the version you just saw announced.

The files under chocolatey/ in this repository are a packaging template. Release CI rewrites the nuspec version and checksums before push; do not treat the in-tree version field as the live community feed version. Check community.chocolatey.org/packages/patchloom for what choco install actually resolves.

From source

Install from source (requires Rust 1.95+):

git clone https://github.com/patchloom/patchloom.git
cd patchloom
cargo install --path .

This builds with all features by default (CLI + MCP server + AST operations). To build a smaller binary without optional features (CLI is always included for the binary):

# CLI + AST only (no MCP server, no tokio/async)
cargo install --path . --no-default-features --features "cli,ast"

# CLI + MCP only (no AST grammars)
cargo install --path . --no-default-features --features "cli,mcp"

# CLI only (no MCP, no AST)
cargo install --path . --no-default-features --features cli

If you're contributing from a source checkout, use make check-fast while iterating and make check before committing.

As a Rust library

Add patchloom as a dependency to embed structured file editing in your own Rust tools. Disable default features to omit CLI (clap), MCP server, and AST:

[dependencies]
patchloom = { version = "0.33.0", default-features = false } <!-- x-release-please-version -->

To add AST support without CLI/MCP (LLM agent embedders typically use ast + files for plan execution and AST file mutators):

patchloom = { version = "0.33.0", default-features = false, features = ["ast", "files"] } <!-- x-release-please-version -->

With ast, 0.32 pulls tree-sitter 0.27 (links = "tree-sitter"). Cargo allows only one crate with that links key. Bump tree-sitter-highlight (or any other links = "tree-sitter" crate) to 0.27 in the same lock update. See Embedder host.

See the crate documentation for the full API surface (ReplaceOptions::for_agent, fuzzy_span_suspicious, require_change, command_position, ast_rename_batch, find_files_with_symbol, classify_error, restore_path_from_session, run_post_write_validation, match_mode) and the introduction for a quick overview. Host checklist: Embedder host. Embedder tables live under Library API in the reference.

Shell completions

After installing, generate shell completions:

# bash (system-wide; may require sudo and /etc/bash_completion.d in your setup)
patchloom completions bash > /etc/bash_completion.d/patchloom

# zsh (ensure ~/.zfunc is in $fpath, e.g. via oh-my-zsh custom or compinit)
patchloom completions zsh > ~/.zfunc/_patchloom

# fish
patchloom completions fish > ~/.config/fish/completions/patchloom.fish

# elvish
patchloom completions elvish > ~/.config/elvish/rc.elv

# PowerShell
patchloom completions powershell >> $PROFILE

Verify

patchloom --version
patchloom --help