# @tinoy/pi-canon

> Durable system-prompt rules for pi: an on-disk canon store, its tools, and the /canon commands.

Latest version **0.3.0** (published 2026-09-24) · MIT license · 0 weekly downloads

## Install

```sh
npm install @tinoy/pi-canon
pnpm add @tinoy/pi-canon
yarn add @tinoy/pi-canon
bun add @tinoy/pi-canon
```

## Health

**Score 65/100 (B)** — status: active.

Positive: esm support; no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: low downloads; no types; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.3.0 |
| Published | 2026-09-24 |
| First published | 2026-09-23 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Node | >=22 |
| Dependencies | 1 |
| Unpacked size | 66.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 1 |
| Maintainers | tinoy |
| Keywords | pi-package |

## Links

- npm: https://www.npmjs.com/package/@tinoy/pi-canon
- Repository: https://github.com/tinoy1336/pi-extensions
- Homepage: https://github.com/tinoy1336/pi-extensions/tree/main/packages/canon#readme
- Issues: https://github.com/tinoy1336/pi-extensions/issues
- npm.io page: https://npm.io/package/@tinoy/pi-canon

## Dependencies (1)

- [@tinoy/pi-ext-lib](https://npm.io/package/@tinoy/pi-ext-lib.md) *

## Recent versions

- 0.3.0 (latest) — 2026-09-24
- 0.2.0 — 2026-09-23
- 0.1.0 — 2026-09-23

## README

# @tinoy/pi-canon

Durable system-prompt rules ("canon") for pi. Rules and learned facts are stored
on disk, scoped by model (`global` or a model id) and audience (`all`, `parent`,
`foreman`, `subagent`), and injected into every matching session's system prompt.
Runtime edits reach running sessions as notices; the injected block is a
session-start snapshot, so a running session's prompt never changes mid-session.

```bash
pi install npm:@tinoy/pi-canon
```

## What it does

- **Store** — `~/.pi/agent/canon/canon.json`: `{entries: [{id, text, model, audience, reason?, category?}], categories: [{id, title, description?}]}`. Written atomically; a missing or corrupt store reads as empty.
- **Tools** — `canon_add`, `canon_remove`, `canon_edit`, `canon_category`.
- **Commands** — `/canon` (list, add, remove, edit, category management) and `/canon-dump`.
- **Injection** — the block is appended at `before_agent_start` and re-normalized on every provider request, so a run started by an injected message carries the same bytes as an interactive prompt.
- **Peer notices** — entry changes are broadcast over the pi-intercom bus (namespace `canon`); receivers match the entry scope against their own model and audience.
- **Tail sections** — another extension contributes prompt text through the `canon:section` event; its ids are published on `canon:sections`.

## Exports

`index.ts` is the package entry, and it is also the module API:

| Export | What it is |
| --- | --- |
| default | the pi extension factory — the hooks, the four tools and the two commands |
| `setTailSection(id, text)` | contribute a tail section, replaced per id |
| `registeredSectionIds()` | the ids currently registered |

The tail-section registry stays here because it owns this package's event contract: the
`canon:section` / `canon:sections` names, the `canon` hook-log source, and the section
cap. `setTailSection` / `registeredSectionIds` are exported for this package's own use
and are never re-exported elsewhere; another extension reaches the registry through the
`canon:section` event, because an exported function is unreachable across the loader's
module isolation.

## The system-prompt seam

The seam canon composes the tail through — `canonicalSystemPrompt(systemPrompt, block)`,
`systemPromptSlot(payload)` and the append separator `PROMPT_APPEND_SEP` — is NOT
exported from this package. It lives in `@tinoy/pi-ext-lib` (`src/system-prompt.ts`),
together with the rule that makes it shared: `before_agent_start` fires only from the
interactive `prompt()` path, so an appended block has to be re-normalized on every
provider request for the request prefix to stay byte-identical. Canon imports it from
there, and so does any other extension that appends to the system prompt — import
`@tinoy/pi-ext-lib`, not this package. What stays here is the policy: the block's
content, its scope rules, and what happens when the payload carries no rewritable slot.

## Dependencies

pi supplies these, so they are declared as peer dependencies with `*` and are not
bundled: `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, `typebox`.
`@tinoy/pi-ext-lib` is a plain dependency; the prompt seam above is imported from it,
not re-exported by this package.

## Licence

MIT — see the repository [LICENSE](../../LICENSE).

---
_Source: https://npm.io/package/@tinoy/pi-canon · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
