/create-plugin
Build a Clodex plugin end to end - scaffold it, wire the surfaces it needs, and verify it against the real loader. Usage - /clodex-plugin-builder:create-plugin <id> [what it should do]
$ npx -y skills add avirtual/clodex --skill create-plugin --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/create-plugin
Context preview
The summary Claude sees to decide when to auto-load this skill.
Build a Clodex plugin end to end - scaffold it, wire the surfaces it needs, and verify it against the real loader. Usage - /clodex-plugin-builder:create-plugin <id> [what it should do]
SKILL.md
create-plugin.SKILL.mddescription: Build a Clodex plugin end to end - scaffold it, wire the surfaces it needs, and verify it against the real loader. Usage - /clodex-plugin-builder:create-plugin <id> [what it should do]
Build a Clodex plugin
You are building a plugin for Clodex, the app you are running inside. This skill carries the facts that are expensive to rediscover; the authority is the contract, and where they disagree the contract wins.
Step 0 — find the contract
A Clodex **checkout** carries the contract. The installed app does not give you one you can read: its copy is inside the app archive, which your shell cannot list. So look for a checkout first:
find ~/projects /Applications -maxdepth 4 -name plugin-api.md -path '*plugins*' 2>/dev/null | head -3
A checkout also carries the author tools, and they are the fastest path by a wide margin:
node plugins/tools/build-context.js /tmp/plugin-context.md # the full pack
node plugins/tools/scaffold.js <id> <target-dir> # a plugin that already passes
node plugins/tools/verify.js <dir> # run it against the REAL loader
**If `verify.js` exists, you must use it** — it loads the plugin through the host's own loader, so it catches what reading cannot.
With no checkout, fetch the four docs from the public repo, and say in your final message that the plugin is unverified — nothing ran it:
https://raw.githubusercontent.com/avirtual/clodex/master/plugins/plugin-api.md
https://raw.githubusercontent.com/avirtual/clodex/master/plugins/what-plugins-can-do.md
https://raw.githubusercontent.com/avirtual/clodex/master/plugins/plugin-sources.md
https://raw.githubusercontent.com/avirtual/clodex/master/plugins/README.md
`master` may describe a Clodex newer than the one installed, so prefer whatever is on disk. If the running app refuses your plugin over `hostApi`, you read the docs for a different host.
Delegate the reading to `clodex-plugin-builder:api-scout` rather than pulling the whole contract into your own context. Ask it for the specific sections your plugin needs; it returns the rules and the signatures, not the prose.
`plugin-api.md` is ~2,000 lines and sectioned. **Do not read it end to end** — send the scout to the section:
| Building | Section | |---|---| | Deciding whether this should be a plugin at all | `what-plugins-can-do.md`, whole — it is short | | The manifest, and why one gets refused | §2 | | Per-seat visibility, `scope`, capability grants | §2.1 | | The engine `host` object | §4 | | Session hooks, the turn-text feed | §4 (`sessions`) | | Any UI at all — seven slots, one subsection each | §6 | | A button plus an overlay plus reading files | §6.3, §6.7, §8 | | An `[agent:…]` verb | §7, then `host.intents` in §4 | | Talking between your halves | §8 (`invoke`) | | Engine → renderer events | §9 | | Enable, disable, failure, quarantine | §10 | | **What you may not reach** | §13 — read before designing, not after | | Known gaps and unspecified behaviour | §14 |
Three shipped plugins are better than any summary, and a checkout has them: **git-branches** (row badge + settings panel + a verb), **memory-viewer** (footer button + overlay + `invoke` for filesystem work — the commonest shape) and **workbench** (a full overlay application). Read the one whose shape matches what you are building.
Step 1 — decide the shape
Ask, if the user has not said:
- **What should it DO** for the operator or for agents?
- **Where should it appear** — a sidebar button, a status-bar readout, a badge
on session rows, a full overlay, a settings panel?
- **Does an agent need to reach it** — an `[agent:…]` verb?
- **Does it need code at all?**
That last one first, because it changes everything. **Three complete shapes**, and picking the smallest one that works is most of the job:
- **Content only** — `skills/`, `agents/`, `prompts/`, `templates/` and no
JavaScript at all. `"entry": {}` is legal when the directory carries a content bundle. If what the user wants is a skill and some subagents, build that and stop; do not add an engine in order to have one.
- **Engine only** — a verb, a session hook, or a feed subscriber with no UI.
A normal, complete plugin; the renderer half is optional.
- **Both halves** — anything the operator has to see or click.
A renderer half with no engine is legal too, but rare: it can only draw, so it has nothing to draw *from*.
Step 2 — the manifest
{
"id": "my-plugin",
"name": "My Plugin",
"version": "0.1.0",
"hostApi": "1",
"scope": "session",
"entry": { "engine": "engine.js", "renderer": "renderer.js" },
"style": "style.css",
"surfaces": { "index": "any", "doc": "any" },
"enabledByDefault": false,
"announce": "One sentence. Shown in Manage Plugins AND as the skill's description in Claude Code."
}Rules that refuse a manifest outright, so get them right first:
- **The folder name must equal `id`.** Lowercase, digits and hyphens, starting
and ending alphanumeric, 1–40 characters. `enabled` is reserved and refused, as is any id a built-in plugin already uses.
- **`hostApi` is the string `"1"`.** Required — an absent one is refused, not
defaulted.
- **`entry` must be an object**, even when empty.
- **`scope`, if present, is exactly `"global"` or `"session"`.** `"Session"` is
a refusal. Add `scope: "session"` **only** if the plugin consumes a capability grant (today: the turn-text feed). It no longer controls visibility — a seat's plugin list does that.
- Entry and `style` paths must stay inside the plugin folder.
- **If the plugin has a renderer half, it needs a `surfaces` table.** See Step 3a
— this is the one field whose default costs you reach rather than granting it, and forgetting it is the commonest way a working plugin is broken in the browser.
- **`announce` and `version` are read twice.** If the plugin ships a `skills/` or
`agents/` bundle, Clodex generates a `.claude-plugin/plugin.j
Read more
description: Build a Clodex plugin end to end - scaffold it, wire the surfaces it needs, and verify it against the real loader. Usage - /clodex-plugin-builder:create-plugin <id> [what it should do]
Build a Clodex plugin
You are building a plugin for Clodex, the app you are running inside. This skill carries the facts that are expensive to rediscover; the authority is the contract, and where they disagree the contract wins.
Step 0 — find the contract
A Clodex **checkout** carries the contract. The installed app does not give you one you can read: its copy is inside the app archive, which your shell cannot list. So look for a checkout first:
find ~/projects /Applications -maxdepth 4 -name plugin-api.md -path '*plugins*' 2>/dev/null | head -3
A checkout also carries the author tools, and they are the fastest path by a wide margin:
node plugins/tools/build-context.js /tmp/plugin-context.md # the full pack node plugins/tools/scaffold.js <id> <target-dir> # a plugin that already passes node plugins/tools/verify.js <dir> # run it against the REAL loader
**If `verify.js` exists, you must use it** — it loads the plugin through the host's own loader, so it catches what reading cannot.
With no checkout, fetch the four docs from the public repo, and say in your final message that the plugin is unverified — nothing ran it:
https://raw.githubusercontent.com/avirtual/clodex/master/plugins/plugin-api.md https://raw.githubusercontent.com/avirtual/clodex/master/plugins/what-plugins-can-do.md https://raw.githubusercontent.com/avirtual/clodex/master/plugins/plugin-sources.md https://raw.githubusercontent.com/avirtual/clodex/master/plugins/README.md
`master` may describe a Clodex newer than the one installed, so prefer whatever is on disk. If the running app refuses your plugin over `hostApi`, you read the docs for a different host.
Delegate the reading to `clodex-plugin-builder:api-scout` rather than pulling the whole contract into your own context. Ask it for the specific sections your plugin needs; it returns the rules and the signatures, not the prose.
`plugin-api.md` is ~2,000 lines and sectioned. **Do not read it end to end** — send the scout to the section:
| Building | Section | |---|---| | Deciding whether this should be a plugin at all | `what-plugins-can-do.md`, whole — it is short | | The manifest, and why one gets refused | §2 | | Per-seat visibility, `scope`, capability grants | §2.1 | | The engine `host` object | §4 | | Session hooks, the turn-text feed | §4 (`sessions`) | | Any UI at all — seven slots, one subsection each | §6 | | A button plus an overlay plus reading files | §6.3, §6.7, §8 | | An `[agent:…]` verb | §7, then `host.intents` in §4 | | Talking between your halves | §8 (`invoke`) | | Engine → renderer events | §9 | | Enable, disable, failure, quarantine | §10 | | **What you may not reach** | §13 — read before designing, not after | | Known gaps and unspecified behaviour | §14 |
Three shipped plugins are better than any summary, and a checkout has them: **git-branches** (row badge + settings panel + a verb), **memory-viewer** (footer button + overlay + `invoke` for filesystem work — the commonest shape) and **workbench** (a full overlay application). Read the one whose shape matches what you are building.
Step 1 — decide the shape
Ask, if the user has not said:
- **What should it DO** for the operator or for agents?
- **Where should it appear** — a sidebar button, a status-bar readout, a badge
on session rows, a full overlay, a settings panel?
- **Does an agent need to reach it** — an `[agent:…]` verb?
- **Does it need code at all?**
That last one first, because it changes everything. **Three complete shapes**, and picking the smallest one that works is most of the job:
- **Content only** — `skills/`, `agents/`, `prompts/`, `templates/` and no
JavaScript at all. `"entry": {}` is legal when the directory carries a content bundle. If what the user wants is a skill and some subagents, build that and stop; do not add an engine in order to have one.
- **Engine only** — a verb, a session hook, or a feed subscriber with no UI.
A normal, complete plugin; the renderer half is optional.
- **Both halves** — anything the operator has to see or click.
A renderer half with no engine is legal too, but rare: it can only draw, so it has nothing to draw *from*.
Step 2 — the manifest
{
"id": "my-plugin",
"name": "My Plugin",
"version": "0.1.0",
"hostApi": "1",
"scope": "session",
"entry": { "engine": "engine.js", "renderer": "renderer.js" },
"style": "style.css",
"surfaces": { "index": "any", "doc": "any" },
"enabledByDefault": false,
"announce": "One sentence. Shown in Manage Plugins AND as the skill's description in Claude Code."
}Rules that refuse a manifest outright, so get them right first:
- **The folder name must equal `id`.** Lowercase, digits and hyphens, starting
and ending alphanumeric, 1–40 characters. `enabled` is reserved and refused, as is any id a built-in plugin already uses.
- **`hostApi` is the string `"1"`.** Required — an absent one is refused, not
defaulted.
- **`entry` must be an object**, even when empty.
- **`scope`, if present, is exactly `"global"` or `"session"`.** `"Session"` is
a refusal. Add `scope: "session"` **only** if the plugin consumes a capability grant (today: the turn-text feed). It no longer controls visibility — a seat's plugin list does that.
- Entry and `style` paths must stay inside the plugin folder.
- **If the plugin has a renderer half, it needs a `surfaces` table.** See Step 3a
— this is the one field whose default costs you reach rather than granting it, and forgetting it is the commonest way a working plugin is broken in the browser.
- **`announce` and `version` are read twice.** If the plugin ships a `skills/` or
`agents/` bundle, Clodex generates a `.claude-plugin/plugin.j
A session manager for fleets of coding agents. Clodex runs Claude Code and Codex sessions as terminals and adds three layers around them: a sidebar that shows the state of every session, a message bus that lets agents coordinate with each other, and a wire

