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

# Pi

> Asymptote support details for Pi endpoint telemetry

## Runtime overview

Asymptote supports [Pi](https://pi.dev/) through a managed local extension.

Pi fits neither of Asymptote's two usual integration shapes. It has no hooks configuration file to merge a managed hook block into, and no OpenTelemetry support to point at the local collector. Its documented observation surface is the TypeScript extension API, so the integration is extension-shaped: one Asymptote-owned extension file forwards runtime events to `beacon-hooks`, the same shape as the OpenCode and Cline plugins.

```bash theme={null}
beacon endpoint hooks install --harness pi
```

## Prerequisites

Before enabling Pi telemetry, make sure:

* Pi is installed and available as the `pi` executable, or has a local state directory at `~/.pi/agent`.
* `beacon endpoint install` has run so shared endpoint config and runtime log paths exist.
* Pi is restarted after install or removal so new sessions load the updated extension.

## Collection path

Asymptote's managed Pi extension is a single TypeScript file at one of two documented extension locations:

| Level   | Extension path                     |
| ------- | ---------------------------------- |
| User    | `~/.pi/agent/extensions/beacon.ts` |
| Project | `./.pi/extensions/beacon.ts`       |

User level is the default. A project-level extension is subject to Pi's project-trust prompt, and `beacon endpoint discover` reports on the user path only, so a project-level extension does not appear in discovery output.

Asymptote identifies its own extension file by the marker `beacon-managed-pi-extension:v1`. The version suffix is part of the contract with the extension source: it is what lets a repair recognize a stale file instead of leaving it in place. A `beacon.ts` without the marker belongs to somebody else, so install will not overwrite it and discovery does not report it as Asymptote telemetry.

Pi has no OpenTelemetry export for Asymptote to configure, so there is no OTLP path for this runtime.

## Discovery and status

Asymptote detects Pi through the `pi` executable, and treats the `~/.pi/agent` state directory as an additional signal. Pi installed through npm, pnpm, or bun is often missing from the `PATH` the endpoint process inherited, because a shell alias, a version manager, or a per-project install can all hide it while the state directory is still present. The OpenCode, Cursor, and Hermes probes use the same fallback.

```bash title="Show Pi discovery state" theme={null}
beacon endpoint discover --all --json
```

Pi reports as the `pi_cli` harness with capability `plugin`:

| Telemetry status | Meaning                                                                                                       |
| ---------------- | ------------------------------------------------------------------------------------------------------------- |
| `missing`        | No extension file at the user-level managed path                                                              |
| `disabled`       | A `beacon.ts` exists but carries no Asymptote marker, so it is somebody else's extension sharing the filename |
| `enabled`        | Asymptote's managed extension is in place                                                                     |

An unmarked extension file reports `disabled` rather than `enabled`, because reporting it as enabled would show the runtime as covered while no events arrive.

## Install or configuration support

`beacon endpoint install` prepares shared endpoint config and runtime log paths. The extension is installed separately, because Pi loads it from the user's own profile rather than from a machine-wide location:

```bash theme={null}
beacon endpoint hooks install --harness pi            # user level (default)
beacon endpoint hooks install --harness pi --level project
beacon endpoint hooks status --harness pi
beacon endpoint hooks uninstall --harness pi
```

Install writes one file and refuses to touch a `beacon.ts` it did not write, so an extension of your own that happens to share the filename is left alone and the install fails loudly rather than replacing it.

`status` reports `installed=false` when the extension exists but points at a hook binary that is no longer there, which happens after a Beacon uninstall, a partly applied update, or a home directory restored onto a different machine. In each case Pi loads an extension that spawns nothing.

## Telemetry coverage

| Area                                             | Support                                                                                                                                         |
| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Runtime discovery                                | Supported through executable and `~/.pi/agent` detection, managed extension path, and telemetry status                                          |
| Harness attribution                              | Supported. `pi`, `pi.dev`, `pi_cli`, `pi-cli`, `pi_agent`, `pi-agent`, and `pi agent` all normalize to `pi_cli`                                 |
| Extension install, status, uninstall, and repair | Supported                                                                                                                                       |
| Session lifecycle                                | Supported. `session.started` and `session.ended`, carrying why the session started or stopped                                                   |
| Prompts                                          | Supported. `prompt.submitted`, with whether the input was typed, delivered over RPC, or injected by another extension                           |
| Tool use                                         | Supported. `tool.invoked` before execution, then `tool.completed` or `tool.failed`                                                              |
| Commands                                         | Supported. `command.executed` for the agent's `bash` tool and for commands you run with Pi's `!` prefix, which are marked as operator-initiated |
| File activity                                    | Supported. `file.read`, `file.created`, and `file.modified`, with the unified patch on an edit                                                  |
| Agent reasoning                                  | Supported. `agent.reasoning` from an assistant message's thinking parts, in the OTel GenAI reasoning-part shape                                 |
| Token usage and cost                             | Supported. `token.usage` normalized into `gen_ai.usage`, including cache and reasoning tokens and runtime-reported cost                         |
| Approval decisions                               | Not available. Pi exposes no operator approval decision to observe. See [Known gaps](#known-gaps)                                               |
| Local JSONL and dashboard                        | Supported                                                                                                                                       |
| MDM deployment                                   | Supported for the endpoint agent. The Pi extension installs separately in the logged-in user's context                                          |

Harness names are matched against a closed set of spellings rather than by substring, because `pi` is two characters and appears inside names belonging to other runtimes. `copilot` contains it, so a substring rule would attribute every GitHub Copilot and VS Code Copilot session to Pi.

## Data handling

Pi content is handled like every other runtime. Prompts, tool arguments, commands, paths, diffs, and reasoning text are retained in local or customer-controlled logs, with local secret redaction and per-string limits applied before writing, and a hash and byte count on each content-bearing event. Events over the 64 KiB limit drop raw and retained content, preserve stable metadata, and set `field_truncated`.

The extension itself sends nothing over the network. It spawns the local `beacon-hooks` binary with a fixed argv and writes the event to its stdin. A send that has not completed in two seconds is abandoned so Beacon cannot stall Pi's agent loop, and a failure to spawn costs the event rather than the run.

## Known gaps

* **No approval telemetry.** Pi's `tool_call` event lets an extension block a call, but that is an extension deciding rather than an operator being asked. Pi exposes no operator approval decision through the extension API, so Beacon records these as tool activity and writes no approval events for Pi. Cline works the same way for the same reason. Detections in `rules/approval-abuse/` do not fire on Pi activity.
* **No enforcement.** As with every other runtime, enforcement stays behind the optional, off-by-default policy provider seam (`BEACON_POLICY_PROVIDER`), which is not wired to Pi. Pi's blocking `tool_call` handler makes it a viable target for that seam later.
* **Streaming events are not collected.** The extension subscribes to seven of Pi's event types and ignores the rest, which are provider-request and TUI-rendering internals. Assistant output is recorded once when a message finalizes rather than token by token, so Beacon stays out of the streaming path.
* **Project-level installs need Pi's trust prompt.** A `.pi/extensions/beacon.ts` is subject to Pi's project-trust prompt, so a user-level install is the one that works without further interaction.

## Deployment notes

The extension is loaded when Pi starts, so an install taken while Pi is running takes effect on the next launch.

Confirm discovery sees the runtime, then generate one Pi event and check the log:

```bash theme={null}
/opt/beacon/bin/beacon endpoint discover --all --json
/opt/beacon/bin/beacon endpoint hooks status --harness pi
/opt/beacon/bin/beacon endpoint doctor --system
grep '"name":"pi_cli"' ~/.beacon/endpoint/logs/runtime.jsonl | tail -3
```

## Related

<Columns cols={2}>
  <Card title="Supported agent harnesses" icon="list-check" href="/runtimes">
    Return to the runtime support overview.
  </Card>

  <Card title="Agent harness integration model" icon="plug" href="/runtimes/integration-model">
    See how Asymptote discovers and configures each runtime.
  </Card>
</Columns>
