docs/guides/create-plugin.md
The fastest way to understand Agent Zero plugins is to make one small enough to hold in your head.
This guide walks through a real example: a local plugin named unread_dot that
adds a pulsing dot beside a chat when that chat receives new activity while you
are looking somewhere else.
For architecture and source-linked internals, use DeepWiki for Agent Zero. This page stays practical: what to ask, where files appear, what to check, and how to know the plugin actually works.
unread_dot is intentionally tiny:
localStorage key.That makes it a good first plugin. You can see the whole shape without learning every plugin feature at once.
Open a new chat and give Agent Zero a very specific plugin task:
Use the a0-create-plugin skill.
Create a local-only plugin named unread_dot in /a0/usr/plugins/unread_dot.
The plugin should show a pulsing dot in the chat list whenever a non-selected
chat receives new agent activity.
Keep it minimal and frontend-only:
- no external dependencies;
- no backend API;
- no tools;
- no network calls.
If the plugin already exists, improve it instead of creating a duplicate.
When finished, run the a0-review-plugin skill on unread_dot and summarize
PASS/WARN/FAIL. Do not run CodeRabbit.
The important part is not the exact wording. The important part is giving Agent Zero the plugin name, the location, the visible behavior, and the boundaries.
Local plugins live under /a0/usr/plugins/<plugin_name>/ inside the running
Agent Zero instance. For this example, the final plugin shape is:
/a0/usr/plugins/unread_dot/
├── plugin.yaml
├── README.md
├── extensions/
│ └── webui/
│ ├── apply_snapshot_before/
│ │ └── track-unread.js
│ └── initFw_end/
│ └── bootstrap-unread-dot.js
└── webui/
├── unread-dot.css
└── unread-dot-store.js
plugin.yaml is the plugin's name tag:
name: unread_dot
title: Unread Dot
description: Shows a pulsing dot beside chats that received new activity while you were elsewhere.
version: 1.0.0
settings_sections: []
per_project_config: false
per_agent_config: false
The two Web UI extension files are the little doorways into the running interface:
initFw_end/bootstrap-unread-dot.js loads the store and stylesheet after the Web UI starts.apply_snapshot_before/track-unread.js watches state snapshots so the plugin can notice when another chat changes.The store keeps the unread state. The CSS draws the dot.
After creating or changing a plugin, restart Agent Zero so the Web UI extension list is rebuilt.
Then test the behavior:
Open a fresh chat.
Send a short prompt, such as:
Please reply with one short sentence: unread dot live test complete.
Immediately switch to another chat.
Wait for Agent Zero to keep working in the first chat.
Look at the chat list.
If the first chat receives new activity while it is not selected, the dot appears. When you open that chat again, the dot clears.
This example watches for chat activity. In normal use, that means "the agent did something in a chat you were not watching." It does not read every message in every other chat.
Run the plugin review skill before treating the plugin as done:
Use the a0-review-plugin skill to review /a0/usr/plugins/unread_dot.
Report PASS/WARN/FAIL by phase.
For this example, the review result is:
| Phase | Result | Notes |
|---|---|---|
| Manifest | PASS | plugin.yaml is valid, named correctly, and uses simple local settings. |
| Structure | PASS with WARN | The layout is standard. LICENSE is absent, which is fine locally but blocks Plugin Index submission. |
| Code patterns | PASS with WARN | The store uses Agent Zero's createStore pattern. The unread signal is chat activity, not a parsed message-author check. |
| Security and index | PASS with WARN | No secrets, subprocesses, dependencies, or outbound calls. The community index already has a related Chat Status Marklet plugin, so treat this as a learning example unless you make it clearly different. |
Status: ready as a local demo plugin. Not ready as a new community submission until it has a license and a reason to exist separately from similar plugins.
Once the small version works, change only one thing at a time:
LICENSE, screenshots, and a clearer README.Small plugins are good teachers. You can see the whole machine turning without standing inside the engine.