# @remnic/plugin-pi

Remnic memory and context for [Pi Coding Agent](https://pi.dev).

This package is the first-class Remnic extension for Pi. It uses Pi's extension hooks directly, so Remnic can recall context before a model call, observe useful session events after the turn, expose Remnic MCP tools inside Pi, and coordinate Pi compaction with Remnic's long-context memory archive.

> **Oh My Pi (omp).** The [omp](https://omp.sh) fork preserves Pi's extension API, so this package's runtime extension runs there too. Install it with `remnic connectors install omp` (writes to `~/.omp/agent/extensions/remnic/`) via the `OmpMemoryExtensionPublisher`. See [docs/integration/omp.md](../../docs/integration/omp.md).
>
> ⚠️ **omp loader bug:** current omp builds (≥ v16.3.5 confirmed) cannot resolve this package's npm dependencies from the extension's `node_modules`, so the installed extension fails to load every session (`Cannot find module '@sinclair/typebox'`). Pre-bundle it with `bun build` as described in [docs/integration/omp.md → Known issue](../../docs/integration/omp.md#known-issue-omp-cannot-resolve-the-extensions-npm-dependencies).

## What It Does

- Recalls relevant Remnic context in Pi's `context` hook before an agent turn.
- Observes Pi user, assistant, and tool messages with `sourceFormat: "pi"`.
- Flushes Remnic long-context memory before Pi compacts a session.
- Records Pi compaction checkpoints and token deltas back to Remnic.
- Registers Remnic MCP tools as Pi tools when daemon authentication is configured.
- Persists lightweight dedupe state with Pi custom entries so repeated turns are not re-observed.

## Recommended Install

Install through the Remnic CLI. This writes the Pi auto-discovery wrapper, private connector config, and local operator notes into Pi's extension directory.

```bash
npm install -g @remnic/cli
remnic daemon start
remnic connectors install pi
```

The connector installer writes:

- `~/.pi/agent/extensions/remnic/index.ts`
- `~/.pi/agent/extensions/remnic/remnic.config.json`
- `~/.pi/agent/extensions/remnic/README.md`

The generated `remnic.config.json` contains the Remnic daemon URL, namespace, and connector auth token. Remnic writes it with owner-only permissions where the platform supports file modes.

To install the token and connector config without writing the Pi extension files:

```bash
remnic connectors install pi --config installExtension=false
```

## Direct Pi Load

You can also load the npm package directly from Pi after configuring the daemon URL and auth token:

```bash
pi -e npm:@remnic/plugin-pi
```

For direct loading, provide either `REMNIC_PI_CONFIG` or the default config file at `~/.pi/agent/extensions/remnic/remnic.config.json`.

## Configuration

The extension loads configuration in this order:

1. `REMNIC_PI_CONFIG`
2. `~/.pi/agent/extensions/remnic/remnic.config.json`

Supported environment variables:

| Variable | Description |
| --- | --- |
| `REMNIC_PI_CONFIG` | Path to the Remnic Pi JSON config file |
| `REMNIC_DAEMON_URL` | Remnic daemon URL when the config file does not set `remnicDaemonUrl` |
| `REMNIC_PI_AUTH_TOKEN` | Connector token when the config file does not set `authToken` |
| `PI_CODING_AGENT_DIR` | Pi agent home override used to resolve the extension directory |
| `PI_AGENT_HOME` | Alternate Pi agent home override |
| `PI_HOME` | Alternate Pi agent home override |

Supported config keys:

| Key | Default | Description |
| --- | --- | --- |
| `remnicDaemonUrl` | `http://127.0.0.1:4318` | Remnic HTTP/MCP daemon URL |
| `authToken` | unset | Connector token generated by `remnic connectors install pi` |
| `namespace` | unset | Remnic namespace for recall, observe, store, and LCM requests |
| `recallMode` | `auto` | Recall mode: `auto`, `minimal`, `full`, `graph_mode`, or `no_recall` |
| `recallTopK` | `8` | Maximum recalled results |
| `recallBudgetChars` | `12000` | Maximum recalled context injected into Pi |
| `recallEnabled` | `true` | Enable context-hook recall |
| `observeEnabled` | `true` | Enable Pi turn observation |
| `observeSkipExtraction` | `false` | Archive observed messages without extraction |
| `compactionEnabled` | `true` | Enable LCM flush and checkpoint coordination |
| `mcpToolsEnabled` | `true` | Register Remnic MCP tools as Pi tools |
| `statusEnabled` | `true` | Set Pi UI status from daemon health |
| `requestTimeoutMs` | `60000` | HTTP/MCP request timeout for recall/observe/compaction/commands |
| `startupRequestTimeoutMs` | `1000` | Shorter timeout for startup-sensitive probes (MCP `tools/list` registration and the `session_start` health/status check) so a slow or offline daemon can't stall Pi boot |

Boolean-like strings such as `"false"`, `"0"`, `"no"`, and `"off"` are treated as false.

> **Remote daemons: raise `startupRequestTimeoutMs`.** MCP tool registration happens once at session start (`tools/list` against the daemon) under this timeout, and a timeout is swallowed silently — the session simply runs without any `remnic_*` tools, while the separate (lighter) health probe can still report the daemon as ready. The `1000` default is tuned for a localhost daemon; when `remnicDaemonUrl` points at another machine (Tailscale/MagicDNS, VPN, LAN), one cold DNS resolution or relayed round trip can exceed it. Set `"startupRequestTimeoutMs": 10000` for remote daemons, and prefer a stable Tailscale IP over a MagicDNS name on hosts where MagicDNS is not enabled.

Example:

```json
{
  "remnicDaemonUrl": "http://127.0.0.1:4318",
  "namespace": "work",
  "recallMode": "auto",
  "recallTopK": 8,
  "recallBudgetChars": 12000,
  "recallEnabled": true,
  "observeEnabled": true,
  "compactionEnabled": true,
  "mcpToolsEnabled": true,
  "statusEnabled": true,
  "requestTimeoutMs": 60000,
  "startupRequestTimeoutMs": 1000
}
```

## Pi Commands

The extension registers these Pi slash commands:

| Command | Description |
| --- | --- |
| `/remnic-status` | Check Remnic daemon health |
| `/remnic-recall <query>` | Recall Remnic context for a query |
| `/remnic-remember <memory>` | Explicitly store a memory |
| `/remnic-lcm-search <query>` | Search archived Pi context |
| `/remnic-why` | Inspect the last recall explanation |
| `/remnic-compact` | Request Pi compaction with Remnic LCM coordination |

## Security And Boundaries

- Remnic routes Pi traffic with the active Pi session key, working directory, and configured namespace.
- MCP tool calls strip caller-provided `sessionKey`, `namespace`, and `cwd` before the extension injects trusted values from the Pi runtime.
- The connector config stores the daemon token locally and is written with `0600` permissions by the Remnic installer.
- Invalid config values fail closed instead of silently falling back to unsafe defaults.
- The default daemon URL is local: `http://127.0.0.1:4318`.

## Troubleshooting

If Pi cannot reach Remnic, start the daemon and check the configured URL:

```bash
remnic daemon start
remnic status
```

If commands return `401` or MCP tools do not appear, reinstall the connector so the Pi config receives a fresh token:

```bash
remnic token generate pi
remnic connectors install pi --force
```

If Pi uses a non-default home directory, set one of the supported Pi home variables before installing:

```bash
PI_CODING_AGENT_DIR=/path/to/pi/agent remnic connectors install pi
```

## Development

From the Remnic monorepo:

```bash
pnpm install
pnpm --filter @remnic/plugin-pi test
pnpm --filter @remnic/plugin-pi build
```

The package exports:

- `@remnic/plugin-pi` - Pi extension entrypoint and `createRemnicPiExtension`
- `@remnic/plugin-pi/publisher` - Remnic connector publisher used by `remnic connectors install pi`

## More

- Full integration guide: https://github.com/joshuaswarren/remnic/blob/main/docs/integration/pi.md
- Remnic: https://github.com/joshuaswarren/remnic
- Pi Coding Agent: https://pi.dev
