Repository navigation
Example Plugins
English · 中文
Tracks v0.12.0 (
8dd8ae9). Every tool, command, event and grant below was read out of the plugin sources, not remembered. The sources are underexamples/in the repo — if this page disagrees with them, the repo wins.
Three of them demonstrate the mechanism. Two are meant to be installed and used.
| Plugin | What it is for | Tools | Commands | Events |
|---|---|---|---|---|
wasm-plugin-minimal |
The skeleton to copy. The smallest plugin that still exercises a capability gate — one pure tool, one gated one, split into "boilerplate" and "your part" by a single marker comment. |
greet, fetch_head
|
— | — |
wasm-plugin |
The reference. Four tools, slash commands, and all three command actions (print / send_user_message / error). |
wordcount, readfile, fetch, rot13
|
/todo, /explain
|
— |
wasm-plugin-events |
Event subscription, and the two-list grant: the plugin's list-events and the config's events must agree, or nothing is delivered. Also carries the trap/spin fixtures the hang-breaker tests use. |
events_seen, busy, greet
|
(none — an [] stub, the ladder's cost) |
tool_execution_start, turn_start, input
|
wasm-plugin-memory |
Durable project memory. Facts become markdown files under .nanopi/memory/ that you can read, edit, diff and commit. Only the compact index enters the model's context; it calls recall for the full text of whatever looks relevant. |
remember, recall, forget
|
/memory |
— |
wasm-plugin-report |
Where the time went. Per-tool call counts, duration and failures, kept across sessions. Exists because tool_execution_end carries a duration_ms that nothing else persists — so "why was that slow" and "what keeps failing" otherwise have no answer at all. |
tool_stats |
/tools-report |
tool_execution_end, session_start
|
Start from wasm-plugin-minimal. It is the one designed to be copied: everything above its YOUR TOOLS marker is boilerplate you keep verbatim, everything below it is yours. Read wasm-plugin next when you need commands or a second capability.
Read wasm-plugin-memory and wasm-plugin-report if you want to see the capabilities actually used rather than demonstrated. They are deliberately complementary: between the two of them they exercise the whole outbound surface (see Plugin Capabilities).
A plugin reaches nothing it was not granted. These go in its [[extensions]] entry; each plugin's own README spells out the exact block.
| Plugin | Grants | Host imports it calls |
|---|---|---|
wasm-plugin-minimal |
allow_network + url_allowlist
|
host-log, host-http-get
|
wasm-plugin |
allow_fs, allow_network + url_allowlist
|
host-log, host-fs-read, host-http-get
|
wasm-plugin-events |
events = [...] |
host-log |
wasm-plugin-memory |
allow_fs, allow_tools = ["write"], allow_context
|
host-log, host-fs-read, host-notify, host-set-context, host-call-tool
|
wasm-plugin-report |
allow_store, events = [...]
|
host-log, host-notify, host-store-get, host-store-set
|
Two details in that table are easy to get wrong:
-
wasm-plugin-minimaldoes not needallow_fs, even though its source declareshost-fs-read. The declaration sits behind#[allow(dead_code)]and nothing calls it, so LTO drops the import and it is absent from the built world.wasm-tools component witon the component is the way to check what a plugin really imports — the source can over-declare. -
host-notifyneeds no grant. It is output, not access: it reaches nothing and reads nothing. It is bounded by a per-turn rate limit instead, and the host applies the attribution prefix so one plugin cannot pose as another.
The WIT worlds are a linear ladder — extension ⊂ extension-commands ⊂ extension-events — so a plugin targets the lowest one that covers what it exports. Targeting a higher world than you need means owing stub exports for the parts you do not use.
| Plugin | World | Build |
|---|---|---|
wasm-plugin-minimal |
extension |
no make target — by hand, see its README |
wasm-plugin |
extension-commands |
make plugin |
wasm-plugin-events |
extension-events |
make plugin-events |
wasm-plugin-memory |
extension-commands |
make plugin-memory |
wasm-plugin-report |
extension-events |
make plugin-report |
Always build from the repo root. wasm-tools component embed wit/ resolves wit/ against the working directory, so building from inside an example silently embeds a stale module. Output lands in dist/.
The host needs --features wasm; the stock release binary has no WASM runtime and will tell you so — it prints how many [[extensions]] entries it ignored rather than failing silently.
examples/hooks/ holds scripts for [[hooks.*]] — check-rm-rf.sh, protected-paths.sh, redact-secrets.sh, dirty-repo-guard.sh, audit-log.sh, session-log.sh. See Hooks.
Two things only a hook can do, and both are design decisions rather than gaps:
- Veto. A hook can block or rewrite a tool call. Plugins observe events and cannot refuse them. If you want to stop something from happening, it is a hook.
-
Never miss an event. Hooks are synchronous. Plugin event delivery is drop-on-busy and does not queue — a plugin already inside a guest call misses the next event entirely. So anything that has to be complete belongs in a hook.
wasm-plugin-reportsays exactly this in its own output, and prints≥on its counts, because a statistic that quietly undercounts is worse than one that admits it.
tests/fixtures/runaway-plugin/ is a plugin whose execute-tool never returns, used to prove the epoch hang-breaker fires. Its own header says why it is not an example: "Deliberately NOT in examples/ — nothing here is worth copying." A directory whose other READMEs say "copy this as a starting point" is the wrong home for a component that hangs.
- Plugin Development — writing one from scratch, including the full ABI boilerplate
- Plugin Capabilities — what a plugin may do, and the reasoning behind each gate
- Plugin Events — the eleven events and their payloads
- Debugging Plugins — when a plugin will not load or a call is refused
English
- Home
- Features
- Configuration
- Hooks
- Plugin Development
- Example Plugins
- Plugin Capabilities
- Plugin Events
- Debugging Plugins
中文
v0.12.0 · source of truth:
wit/nanopi-extension.wit