Patchloom Reference
This is the reference for Patchloom's meaningful commands, actions, operations, and notable command modes.
- Start with Quickstart if you want a first success.
- Read Core Concepts for shared semantics like write modes, exit codes, and transaction behavior.
- Use this file when you need to choose the right feature or mode for a job, or when a pull request adds meaningful CLI surface and the docs coverage test expects it here.
Global behaviors
Patchloom has a small set of global features that shape how other commands behave.
Write modes
Patchloom write commands default to preview mode. The canonical semantics live in Core Concepts. The sections below focus on when to choose each mode.
--diff
- What it does: Prints the unified diff for a write command without mutating files.
- Use when: You want a human review step before applying a change, or you want to inspect the exact patch Patchloom would write.
- Prefer instead: Use
--checkfor CI pass or fail behavior, or--applyto actually write files.
--apply
- What it does: Writes the requested change to disk.
- Use when: You have already previewed the change, or you trust the command and want the mutation to happen now.
- Prefer instead: Use
--diffwhen reviewing, or--checkwhen you only need a clean or dirty signal.
--check
- What it does: Calculates whether a write command would change files and returns exit code 2 when changes are pending.
- Use when: You are wiring Patchloom into CI, pre-commit validation, or agent workflows that should fail on drift.
- Prefer instead: Use
--diffwhen you need the actual patch text, or--applywhen you want the mutation.
--confirm
- What it does: Shows the diff preview, then prompts
Apply? [Y/n]on stderr. If confirmed, applies the change; if declined, exits without writing. - Use when: You want a single-command preview-then-apply workflow instead of running the command twice.
- Prefer instead: Use
--applywhen scripting (no interactive prompt), or--diffwhen you only want the preview.
--diff, --apply, --check, and --confirm are mutually exclusive. Passing more than one is rejected with an error. When none is specified, --diff is the default. When --confirm is used and stdin is not a TTY, the command shows the diff without prompting (same as --diff).
Write policy flags
These flags shape how written content is normalized before it reaches disk.
--ensure-final-newline
- What it does: Ensures non-empty written files end with
\n. - Use when: You want simple newline hygiene on every touched file without running a separate cleanup command.
- Prefer instead: Use
tidy fixwhen the goal is repo cleanup, not just normalization of files already being edited.
--normalize-eol
- What it does: Normalizes written line endings to
keep,lf,crlf, orcr. - Use when: A repo or downstream tool expects a specific line ending convention.
- Prefer instead: Use
--respect-editorconfigwhen the repo already declares the desired convention there.
--trim-trailing-whitespace
- What it does: Removes trailing spaces and tabs from touched lines before writing.
- Use when: You want text cleanup to happen automatically as part of another write command.
- Prefer instead: Use
tidy fixwhen the goal is to sweep existing files for whitespace problems.
--respect-editorconfig
- What it does: Reads
.editorconfigwhen present and applies matching write policy. - Use when: The repo already encodes formatting policy in
.editorconfigand Patchloom should follow it automatically. - Prefer instead: Use explicit write flags, or
txwrite_policy, when the command should be self-contained and not depend on repo metadata.
--collapse-blanks
- What it does: Collapses consecutive blank lines into a single blank line after writing. Useful after line deletion to prevent double-blank gaps.
- Use when: You are deleting lines (e.g. with
replace --whole-line --new '') and want to clean up the resulting blank line runs. - Prefer instead: Omit when consecutive blank lines are intentional (e.g. section separators in code).
--format
- What it does: Runs a shell command after every successful
--applywrite. Intended for formatters (e.g.prettier --write .,cargo fmt). - Use when: The repo has an autoformatter and you want Patchloom to invoke it after each mutation so files stay formatted.
- Prefer instead: Omit when the formatter is already run separately, or when using
--diff/--checkmodes (the command only fires on--apply).
--format-timeout
- What it does: Sets the maximum time in seconds the
--formatcommand is allowed to run before being killed. Defaults to 30 seconds. - Use when: The formatter is slow (e.g. large monorepo) and the default 30 second timeout is insufficient.
- Prefer instead: Keep the default unless the formatter demonstrably needs more time.
--no-format
- What it does: Disables post-write formatting even if configured in
.patchloom.toml(via[format] auto = trueor[defaults] format). - Use when: You want to skip formatting for a single invocation without changing the project config.
- Prefer instead: Omit when you want the configured formatter to run normally.
Output and scope flags
These flags affect how Patchloom reports results or chooses which files to touch.
--json
- What it does: Emits one machine readable JSON document for the command result.
- Use when: Another tool, script, or agent needs structured output instead of human oriented text.
- Prefer instead: Use
--jsonlwhen you want one JSON object per result line for streaming style consumers.
--jsonl
- What it does: Emits one compact JSON value per result line instead of one aggregate document.
- Use when: A command naturally yields multiple result records, or you want compact machine-readable output from single-result commands like
create,delete,rename,status,tx,explain, orundo. - Prefer instead: Use
--jsonwhen you want one aggregate document for the whole command.
--quiet
- What it does: Suppresses non-JSON human readable output.
- Use when: Only the exit code or the file mutation matters and extra stdout noise would get in the way.
- Prefer instead: Use
--jsonwhen another tool still needs structured output.
--cwd
- What it does: Sets the working directory used to resolve relative paths.
- Use when: You are invoking Patchloom from outside the target repo, or you want scripts to behave predictably regardless of the caller's current directory.
- Prefer instead: Use a plan level
cwdintxwhen the directory choice should travel with the plan itself, but keep it inside the invocation root. Relative plancwdvalues resolve from the caller's working directory (--cwdor the process cwd), not from the plan file location. - Not a sandbox: Without
--contain, paths may escape via../or absolute paths. MCP always enforces containment; use--containfor the same on CLI.
--contain
- What it does: Rejects file paths that escape the working directory (via
../, absolute paths outside the policy, or symlinks that resolve outside the workspace). Mirrors MCP / libraryPathGuardfor reads and writes: explicit paths onsearch/read/replace/create/delete/rename/append/prepend/patch/md/doc/tidy/tx/batch(including binary/case-only rename). - Use when: An agent or automation should not be able to read or write outside
--cwd(or the process cwd). Pair with--cwdfor a workspace root. - Default: Off. CLI remains unrestricted for human scripts (same trust model as
make/sh). - Prefer instead: Use the MCP server when the agent already has MCP tools; containment is always on there.
--glob
- What it does: Restricts candidate files by one or more glob patterns. Patterns match either the basename or the path relative to the input root, so
sub/*.txtmatches files under a searchedsub/directory. - Use when: A command should only see a narrow file type or subtree, even if the input path is broader.
- Prefer instead: Use
--files-fromwhen another tool has already determined the exact file list.
--exclude
- What it does: Excludes paths matching the given glob patterns (applied after .gitignore and any custom ignore files). May be repeated. Complements
--glob. - Use when: You want to layer additional excludes (e.g.
target/**or build artifacts) on top of.blineignore/.gitignorefor search, replace, or tidy. - Parity: Matches
SearchOptions.exclude_patternsand the librarycollect_file_paths_with_ignoresprecedence.
--ignore-file
- What it does: Specifies additional gitignore-style ignore files (e.g.
.blineignore) to respect during file collection. May be repeated. - Use when: Agents or projects use custom ignore files (Bline-style) and want CLI / tx / MCP search (and replace/tidy) to honor the same layered ignores as the pure-library API.
- Parity: Matches
SearchOptions.custom_ignore_filenames.
--files-from
- What it does: Reads the target file list from a file, or from stdin when passed
-. A relative list path is resolved under--cwdwhen that flag is set (absolute list paths are unchanged). Paths inside the list are still resolved against--cwd/ the process cwd as usual, and under--containeach listed path must stay in the workspace. - Use when: Another tool already selected the exact paths and Patchloom should operate only on that set.
- Prefer instead: Use
--globfor pattern based scoping, or direct path arguments when the target set is already small and obvious.
--color
- What it does: Controls when ANSI color codes appear in output.
auto(default) enables color when stdout is a terminal and theNO_COLORenvironment variable is not set.alwaysforces color even when piped.neverdisables color unconditionally. - Use when: You need to override the default terminal detection, for example forcing color into a pager or disabling it in a terminal that renders escape codes literally.
- Prefer instead: Set the
NO_COLORenvironment variable when you want a global, tool-agnostic way to disable color across all CLI tools.
format_config (internal)
- What it does: Carries the per-extension formatter configuration loaded from
.patchloom.toml([format.by_extension]table) so that post-write formatting can run the correct formatter for each file type. - Use when: You configure
[format] auto = trueand[format.by_extension]in.patchloom.toml. The field is populated automatically; it is not set via CLI flags.
--verbose
- What it does: Prints diagnostic messages to stderr prefixed with
[patchloom]. Shows which operations are running, search parameters, selector path evaluation steps, and MCP tool call timing. Can also be enabled by setting thePATCHLOOM_LOGenvironment variable to any value. - Use when: A command produces unexpected results and you need to see what Patchloom is doing internally without reading source code.
- Prefer instead: Use
--jsonwhen you need machine-readable output for downstream tools.
Exit codes
Use Core Concepts as the canonical exit code table. When integrating Patchloom into CI or agent workflows, branch on exit codes instead of parsing human readable output.
Commands
These are the main entry points. If you are deciding between commands, start here.
search
- What it does: Searches text files with literal or regex matching, optional context, counts, and file only results. Binary and invalid UTF-8 files are skipped.
- Use when: You need to locate candidate edits, audit repo state, or narrow inputs before changing files. For AI agents, native search/grep tools are typically faster for simple pattern matching.
- Prefer instead: Use
replacefor actual text mutation, ordoc,md, orpatchwhen you already know the structured change you want. - Related:
--glob,--files-from,replace
replace
- What it does: Performs mechanical string replacement across one or many text files, with literal or regex matching. Binary and invalid UTF-8 files are skipped.
- Use when: You are doing a rename, version bump, boilerplate rewrite, or another string level change where plain text semantics are enough. For AI agents doing single-file replacements, native search_replace tools are typically faster; use patchloom
replaceinsidetxplans when batching multiple file edits. - Prefer instead: Use
docfor structured data,mdfor heading aware markdown, orpatchwhen you already have a unified diff. - Related:
search,tx
patch
- What it does: Checks or applies a unified diff.
- Use when: The change already exists as a patch, or you want stale context detection instead of search and replace semantics.
- Prefer instead: Use
replace,doc, ormdwhen you want to describe the mutation directly instead of carrying a diff artifact. - Related:
patch check,patch apply,patch merge,tx patch.apply
md
- What it does: Performs heading aware markdown edits for sections, bullets, tables, and AGENTS linting.
- Use when: Documentation needs semantic markdown edits that should not depend on raw byte offsets.
- Prefer instead: Use
replacefor simple line level edits, orpatchfor exact diff application. - Related:
mdactions,txmarkdown operations
doc
- What it does: Performs parser backed JSON, YAML, and TOML queries and mutations.
- Use when: Config or metadata changes should operate on keys and arrays instead of brittle text matching.
- Prefer instead: Use
replacefor plain text,mdfor markdown, orpatchfor existing diffs. - Related:
docactions,txdocument operations
tidy
- What it does: Checks or fixes trailing whitespace, line endings, and final newlines in text files. Binary and invalid UTF-8 files are skipped.
- Use when: You need repo text normalization, or a CI guard for basic text tidiness.
- Prefer instead: Use write policy flags when the cleanup should only apply to files already being touched by another command.
- Related:
tidy check,tidy fix,tx tidy.fix
append
- What it does: Appends content to the end of an existing file. If the file does not end with a newline, one is inserted before the appended content. Exactly one of
--contentor--stdinis required. Fails if the file does not exist (unlikecreate). - Use when: Adding tests, changelog entries, rules, or any content to the end of a file without reading the entire file to find a unique anchor.
- Prefer instead: Use
replacewhen the insertion point is not the end of the file. - Related:
create,prepend,tx file.append
prepend
- What it does: Prepends content to the beginning of an existing file. Exactly one of
--contentor--stdinis required. Fails if the file does not exist or if the target is a directory. - Use when: Adding headers, copyright notices, shebang lines, or any content to the beginning of a file without reading the entire file to find a unique anchor.
- Prefer instead: Use
replacewhen the insertion point is not the beginning of the file. - Related:
append,create,tx file.prepend
create
- What it does: Creates a file from literal content or stdin. Exactly one of
--contentor--stdinis required. Passing both is rejected with--content and --stdin cannot be combined, and passing neither is rejected witheither --content or --stdin must be provided. Directory targets are rejected in all modes. When combined with--confirmand--jsonor--jsonl, the structured output includesapplied: true|falseso callers can tell whether the prompt was accepted. - Use when: Generating a new tracked file is the whole task, or one step in a larger transaction. For AI agents creating a single file, native file creation tools are typically faster; use
file.createinsidetxplans when bundling with other edits. - Prefer instead: Use
doc,md, orreplacewhen the file already exists and only needs edits. - Related:
delete,tx file.create
delete
- What it does: Removes a file. Directory targets are rejected in all modes. When combined with
--confirmand--jsonor--jsonl, the structured output includesapplied: true|falseso callers can tell whether the prompt was accepted. - Use when: A file should disappear outright and no other atomic edits are needed. For AI agents deleting a single file, native delete tools are typically faster; use
file.deleteinsidetxplans when bundling with other edits. - Prefer instead: Use
tx file.deletewhen the removal must be bundled atomically with other changes. - Related:
create,tx file.delete
rename
- What it does: Moves (renames) a file from one path to another. Source and destination must both be file paths, not directories. When combined with
--confirmand--jsonor--jsonl, the structured output includesapplied: true|falseso callers can tell whether the prompt was accepted. - Use when: A file needs to be relocated and no other atomic edits are needed. Use
file.renameinsidetxplans when bundling with other edits. - Prefer instead: Use
tx file.renamewhen the rename must be bundled atomically with other changes. - Related:
create,delete,tx file.rename
tx
- What it does: Runs multiple operations atomically, then optional format and validate steps.
- Use when: Editing 3 or more files in one task. Batches N operations into 1 tool call, eliminating agent round-trips. Also provides atomicity, rollback, and format/validate lifecycle. For AI agents, this is the primary speed advantage: one call instead of N.
- Prefer instead: Use standalone commands when one direct operation is enough.
- Related: examples,
txfields,txoperations
batch
- What it does: Executes multiple operations from a simple line-oriented format. Each line is one operation with positional arguments (e.g.,
doc.set config.json version "2.0.0"). Internally builds a tx plan and delegates to the tx engine. - Use when: Editing multiple files and the JSON tx plan format is too verbose. The line format covers 26 operations (doc.set, doc.delete, doc.merge, doc.ensure, doc.append, doc.prepend, doc.update, doc.move, doc.delete_where, replace, file.append, file.prepend, file.create, file.delete, file.rename, md.upsert_bullet, md.table_append, md.replace_section, md.insert_after_heading, md.insert_before_heading, md.move_section, md.dedupe_headings, md.lint_agents, tidy.fix, ast.rename, ast.replace) with minimal syntax. For AI agents, this is faster to generate than a full JSON plan.
- Prefer instead: Use
txwhen you need format/validate lifecycle steps, strict mode, or operations not supported by the line format (patch.apply, replace with regex/nth, search, read). - Related:
tx
read
- What it does: Prints the contents of one or more files, optionally restricted to a line range. Multiple files get
==> path <==separators in text mode, a JSON array in--jsonmode, and one object per line in--jsonlmode. If at least one requested file is read successfully, the command still exits successfully and reports errors only for the missing files. - Use when: An agent needs to inspect one or several files before deciding on an edit. For AI agents, native read_file tools are typically faster for single-file reads.
- Prefer instead: Use
searchwhen you need pattern matching, ordoc getwhen the file is structured and you want a single value.
Library API
Patchloom can be used as a Rust library (disable default cli feature for smaller dep). See patchloom::api (search_directory with context/globs/max_results, replace_text, read, etc) and execute_plan for tx. Full details and examples in crate docs and README "Embedding as a library". Recent expansions (#779 etc) and hygiene (#784) improved coverage.
- Related:
search,doc get
status
- What it does: Shows which files have uncommitted changes compared to git HEAD. This command is git-backed, so it must run inside a git repository.
- Use when: An agent needs a quick summary of the working tree before committing, staging, or choosing which files to process. For AI agents, native git status or terminal commands are typically equivalent.
- Prefer instead: Use
git statusdirectly when you need full git porcelain output or staging details. - Related:
search,read
undo
- What it does: Restores files from a backup created by a previous
--applyoperation. Before any--applywrite, patchloom saves the original content of affected files to.patchloom/backups/<timestamp>/. In dry-run mode,undoreports what would be restored and exits with code2(CHANGES_DETECTED).--jsonor--jsonlemit that preview as structured output. - Use when: An
--applyoperation produced an undesirable result and you want to revert. Especially useful when the working tree was not committed before applying changes. - Notable flags:
--listshows available backup sessions.--jsonemits the full session list as one array, while--jsonlemits one session object per line.--session <timestamp>targets a specific session (defaults to most recent).--applyactually restores files (dry-run by default, showing what would change).
- Prefer instead: Use
git checkoutorgit stashwhen working in a committed git repo. - Related:
tx,replace,tidy
explain
- What it does: Parses a tx plan (JSON, YAML, or TOML) and prints a numbered, human-readable summary of each operation. Supports
--jsonand--jsonlfor structured output, plus--stdinfor piped input. If both a path and--stdinare provided, stdin takes precedence and the path is ignored. - Use when: A user or agent wants to review what a tx plan will do before running
tx --apply. Converts machine-readable plan format into plain English descriptions. - Prefer instead: Use
txdirectly (without--apply) to see the actual diff preview. Useexplainwhen you want a quick overview without touching any files. - Related:
tx,batch
schema
- What it does: Exports the complete registry of patchloom operations with JSON Schemas, tier-filtered subsets, and LLM-ready system prompt fragments. Each operation is annotated with a minimum capability tier (weak, medium, strong).
- Use when: You are building an AI agent that uses patchloom programmatically and need machine-readable operation schemas, or you want to generate a system prompt tailored to a specific model tier.
- Notable flags:
--format json|prompt(default:json):jsonoutputs operation schemas as JSON,promptoutputs markdown suitable for LLM system prompts.--tier weak|medium|strong: Filter operations by minimum capability tier. Help lists these as the only allowed values (clap enum; nosmall/largealiases).--examples: Include usage examples in JSON output (omitted by default).
- Prefer instead: Nothing; this is the only programmatic way to discover available operations and their schemas.
- Related:
agent-rules,mcp-server
agent-rules
- What it does: Prints an end-user AGENTS.md that teaches AI agents how to use patchloom. Includes command reference, exit codes, write modes, transaction plan format, and usage examples.
- Use when: You are setting up a project where agents should use patchloom for file operations and need an AGENTS.md or SKILL.md that describes patchloom's interface.
- Notable flags:
--mode cli|mcp|all(default:all):cliomits MCP section,mcpomits CLI shell examples,allincludes everything.--platform linux|windows|all(default:all):linuxuses heredocs and single-quote syntax,windowsuses file arguments and double-quote escaping,allshows both.
- Prefer instead: Nothing; this is the only way to generate the end-user agent documentation.
- Related:
completions,mcp-server
init
- What it does: Sets up patchloom in the current project: creates
AGENTS.mdif needed, otherwise appends the rules to an existing agent instructions file, prints shell completion instructions, and detects MCP configuration opportunities. When.vscode/or.cursor/already exists, it prints ready-to-copy.vscode/mcp.jsonor.cursor/mcp.jsonsnippets. - Use when: You just installed patchloom and want a single command to configure a project instead of running
agent-rules,completions, and MCP setup separately. - Notable flags:
-y, --yes: Skip confirmation prompts and auto-accept all actions.
- Prefer instead:
agent-rulesif you only need the rules text, orcompletionsif you only need shell completions. - Related:
agent-rules,completions,mcp-server
mcp-server
- What it does: Starts an MCP (Model Context Protocol) server, exposing patchloom operations as structured tool calls. Supports stdio (default) and Streamable HTTP transport (with
--http). Included by default in all builds. - Use when: An MCP-capable AI agent can call patchloom tools directly via structured tool calls instead of constructing shell commands. Use
--httpfor remote agents. - Notable flags:
--log <path>: Log tool calls to a JSONL file (also settable viaPATCHLOOM_MCP_LOGenv var).--http: Use Streamable HTTP transport instead of stdio.--host <addr>(default:127.0.0.1): Bind address (requires--http).--port <port>(default:8080): Bind port (requires--http).--tls-cert <path>/--tls-key <path>: TLS certificate and key PEM files for HTTPS (requires--http; both must be provided together).
- Prefer instead: Use the CLI directly when the agent does not support MCP, or when patchloom is invoked from scripts and CI.
- Related:
batch,tx
completions
- What it does: Generates shell completion scripts for bash, zsh, fish, or elvish.
- Use when: You are installing Patchloom into an interactive shell and want faster command discovery.
- Prefer instead: Nothing, if Patchloom is only used from scripts or ephemeral CI runners.
- Related: installation guide
ast
- What it does: AST-aware operations on source code (20 languages). Subcommands:
list(extract symbol definitions),read(read a symbol by name),rename(rename identifiers, skipping strings/comments),validate(syntax validation),search(structural queries),refs(find references),deps(extract imports),map(ranked repo map via PageRank),diff(structural diff vs git refs),impact(transitive impact analysis),replace(scoped text replacement within a symbol). - Use when: You need to list, read, rename, validate, search, or analyze symbols with structural awareness (skip strings, comments, and documentation). Especially useful for rename operations where the old name appears inside strings that should not be changed, and for impact analysis before refactoring.
- Prefer instead: Use
replace --word-boundaryfor quick identifier renames when AST precision is not required. Use a language server (LSP) when cross-file type-aware rename is needed. - Related:
replace,search
Command modes
These are meaningful command-specific modes that change how a top-level command behaves, even though they are not separate subcommands.
search --files-with-matches
- What it does: Emits only file paths that contain at least one match.
- Use when: You need a path list to feed into another tool or command instead of the matching lines themselves.
- Prefer instead: Use
search --countwhen per-file match totals matter, or plainsearchwhen the matching lines matter.
search --count
- What it does: Emits match counts per file instead of full matching lines.
- Use when: You are auditing prevalence, comparing files, or gating on how many matches remain.
- Prefer instead: Use plain
searchwhen you need the matching text, orsearch --files-with-matcheswhen only file membership matters.
search --invert-match
- What it does: Shows lines that do not match the pattern.
- Use when: You are looking for non-conforming lines or excluding content that matches a known pattern.
- Prefer instead: Use plain
searchwhen you want the matching lines themselves.
search --multiline
- What it does: Lets regex matches span multiple lines by making
.match newlines. - Use when: The pattern you care about is inherently block-shaped, such as a function body or multi-line stanza.
- Prefer instead: Use plain
searchfor line-oriented patterns because it is simpler and easier to reason about.
search --before-context
- What it does: Shows N lines before each match but none after (unless combined with
-A). - Use when: You need to see what precedes a match (function signature before a body, imports before usage) without cluttering output with lines after.
- Prefer instead: Use
--context(-C) when symmetric context is fine, or combine-Band-Afor independent before/after counts.
search --after-context
- What it does: Shows N lines after each match but none before (unless combined with
-B). - Use when: You need to see what follows a match (function body after signature, error handling after a call) without lines before.
- Prefer instead: Use
--context(-C) when symmetric context is fine, or combine-Band-Afor independent before/after counts.
search --case-insensitive
- What it does: Matches regardless of case.
- Use when: The target text may appear in inconsistent capitalization across files.
- Prefer instead: Use case-sensitive search when exact spelling matters and false positives would be noisy.
search --assert-count
- What it does: Succeeds (exit 0) only if the total match count equals the given number. Exits 2 otherwise.
- Use when: An agent or CI pipeline needs to verify an invariant (e.g. "exactly 18 markers exist") in one call instead of searching and then comparing the count manually.
- Prefer instead: Use plain
search --countwhen you want to see counts without a pass/fail assertion.
replace --regex
- What it does: Treats the pattern as a regex instead of a literal string.
- Use when: The change is pattern-based, or capture groups should shape the replacement.
- Prefer instead: Use literal replace for fixed text because it is simpler and less error-prone.
replace --if-exists
- What it does: Returns success even when no matches are found.
- Use when: The replacement is intentionally idempotent and should not fail if the repo is already in the desired state.
- Prefer instead: Use default replace behavior when a missing match should be treated as drift or an error.
replace --nth
- What it does: Replaces only the Nth occurrence of the target.
- Use when: Replacing every occurrence would be too broad and the exact positional match matters.
- Prefer instead: Use plain replace when every occurrence should change, or regex when the target can be narrowed semantically.
replace --insert-before
- What it does: Inserts text before each match instead of replacing it. The matched text is preserved.
- Use when: You need to add a line or annotation above an existing anchor without repeating the anchor in the replacement text.
- Prefer instead: Use
--newwhen the matched text should actually change, not just receive a prefix.
replace --insert-after
- What it does: Inserts text after each match instead of replacing it. The matched text is preserved.
- Use when: You need to append content after an existing anchor, such as adding a comment or tag after a specific line.
- Prefer instead: Use
--newwhen the matched text should actually change, not just receive a suffix.
replace --multiline
- What it does: Lets regex replacement span multiple lines by making
.match newlines. - Use when: The target pattern is a multi-line block rather than a single line.
- Prefer instead: Use line-oriented replace when the match should stay local and easy to inspect.
replace --case-insensitive
- What it does: Matches regardless of case during replacement.
- Use when: The target text appears with inconsistent capitalization and should still be updated uniformly.
- Prefer instead: Use case-sensitive replace when exact spelling is part of the safety boundary.
replace --word-boundary
- What it does: Wraps the search pattern with
\b(word boundary) anchors so it only matches as a standalone word. PreventsSetupFilefrom matching insideBenchSetupFile. The pattern is auto-escaped for regex metacharacters before anchoring. - Use when: Renaming identifiers where the old name is a substring of other identifiers (e.g.
SetupFilevsBenchSetupFile,TaskvsTaskResult). - Prefer instead: Use AST-aware rename (#647) when you need to skip matches inside strings and comments. Word boundary only prevents partial-word matches, not string/comment matches.
replace --whole-line
- What it does: Replaces (or deletes) entire lines that contain a match, instead of replacing only the matched span. When combined with
--new '', removes matching lines entirely. - Use when: You need to delete lines matching a pattern (dead code, lint suppressions, debug statements) or replace full lines based on a partial match.
- Prefer instead: Use regular replace when only the matched text should change while the rest of the line stays intact.
replace --range
- What it does: Restricts
--whole-linematching to a line range (e.g.--range 10:50). Lines outside the range are not considered for matching. Requires--whole-line. - Use when: The pattern matches lines you want to keep in other parts of the file (e.g. removing dead code from implementation but not from tests).
- Prefer instead: Omit when the pattern is specific enough to avoid false positives.
replace --unique
- What it does: Fails with exit code 5 (AMBIGUOUS) if the pattern matches more than once in any single file. Enforces unambiguous, single-target edits. The check is per-file: matching once in file A and once in file B is allowed.
- Use when: You need a guardrail that the replacement targets exactly one location per file (CI scripts, automated pipelines, agent-driven edits where accidental bulk replacement is dangerous).
- Prefer instead: Use
--nthto target a specific occurrence when you know which one you want, or omit when replacing all occurrences is the intent.
replace --before-context
- What it does: Provides context line(s) that must appear before the target for anchor-based disambiguation. When the pattern matches multiple times, the match nearest to this context is selected. Routes through the tx engine fallback chain, which supports fuzzy anchor matching when the exact text is not found.
- Use when: The pattern matches multiple times in a file and you need to target one specific occurrence by its surrounding code. Requires explicit file paths (not directory scan).
- Prefer instead: Use
--nthwhen you know the ordinal position. Use--uniquewhen you want to enforce single-match without specifying context.
replace --after-context
- What it does: Provides context line(s) that must appear after the target for anchor-based disambiguation. Same semantics as
--before-contextbut anchors on what follows the match instead of what precedes it. Both can be combined for even more precise targeting. - Use when: The pattern matches multiple times and the distinguishing context comes after the match, not before.
- Prefer instead: Use
--before-contextwhen the preceding lines are more distinctive.
create --stdin
- What it does: Reads the new file content from stdin instead of
--content. - Use when: Another tool is generating the content, or shell composition is cleaner than embedding the full text in one argument.
- Prefer instead: Use
create --contentfor short inline content that should stay visible in the command itself.
create --force
- What it does: Overwrites an existing file instead of failing.
- Use when: File recreation is intentional and should replace previous contents deterministically.
- Prefer instead: Use default create behavior when accidental overwrite would be dangerous.
patch FILE
- What it does: Reads the unified diff from a file path (positional argument).
- Use when: The patch already exists as a saved artifact that should be reviewed, reused, or passed around directly.
- Prefer instead: Use
patch --stdinwhen another tool is piping the patch text dynamically.
patch --stdin
- What it does: Reads the unified diff from stdin instead of a file argument.
- Use when: Another tool is generating or piping the patch text directly.
- Prefer instead: Use
patch FILEwhen the diff should be stored as a tangible artifact.
doc --predicate
- What it does: Supplies the key-value predicate used by
doc delete-where. Object arrays use a field key (e.g.name=react). Scalar arrays match the element with.=a,_=a, orvalue=a(valueis accepted as an agent-friendly alias for element match). - Use when: Array cleanup should target matching objects or scalar values instead of deleting by fixed index or selector path alone.
- Prefer instead: Use
doc deletewhen one direct selector path can remove the target without predicate filtering.
doc --stdin
- What it does: Reads merge payload content from stdin for
doc merge. - Use when: The object being merged is generated by another tool or is awkward to express inline.
- Prefer instead: Use
doc merge --valuefor short, self-contained object literals.
md --stdin
- What it does: Reads replacement or inserted markdown content from stdin for the section-editing commands.
- Use when: The markdown payload is generated, large, or easier to stream than to quote inline.
- Prefer instead: Use
--contentwhen the inserted text is small and should stay visible in the command.
tx -
- What it does: Reads the transaction plan from stdin instead of a plan file. Defaults to JSON; use
--plan-formatfor YAML or TOML. - Use when: The plan is generated on the fly or piped from another tool.
- Prefer instead: Use
tx FILEwhen the plan should be stored, reviewed, or reused.
tx --plan-format yaml
- What it does: Tells
txto parse the plan as YAML (or TOML) instead of JSON. Auto-detected from file extension for plan files; required when piping YAML from stdin. - Use when: The plan is easier to write or generate in YAML/TOML, or when JSON verbosity is friction for inline agent-generated plans.
- Prefer instead: Use JSON plans when interoperability or strict schema validation matters more than writability.
doc actions
Use these when the top level doc command is right, but you need a specific structured operation.
Comment preservation: All doc write operations preserve inline comments, section comments, and formatting in YAML and TOML files. The parser edits the concrete syntax tree (CST) directly, so only the changed values are rewritten while surrounding comments and whitespace stay intact. This includes operations that change array length (append, prepend, delete-where), which use text-level splicing to preserve comments on the affected file.
doc get
- What it does: Reads the value at a selector path from a JSON, YAML, or TOML file.
- Use when: You need one precise value without mutating the document.
- Prefer instead: Use
doc flattenwhen you are exploring an unfamiliar file and need a broader map of its contents.
doc has
- What it does: Checks whether a selector path exists.
- Use when: A script or workflow needs a presence check before choosing a later action.
- Prefer instead: Use
doc ensurewhen the real goal is to create the value if it is missing.
doc keys
- What it does: Lists the keys of an object at a selector path.
- Use when: You want to inspect the shape of a structured object before choosing an edit.
- Prefer instead: Use
doc getwhen you already know the exact selector path you want.
doc len
- What it does: Counts items in an array or object.
- Use when: You need a quick cardinality check in scripts, CI, or exploratory work.
- Prefer instead: Use
doc selectordoc getwhen the actual values matter more than the count.
doc set
- What it does: Sets or creates a value at a selector path.
- Use when: One exact selector path should be updated deterministically.
- Prefer instead: Use
doc mergefor multi field updates, ordoc ensurewhen existing values should be preserved.
doc delete
- What it does: Removes the value at a selector path.
- Use when: A selector path or node is obsolete and should disappear cleanly.
- Prefer instead: Use
doc delete-wherewhen the target is a subset of array items instead of one direct selector path.
doc delete-where
- What it does: Deletes array items that match a predicate (
--predicate key=value). For scalar arrays, use.=x,_=x, orvalue=x. - Use when: You need to remove selected objects or scalar values from a list without rebuilding the whole array by hand.
- Idempotency: When no elements match the predicate, the command exits 0 and does not rewrite the file (same as
doc deleteon a missing key). Usedoc updatewhen a missing match should be an error. - Prefer instead: Use
doc deletewhen one direct selector path can remove the target.
doc merge
- What it does: Deep merges an object payload into an existing document.
- Use when: Several related fields should be added or updated together.
- Prefer instead: Use
doc setwhen one exact path should change and merge semantics are unnecessary.
doc append
- What it does: Appends a value to an array.
- Use when: New items should appear at the end of the list.
- Prefer instead: Use
doc prependwhen order or precedence means the new item should come first.
doc prepend
- What it does: Inserts a value at the front of an array.
- Use when: The new item should win by order, or defaults should be introduced at the front of the list.
- Prefer instead: Use
doc appendwhen simple chronological growth is enough.
doc select
- What it does: Reads only the values that match a selector path or predicate.
- Use when: You need a filtered read view of a larger structure.
- Prefer instead: Use
doc updateordoc delete-wherewhen the end goal is mutation rather than inspection.
doc update
- What it does: Updates all matching nodes to the same value.
- Use when: A broad but uniform change should apply across many selected elements.
- Prefer instead: Use
doc setwhen the change only targets one path.
doc move
- What it does: Moves or renames a selector path.
- Use when: Schema cleanup or path migration should preserve the value while changing the selector path.
- Prefer instead: Use
doc setplusdoc deleteonly when the move semantics are not a clean fit.
doc ensure
- What it does: Creates a value only if it is currently missing.
- Use when: You need idempotent config bootstrapping and must not overwrite existing values.
- Prefer instead: Use
doc setwhen the desired value should win even if the selector path already exists.
doc flatten
- What it does: Lists leaf selector paths and their values.
- Use when: You are discovering the shape of an unfamiliar structured file.
- Prefer instead: Use
doc getfor one targeted read, ordoc keyswhen only the object shape matters.
doc diff
- What it does: Compares two structured files by their semantic content.
- Use when: You care about structural value changes more than raw formatting differences.
- Prefer instead: Use
patchor ordinary diff tooling when the exact textual patch matters.
md actions
Use these when markdown structure matters more than raw text matching.
md replace-section
- What it does: Replaces the body of a heading section.
- Use when: A section should be treated as authoritative content that can be rewritten in one step.
- Prefer instead: Use
md insert-after-headingwhen existing section content should stay and you only need to add more text.
md insert-after-heading
- What it does: Inserts content immediately after a heading.
- Use when: You want to add a note, release entry, or status line while preserving the existing section body.
- Prefer instead: Use
md replace-sectionwhen the whole section should be regenerated.
md insert-before-heading
- What it does: Inserts content immediately before a heading.
- Use when: You want to add a preface or a new section boundary before an existing heading.
- Prefer instead: Use
md insert-after-headingwhen the addition belongs inside the section that starts at the heading.
md upsert-bullet
- What it does: Ensures a bullet exists under a heading, without duplicating it.
- Use when: Rules, checklists, or recurring notes should be added idempotently.
- Prefer instead: Use
md replace-sectionwhen the entire list should be rewritten.
md dedupe-headings
- What it does: Removes duplicate headings.
- Use when: Generated markdown or hand edited docs have accumulated repeated sections that should collapse to one.
- Prefer instead: Use
md lint-agentswhen the goal is diagnosis rather than mutation.
md lint-agents
- What it does: Checks AGENTS style markdown for common problems.
- Use when: You want a CI style guard for agent instruction files before they drift into invalid or confusing structure.
- Prefer instead: Use
md dedupe-headingswhen you already know the file should be auto corrected.
md table-append
- What it does: Appends a row to the markdown table under a heading.
- Use when: A docs table should grow without manually rebuilding its existing rows.
- Prefer instead: Use
md replace-sectionwhen the whole table should be regenerated from source data.
md move-section
- What it does: Moves a heading section to a new position, either within the same file (reorder) or to a different file. The section (heading plus body) is extracted from the source and inserted at the target location. Both files are updated atomically.
- Use when: Reorganizing documentation structure by moving sections between files or reordering sections within a file.
- Prefer instead: Use
md replace-sectionfor rewriting content in place, or manual cut and paste when the move involves non-contiguous content.
patch actions
Use these when the change already exists as a unified diff.
patch check
- What it does: Verifies whether a patch applies cleanly, without writing files.
- Use when: CI or review should fail early on stale patch context.
- Prefer instead: Use
patch applywhen the patch should be written, orreplaceanddocwhen you do not actually need to carry a diff file.
patch apply
- What it does: Applies a unified diff. Use
--on-stale mergeto retry with three-way merge when context is stale. - Use when: The desired change is already available as patch text and should be replayed directly.
- Prefer instead: Use
replace,md, ordocwhen you would rather describe the desired mutation at a higher level.
patch merge
- What it does: Three-way merges a unified diff. Conflicts emit
<<<<<<< patchloom (ours)/=======/>>>>>>> patch (theirs)markers. - Use when: Patch context is stale but you still want partial replay instead of regenerating the diff.
- Flags:
--checkreportsclean/merged/conflictper file. Conflicts block--applyunless--allow-conflicts. Exit 8 (CONFLICTS) when conflicts remain.
tidy actions
Use these when newline and whitespace correctness is the main concern.
tidy check
- What it does: Reports missing final newlines, mixed line endings, and trailing whitespace in text files. Binary and invalid UTF-8 files are skipped.
- Use when: You want a non mutating tidy audit for CI or local review.
- Prefer instead: Use
tidy fixwhen the goal is to normalize the files immediately.
tidy fix
- What it does: Applies newline and whitespace normalization to text files. Binary and invalid UTF-8 files are skipped. With no write-policy flags (and without
--respect-editorconfig), it enables final-newline and trailing-whitespace fixes so it matches the issues baretidy checkalways reports. Pass explicit flags (or EditorConfig) to narrow the fix set. - Use when: Existing files already need cleanup and the cleanup itself is the task.
- Prefer instead: Use write policy flags on another write command when normalization should only apply to files already being touched by that command.
tx reference
tx is the place where Patchloom's features compose. Use Core Concepts for the canonical explanation of rollback and exit codes, and examples for plan templates.
Plan fields
version
- What it does: Declares the plan schema version. Patchloom rejects plans whose version does not match the version it supports.
- Use when: Every plan must include this field. It ensures forward-compatibility safety so an old patchloom build does not silently misinterpret a plan written for a newer schema.
- Required: Yes. Plans without a version field are rejected.
cwd
- What it does: Sets the base directory used to resolve relative paths inside the plan.
- Use when: You need plan operations and lifecycle steps to run from a specific subdirectory under the invocation root.
- Important: Relative values resolve from the invocation working directory (
--cwdor the process cwd), not from the plan file's directory. In MCP mode, the resolved directory must stay inside the server root. If the resolved path does not exist or is not a directory, the plan is rejected with PARSE_ERROR (exit 4). - Prefer instead: Use the CLI
--cwdflag when the directory choice is a caller concern rather than part of the plan itself.
write_policy
- What it does: Applies newline, EOL, and whitespace normalization across all pending writes in the plan.
- Use when: Every write in the transaction should share the same normalization policy.
- Fields: Supports
ensure_final_newline(bool),normalize_eol(keep,lf,crlf, orcr),trim_trailing_whitespace(bool), andcollapse_blanks(bool). - Precedence: Patchloom starts from the invocation's per-file write policy, including CLI flags and any
--respect-editorconfigvalues, then overrides only the keys set here. - Prefer instead: Use CLI write flags when one invocation needs defaults, but the plan itself should stay generic.
strict
- What it does: Rolls back file writes when a format or validation step fails. Defaults to
truewhen omitted from the plan. - Use when: Partial writes are unacceptable and post-write failure should behave like a full transaction failure (the default for agent workflows).
- Prefer instead: Set
"strict": falsein the plan,[tx] strict = falsein.patchloom.toml, orpatchloom tx plan.json --apply --no-strictwhen writes may stay on disk even if later validation reports a problem.
operations
- What it does: Lists the ordered mutations that make up the transaction.
- Use when: One logical change spans several steps or several mutation types.
- Prefer instead: Use a standalone command when one direct operation is enough.
format
- What it does: Runs shell commands after writes are staged to disk but before validation.
- Use when: Generated or edited files should be normalized by tools like
cargo fmt,prettier, orblackas part of the same workflow. - Step fields: Each entry accepts
cmd(required shell command) andtimeout(seconds, default60). - Failure behavior: Any non-zero exit or timeout fails the transaction. Error output reports the failing step number, exit status, the lifecycle working directory (
cwd), and a truncated snippet of the command's stderr when available. Withstrict: true, Patchloom rolls back the staged writes. - Prefer instead: Run formatting outside
txwhen it does not need to participate in the transaction's success criteria.
validate
- What it does: Runs shell commands that decide whether the transaction should be reported as valid.
- Use when: Build, test, or policy checks are part of the definition of success for the change.
- Step fields: Each entry accepts
cmd(required shell command),required(bool, defaultfalse), andtimeout(seconds, default60). - Failure behavior:
required: truemakes the step gate transaction success.required: falsestill reports the validation problem to stderr. Error output reports the failing step number, exit status, the lifecycle working directory (cwd), and a truncated snippet of the command's stderr when available. - Prefer instead: Use standalone verification outside
txwhen the mutation and the validation lifecycle should stay separate.
verify
- What it does: Runs pre/post-operation symbol verification checks to ensure structural safety.
- Use when: A refactoring plan must preserve the number of functions, test methods, or other AST symbols.
- Field value: Array of check objects. Each is either
{"kind": "function", "attr": "test"}(symbol count) or{"check": "unique_names"}(named check). - CLI equivalent:
--verify="kind=function,attr=test"(repeatable). - Failure behavior: When a check fails, the transaction rolls back and exits with
VALIDATION_FAILED(6). - Prefer instead: Omit when the plan only touches configuration files or non-code content.
for_each
- What it does: Glob-driven batch expansion. When present, the plan's
operationsare treated as templates and expanded once per matching file. Template variables ({path},{dir},{stem},{ext},{name}) are substituted in all operation fields. - Escape mechanism: Double the braces to produce a literal brace in the output.
{{path}}becomes{path}(not substituted),{{stem}}becomes{stem}, etc. Use this when operation values must contain literal brace-wrapped text that should not be treated as template variables. - Use when: The same structural transform (extract tests, add headers, reorder symbols) must be applied to many files matching a glob pattern.
- Field value: Object with
glob(required),exclude(optional array of glob patterns), andfilter(optional, e.g.has_symbol(tests)). - Failure behavior: If the glob matches zero files, the plan produces zero operations (success with no changes). If any expanded operation fails, the entire batch rolls back atomically.
Transaction operations
The operations below are the building blocks inside operations.
replace
- What it does: Runs text replacement inside a transaction.
- Use when: A text rewrite needs to share atomic rollback, formatting, or validation with other operations.
- Requires: Exactly one of
to,insert_before, orinsert_after, matching top levelreplace. - Regex insert semantics: In regex mode,
insert_beforeandinsert_afterpreserve the matched text, they do not insert the raw pattern string. - Optional fields:
case_insensitive(bool, default false),multiline(bool, default false), andif_exists(bool, default false) match the top levelreplace --case-insensitive,--multiline, and--if-existsflags. - Related: top level
replace
doc.set
- What it does: Runs a targeted structured set inside a transaction.
- Use when: A precise config update must be bundled atomically with other repo changes.
- Field naming: Use
selectorfor the path expression indoc.set,doc.delete,doc.append,doc.prepend,doc.update,doc.ensure, anddoc.delete_where. - Related: top level
doc set
doc.delete
- What it does: Removes a structured value inside a transaction.
- Use when: Schema cleanup should happen as one step in a larger atomic change.
- Related: top level
doc delete
doc.merge
- What it does: Deep merges structured content inside a transaction.
- Use when: Several related structured fields should change together as part of one plan.
- Related: top level
doc merge
doc.append
- What it does: Appends to an array inside a transaction.
- Use when: List growth must stay atomic with other edits in the same plan.
- Related: top level
doc append
doc.prepend
- What it does: Prepends to an array inside a transaction.
- Use when: Ordered config precedence should change as part of a larger atomic mutation.
- Related: top level
doc prepend
doc.update
- What it does: Updates all matching structured nodes inside a transaction.
- Use when: A broad structured rewrite should be coupled to other edits and validations.
- Related: top level
doc update
doc.move
- What it does: Moves or renames a structured selector path inside a transaction.
- Use when: Schema migration must stay atomic with related code or docs edits.
- Related: top level
doc move
doc.ensure
- What it does: Adds a structured value only if it is missing, inside a transaction.
- Use when: Idempotent bootstrapping should happen together with other plan steps.
- Related: top level
doc ensure
doc.delete_where
- What it does: Deletes array items matching a predicate inside a transaction.
- Use when: Targeted list cleanup must be coordinated with other transactional edits.
- Related: top level
doc delete-where
md.replace_section
- What it does: Replaces a markdown section inside a transaction.
- Use when: Docs regeneration should be part of a larger all or nothing repo change.
- Related: top level
md replace-section
md.insert_after_heading
- What it does: Inserts markdown content after a heading inside a transaction.
- Use when: A release note or docs annotation must be added atomically with code or config changes.
- Related: top level
md insert-after-heading
md.insert_before_heading
- What it does: Inserts markdown content before a heading inside a transaction.
- Use when: Docs structure must change as one step in a broader plan.
- Related: top level
md insert-before-heading
md.upsert_bullet
- What it does: Ensures a markdown bullet exists inside a transaction.
- Use when: Idempotent docs or checklist updates should stay coupled to other edits.
- Related: top level
md upsert-bullet
md.table_append
- What it does: Appends a markdown table row inside a transaction.
- Use when: Documentation tables should be updated together with the code or metadata they describe.
- Related: top level
md table-append
md.move_section
- What it does: Moves a markdown section to a new position, optionally to a different file.
- Use when: Section reordering or cross-file moves should be atomic with the rest of the plan.
- Related: top level
md move-section
md.dedupe_headings
- What it does: Removes duplicate markdown headings inside a transaction.
- Use when: Cleanup of generated docs should stay atomic with the rest of the plan.
- Related: top level
md dedupe-headings
md.lint_agents
- What it does: Lints an AGENTS.md file for common problems (duplicate headings, dangerous commands outside code fences, missing final newline) inside a transaction.
- Use when: Agent rules validation should be part of a larger plan, e.g., lint before and after markdown edits to confirm no new issues.
- Related: top level
md lint-agents, MCPmd_lint
tidy.fix
- What it does: Applies tidy normalization inside a transaction.
- Use when: Text cleanup should be part of the same atomic success criteria as other edits.
- Related: top level
tidy fix
file.append
- What it does: Appends content to the end of an existing file inside a transaction. Inserts a newline separator if the file does not end with one.
- Use when: Adding content to a file must be atomic with other operations in the same plan. Fails if the file does not exist.
- Related: top level
append
file.prepend
- What it does: Prepends content to the beginning of an existing file inside a transaction.
- Use when: Adding a header, license, or shebang line must be atomic with other operations in the same plan. Fails if the file does not exist.
- Related:
file.append, top levelappend
file.create
- What it does: Creates a file inside a transaction.
- Use when: New files must appear only if the full plan succeeds.
- Related: top level
create
file.delete
- What it does: Deletes a file inside a transaction.
- Use when: File removal should roll back if later format or validation steps fail.
- Related: top level
delete
file.rename
- What it does: Renames (moves) a file inside a transaction.
- Use when: File renames should roll back if later format or validation steps fail. More efficient than
read+file.create+file.deleteas a single operation. - Related: top level
rename
search
- What it does: Searches a file for a pattern inside a transaction and includes match results in the JSON output without writing anything.
- Use when: An agent needs to locate patterns before replacing them in the same plan, enabling locate-then-edit in a single call.
- Optional fields:
literal,regex,case_insensitive,multiline,invert_match,context/before_context/after_context,globs,exclude_patterns,custom_ignore_filenames(for .blineignore layering),max_results,assert_count. These provide full parity with the top-levelsearchcommand and librarySearchOptions. - Related: top level
search
read
- What it does: Reads a file inside a transaction and includes its content in the JSON output without writing anything. The JSON read result carries the same line metadata as top level
read(start_line,end_line,total_lines), and when no line range is requested it preserves the raw file content exactly. - Use when: An agent needs to inspect file content before or after other operations in the same plan, enabling "understand then edit" in a single call.
- Related: top level
read
patch.apply
- What it does: Applies a unified diff inside a transaction. Supports
on_stale: "merge"for three-way merge when the on-disk file diverged from the patch base, andallow_conflicts: trueto write conflict markers instead of failing during staging. - Use when: Patch replay needs to compose with earlier in-plan edits and share the same rollback or validation behavior.
- Related: top level
patch apply,patch merge
ast.rename
- What it does: Renames all occurrences of an identifier within a file using tree-sitter AST awareness, skipping strings, comments, and documentation. References inside the renamed symbol and callers are updated atomically. Fields are
path,old, andnew(same names asreplace/ast.replace). CLI:ast rename <path> --old <OLD> --new <NEW>. - Use when: You need a precise identifier rename that respects language semantics (e.g., renaming
old_fntonew_fnwithout touching the string"old_fn"in a log message). - Related:
replace(text-level),ast replace
ast.replace
- What it does: Performs a scoped text replacement within a single symbol's body. Only the text inside the named symbol is searched and modified; the rest of the file is untouched.
- Use when: You need to change a value, string, or expression inside a specific function or struct without affecting identically-named text in other symbols.
- Related:
replace(file-level),ast.rename(identifier rename)
ast.insert
- What it does: Inserts new source code at a position relative to an existing symbol (before, after, inside-start, inside-end). Handles indentation matching and blank-line separation.
- Use when: You need to add a new function, field, or statement adjacent to or inside an existing symbol without manually computing line numbers.
- Related:
ast.wrap,ast.group
ast.wrap
- What it does: Wraps an existing symbol with a prefix and suffix, re-indenting the original body. Commonly used for wrapping a function in an
implblock, amodblock, or anifguard. - Use when: You need to add structural nesting around an existing symbol (e.g., wrapping free functions in an
impl, adding#[cfg(test)]module wrappers). - Related:
ast.insert,ast.group
ast.imports
- What it does: Adds or removes import statements from a file. Supports
addandremoveactions with deduplication. Language-aware: handlesuse(Rust),import(Python/JS/TS/Go/Java),#include(C/C++). - Use when: You need to manage imports programmatically after moving symbols, adding new dependencies, or cleaning up unused imports.
- Related:
ast.move,ast.extract_to_file
ast.reorder
- What it does: Reorders top-level symbols (or symbols inside a scope) according to a strategy:
alphabetical,reverse,kind-first(types before functions), or a custom ordered list of names. Preserves attached doc comments and attributes. - Use when: You want to enforce a consistent declaration order (e.g., alphabetical functions, types-first convention) or manually arrange symbols to match a specification.
- Related:
ast.group,ast.move
ast.group
- What it does: Moves one or more symbols into a new or existing module block within the same file. Supports a preamble (e.g.,
use super::*;) and configurable placement (first-symbol position, end of file, or after a specific symbol). - Use when: You want to organize related symbols into a
mod tests { ... }block or group utility functions into a sub-module without extracting to a separate file. - Related:
ast.extract_to_file,ast.move,ast.reorder
ast.move
- What it does: Moves symbols from one file to another, removing them from the source and inserting at a specified position in the target. Supports creating the target file with an optional prepend. Preserves attached doc comments and attributes.
- Use when: You need to relocate functions, structs, or constants between files during a refactoring (e.g., moving helpers from
lib.rstoutils.rs). - Related:
ast.extract_to_file,ast.group,ast.imports
ast.extract_to_file
- What it does: Extracts a single symbol from a source file into a new target file. For module blocks, it can unwrap the module wrapper and un-indent the body. Leaves an optional replacement text (e.g.,
mod tests;) in the source. Supports a prepend for the target (e.g.,use super::*;). - Use when: You want to extract a test module, a large struct, or a helper block into its own file while leaving a
moddeclaration behind. - Related:
ast.split,ast.move,ast.imports
ast.split
- What it does: Splits a file into multiple target files by distributing symbols. Each target specifies which symbols it receives and an optional prepend. Symbols not assigned to any target stay in the source (controlled by
keep_in_source). Supportssource_suffixandsource_prefixfor addingmoddeclarations. Enforces exhaustive accounting by default. - Use when: A file has grown too large and you want to distribute its symbols across several new files in one atomic operation, with
modre-exports generated automatically. - Related:
ast.extract_to_file,ast.move,ast.group
Library API
- What it does: Use patchloom as a Rust library (
default-features = false, enableast/mcpas needed). High level entry points inpatchloom::api(search, replace_text, etc), plusexecute_plan,make_plan,PathGuardfor containment, and full plan types for tx. All public types areSend + Sync. - Use when: Embedding in agents (e.g. bline), custom tools, or tests without CLI spawn overhead. See
cargo doc --no-default-features --features ast --open. - Notable:
search_directory(root, pattern, opts)for parallel content search with globs/context (library equivalent of CLI search). Error paths and guards documented in api.rs. - Related: README "As a library",
src/api.rs,src/lib.rsdocs, examples/README.md entry for search_directory.
