> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Plugin @coder

> Builtin engineering tool for reading, editing, patching, and executing tasks with rollback.

`@coder` is the engineering suite used by [Coder Mode (/coder)](/core-concepts/coder-mode). It provides actions for reading/searching files, safely applying patches, running commands, and reverting changes.

<Info>
  `@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`.
</Info>

***

## Quick Reference

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

| Subcommand    | Description                                                                                             | Key Flags                                                        |
| ------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `read`        | Read file contents                                                                                      | `--file` (req.), `--start`, `--end`, `--head`, `--tail`          |
| `write`       | Write file with backup                                                                                  | `--file` (req.), `--content` (req.), `--append`, `--encoding`    |
| `patch`       | Apply search/replace or unified diff                                                                    | `--file`, `--search`, `--replace`, `--diff`, `--encoding`        |
| `multipatch`  | **Atomic transaction** of multiple search/replace edits across multiple files. All-or-nothing rollback. | `--edits` (req., JSON array)                                     |
| `tree`        | Directory structure                                                                                     | `--dir`, `--glob`, `--max-entries`                               |
| `search`      | Full-text search in files                                                                               | `--term` (req.), `--dir`, `--glob`, `--max-results`, `--context` |
| `exec`        | Execute shell commands                                                                                  | `--cmd` (req.), `--command`                                      |
| `test`        | Run tests                                                                                               | `--dir`, `--pattern`, `--timeout`                                |
| `git-status`  | Repository status                                                                                       | *(no flags)*                                                     |
| `git-diff`    | Pending differences                                                                                     | `--file`, `--staged`                                             |
| `git-log`     | Commit history                                                                                          | `--oneline`, `--limit`                                           |
| `git-changed` | Changed files                                                                                           | `--staged`                                                       |
| `git-branch`  | List branches                                                                                           | `--all`                                                          |
| `rollback`    | Restore file from `.bak` backup                                                                         | `--file` (req.)                                                  |
| `clean`       | Remove `.bak` files                                                                                     | *(no required flags)*                                            |

***

## Argument Formats

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

<Tabs>
  <Tab title="JSON Format (recommended)">
    The JSON format is used inside the `args` attribute of a `<tool_call>`. The structure is:

    ```json theme={"system"}
    {
      "cmd": "<subcommand>",
      "args": {
        "<flag>": "<value>",
        ...
      }
    }
    ```

    Full example:

    ```xml theme={"system"}
    <tool_call name="@coder" args='{"cmd":"read","args":{"file":"main.go","start":10,"end":50}}'/>
    ```

    <Tip>
      The JSON format is recommended because it avoids escaping issues and is what language models generate most consistently.
    </Tip>
  </Tab>

  <Tab title="CLI-style Format">
    You can also pass arguments in command-line style, separated by spaces:

    ```
    read --file main.go --start 10 --end 50
    ```

    Here, the `cmd` field is the first word and flags follow in `--flag value` format.

    Example in tool\_call:

    ```xml theme={"system"}
    <tool_call name="@coder" args='{"cmd":"read --file main.go --start 10 --end 50"}'/>
    ```

    <Note>
      In CLI-style format, values with spaces must be quoted: `--content "hello world"`.
    </Note>
  </Tab>
</Tabs>

***

## Subcommands -- Complete Reference

