Skip to content

Commit 5fc454e

Browse files
authored
feat(plugin-dev): unify plugin creation across runtimes with multi-format (#252)
* feat(plugin-dev): add multi-format command and unify plugin creation across runtimes - add /plugin-dev:multi-format command wrapping the Codex/Antigravity/Cursor manifest generator - add plugin-authoring skill teaching the author-once → multi-format workflow - chain /plugin-dev:scaffold into the multi-format generator so a new plugin loads in all four runtimes - bump plugin-dev to 1.1.0 and regenerate Codex/Cursor manifests * chore(plugin-dev): apply AI code review suggestions * chore: update agent memory
1 parent ca50a8a commit 5fc454e

10 files changed

Lines changed: 272 additions & 9 deletions

File tree

.claude/agent-memory/review-review-cubic-reviewer/MEMORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
- [Graphite please-config opt-in review (PR #181)](pr181-graphite-please-config-opt-in.md) — cubic clean pass (0 issues); AWK YAML parser tightened to match `enabled: true` only at direct-child indent level of `graphite:`
99
- [PortOne plugin review (PR #184)](pr184-portone-plugin.md) — initial pass: P1 misleading `express.raw()` note, P2 false positive on named import; follow-up uncommitted edit (Express 4 `next(e)` fix) → cubic clean (0 issues)
1010
- [Graphite awk state-reset fix (PR #189)](pr189-graphite-awk-state-reset.md) — cubic clean pass (0 issues); state-leakage fix in graphite-context.sh awk parser
11+
- [plugin-dev docs review (PR #252)](pr252-plugin-dev-docs.md) — cubic clean pass (0 issues); reviewed uncommitted changes with plain `-j`, overriding default `-b` per task context
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: pr252-plugin-dev-docs
3+
description: cubic review of PR #252 docs-only changes to plugin-dev plugin (scaffold.md, multi-format.md, SKILL.md)
4+
metadata:
5+
type: project
6+
---
7+
8+
PR #252 applied AI review suggestions to 3 markdown files in `plugins/plugin-dev/`
9+
(`commands/scaffold.md`, `commands/multi-format.md`, `skills/plugin-authoring/SKILL.md`).
10+
Reviewed via `cubic review -j` against uncommitted working-tree changes (not `-b`),
11+
since the task explicitly requested reviewing local uncommitted changes rather than a
12+
full base-branch diff. Result: 0 issues (clean pass).
13+
14+
**Why:** Confirms cubic can be pointed at uncommitted changes even when
15+
`REVIEW_CUBIC_DEFAULT_FLAGS` defaults to `-b`; when the invoking context explicitly says
16+
"review local uncommitted changes," override the configured default and drop `-b`.
17+
18+
**How to apply:** For future docs-only or small doc-tweak PRs in this repo, prefer
19+
plain `cubic review -j` (uncommitted diff) when the task description says so, even if
20+
`.please/config.yml` sets `-b` as the default flag.

plugins/plugin-dev/.codex-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "plugin-dev",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"description": "Best practices, guidelines, and validation tools for Claude Code plugin development",
55
"author": {
66
"name": "Passion Factory",

plugins/plugin-dev/.cursor-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "plugin-dev",
33
"displayName": "Plugin Dev",
44
"description": "Best practices, guidelines, and validation tools for Claude Code plugin development",
5-
"version": "1.0.0",
5+
"version": "1.1.0",
66
"author": {
77
"name": "Passion Factory"
88
},

plugins/plugin-dev/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ All notable changes to the plugin-dev plugin will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.1.0] - 2026-07-07
9+
10+
### Added
11+
- `/plugin-dev:multi-format` command — generate Codex, Antigravity, and Cursor manifests from the Claude Code source of truth
12+
- `plugin-authoring` skill — teaches the author-once → multi-format workflow so the plugin is self-contained across runtimes
13+
14+
### Changed
15+
- `/plugin-dev:scaffold` now chains into the multi-format generator so a new plugin loads in all four runtimes in one flow
16+
817
## [1.0.0] - 2025-10-17
918

1019
### Added

plugins/plugin-dev/README.md

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Best practices, guidelines, and validation tools for Claude Code plugin developm
1111
- 🎯 **Best Practices Guidance** - Expert advice on plugin development
1212
-**Plugin Validation** - Automated manifest and structure validation
1313
- 🏗️ **Plugin Scaffolding** - Quick-start templates for new plugins
14+
- 🌐 **Multi-Runtime Manifests** - Author once in Claude Code format, generate Codex, Antigravity, and Cursor manifests
1415
- 🔄 **Gemini Migration** - Tools to migrate Gemini CLI extensions
1516
- 🔍 **Real-time Validation** - Automatic validation when editing plugin files
1617

@@ -84,6 +85,27 @@ Generate a new plugin with proper structure and best practices baked in.
8485
I need a new plugin called "api-tools" that provides commands for API testing
8586
```
8687

88+
### `/plugin-dev:multi-format`
89+
90+
Generate the Codex, Antigravity, and Cursor manifests for the marketplace's local plugins from the
91+
Claude Code source of truth. The Claude manifest is the only file you author by hand — this command
92+
keeps every runtime in sync.
93+
94+
**Generates (per local plugin):**
95+
- `.codex-plugin/plugin.json` (+ `.mcp.json` when MCP is present)
96+
- root `plugin.json` + `mcp_config.json` + `hooks.json` (Antigravity)
97+
- `.cursor-plugin/plugin.json`
98+
- `.agents/plugins/marketplace.json` and `.cursor-plugin/marketplace.json`
99+
100+
**Example:**
101+
```
102+
/plugin-dev:multi-format
103+
104+
I just edited plugins/api-tools — regenerate its Codex and Cursor manifests
105+
```
106+
107+
> The generator rewrites all local plugins; scope your commit to the plugin(s) you changed.
108+
87109
### `/plugin-dev:migrate-gemini`
88110

89111
Migrate existing Gemini CLI extensions to Claude Code plugins.
@@ -182,24 +204,29 @@ plugin-name/
182204
- Create agents in `agents/`
183205
- Configure hooks in `hooks/`
184206

185-
3. **Validate continuously**
207+
3. **Generate multi-runtime manifests**
208+
```bash
209+
/plugin-dev:multi-format
210+
```
211+
212+
4. **Validate continuously**
186213
```bash
187214
/plugin-dev:validate
188215
```
189216

190-
4. **Test locally**
217+
5. **Test locally**
191218
```bash
192219
claude --debug
193220
/plugin list
194221
/your-plugin:command
195222
```
196223

197-
5. **Version and document**
224+
6. **Version and document**
198225
- Update version in plugin.json
199226
- Document changes in CHANGELOG.md
200227
- Update README with new features
201228

202-
6. **Publish**
229+
7. **Publish**
203230
- Add to marketplace
204231
- Tag release in git
205232
- Share with community
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Generate Multi-Runtime Manifests
2+
3+
You are a multi-runtime plugin packaging expert. Generate the Codex, Antigravity, and Cursor
4+
manifests for the marketplace's local plugins from the Claude Code source of truth, keeping every
5+
runtime in sync.
6+
7+
## Background
8+
9+
This repository ships the **same plugin set across four runtimes**. The Claude Code manifest is the
10+
**single source of truth**; the others are **generated** and must never be hand-edited.
11+
12+
| Runtime | Manifest path | Companion files |
13+
|--------------|----------------------------------------|---------------------------------------|
14+
| Claude Code | `.claude-plugin/plugin.json` (or root `plugin.json`) | `hooks/hooks.json`, inline `mcpServers` |
15+
| Codex | `.codex-plugin/plugin.json` | `.mcp.json` (when MCP present) |
16+
| Antigravity | `plugin.json` (root) | `mcp_config.json`, root `hooks.json` |
17+
| Cursor | `.cursor-plugin/plugin.json` | none — components auto-discovered |
18+
19+
Shared assets (`commands/`, `agents/`, `skills/`, `hooks/`) live once at the plugin root and are
20+
referenced by every manifest. Only manifest-level fields differ per runtime.
21+
22+
## Your Task
23+
24+
### 1. Run the generator
25+
26+
> **New plugin? Wire its `.claude-plugin/marketplace.json` entry first.** The generator resolves
27+
> each plugin's metadata (notably `category`) from the marketplace entry. A plugin dir not yet
28+
> listed there is generated with no entry — its Codex manifest falls back to the default category
29+
> and it is omitted from the emitted Codex/Cursor marketplace files. Add the entry, then run:
30+
31+
```bash
32+
bun scripts/cli.ts multi-format
33+
```
34+
35+
For every local plugin (`source: "./plugins/..."` in `.claude-plugin/marketplace.json`) this emits:
36+
37+
- `plugins/<name>/.codex-plugin/plugin.json` (+ `.mcp.json` when the plugin defines `mcpServers`)
38+
- `plugins/<name>/plugin.json` + `mcp_config.json` + root `hooks.json` (Antigravity)
39+
- `plugins/<name>/.cursor-plugin/plugin.json`
40+
- `.agents/plugins/marketplace.json` (Codex marketplace, local plugins only)
41+
- `.cursor-plugin/marketplace.json` (Cursor marketplace, local plugins only)
42+
43+
The generator only writes files whose content actually changed, and prints per-plugin status
44+
(`wrote N file(s)` / `up to date` / `skipped`).
45+
46+
### 2. Scope the diff to your change
47+
48+
⚠️ **`multi-format` rewrites all local plugins, not just the one you touched.** If the committed
49+
artifacts had pre-existing drift, the command produces a large unrelated diff. Keep the change
50+
atomic:
51+
52+
```bash
53+
git status --short
54+
# Revert churn from plugins you did NOT intend to change:
55+
git restore plugins/<other-plugin>/...
56+
```
57+
58+
Commit only the files for the plugin(s) you actually changed.
59+
60+
### 3. Claude-only fields do not propagate
61+
62+
Fields that exist only in the Claude runtime — notably `relevance` (plugin suggestion signals) — are
63+
intentionally **not** copied to the Codex/Cursor marketplaces. Author them only in
64+
`.claude-plugin/marketplace.json`.
65+
66+
### 4. Verify
67+
68+
```bash
69+
claude plugin validate .claude-plugin/marketplace.json
70+
claude plugin validate plugins/<name>
71+
```
72+
73+
## When to Run
74+
75+
- After scaffolding a new plugin (`/plugin-dev:scaffold`)
76+
- After editing any plugin's Claude manifest (name, version, description, `mcpServers`, hooks)
77+
- After adding, removing, or reordering a plugin entry in `.claude-plugin/marketplace.json`
78+
79+
Do **not** hand-edit `.codex-plugin/`, `.cursor-plugin/`, root Antigravity `plugin.json`, or the
80+
generated marketplaces — re-run this command instead.
81+
82+
Now, run the generator, scope the diff to the intended plugin(s), and report what changed.

plugins/plugin-dev/commands/scaffold.md

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
# Scaffold New Plugin
22

3-
You are a plugin scaffolding expert. Help users create a new Claude Code plugin with proper structure and best practices.
3+
You are a plugin scaffolding expert. Help users create a new plugin with proper structure and best practices.
4+
5+
Author the plugin **once in Claude Code format** (the source of truth), then generate the
6+
Codex / Antigravity / Cursor manifests from it in a single step. One directory, four runtimes —
7+
you never hand-write the other manifests.
48

59
## Your Task
610

7-
Create a complete plugin structure based on user requirements. Ask clarifying questions if needed, then generate all necessary files.
11+
Create a complete plugin structure based on user requirements. Ask clarifying questions if needed,
12+
generate all necessary files in Claude Code format, then run the multi-format generator so the same
13+
directory loads in Codex, Antigravity, and Cursor too.
814

915
## Scaffolding Process
1016

@@ -192,6 +198,44 @@ All notable changes to this project will be documented in this file.
192198
- Feature 2
193199
```
194200

201+
### 10. Wire the Marketplace Entry, Then Generate Multi-Runtime Manifests
202+
203+
The plugin is authored in Claude Code format (`.claude-plugin/plugin.json`, or a root-level
204+
`plugin.json` for plugins that also serve as the Antigravity manifest). This is the **source of
205+
truth** — never hand-write the other runtimes' manifests; generate them instead.
206+
207+
**Order matters — wire the marketplace entry _first_.** The generator resolves each plugin's
208+
metadata (notably `category`) from `.claude-plugin/marketplace.json`. A plugin dir that is not yet
209+
listed there is generated with no entry, so its Codex manifest falls back to the default category
210+
and it is omitted from the emitted Codex/Cursor marketplace files. So for a brand-new plugin, wire
211+
the companion files described in `.claude/rules/marketplace-sync.md` **before** running the
212+
generator:
213+
214+
1. Add the marketplace entry to `.claude-plugin/marketplace.json` (source of truth).
215+
2. If the plugin is release-managed, add a `plugins/<name>` entry to `release-please-config.json`
216+
+ `.release-please-manifest.json` covering every version-bearing manifest the plugin ships.
217+
218+
Then generate the other runtimes' manifests in a single pass:
219+
220+
```bash
221+
bun scripts/cli.ts multi-format
222+
```
223+
224+
This reads the Claude manifest + the marketplace entry and emits, for every local plugin
225+
(`source: "./plugins/..."`):
226+
227+
- `plugins/<name>/.codex-plugin/plugin.json` (+ `.mcp.json` when the plugin defines `mcpServers`)
228+
- `plugins/<name>/plugin.json` + `mcp_config.json` + root `hooks.json` (Antigravity)
229+
- `plugins/<name>/.cursor-plugin/plugin.json`
230+
- `.agents/plugins/marketplace.json` (Codex marketplace) and `.cursor-plugin/marketplace.json` (Cursor marketplace)
231+
232+
Shared assets (`commands/`, `agents/`, `skills/`, `hooks/`) live **once** at the plugin root and
233+
are referenced by every manifest — only manifest-level fields differ per runtime.
234+
235+
> **This command rewrites all local plugins, not just the new one.** If unrelated plugins show up
236+
> in the diff (pre-existing drift), `git restore` those files and commit only the new plugin's
237+
> artifacts so the change stays atomic. See `/plugin-dev:multi-format` for the dedicated wrapper.
238+
195239
## After Scaffolding
196240

197241
1. **Validate structure** using `/plugin-dev:validate`

plugins/plugin-dev/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "plugin-dev",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"description": "Best practices, guidelines, and validation tools for Claude Code plugin development",
55
"author": {
66
"name": "Passion Factory",
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
name: Authoring Plugins (Multi-Runtime)
3+
description: Author a plugin once in Claude Code format, then generate Codex, Antigravity, and Cursor manifests from it so one directory loads in all four runtimes. Use when creating, scaffolding, or editing a plugin in this marketplace, wiring a marketplace entry, running the multi-format generator, or when the user mentions "plugin.json", ".claude-plugin", ".codex-plugin", ".cursor-plugin", "multi-format", "marketplace.json", or "Codex/Cursor/Antigravity plugin".
4+
---
5+
6+
# Plugin Authoring — Multi-Runtime
7+
8+
This marketplace ships the **same plugin directory across four runtimes**. You author **once** in
9+
Claude Code format (the source of truth) and **generate** the rest. Never hand-write the Codex,
10+
Antigravity, or Cursor manifests.
11+
12+
## The one rule: edit Claude → generate the rest
13+
14+
```
15+
.claude-plugin/plugin.json (or root plugin.json) ← author here, source of truth
16+
17+
│ bun scripts/cli.ts multi-format
18+
19+
.codex-plugin/plugin.json + .mcp.json ← generated
20+
plugin.json (root) + mcp_config.json + hooks.json ← generated (Antigravity)
21+
.cursor-plugin/plugin.json ← generated
22+
.agents/plugins/marketplace.json ← generated (Codex marketplace)
23+
.cursor-plugin/marketplace.json ← generated (Cursor marketplace)
24+
```
25+
26+
Shared assets (`commands/`, `agents/`, `skills/`, `hooks/`) live **once** at the plugin root and are
27+
referenced by every manifest. Only manifest-level fields differ per runtime.
28+
29+
## Workflow
30+
31+
1. **Scaffold / edit** the plugin in Claude Code format — run `/plugin-dev:scaffold` for a new one.
32+
Components go at the plugin **root**, never inside `.claude-plugin/`:
33+
```
34+
plugins/<name>/
35+
├── .claude-plugin/plugin.json # manifest only (or root plugin.json — see below)
36+
├── commands/ # at root
37+
├── agents/ # at root
38+
├── skills/ # at root
39+
└── hooks/hooks.json # at root
40+
```
41+
2. **Register** in the source-of-truth marketplace `.claude-plugin/marketplace.json`
42+
(`source: "./plugins/<name>"`). Claude-only fields like `relevance` live **only** here.
43+
3. **Generate** the other runtimes: `/plugin-dev:multi-format` (or `bun scripts/cli.ts multi-format`).
44+
4. **Scope the diff** — the generator rewrites *all* local plugins; `git restore` any unrelated
45+
churn so the commit stays atomic.
46+
5. **Validate**: `/plugin-dev:validate`, then `claude plugin validate plugins/<name>`.
47+
48+
## Root-level `plugin.json` plugins
49+
50+
A few plugins (e.g. `plugin-dev`, `bun`) use a **root** `plugin.json` that serves as *both* the
51+
Claude Code manifest *and* the Antigravity manifest. Edit that root file as the source of truth;
52+
`multi-format` still regenerates `.codex-plugin/` and `.cursor-plugin/` from it.
53+
54+
## Companion files for a NEW plugin
55+
56+
Wire these in the same change (see `.claude/rules/marketplace-sync.md`):
57+
58+
- `.claude-plugin/marketplace.json` — add the plugin entry (source of truth).
59+
- `release-please-config.json` + `.release-please-manifest.json` — add a `plugins/<name>` entry
60+
covering **every** version-bearing manifest the plugin ships (`.claude-plugin/plugin.json` and,
61+
when multi-format generates them, `.codex-plugin/plugin.json` + root `plugin.json` +
62+
`.cursor-plugin/plugin.json`). *Only if the plugin is release-managed.*
63+
- `README.md` — add the plugin under **Built-in Plugins**.
64+
65+
## What NOT to do
66+
67+
- ❌ Hand-edit `.codex-plugin/`, `.cursor-plugin/`, generated root Antigravity `plugin.json`, or the
68+
Codex/Cursor `marketplace.json` — re-run `multi-format`.
69+
- ❌ Put `relevance` (or other Claude-only fields) in the Codex/Cursor marketplaces — the generator
70+
intentionally drops them.
71+
- ❌ Nest `commands/` / `agents/` / `skills/` inside `.claude-plugin/` — they won't load.
72+
73+
## Related
74+
75+
- Deep Claude Code component reference (commands, agents, skills, hooks, MCP, Gemini migration):
76+
the `claude-code-plugin-builder` skill.
77+
- Codex-native creation (inside Codex): the `plugin-creator` skill.
78+
- Cursor-native creation (inside Cursor): the `create-plugin-scaffold` skill.
79+
- Commands: `/plugin-dev:scaffold`, `/plugin-dev:multi-format`, `/plugin-dev:validate`,
80+
`/plugin-dev:migrate-gemini`, `/plugin-dev:best-practices`.

0 commit comments

Comments
 (0)