update agents, human docs, plugin skill

Alessandro committed Feb 22, 2026 at 19:37 UTC 6f6348850d9f24498d49ff185b17f9c47b7c9838
6 files changed +330 -311
AGENTS.md
+177 -74
@@ -1,113 +1,216 @@
1 -# Agent Zero — Full-Stack Agent & Plugin Architecture
1 +# Agent Zero - AGENTS.md
2
3 -This document bridges the gap between the **Python Backend** (AgentContext, LLM loop) and the **Frontend Component System** (Alpine.js, Modals). Use this as the canonical reference for building deep integrations.
3 +[Generated using reconnaissance on 2026-02-22]
4 +
5 +## Quick Reference
6 +Tech Stack: Python 3.12+ | Flask | Alpine.js | LiteLLM | WebSocket (Socket.io)
7 +Dev Server: python run_ui.py (runs on http://localhost:50001 by default)
8 +Run Tests: pytest (standard) or pytest tests/test_name.py (file-scoped)
9 +Documentation: README.md | docs/
10 +Frontend Deep Dives: [Component System](docs/agents/AGENTS.components.md) | [Modal System](docs/agents/AGENTS.modals.md) | [Plugin Architecture](AGENTS.plugins.md)
11
12 ---
13
7 -## 1. The Core Concept: `AgentContext`
14 +## Table of Contents
15 +1. [Project Overview](#project-overview)
16 +2. [Core Commands](#core-commands)
17 +3. [Docker Environment](#docker-environment)
18 +4. [Project Structure](#project-structure)
19 +5. [Development Patterns & Conventions](#development-patterns--conventions)
20 +6. [Safety and Permissions](#safety-and-permissions)
21 +7. [Code Examples](#code-examples)
22 +8. [Git Workflow](#git-workflow)
23 +9. [API Documentation](#api-documentation)
24 +10. [Troubleshooting](#troubleshooting)
25 +
26 +---
27
9 -Every conversation in Agent Zero is an `AgentContext`. It owns the message history, the LLM state, the tool definitions, and the log queue.
28 +## Project Overview
29
11 -### Backend: Managing Contexts
12 -When building a plugin, you must interact with the context system correctly:
30 +Agent Zero is a dynamic, organic agentic framework designed to grow and learn. It uses the operating system as a tool, featuring a multi-agent cooperation model where every agent can create subordinates to break down tasks.
31
14 -```python
15 -from agent import AgentContext, AgentContextType, initialize_agent
16 -from python.helpers.messages import UserMessage
32 +Type: Full-Stack Agentic Framework (Python Backend + Alpine.js Frontend)
33 +Status: Active Development
34 +Primary Language(s): Python, JavaScript (ES Modules)
35
18 -# 1. Access an existing context (e.g., from a stored ID)
19 -context = AgentContext.use(context_id)
36 +---
37
21 -# 2. Or create a new one
22 -config = {} # use defaults
23 -context = AgentContext(config=config, type=AgentContextType.USER)
24 -await initialize_agent(context)
38 +## Core Commands
39
26 -# 3. Communicate (send a message and wait for completion)
27 -task = context.communicate(UserMessage("Hello Agent!"))
28 -response_text = await task.result()
40 +### Setup
41 +Do not combine these commands; run them individually:
42 +```bash
43 +pip install -r requirements.txt
44 +pip install -r requirements2.txt
45 ```
46 +- Start WebUI: python run_ui.py
47
31 -### The Glue: `MessageQueue` (mq)
32 -The frontend listens to a WebSocket. To make messages appear in the WebUI from your plugin, use the log helper:
48 +---
49
34 -```python
35 -# In your ApiHandler or bridge
36 -from python.helpers.messages import mq
50 +## Docker Environment
51
38 -# This makes the user message appear in the UI immediately
39 -mq.log_user_message(context.id, "Incoming message from WhatsApp", source="WhatsApp")
40 -```
52 +When running in Docker, Agent Zero uses two distinct Python runtimes to isolate the framework from the code being executed:
53
42 ----
54 +### 1. Framework Runtime (/opt/venv-a0)
55 +- Version: Python 3.12.4
56 +- Purpose: Runs the Agent Zero backend, API, and core logic.
57 +- Packages: Contains all dependencies from requirements.txt.
58 +
59 +### 2. Execution Runtime (/opt/venv)
60 +- Version: Python 3.13
61 +- Purpose: Default environment for the interactive terminal and the agent's code execution tool.
62 +- Behavior: This is the environment active when you docker exec into the container. Packages installed by the agent via pip install during a task are stored here.
63
44 -## 2. The Frontend: Component System
64 +---
65
46 -Agent Zero uses a custom **Component Loader** that fetches HTML, extracts `<style>` and `<script type="module">`, and injects them into the DOM.
66 +## Project Structure
67
48 -### The "Golden Rules" of Frontend Components
68 +```
69 +/
70 +├── agent.py # Core Agent and AgentContext definitions
71 +├── initialize.py # Framework initialization logic
72 +├── models.py # LLM provider configurations
73 +├── run_ui.py # WebUI server entry point
74 +├── python/
75 +│ ├── api/ # API Handlers (ApiHandler subclasses)
76 +│ ├── extensions/ # Backend lifecycle extensions
77 +│ ├── helpers/ # Shared Python utilities (plugins, files, etc.)
78 +│ ├── tools/ # Agent tools (Tool subclasses)
79 +│ └── websocket_handlers/# WebSocket event handlers
80 +├── webui/
81 +│ ├── components/ # Alpine.js components
82 +│ ├── js/ # Core frontend logic (modals, stores, etc.)
83 +│ └── index.html # Main UI shell
84 +├── usr/ # User data directory (isolated from core)
85 +│ ├── plugins/ # Custom user plugins
86 +│ ├── settings.json # User-specific configuration
87 +│ └── workdir/ # Default agent workspace
88 +├── plugins/ # Core system plugins
89 +├── agents/ # Agent profiles (prompts and config)
90 +├── prompts/ # System and message prompt templates
91 +└── tests/ # Pytest suite
92 +```
93
50 -1. **Store Gating (Critical)**: Always wrap your component content in a template that waits for the store. This prevents "undefined" errors during the loading race.
51 - ```html
52 - <div x-data>
53 - <template x-if="$store.myStore">
54 - <div class="content">...</div>
55 - </template>
56 - </div>
57 - ```
58 -2. **Separate Store Files**: Never put store registration logic directly inside the HTML `alpine:init` block. Use a separate `*-store.js` file and import it via `<script type="module" src="...">`.
59 -3. **createStore Proxy**: Use `createStore` from `/js/AlpineStore.js`. It ensures the store is available to the module even before Alpine fully boots.
94 +Key Files:
95 +- agent.py: Defines AgentContext and the main Agent class.
96 +- python/helpers/plugins.py: Plugin discovery and configuration logic.
97 +- webui/js/AlpineStore.js: Store factory for reactive frontend state.
98 +- python/helpers/api.py: Base class for all API endpoints.
99 +- docs/agents/AGENTS.components.md: Deep dive into the frontend component architecture.
100 +- docs/agents/AGENTS.modals.md: Guide to the stacked modal system.
101 +- AGENTS.plugins.md: Comprehensive guide to the full-stack plugin system.
102
103 ---
104
63 -## 3. The Modal System
105 +## Development Patterns & Conventions
106 +
107 +### Backend (Python)
108 +- Context Access: Use from agent import AgentContext, AgentContextType (not python.helpers.context).
109 +- Communication: Use mq from python.helpers.messages to log proactive UI messages:
110 + mq.log_user_message(context.id, "Message", source="Plugin")
111 +- API Handlers: Derive from ApiHandler in python/helpers/api.py.
112 +- Extensions: Use the extension framework in python/helpers/extension.py for lifecycle hooks.
113 +- Error Handling: Use RepairableException for errors the LLM might be able to fix.
114 +
115 +### Frontend (Alpine.js)
116 +- Store Gating: Always wrap store-dependent content in a template:
117 +```html
118 +<div x-data>
119 + <template x-if="$store.myStore">
120 + <div x-init="$store.myStore.onOpen()">...</div>
121 + </template>
122 +</div>
123 +```
124 +- Store Registration: Use createStore from /js/AlpineStore.js.
125 +- Modals: Use openModal(path) and closeModal() from /js/modals.js.
126
65 -Modals in A0 are "stacked" and loaded dynamically via `openModal(path)`.
127 +### Plugin Architecture
128 +- Location: Always develop new plugins in usr/plugins/.
129 +- Manifest: Every plugin requires a plugin.json with name, description, version, and optionally settings_sections.
130 +- Discovery: Conventions based on folder names (api/, tools/, webui/, extensions/).
131 +- Settings: Use get_plugin_config(plugin_name, agent=agent) to retrieve settings. Plugins can expose a UI for settings via webui/config.html. For plugins wrapping core settings, set $store.pluginSettings.saveMode = 'core' in x-init.
132
67 -### Directory Convention
68 -- `webui/components/modals/<feature>/<feature>.html`
69 -- `webui/components/modals/<feature>/<feature>-store.js`
133 +### Lifecycle Synchronization
134 +| Action | Backend Extension | Frontend Lifecycle |
135 +|---|---|---|
136 +| Initialization | agent_init | init() in Store |
137 +| Mounting | N/A | x-create directive |
138 +| Processing | monologue_start/end | UI loading state |
139 +| Cleanup | context_deleted | x-destroy directive |
140
71 -### Plugin Settings
141 +---
142
73 -Plugins get a dedicated settings modal with **Project** and **Agent profile** context selectors. To enable it:
143 +## Safety and Permissions
144
75 -1. Add `webui/config.html` to your plugin (auto-detected).
76 -2. Set `"settings_sections": ["agent"]` in `plugin.json` - this places a subsection with a Settings button in the chosen tab.
145 +### Allowed Without Asking
146 +- Read any file in the repository.
147 +- Update code files in usr/.
148
78 -Your `config.html` binds to `$store.pluginSettings.settings` (a plain object persisted as `config.json`). The modal's Save/Cancel footer handles persistence automatically. See `plugins/README.md` for the full contract and settings resolution priority chain.
149 +### Ask Before Executing
150 +- pip install (new dependencies).
151 +- Deleting core files outside of usr/ or tmp/.
152 +- Modifying agent.py or initialize.py.
153 +- Making git commits or pushes.
154
80 -For plugins that surface **existing core settings** (e.g. wrapping `settings/agent/memory.html`), set `$store.pluginSettings.saveMode = 'core'` in `x-init` to route Save through the core settings API instead.
155 +### Never Do
156 +- Commit, hardcode or leak secrets or .env files.
157 +- Bypass CSRF or authentication checks.
158 +- Hardcode API keys.
159
160 ---
161
84 -## 4. Lifecycle Synchronization
162 +## Code Examples
163
86 -| Action | Backend Extension | Frontend Lifecycle |
87 -|---|---|---|
88 -| **Initialization** | `agent_init` | `init()` in Store |
89 -| **Mounting** | N/A | `x-create` directive |
90 -| **Processing** | `monologue_start/end` | UI loading state |
91 -| **Cleanup** | `context_deleted` | `x-destroy` directive |
164 +### API Handler (Good)
165 +```python
166 +from python.helpers.api import ApiHandler, Request, Response
167 +
168 +class MyHandler(ApiHandler):
169 + async def process(self, input: dict, request: Request) -> dict | Response:
170 + # Business logic here
171 + return {"ok": True, "data": "result"}
172 +```
173 +
174 +### Alpine Store (Good)
175 +```javascript
176 +import { createStore } from "/js/AlpineStore.js";
177 +
178 +export const store = createStore("myStore", {
179 + items: [],
180 + init() { /* global setup */ },
181 + onOpen() { /* mount setup */ },
182 + cleanup() { /* unmount cleanup */ }
183 +});
184 +```
185 +
186 +### Tool Definition (Good)
187 +```python
188 +from python.helpers.tool import Tool, ToolResult
189 +
190 +class MyTool(Tool):
191 + async def execute(self, arg1: str):
192 + # Tool logic
193 + return ToolResult("Success")
194 +```
195
196 ---
197
95 -## 5. Directory Mapping (Plugin Layout)
96 -
97 -> [!IMPORTANT]
98 -> **Always create new plugins in `usr/plugins/`.** The root `/plugins/` folder is reserved for core Agent Zero plugins and may be overwritten during framework updates.
99 -
100 -```text
101 -usr/plugins/my-plugin/
102 -├── plugin.json # Required manifest (name, version, settings_sections)
103 -├── api/ # ApiHandler (python.helpers.api)
104 -├── extensions/
105 -│ ├── python/agent_init/ # Auto-start logic
106 -│ └── webui/ # sidebar-quick-actions-main-start/
107 -└── webui/
108 - ├── config.html # Optional: plugin settings UI
109 - └── my-modal.html # Full plugin pages + stores
198 +## Troubleshooting
199 +
200 +### Dependency Conflicts
201 +If pip install fails, try running in a clean virtual environment:
202 +```bash
203 +python -m venv .venv
204 +source .venv/bin/activate
205 +pip install -r requirements.txt
206 +pip install -r requirements2.txt
207 ```
208
112 -Refer to `docs/agents/AGENTS.components.md` for deep UI technicals and `docs/agents/AGENTS.modals.md` for modal-specific CSS classes (`btn-ok`, `btn-cancel`).
209 +### WebSocket Connection Failures
210 +- Check if X-CSRF-Token is being sent.
211 +- Ensure the runtime ID in the session matches the current server instance.
212 +
213 +---
214
215 +*Last updated: 2026-02-22*
216 +*Maintained by: Agent Zero Core Team*
AGENTS.plugins.md new
+91
@@ -0,0 +1,91 @@
1 +# Agent Zero - Plugins Guide
2 +
3 +This guide covers the Python Backend and Frontend WebUI plugin architecture. Use this as the definitive reference for building and extending Agent Zero.
4 +
5 +---
6 +
7 +## 1. Architecture Overview
8 +
9 +Agent Zero uses a convention-over-configuration plugin model where runtime capabilities are discovered from the directory structure.
10 +
11 +### Internal Components
12 +
13 +1. Backend discovery (python/helpers/plugins.py): Resolves roots (usr/plugins/ first, then plugins/) and builds the effective set of plugins.
14 +2. Path resolution (python/helpers/subagents.py): Injects plugin paths into the agent's search space for prompts, tools, and configurations.
15 +3. Python extensions (python/helpers/extension.py): Executes lifecycle hooks from extensions/python/<point>/.
16 +4. WebUI extensions (webui/js/extensions.js): Injects HTML/JS contributions into core UI breakpoints (x-extension).
17 +
18 +---
19 +
20 +## 2. File Structure
21 +
22 +Each plugin lives in usr/plugins/<plugin_name>/.
23 +
24 +```text
25 +usr/plugins/<plugin_name>/
26 +├── plugin.json # Required: Name, version, settings config
27 +├── api/ # API handlers (ApiHandler subclasses)
28 +├── tools/ # Agent tools (Tool subclasses)
29 +├── helpers/ # Shared Python logic
30 +├── prompts/ # Prompt templates
31 +├── agents/ # Agent profiles
32 +├── extensions/
33 +│ ├── python/<point>/ # Backend lifecycle hooks
34 +│ └── webui/<point>/ # UI HTML/JS contributions
35 +└── webui/
36 + ├── config.html # Optional: Plugin settings UI
37 + └── ... # Full plugin pages/components
38 +```
39 +
40 +### plugin.json format
41 +```json
42 +{
43 + "name": "My Plugin",
44 + "description": "What this plugin does.",
45 + "version": "1.0.0",
46 + "settings_sections": ["agent"]
47 +}
48 +```
49 +settings_sections values: agent, external, mcp, developer, backup.
50 +
51 +---
52 +
53 +## 3. Frontend Extensions
54 +
55 +### HTML Breakpoints
56 +Core UI defines insertion points like <x-extension id="sidebar-quick-actions-main-start"></x-extension>.
57 +To contribute:
58 +1. Place HTML files in extensions/webui/<extension_point>/.
59 +2. Include a root x-data scope.
60 +3. Include an x-move-* directive (e.g., x-move-to-start, x-move-after="#id").
61 +
62 +### JS Hooks
63 +Place *.js files in extensions/webui/<extension_point>/ and export a default async function. They are called via callJsExtensions("<point>", context).
64 +
65 +---
66 +
67 +## 4. Plugin Settings
68 +
69 +1. Add webui/config.html to your plugin.
70 +2. Bind fields to $store.pluginSettings.settings.
71 +3. Settings are scoped per-project and per-agent automatically.
72 +
73 +### Resolution Priority (Highest First)
74 +1. project/.a0proj/agents/<profile>/plugins/<name>/config.json
75 +2. project/.a0proj/plugins/<name>/config.json
76 +3. usr/agents/<profile>/plugins/<name>/config.json
77 +4. usr/plugins/<name>/config.json
78 +
79 +---
80 +
81 +## 5. Routes
82 +
83 +| Route | Purpose |
84 +|---|---|
85 +| GET /plugins/<name>/<path> | Serve static assets |
86 +| POST /api/plugins/<name>/<handler> | Call plugin API |
87 +| POST /api/plugins | Management (action: get_config, save_config) |
88 +
89 +---
90 +
91 +*Refer to AGENTS.md for the main framework guide.*
docs/agents/AGENTS.components.md
+20 -20
@@ -7,11 +7,11 @@
7
8 | Aspect | Value |
9 |--------|-------|
10 -| **Tech Stack** | Alpine.js, ES Modules, CSS Variables |
11 -| **Component Tag** | `<x-component path="...">` |
12 -| **State Management** | `createStore(name, model)` from `/js/AlpineStore.js` |
13 -| **Modals** | `openModal(path)` / `closeModal()` from `/js/modals.js` |
14 -| **API Layer** | `callJsonApi()` / `fetchApi()` from `/js/api.js` |
10 +| Tech Stack | Alpine.js, ES Modules, CSS Variables |
11 +| Component Tag | `<x-component path="...">` |
12 +| State Management | `createStore(name, model)` from `/js/AlpineStore.js` |
13 +| Modals | `openModal(path)` / `closeModal()` from `/js/modals.js` |
14 +| API Layer | `callJsonApi()` / `fetchApi()` from `/js/api.js` |
15
16 ---
17
@@ -182,7 +182,7 @@ This enables safe module-level initialization before Alpine loads.
182 | Module import | `import { store } from "./feature-store.js"; store.prop` |
183 | Global (avoid) | `Alpine.store("featureStore").prop` |
184
185 -**Prefer module imports over global lookups.**
185 +Prefer module imports over global lookups.
186
187 ### Persistence Helpers
188
@@ -262,7 +262,7 @@ const model = {
262 };
263 ```
264
265 -**Key distinction:**
265 +Key distinction:
266 - `init()` → once per app load (store registration)
267 - `onOpen()` → each time component mounts (modal opens, etc.)
268 - `cleanup()`/`destroy()` → teardown resources
@@ -360,7 +360,7 @@ Parent `x-component` attributes accessible via `globalThis.xAttrs(element)`:
360 </div>
361 ```
362
363 -**Always gate components that depend on stores.** Prevents errors during initial load race.
363 +Always gate components that depend on stores. Prevents errors during initial load race.
364
365 ---
366
@@ -422,7 +422,7 @@ When `x-component` wrapper would break flex layout:
422
423 ### Common Mistakes
424
425 -**Race condition: store not ready**
425 +Race condition: store not ready
426 ```html
427 <!-- ❌ BAD: No gate -->
428 <div x-data>
@@ -437,7 +437,7 @@ When `x-component` wrapper would break flex layout:
437 </div>
438 ```
439
440 -**Duplicate initialization**
440 +Duplicate initialization
441 ```javascript
442 // ❌ BAD: Runs every time store accessed
443 init() {
@@ -452,7 +452,7 @@ init() {
452 }
453 ```
454
455 -**Leaking listeners**
455 +Leaking listeners
456 ```javascript
457 // ❌ BAD: No cleanup
458 init() {
@@ -474,7 +474,7 @@ destroy() {
474
475 ### Minimum Requirements for External Apps
476
477 -1. **Files to copy:**
477 +1. Files to copy:
478 ```
479 /js/components.js # Component loader
480 /js/AlpineStore.js # Store factory
@@ -482,11 +482,11 @@ destroy() {
482 /js/initFw.js # Alpine bootstrap + directives
483 ```
484
485 -2. **Dependencies:**
485 +2. Dependencies:
486 - Alpine.js (vendor or CDN)
487 - CSS variables (define your theme)
488
489 -3. **Bootstrap sequence:**
489 +3. Bootstrap sequence:
490 ```javascript
491 // initFw.js pattern:
492 await import("path/to/alpine.min.js");
@@ -497,7 +497,7 @@ destroy() {
497 // etc.
498 ```
499
500 -4. **HTML entry point:**
500 +4. HTML entry point:
501 ```html
502 <script type="module" src="/js/initFw.js"></script>
503 <x-component path="app/root.html"></x-component>
@@ -516,10 +516,10 @@ destroy() {
516
517 | Framework | Consideration |
518 |-----------|--------------|
519 -| **Vanilla/Static** | Works directly, include initFw.js |
520 -| **Electron** | Works, may need CSP adjustments for Blob URLs |
521 -| **React/Vue** | Mount Alpine in specific container, avoid conflicts |
522 -| **SPA Routers** | MutationObserver handles dynamic inserts |
519 +| Vanilla/Static | Works directly, include initFw.js |
520 +| Electron | Works, may need CSP adjustments for Blob URLs |
521 +| React/Vue | Mount Alpine in specific container, avoid conflicts |
522 +| SPA Routers | MutationObserver handles dynamic inserts |
523
524 ---
525
@@ -551,7 +551,7 @@ webui/components/
551 └── ...
552 ```
553
554 -**Naming conventions:**
554 +Naming conventions:
555 - Components: `feature-name.html`
556 - Stores: `feature-store.js` or `feature-name-store.js`
557 - Modals: placed in `modals/` or feature folder
docs/agents/AGENTS.modals.md
+1 -1
@@ -149,7 +149,7 @@ Use these standard button classes for modal actions:
149 | `btn btn-ok` | Positive/confirmatory actions (Save, Create, Confirm) | Solid blue background, white text |
150 | `btn btn-cancel` | Dismissive/negative actions (Cancel, Close, Delete) | Transparent with accent border |
151
152 -Footer button order convention: **positive action first** (left), **negative action second** (right).
152 +Footer button order convention: positive action first (left), negative action second (right).
153
154 Example footer markup:
155
plugins/README.md
+14 -191
@@ -1,199 +1,22 @@
1 -# Agent Zero Plugins
1 +# Agent Zero - Core Plugins
2
3 -This directory contains default plugins. For a full-stack development guide, see [docs/AGENTS.md](../docs/AGENTS.md).
3 +This directory contains the system-level plugins for Agent Zero.
4
5 -> [!TIP]
6 -> While Agent Zero looks for plugins in both `usr/plugins/` and `plugins/`, you should **always develop new plugins in `usr/plugins/`**. This ensures your work is isolated from core system files and persists through framework updates.
5 +## Directory Structure
6
8 -## Architecture
7 +- plugins/: Core system plugins (reserved for framework updates).
8 +- usr/plugins/: Recommended location for user-developed plugins.
9
10 -Agent Zero uses a convention-over-configuration plugin model:
10 +## Documentation
11
12 -- Runtime capabilities are discovered from directory structure.
13 -- Backend owns discovery, routing, and static asset serving.
14 -- Frontend uses explicit `x-extension` breakpoints plus the standard `x-component` loader.
12 +For detailed guides on how to create, extend, or configure plugins, please refer to:
13
16 -### Internal Components
14 +- AGENTS.plugins.md: Full-stack plugin architecture, manifest format, and extension points.
15 +- AGENTS.md: Main framework guide and backend context overview.
16
18 -1. **Backend plugin discovery** (`python/helpers/plugins.py`)
19 - - `get_plugin_roots()` resolves roots in priority order (`usr/plugins` first, then `plugins`).
20 - - `list_plugins()` builds the effective set (first root wins on ID conflicts).
21 - - `get_webui_extensions(extension_point, filters)` scans `extensions/webui/<extension_point>/`.
17 +## Usage
18
23 -2. **Path resolution** (`python/helpers/subagents.py`)
24 - - `get_paths(..., include_plugins=True)` includes plugin candidates for prompts/tools.
25 -
26 -3. **Python extension runtime** (`python/helpers/extension.py`)
27 - - `call_extensions(extension_point, agent, **kwargs)` executes extension classes.
28 - - Searches `python/extensions/<point>/` and `plugins/*/extensions/python/<point>/`.
29 - - Extension classes derive from `Extension` and implement `async execute()`.
30 -
31 -4. **API and static routes** (`run_ui.py`, `python/api/load_webui_extensions.py`)
32 - - `GET /plugins/<plugin_id>/<path>` serves plugin static assets.
33 - - Plugin APIs are mounted under `/api/plugins/<plugin_id>/<handler>`.
34 - - `POST /api/load_webui_extensions` returns extension files for a given extension point.
35 -
36 -5. **Frontend WebUI extension runtime** (`webui/js/extensions.js`)
37 - - HTML flow: discovers `<x-extension>` tags, calls backend API, injects `<x-component>` tags.
38 - - JS flow: `callJsExtensions("<extension_point>", contextObject)` loads and executes plugin JS modules.
39 - - Both HTML and JS lookups are cached per extension point.
40 -
41 -## File Structure
42 -
43 -```text
44 -usr/plugins/
45 - <plugin_name>/
46 - plugin.json # Required manifest (enables discovery)
47 - api/ # API handlers (ApiHandler subclasses)
48 - tools/ # Agent tools (Tool subclasses)
49 - helpers/ # Shared Python helpers
50 - prompts/ # Prompt templates
51 - agents/ # Agent profiles
52 - extensions/
53 - python/<extension_point>/ # Python lifecycle extensions
54 - webui/<extension_point>/ # WebUI HTML/JS hook contributions
55 - webui/
56 - config.html # Optional: plugin settings UI
57 - ... # Full plugin-owned UI pages/components
58 -```
59 -
60 -## Directory Conventions
61 -
62 -Each plugin lives in `usr/plugins/<plugin_name>/`.
63 -
64 -Capability discovery is based on these paths:
65 -
66 -- `plugin.json` - **required** manifest; a directory without it is not recognized as a plugin
67 -- `api/*.py` - API handlers (`ApiHandler` subclasses), exposed under `/api/plugins/<plugin_name>/<handler>`
68 -- `tools/*.py` - agent tools (`Tool` subclasses)
69 -- `helpers/*.py` - shared Python helpers
70 -- `extensions/python/<extension_point>/*.py` - backend lifecycle extensions
71 -- `extensions/webui/<extension_point>/*` - WebUI extension assets (HTML/JS)
72 -- `webui/**` - full plugin-owned UI pages/components (loaded directly by path)
73 -- `webui/config.html` - if present, a Settings button appears for this plugin in the relevant settings tabs
74 -- `prompts/**/*.md` - prompt templates
75 -- `agents/` - agent profiles
76 -
77 -### `plugin.json` format
78 -
79 -```json
80 -{
81 - "name": "My Plugin",
82 - "description": "What this plugin does.",
83 - "version": "1.0.0",
84 - "settings_sections": ["agent"]
85 -}
86 -```
87 -
88 -`settings_sections` controls which Settings tabs show a subsection for this plugin. Current valid values: `agent`, `external`, `mcp`, `developer`, `backup`. Leave empty (`[]`) for no subsection.
89 -
90 -## Frontend Extensions
91 -
92 -### HTML insertion via breakpoints
93 -
94 -Core UI defines insertion points like:
95 -
96 -```html
97 -<x-extension id="sidebar-quick-actions-main-start"></x-extension>
98 -```
99 -
100 -Resolution flow:
101 -
102 -1. `webui/js/extensions.js` finds `x-extension` nodes.
103 -2. It calls `/api/load_webui_extensions` with the extension point and HTML filters.
104 -3. Backend returns matching files from `plugins/*/extensions/webui/<extension_point>/`.
105 -4. `extensions.js` injects returned entries as `<x-component path="...">`.
106 -5. `components.js` loads each component using the standard component pipeline.
107 -
108 -Required baseline for HTML UI extensions in this repository:
109 -- include a root `x-data` scope
110 -- include one explicit `x-move-*` placement directive
111 -
112 -### JS hook extensions
113 -
114 -JS hooks are loaded from the same extension point structure:
115 -
116 -`plugins/<plugin_id>/extensions/webui/<extension_point>/*.js`
117 -
118 -Runtime code calls:
119 -
120 -`callJsExtensions("<extension_point>", contextObject)`
121 -
122 -### Fine placement helpers
123 -
124 -`initFw.js` provides Alpine move directives for plugin markup:
125 -
126 -- `x-move-to-start`
127 -- `x-move-to-end`
128 -- `x-move-to`
129 -- `x-move-before`
130 -- `x-move-after`
131 -
132 -## Plugin Settings
133 -
134 -If your plugin needs user-configurable settings:
135 -
136 -1. Add `webui/config.html` to your plugin. The system detects this file automatically.
137 -2. Declare which settings tabs should show a subsection for your plugin via `settings_sections` in `plugin.json`.
138 -3. The plugin settings modal provides **Project** and **Agent profile** context selectors (same as the Skills list). Settings are scoped per-project and per-agent.
139 -
140 -### Config HTML contract
141 -
142 -Your `config.html` receives context from `$store.pluginSettings`:
143 -
144 -```html
145 -<html>
146 -<head>
147 - <title>My Plugin Config</title>
148 - <script type="module">
149 - import { store } from "/components/plugins/plugin-settings-store.js";
150 - </script>
151 -</head>
152 -<body>
153 - <div x-data>
154 - <!-- bind fields to $store.pluginSettings.settings -->
155 - <input x-model="$store.pluginSettings.settings.my_key" />
156 - </div>
157 -</body>
158 -</html>
159 -```
160 -
161 -- `$store.pluginSettings.settings` - plain object loaded from `config.json`, save-scoped to the selected project/agent.
162 -- The modal's **Save** button calls `POST /plugins` (`action: save_config`) automatically.
163 -- For plugins that surface **core settings** (like memory), set `saveMode = 'core'` in `x-init` so Save delegates to the core settings API instead.
164 -
165 -### Settings resolution priority (highest first)
166 -
167 -```
168 -project/.a0proj/agents/<profile>/plugins/<name>/config.json
169 -project/.a0proj/plugins/<name>/config.json
170 -usr/agents/<profile>/plugins/<name>/config.json
171 -agents/<profile>/plugins/<name>/config.json
172 -usr/plugins/<name>/config.json
173 -plugins/<name>/config.json
174 -```
175 -
176 -## Plugin Author Flow
177 -
178 -1. Create `usr/plugins/<plugin_name>/`.
179 -2. Add `plugin.json` manifest (required for discovery).
180 -3. Add backend capabilities by convention (`api/`, `tools/`, `helpers/`, `extensions/python/`, `prompts/`, `agents/`).
181 -4. Pick a WebUI breakpoint or JS hook extension point.
182 -5. For HTML UI entries: place files under `extensions/webui/<extension_point>/`, use root `x-data` + one `x-move-*` directive.
183 -6. For JS hooks: place `*.js` files under `extensions/webui/<extension_point>/`, export a default async function.
184 -7. Place full plugin pages/components in `webui/` and open them directly by path.
185 -8. Optionally add `webui/config.html` and set `settings_sections` in `plugin.json` to expose settings in the UI.
186 -
187 -## Routes
188 -
189 -- Plugin static assets: `GET /plugins/<plugin_name>/<path>`
190 -- Plugin APIs: `POST /api/plugins/<plugin_name>/<handler>`
191 -- WebUI extension discovery: `POST /api/load_webui_extensions`
192 -- Plugin management (get/save config): `POST /plugins`
193 -
194 -## Notes
195 -
196 -- User plugins in `usr/plugins/` override repo plugins by plugin ID.
197 -- Runtime behavior is fully convention-driven from directory structure.
198 -- Extension point ordering between multiple plugins is currently implicit (filesystem order).
199 -- When you need a new extension point for your plugin, submit a PR - we are actively expanding coverage based on community needs.
19 +Plugins are automatically discovered based on the presence of a plugin.json file. Each plugin can contribute:
20 +- Backend: APIs, Tools, Helpers, and Lifecycle Extensions.
21 +- Frontend: HTML/JS UI contributions via core breakpoints.
22 +- Config: Isolated settings scoped per-project and per-agent profile.
skills/a0-create-plugin/SKILL.md
+27 -25
@@ -6,17 +6,17 @@ description: Create, extend, or modify Agent Zero plugins. Follows strict full-s
6 # Agent Zero Plugin Development
7
8 > [!IMPORTANT]
9 -> **Always create new plugins in `usr/plugins/<plugin_name>/`.** The root `/plugins` directory is reserved for core system plugins.
9 +> Always create new plugins in usr/plugins/<plugin_name>/. The root /plugins directory is reserved for core system plugins.
10
11 Primary references:
12 -- `/a0/AGENTS.md` (Full-stack architecture & AgentContext)
13 -- `/a0/docs/agents/AGENTS.components.md` (Component system deep dive)
14 -- `/a0/docs/agents/AGENTS.modals.md` (Modal system & CSS conventions)
15 -- `/a0/plugins/README.md` (Extension points, plugin.json, settings system)
12 +- /a0/AGENTS.md (Full-stack architecture & AgentContext)
13 +- /a0/docs/agents/AGENTS.components.md (Component system deep dive)
14 +- /a0/docs/agents/AGENTS.modals.md (Modal system & CSS conventions)
15 +- /a0/AGENTS.plugins.md (Extension points, plugin.json, settings system)
16
17 -## 📋 Plugin Manifest (`plugin.json`)
17 +## Plugin Manifest (plugin.json)
18
19 -Every plugin **must** have a `plugin.json` or it will not be discovered:
19 +Every plugin must have a plugin.json or it will not be discovered:
20
21 ```json
22 {
@@ -27,12 +27,12 @@ Every plugin **must** have a `plugin.json` or it will not be discovered:
27 }
28 ```
29
30 -`settings_sections` controls which Settings tabs show a subsection for this plugin. Valid values: `agent`, `external`, `mcp`, `developer`, `backup`. Use `[]` for no subsection.
30 +settings_sections controls which Settings tabs show a subsection for this plugin. Valid values: agent, external, mcp, developer, backup. Use [] for no subsection.
31
32 -## 🛠️ Mandatory Frontend Patterns
32 +## Mandatory Frontend Patterns
33
34 ### 1. The "Store Gate" Template
35 -To avoid race conditions and "undefined" errors, every component must use this wrapper:
35 +To avoid race conditions and undefined errors, every component must use this wrapper:
36 ```html
37 <div x-data>
38 <template x-if="$store.myPluginStore">
@@ -44,30 +44,31 @@ To avoid race conditions and "undefined" errors, every component must use this w
44 ```
45
46 ### 2. Separate Store Module
47 -Place store logic in a separate `.js` file. Do NOT use `alpine:init` listeners inside HTML.
47 +Place store logic in a separate .js file. Do NOT use alpine:init listeners inside HTML.
48 ```javascript
49 // webui/my-store.js
50 import { createStore } from "/js/AlpineStore.js";
51 export const store = createStore("myPluginStore", {
52 status: 'idle',
53 init() { ... },
54 - onOpen() { ... }
54 + onOpen() { ... },
55 + cleanup() { ... }
56 });
57 ```
57 -Import it in the HTML `<head>`:
58 +Import it in the HTML <head>:
59 ```html
60 <head>
61 <script type="module" src="/plugins/<plugin_name>/webui/my-store.js"></script>
62 </head>
63 ```
64
64 -## ⚙️ Plugin Settings
65 +## Plugin Settings
66
66 -If your plugin needs user-configurable settings, add `webui/config.html`. The system detects it automatically and shows a Settings button in the relevant tabs (per `settings_sections` in `plugin.json`).
67 +If your plugin needs user-configurable settings, add webui/config.html. The system detects it automatically and shows a Settings button in the relevant tabs (per settings_sections in plugin.json).
68
69 ### Settings modal contract
70
70 -The modal provides Project + Agent profile context selectors. Your `config.html` binds to `$store.pluginSettings.settings`:
71 +The modal provides Project + Agent profile context selectors. Your config.html binds to $store.pluginSettings.settings:
72
73 ```html
74 <html>
@@ -86,11 +87,11 @@ The modal provides Project + Agent profile context selectors. Your `config.html`
87 </html>
88 ```
89
89 -The modal's Save button persists `$store.pluginSettings.settings` to `config.json` in the correct scope (project/agent/global).
90 +The modal's Save button persists $store.pluginSettings.settings to config.json in the correct scope (project/agent/global).
91
92 ### Surfacing core settings (e.g. memory pattern)
93
93 -If your plugin exposes **existing core settings** rather than plugin-specific ones, set `saveMode = 'core'` so Save delegates to the core settings API:
94 +If your plugin exposes existing core settings rather than plugin-specific ones, set saveMode = 'core' so Save delegates to the core settings API:
95
96 ```html
97 <div x-data x-init="
@@ -102,15 +103,16 @@ If your plugin exposes **existing core settings** rather than plugin-specific on
103 ```
104
105 ### Sidebar Button (sidebar entry point)
105 -- **Extension point**: `sidebar-quick-actions-main-start`
106 -- **Class**: `class="config-button"`
107 -- **Placement**: `x-move-after=".config-button#dashboard"`
108 -- **Action**: `@click="openModal('/plugins/<plugin_name>/webui/my-modal.html')"`
106 +- Extension point: sidebar-quick-actions-main-start
107 +- Class: class="config-button"
108 +- Placement: x-move-after=".config-button#dashboard"
109 +- Action: @click="openModal('/plugins/<plugin_name>/webui/my-modal.html')"
110
110 -## 🐍 Backend API & Context
111 +## Backend API & Context
112
113 ### Import Paths
113 -- **Correct**: `from agent import AgentContext` (not python.helpers.agent)
114 +- Correct: from agent import AgentContext, AgentContextType
115 +- Correct: from initialize import initialize_agent
116
117 ### Sending Messages Proactively
118 ```python
@@ -138,7 +140,7 @@ save_plugin_config(
140 )
141 ```
142
141 -## 📁 Directory Layout
143 +## Directory Layout
144 ```
145 usr/plugins/<name>/
146 plugin.json # Required manifest