<AccordionGroup>
  <Accordion title="read -- Read Files" icon="file-lines">
    Reads the contents of a file from disk. Supports partial reading by line range and byte limits.

    ### Flags

    | Flag          | Type   | Required | Default | Description                         |
    | ------------- | ------ | -------- | ------- | ----------------------------------- |
    | `--file`      | string | **Yes**  | --      | Path of the file to read            |
    | `--start`     | int    | No       | --      | Start line (1-based)                |
    | `--end`       | int    | No       | --      | End line (1-based)                  |
    | `--head`      | int    | No       | --      | First N lines                       |
    | `--tail`      | int    | No       | --      | Last N lines                        |
    | `--max-bytes` | int    | No       | 200000  | Maximum byte limit for output       |
    | `--encoding`  | string | No       | `text`  | Output encoding: `text` or `base64` |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- Read entire file -->
        <tool_call name="@coder" args='{"cmd":"read","args":{"file":"README.md"}}'/>

        <!-- Read lines 10 to 50 -->
        <tool_call name="@coder" args='{"cmd":"read","args":{"file":"main.go","start":10,"end":50}}'/>

        <!-- First 20 lines -->
        <tool_call name="@coder" args='{"cmd":"read","args":{"file":"config.yaml","head":20}}'/>

        <!-- Last 30 lines -->
        <tool_call name="@coder" args='{"cmd":"read","args":{"file":"app.log","tail":30}}'/>

        <!-- Output in base64 (useful for binaries) -->
        <tool_call name="@coder" args='{"cmd":"read","args":{"file":"image.png","encoding":"base64","max-bytes":500000}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        read --file README.md
        read --file main.go --start 10 --end 50
        read --file config.yaml --head 20
        read --file app.log --tail 30
        read --file image.png --encoding base64 --max-bytes 500000
        ```
      </Tab>
    </Tabs>

    <Tip>
      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.
    </Tip>
  </Accordion>

  <Accordion title="write -- Write Files" icon="pen">
    Writes content to a file. Automatically creates a `.bak` backup of the existing file before overwriting.

    ### Flags

    | Flag         | Type   | Required | Default | Description                                           |
    | ------------ | ------ | -------- | ------- | ----------------------------------------------------- |
    | `--file`     | string | **Yes**  | --      | Path of the file to write                             |
    | `--content`  | string | **Yes**  | --      | Content to write                                      |
    | `--encoding` | string | No       | `text`  | Content encoding: `text` or `base64`                  |
    | `--append`   | bool   | No       | `false` | If `true`, appends to the file instead of overwriting |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- Write new file (text) -->
        <tool_call name="@coder" args='{"cmd":"write","args":{"file":"hello.txt","content":"Hello, World!"}}'/>

        <!-- Write with base64-encoded content -->
        <tool_call name="@coder" args='{"cmd":"write","args":{"file":"data.bin","content":"SGVsbG8gV29ybGQ=","encoding":"base64"}}'/>

        <!-- Append to an existing file -->
        <tool_call name="@coder" args='{"cmd":"write","args":{"file":"notes.txt","content":"\nNew line appended","append":true}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        write --file hello.txt --content "Hello, World!"
        write --file data.bin --content "SGVsbG8gV29ybGQ=" --encoding base64
        write --file notes.txt --content "New line" --append
        ```
      </Tab>
    </Tabs>

    <Warning>
      Use `--encoding base64` for content containing special characters, complex line breaks, or binary data. This avoids escaping issues in JSON.
    </Warning>
  </Accordion>

  <Accordion title="patch -- Apply Patches" icon="code-compare">
    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

    | Flag              | Type   | Required    | Default | Description                                                                                |
    | ----------------- | ------ | ----------- | ------- | ------------------------------------------------------------------------------------------ |
    | `--file`          | string | Conditional | --      | File to patch. Required for search/replace; optional for diff (the diff may contain paths) |
    | `--search`        | string | Conditional | --      | Text to find (search/replace mode)                                                         |
    | `--replace`       | string | Conditional | --      | Replacement text (search/replace mode)                                                     |
    | `--diff`          | string | Conditional | --      | Unified diff content (diff mode)                                                           |
    | `--encoding`      | string | No          | `text`  | Encoding for `--search` and `--replace`: `text` or `base64`                                |
    | `--diff-encoding` | string | No          | `text`  | Encoding for `--diff`: `text` or `base64`                                                  |

    <Note>
      You must use **either** search/replace mode (`--search` + `--replace`) **or** diff mode (`--diff`). Do not combine both.
    </Note>

    ### Search/Replace Mode

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- Replace text (plain text) -->
        <tool_call name="@coder" args='{"cmd":"patch","args":{"file":"main.go","search":"fmt.Println(\"old\")","replace":"fmt.Println(\"new\")"}}'/>

        <!-- Replace text (base64 to avoid escaping) -->
        <tool_call name="@coder" args='{"cmd":"patch","args":{"file":"main.go","search":"Zm10LlByaW50bG4oIm9sZCIp","replace":"Zm10LlByaW50bG4oIm5ldyIp","encoding":"base64"}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        patch --file main.go --search "fmt.Println(\"old\")" --replace "fmt.Println(\"new\")"
        patch --file main.go --search "base64str" --replace "base64str" --encoding base64
        ```
      </Tab>
    </Tabs>

    ### Unified Diff Mode

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- Apply diff as text -->
        <tool_call name="@coder" args='{"cmd":"patch","args":{"diff":"--- a/main.go\n+++ b/main.go\n@@ -5,3 +5,3 @@\n-old line\n+new line"}}'/>

        <!-- Apply diff as base64 -->
        <tool_call name="@coder" args='{"cmd":"patch","args":{"diff":"LS0tIGEvbWFpbi5nbw...","diff-encoding":"base64"}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        patch --diff "--- a/main.go\n+++ b/main.go\n@@ -5,3 +5,3 @@\n-old\n+new"
        patch --diff "base64content" --diff-encoding base64
        ```
      </Tab>
    </Tabs>

    <Tip>
      The **base64** mode is strongly recommended for patches, especially when the content contains quotes, backslashes, or multiple lines. This eliminates JSON escaping issues entirely.
    </Tip>
  </Accordion>

  <Accordion title="tree -- Directory Structure" icon="folder-tree">
    Lists the directory structure in tree format. Useful for understanding project organization.

    ### Flags

    | Flag            | Type   | Required | Default | Description                                   |
    | --------------- | ------ | -------- | ------- | --------------------------------------------- |
    | `--dir`         | string | No       | `"."`   | Root directory to list                        |
    | `--glob`        | string | No       | --      | Glob pattern to filter files (e.g., `"*.go"`) |
    | `--max-entries` | int    | No       | 2000    | Maximum number of entries returned            |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- List current directory -->
        <tool_call name="@coder" args='{"cmd":"tree","args":{"dir":"."}}'/>

        <!-- List only Go files -->
        <tool_call name="@coder" args='{"cmd":"tree","args":{"dir":".","glob":"*.go"}}'/>

        <!-- List subdirectory with limit -->
        <tool_call name="@coder" args='{"cmd":"tree","args":{"dir":"./internal","max-entries":500}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        tree --dir .
        tree --dir . --glob "*.go"
        tree --dir ./internal --max-entries 500
        ```
      </Tab>
    </Tabs>
  </Accordion>

  <Accordion title="search -- Full-Text Search" icon="magnifying-glass">
    Searches for a term across all files in a directory. Returns snippets with surrounding context.

    ### Flags

    | Flag            | Type   | Required | Default | Description                                             |
    | --------------- | ------ | -------- | ------- | ------------------------------------------------------- |
    | `--term`        | string | **Yes**  | --      | Search term                                             |
    | `--dir`         | string | No       | `"."`   | Directory to search in                                  |
    | `--glob`        | string | No       | --      | Glob pattern to filter files (e.g., `"*.go"`, `"*.ts"`) |
    | `--max-results` | int    | No       | 100     | Maximum number of results                               |
    | `--context`     | int    | No       | 2       | Context lines before and after each match               |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- Simple search -->
        <tool_call name="@coder" args='{"cmd":"search","args":{"term":"TODO","dir":"."}}'/>

        <!-- Search in Go files with more context -->
        <tool_call name="@coder" args='{"cmd":"search","args":{"term":"func main","dir":".","glob":"*.go","context":5}}'/>

        <!-- Search with result limit -->
        <tool_call name="@coder" args='{"cmd":"search","args":{"term":"error","dir":"./pkg","max-results":20}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        search --term "TODO" --dir .
        search --term "func main" --dir . --glob "*.go" --context 5
        search --term "error" --dir ./pkg --max-results 20
        ```
      </Tab>
    </Tabs>
  </Accordion>

  <Accordion title="exec -- Execute Commands" icon="terminal">
    Executes an arbitrary command in the shell. Has built-in security protections against destructive commands.

    ### Flags

    | Flag        | Type   | Required | Default | Description        |
    | ----------- | ------ | -------- | ------- | ------------------ |
    | `--cmd`     | string | **Yes**  | --      | Command to execute |
    | `--command` | string | No       | --      | Alias for `--cmd`  |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- Execute a simple command -->
        <tool_call name="@coder" args='{"cmd":"exec","args":{"cmd":"go build ./..."}}'/>

        <!-- List processes -->
        <tool_call name="@coder" args='{"cmd":"exec","args":{"cmd":"ps aux | grep myapp"}}'/>

        <!-- Using the --command alias -->
        <tool_call name="@coder" args='{"cmd":"exec","args":{"command":"ls -la"}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        exec --cmd "go build ./..."
        exec --cmd "ps aux | grep myapp"
        exec --command "ls -la"
        ```
      </Tab>
    </Tabs>

    <Warning>
      `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.
    </Warning>
  </Accordion>

  <Accordion title="test -- Run Tests" icon="vial">
    Runs project tests automatically, detecting the framework based on the directory contents.

    ### Flags

    | Flag        | Type   | Required | Default | Description                             |
    | ----------- | ------ | -------- | ------- | --------------------------------------- |
    | `--dir`     | string | No       | `"."`   | Directory where to run tests            |
    | `--pattern` | string | No       | --      | Test file pattern (e.g., `"*_test.go"`) |
    | `--timeout` | int    | No       | 30      | Timeout in seconds                      |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- Run all tests -->
        <tool_call name="@coder" args='{"cmd":"test","args":{"dir":"."}}'/>

        <!-- Run tests with specific pattern -->
        <tool_call name="@coder" args='{"cmd":"test","args":{"dir":"./pkg","pattern":"*_test.go","timeout":60}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        test --dir .
        test --dir ./pkg --pattern "*_test.go" --timeout 60
        ```
      </Tab>
    </Tabs>
  </Accordion>

  <Accordion title="git-status -- Repository Status" icon="code-branch">
    Shows the Git repository status (modified, staged, untracked files, etc.).

    **No flags required.**

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <tool_call name="@coder" args='{"cmd":"git-status","args":{}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        git-status
        ```
      </Tab>
    </Tabs>
  </Accordion>

  <Accordion title="git-diff -- Pending Differences" icon="code-compare">
    Shows the diff of modified files in the repository.

    ### Flags

    | Flag       | Type   | Required | Default | Description                                 |
    | ---------- | ------ | -------- | ------- | ------------------------------------------- |
    | `--file`   | string | No       | --      | Filter diff to a specific file              |
    | `--staged` | bool   | No       | `false` | Show only staged changes (ready for commit) |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- Full diff -->
        <tool_call name="@coder" args='{"cmd":"git-diff","args":{}}'/>

        <!-- Diff for a specific file -->
        <tool_call name="@coder" args='{"cmd":"git-diff","args":{"file":"main.go"}}'/>

        <!-- Staged diff -->
        <tool_call name="@coder" args='{"cmd":"git-diff","args":{"staged":true}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        git-diff
        git-diff --file main.go
        git-diff --staged
        ```
      </Tab>
    </Tabs>
  </Accordion>

  <Accordion title="git-log -- Commit History" icon="clock-rotate-left">
    Displays the repository's commit history.

    ### Flags

    | Flag        | Type | Required | Default | Description                          |
    | ----------- | ---- | -------- | ------- | ------------------------------------ |
    | `--oneline` | bool | No       | `false` | Compact format (one line per commit) |
    | `--limit`   | int  | No       | 10      | Maximum number of commits shown      |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- Last 10 commits -->
        <tool_call name="@coder" args='{"cmd":"git-log","args":{}}'/>

        <!-- Last 5 commits in compact format -->
        <tool_call name="@coder" args='{"cmd":"git-log","args":{"oneline":true,"limit":5}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        git-log
        git-log --oneline --limit 5
        ```
      </Tab>
    </Tabs>
  </Accordion>

  <Accordion title="git-changed -- Changed Files" icon="file-pen">
    Lists changed files in the repository (similar to `git diff --name-only`).

    ### Flags

    | Flag       | Type | Required | Default | Description            |
    | ---------- | ---- | -------- | ------- | ---------------------- |
    | `--staged` | bool | No       | `false` | List only staged files |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- All changed files -->
        <tool_call name="@coder" args='{"cmd":"git-changed","args":{}}'/>

        <!-- Only staged files -->
        <tool_call name="@coder" args='{"cmd":"git-changed","args":{"staged":true}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        git-changed
        git-changed --staged
        ```
      </Tab>
    </Tabs>
  </Accordion>

  <Accordion title="git-branch -- Branch Listing" icon="code-branch">
    Lists the repository's branches.

    ### Flags

    | Flag    | Type | Required | Default | Description             |
    | ------- | ---- | -------- | ------- | ----------------------- |
    | `--all` | bool | No       | `false` | Include remote branches |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <!-- Local branches -->
        <tool_call name="@coder" args='{"cmd":"git-branch","args":{}}'/>

        <!-- All branches (local + remote) -->
        <tool_call name="@coder" args='{"cmd":"git-branch","args":{"all":true}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        git-branch
        git-branch --all
        ```
      </Tab>
    </Tabs>
  </Accordion>

  <Accordion title="rollback -- Revert Changes" icon="rotate-left">
    Restores a file from its `.bak` backup, automatically created by `write` or `patch`.

    ### Flags

    | Flag     | Type   | Required | Default | Description                 |
    | -------- | ------ | -------- | ------- | --------------------------- |
    | `--file` | string | **Yes**  | --      | Path of the file to restore |

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <tool_call name="@coder" args='{"cmd":"rollback","args":{"file":"main.go"}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        rollback --file main.go
        ```
      </Tab>
    </Tabs>

    <Note>
      `rollback` only works if a corresponding `.bak` file exists. Backups are automatically created by the `write` and `patch` commands.
    </Note>
  </Accordion>

  <Accordion title="clean -- Remove Backups" icon="broom">
    Removes `.bak` files created by the backup system.

    **No required flags.**

    ### Examples

    <Tabs>
      <Tab title="JSON">
        ```xml theme={"system"}
        <tool_call name="@coder" args='{"cmd":"clean","args":{}}'/>
        ```
      </Tab>

      <Tab title="CLI-style">
        ```
        clean
        ```
      </Tab>
    </Tabs>
  </Accordion>
</AccordionGroup>

***

## 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:

<Steps>
  <Step title="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**.
  </Step>

  <Step title="Phase 2 — commit">
    Snapshot of each affected file in memory + write the new content. Any write failure restores all touched files from the snapshot.
  </Step>

  <Step title="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.
  </Step>
</Steps>

```json theme={"system"}
{
  "cmd": "multipatch",
  "args": {
    "edits": [
      {"file": "internal/auth/login.go", "search": "loginV1", "replace": "loginV2"},
      {"file": "internal/auth/login_test.go", "search": "loginV1", "replace": "loginV2"},
      {"file": "cmd/server/main.go", "search": "auth.loginV1", "replace": "auth.loginV2"}
    ]
  }
}
```

<Note>
  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.
</Note>

***

## Backup System

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

<Steps>
  <Step title="Write or Patch">
    When you execute `write` or `patch`, the plugin checks whether the target file already exists.
  </Step>

  <Step title="Backup Creation">
    If the file exists, a copy is saved with the `.bak` extension (e.g., `main.go` -> `main.go.bak`).
  </Step>

  <Step title="Change Application">
    The new content is written (or the patch is applied) to the original file.
  </Step>

  <Step title="Rollback Available">
    At any point, you can use `rollback --file main.go` to restore the previous version from the `.bak` file.
  </Step>

  <Step title="Cleanup">
    Use `clean` to remove all `.bak` files when you no longer need the backups.
  </Step>
</Steps>

<Tip>
  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.
</Tip>

***

## Path Validation and Security

`@coder` applies several security validations to all file paths:

<CardGroup cols={2}>
  <Card title="Workspace Boundary" icon="shield">
    All paths are resolved relative to the working directory (workspace). Attempts to access files outside the workspace are blocked (e.g., `../../etc/passwd`).
  </Card>

  <Card title="Symlink Resolution" icon="link">
    Symlinks are resolved before validation. A symlink pointing outside the workspace will be rejected, even if the apparent path is within the allowed directory.
  </Card>

  <Card title="Sensitive Paths" icon="lock">
    Paths to sensitive system files (e.g., `/etc/shadow`, `/etc/passwd`) are blocked by default, preventing read or write operations.
  </Card>

  <Card title="Dangerous Commands" icon="triangle-exclamation">
    The `exec` subcommand filters known destructive patterns such as `rm -rf /`, `dd`, fork bombs, and others. These commands are rejected before execution.
  </Card>
</CardGroup>

***

## 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:

```xml theme={"system"}
<!-- 1. Understand the project structure -->
<tool_call name="@coder" args='{"cmd":"tree","args":{"dir":".","glob":"*.go"}}'/>

