Skip to main content
@coder is the engineering suite used by Coder Mode (/coder). It provides actions for reading/searching files, safely applying patches, running commands, and reverting changes.
@coder is a builtin plugin — it comes embedded in the ChatCLI binary and works immediately, without installation. If you need a custom version, simply place the binary in ~/.chatcli/plugins/ and it will take precedence over the builtin. When removed, the builtin returns automatically on the next /plugin reload.

Quick Reference

All subcommands and their most commonly used flags at a glance:

Argument Formats

@coder accepts two argument formats: JSON and CLI-style. Both are equivalent.

Subcommands — Complete Reference

Reads the contents of a file from disk. Supports partial reading by line range and byte limits.

Flags

Examples

Use --head or --tail to avoid very large outputs. The --max-bytes limit (default 200KB) acts as a safety net even when not explicitly specified.
Writes content to a file. Automatically creates a .bak backup of the existing file before overwriting.

Flags

Examples

Use --encoding base64 for content containing special characters, complex line breaks, or binary data. This avoids escaping issues in JSON.
Post-edit diagnostics. After a successful write (also patch and multipatch), ChatCLI runs the language server over the touched files and appends any findings to the tool result as a [DIAGNOSTICS] block — so a broken edit is caught immediately, in the same turn, instead of turns later when a test fails. It is silent on clean files, capped at 5 files / 3000 characters, and disabled with CHATCLI_CODER_AUTODIAG=off. A language server must be available for the file’s language (see LSP Diagnostics).
Applies changes to an existing file. Supports two modes: search/replace (replaces a specific section) and unified diff (applies a patch in diff format).

Flags

You must use either search/replace mode (--search + --replace) or diff mode (--diff). Do not combine both.

Search/Replace Mode

Unified Diff Mode

The base64 mode is strongly recommended for patches, especially when the content contains quotes, backslashes, or multiple lines. This eliminates JSON escaping issues entirely.
Lists the directory structure in tree format. Useful for understanding project organization.

Flags

Examples

Searches for a term across all files in a directory. Returns snippets with surrounding context.

Flags

Examples

Renders a file’s symbol skeleton — its declarations with line numbers — so you understand a file’s shape without reading the whole thing. For Go files the signatures are exact (parsed with Go’s go/ast: functions with their receiver, structs, interfaces, consts, vars); for Python, JS/TS/JSX, Java, Ruby, Rust, Kotlin, C# and PHP a pattern-based outline recognizes the common declaration forms. Read-only.

Flags

Examples

Reach for outline before read when you only need to know what is in a file (which functions, types, methods) and where — it costs a fraction of the tokens of reading the whole file.
Renders a character-budgeted structural map of a whole tree: every source file is outlined, files are ranked by how much structure they carry, and their skeletons are printed until the budget is spent — with an explicit note when files are elided. It ignores .git, node_modules, vendor, dist, build, hidden files and *_test.go. Read-only. Use it to orient yourself in a large codebase without reading whole files.

Flags

Examples

Executes an arbitrary command in the shell. Has built-in security protections against destructive commands.

Flags

Examples

exec automatically blocks commands considered dangerous, including:
  • rm -rf / and destructive variants
  • dd targeting disk devices
  • Fork bombs (e.g., :(){ :|:& };:)
  • Other recognizably destructive patterns
These blocks exist to protect the system. Use responsibly.
Runs project tests automatically, detecting the framework based on the directory contents.

Flags

Examples

Shows the Git repository status (modified, staged, untracked files, etc.).No flags required.

Examples

Shows the diff of modified files in the repository.

Flags

Examples

Displays the repository’s commit history.

Flags

Examples

Lists changed files in the repository (similar to git diff --name-only).

Flags

Examples

Lists the repository’s branches.

Flags

Examples

Restores a file from its .bak backup, automatically created by write or patch.

Flags

Examples

rollback only works if a corresponding .bak file exists. Backups are automatically created by the write and patch commands.
Removes .bak files created by the backup system.No required flags.

Examples

Workspace snapshots into a shadow git repository, a stronger safety net than the per-file .bak rollback — it covers multi-file edits and exec side effects, not just a single file.A checkpoint is taken automatically before every mutating subcommand (write, patch, multipatch, exec). The snapshot lives in a separate GIT_DIR under ~/.chatcli/checkpoints/<hash> with your workspace as its work tree, so your own .git is never touched and your project’s .gitignore is honored.

Flags

Examples

--restore never deletes files added after the snapshot; it only rewinds what the snapshot tracked. It goes through the security gate; --list and --create are read-only.
Auto-snapshots are best-effort (a checkpoint failure never blocks the edit), throttled to at most one per 15 seconds (a burst of writes produces one checkpoint), a no-op when git is not installed, and switched off entirely with CHATCLI_CODER_CHECKPOINTS=off.They are also bounded: workspaces as broad as your home directory (or any directory containing it) are never auto-snapshotted — hashing that much of the disk would freeze every command — and each snapshot runs under a hard deadline (10s automatic, 60s for an explicit checkpoint create, overridable in seconds via CHATCLI_CODER_CHECKPOINT_TIMEOUT). Repeated snapshot failures back off exponentially and, after three in a row, disable automatic snapshots for the rest of the session with a one-line warning.

