<!-- SPDX-License-Identifier: Apache-2.0 -->

# Plugins

`config/plugins.toml` declares plugins that extend agents with additional tools.

Each plugin is a JavaScript package that runs in-process in a constrained JavaScript engine inside the runtime process.

Plugins are trusted host extensions, not sandboxed agent actions.
The runtime protects the operator from the agent; it does not protect the operator from plugin code they install.

Only install plugins you trust, and give them only the configuration and network access they need.

## Declaring plugins

Every plugin must be listed in `config/plugins.toml`; there is no auto-discovery.

```toml
[[plugins]]
package = "@cireilclaw/plugin-brave-search"

[[plugins]]
name = "local-plugin"
allowOverride = true
stateQuotaBytes = 16777216
```

Each entry sets exactly one of:

- `package` — a package resolved from `<root>/node_modules/<package>`.
- `name` — a local directory resolved from `<root>/plugins/<name>`.

### Entry flags

| Field | Default | Description |
| --- | --- | --- |
| `allowOverride` | `false` | Permit this plugin's tools to shadow built-in tools. |
| `stateQuotaBytes` | `16777216` | Per-agent plugin state quota in bytes. |

A tool name collision against a built-in fails loudly at startup unless the plugin sets `allowOverride`.
Two plugins with the same tool name always fail regardless.

Treat overrides as security-sensitive: replacing a built-in tool changes part of the boundary the runtime presents to the agent.

## Installing packages

Install npm packages into the runtime root so the runtime can resolve them.

```bash
npm install --prefix ~/.cireilclaw @cireilclaw/plugin-brave-search
```

Local plugins are directories under `plugins/`; the plugin's entry module must be compiled JavaScript.

Local plugins with no external imports do not need a `node_modules` directory.
If a local plugin imports another package, place that dependency in the plugin's `node_modules` directory or in the runtime root's `node_modules` directory.

Package resolution checks the `exports` map first, then `main`, then `dist/index.mjs`, `dist/index.js`, `index.mjs`, and `index.js`.

## Plugin configuration

Plugins read their own configuration through their SDK context.

By convention these live at:

- `<root>/config/plugins/<name>.toml` — global.
- `<root>/agents/<slug>/config/plugins/<name>.toml` — per-agent override.

The `<name>` value must be a single file name without path separators or `.`/`..` path segments.
The runtime rejects names that would escape the plugin configuration directory.
The plugin decides which valid `<name>` it reads and which keys it expects; consult the plugin's documentation.

Per-plugin configuration files are re-read on access; edits take effect on the next tool invocation that reads them.

## Enabling plugin tools

Plugin tools are enabled per agent in `tools.toml` just like built-in tools.

```toml
example-search = true
```

## Plugin state

Plugins keep private, persistent state per agent under `agents/<slug>/state/<plugin-slug>/`.
State survives restarts and is not visible to the agent sandbox.

## Restart requirements

Changes to `plugins.toml` or plugin code require a full runtime restart; they are not hot-reloaded.