<!-- 2. Search where a function is defined -->
<tool_call name="@coder" args='{"cmd":"search","args":{"term":"func HandleRequest","dir":".","glob":"*.go"}}'/>

<!-- 3. Read the relevant file -->
<tool_call name="@coder" args='{"cmd":"read","args":{"file":"handler.go","start":15,"end":45}}'/>

<!-- 4. Apply a fix -->
<tool_call name="@coder" args='{"cmd":"patch","args":{"file":"handler.go","search":"return nil","replace":"return fmt.Errorf(\"missing parameter: %s\", name)"}}'/>

<!-- 5. Run the tests -->
<tool_call name="@coder" args='{"cmd":"test","args":{"dir":".","timeout":60}}'/>

<!-- 6. Check what changed -->
<tool_call name="@coder" args='{"cmd":"git-diff","args":{}}'/>

<!-- 7. If something went wrong, revert -->
<tool_call name="@coder" args='{"cmd":"rollback","args":{"file":"handler.go"}}'/>
```

***

## JSON Recovery and Robust Parsing

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

<CardGroup cols={2}>
  <Card title="7 Recovery Strategies" icon="screwdriver-wrench">
    Single quotes, unquoted keys, trailing commas, plain string wrapping, and more. See [JSON Recovery](/features/json-recovery) for details.
  </Card>

  <Card title="Escaped Quotes in Shell" icon="terminal">
    Improved handling of escaped quotes in shell commands, avoiding parsing failures when the model generates `exec --cmd "echo \"hello\""`.
  </Card>

  <Card title="Unicode Quote Normalization" icon="font">
    Curly (typographic) quotes are automatically converted to straight quotes in code files, preventing compilation errors.
  </Card>

  <Card title="Concurrent Execution" icon="arrows-split-up-and-left">
    Tool calls that operate on different files are executed in parallel (file-scoped parallelization), speeding up read and search operations.
  </Card>
</CardGroup>

***

## Important Notes

<Warning>
  `@coder` grants read/write power over files and command execution, all subject to rollback when requested. Use in trusted repositories.
</Warning>

<Note>
  Being builtin, `@coder` appears in `/plugin list` with the `[builtin]` tag. It cannot be uninstalled via `/plugin uninstall`.
</Note>

***

## Plugin @coder FAQ

<AccordionGroup>
  <Accordion title="Does @coder accept JSON in args?">
    Yes. The recommended format is JSON. Example:

    ```xml theme={"system"}
    <tool_call name="@coder" args='{"cmd":"read","args":{"file":"README.md"}}'/>
    ```
  </Accordion>

  <Accordion title="When to use patch --diff vs --search/--replace?">
    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`.
  </Accordion>

  <Accordion title="Is exec dangerous?">
    `@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.
  </Accordion>

  <Accordion title="Is there a read limit?">
    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.
  </Accordion>

  <Accordion title="What happens if I write to the same file twice?">
    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.
  </Accordion>

  <Accordion title="Can I use @coder outside of /coder mode?">
    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.
  </Accordion>

  <Accordion title="How do I replace the builtin @coder with a custom version?">
    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`.
  </Accordion>

  <Accordion title="Is --encoding base64 necessary?">
    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.
  </Accordion>
</AccordionGroup>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Coder Mode" icon="code" href="/core-concepts/coder-mode">
    How `/coder` orchestrates `@coder` in a full ReAct loop.
  </Card>

  <Card title="Coder Security" icon="shield-halved" href="/features/coder-security">
    Policies, allowlist, and execution governance.
  </Card>

  <Card title="Enhanced Permissions" icon="shield-alert" href="/features/enhanced-permissions">
    40+ immune patterns and 90+ read-only allowlist.
  </Card>

  <Card title="JSON Recovery" icon="wrench" href="/features/json-recovery">
    7 strategies to recover malformed JSON in tool calls.
  </Card>

  <Card title="File Staleness" icon="clock-rotate-left" href="/features/file-staleness">
    Track mtime + SHA-256 between read/write to avoid conflicts.
  </Card>

  <Card title="Cookbook: Fix tests" icon="vial" href="/cookbook/coder-fix-tests">
    Practical recipe using `@coder` to autonomously fix tests.
  </Card>
</CardGroup>