Transactional multipatch

When a refactor needs to touch multiple files as one unit (rename an identifier propagated across 5 files, update an import in every consumer, etc.), use multipatch instead of chaining patch calls. The contract:
1

Phase 1 — validation (no writes)

For each edit in declaration order, the engine loads the file, simulates the search→replace in memory, and verifies the search text is still present after prior in-flight edits to the same file. A failure on any edit aborts the transaction before any disk write.
2

Phase 2 — commit

Snapshot of each affected file in memory + write the new content. Any write failure restores all touched files from the snapshot.
3

Concurrency

Per-file mutex (keyed by absolute path), acquisition in sorted order — two transactions touching the same pair of files never deadlock. File permissions (chmod) are preserved across the rewrite.
Each edit applies its search→replace exactly once (strings.Replace with n=1). To replace multiple occurrences in the same file, declare multiple edits. Per-edit base64 encoding is supported ("encoding":"base64") for payloads with non-UTF8 bytes.

Backup System

@coder implements an automatic backup system to protect against unwanted changes.
1

Write or Patch

When you execute write or patch, the plugin checks whether the target file already exists.
2

Backup Creation

If the file exists, a copy is saved with the .bak extension (e.g., main.go -> main.go.bak).
3

Change Application

The new content is written (or the patch is applied) to the original file.
4

Rollback Available

At any point, you can use rollback --file main.go to restore the previous version from the .bak file.
5

Cleanup

Use clean to remove all .bak files when you no longer need the backups.
The backup is overwritten on each new write or patch operation on the same file. If you make multiple changes, only the version immediately before the last operation will be available for rollback.

Path Validation and Security

@coder applies several security validations to all file paths:

Workspace Boundary

All paths are resolved relative to the working directory (workspace). Attempts to access files outside the workspace are blocked (e.g., ../../etc/passwd).

Symlink Resolution

Symlinks are resolved before validation. A symlink pointing outside the workspace will be rejected, even if the apparent path is within the allowed directory.

Sensitive Paths

Paths to sensitive system files (e.g., /etc/shadow, /etc/passwd) are blocked by default, preventing read or write operations.

Dangerous Commands

The exec subcommand filters known destructive patterns such as rm -rf /, dd, fork bombs, and others. These commands are rejected before execution.

Complete Usage Example (in /coder)

In /coder mode, the assistant responds with a reasoning block followed by a tool_call. Here is a complete engineering workflow:

JSON Recovery and Robust Parsing

@coder includes a JSON recovery system that automatically fixes malformed arguments generated by LLMs:

7 Recovery Strategies

Single quotes, unquoted keys, trailing commas, plain string wrapping, and more. See JSON Recovery for details.

Escaped Quotes in Shell

Improved handling of escaped quotes in shell commands, avoiding parsing failures when the model generates exec --cmd "echo \"hello\"".

Unicode Quote Normalization

Curly (typographic) quotes are automatically converted to straight quotes in code files, preventing compilation errors.

Concurrent Execution

Tool calls that operate on different files are executed in parallel (file-scoped parallelization), speeding up read and search operations.

Important Notes

@coder grants read/write power over files and command execution, all subject to rollback when requested. Use in trusted repositories.
Being builtin, @coder appears in /plugin list with the [builtin] tag. It cannot be uninstalled via /plugin uninstall.

Plugin @coder FAQ

Yes. The recommended format is JSON. Example:
Use --search/--replace for simple, targeted substitutions at a single location in the file. Use --diff when you need to apply multiple changes at once or when the change involves adding/removing lines in different sections of the file. The diff can be encoded as text or base64.
@coder exec blocks dangerous patterns by default, such as rm -rf /, dd targeting disk devices, and fork bombs. The protection is automatic and requires no configuration.
Yes. The default is --max-bytes 200000 (200KB). You can also use --head or --tail to read only portions of the file. This prevents very large outputs from overwhelming the model’s context window.
The .bak backup is overwritten on each operation. Only the version immediately before the last write will be available for rollback. If you need full history, use git for version management.
Yes. The @coder plugin can be invoked in any mode that supports tool_calls. The /coder mode simply configures the system prompt to guide the model to use @coder as its primary tool.
Place a binary with the same name in the ~/.chatcli/plugins/ directory. It will take precedence over the builtin. To revert to the builtin, remove the custom binary and run /plugin reload.
It is not mandatory, but strongly recommended for write and patch when the content contains special characters, quotes, backslashes, or multiple lines. Base64 completely eliminates JSON escaping issues.

Next steps

Coder Mode

How /coder orchestrates @coder in a full ReAct loop.

Coder Security

Policies, allowlist, and execution governance.

Enhanced Permissions

40+ immune patterns and 90+ read-only allowlist.

JSON Recovery

7 strategies to recover malformed JSON in tool calls.

File Staleness

Track mtime + SHA-256 between read/write to avoid conflicts.

Cookbook: Fix tests

Practical recipe using @coder to autonomously fix tests.