Plugin Creator
Quick Start
- •Run the scaffold script:
# Plugin names are normalized to lower-case hyphen-case and must be <= 64 chars. # The generated folder and plugin.json name are always the same. # Run from repo root (or replace .agents/... with the absolute path to this SKILL). # By default creates in <repo_root>/plugins/<plugin-name>. python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py <plugin-name>
- •
Open
<plugin-path>/.codex-plugin/plugin.jsonand replace[TODO: ...]placeholders. - •
Generate or update the repo marketplace entry when the plugin should appear in Codex UI ordering:
# marketplace.json always lives at <repo-root>/.agents/plugins/marketplace.json python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin --with-marketplace
For a home-local plugin, treat <home> as the root and use:
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin \ --path ~/plugins \ --marketplace-path ~/.agents/plugins/marketplace.json \ --with-marketplace
- •Generate/adjust optional companion folders as needed:
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin --path <parent-plugin-directory> \ --with-skills --with-hooks --with-scripts --with-assets --with-mcp --with-apps --with-marketplace
<parent-plugin-directory> is the directory where the plugin folder <plugin-name> will be created (for example ~/code/plugins).
What this skill creates
- •If the user has not made the plugin location explicit, ask whether they want a repo-local plugin or a home-local plugin before generating marketplace entries.
- •Creates plugin root at
/<parent-plugin-directory>/<plugin-name>/. - •Always creates
/<parent-plugin-directory>/<plugin-name>/.codex-plugin/plugin.json. - •Fills the manifest with the full schema shape, placeholder values, and the complete
interfacesection. - •Creates or updates
<repo-root>/.agents/plugins/marketplace.jsonwhen--with-marketplaceis set.- •If the marketplace file does not exist yet, seed top-level
nameplusinterface.displayNameplaceholders before adding the first plugin entry.
- •If the marketplace file does not exist yet, seed top-level
- •
<plugin-name>is normalized using skill-creator naming rules:- •
My Plugin→my-plugin - •
My--Plugin→my-plugin - •underscores, spaces, and punctuation are converted to
- - •result is lower-case hyphen-delimited with consecutive hyphens collapsed
- •
- •Supports optional creation of:
- •
skills/ - •
hooks/ - •
scripts/ - •
assets/ - •
.mcp.json - •
.app.json
- •
Marketplace workflow
- •
marketplace.jsonalways lives at<repo-root>/.agents/plugins/marketplace.json. - •For a home-local plugin, use the same convention with
<home>as the root:~/.agents/plugins/marketplace.jsonplus./plugins/<plugin-name>. - •Marketplace root metadata supports top-level
nameplus optionalinterface.displayName. - •Treat plugin order in
plugins[]as render order in Codex. Append new entries unless a user explicitly asks to reorder the list. - •
displayNamebelongs inside the marketplaceinterfaceobject, not individualplugins[]entries. - •Each generated marketplace entry must include all of:
- •
policy.installation - •
policy.authentication - •
category
- •
- •Default new entries to:
- •
policy.installation: "AVAILABLE" - •
policy.authentication: "ON_INSTALL"
- •
- •Override defaults only when the user explicitly specifies another allowed value.
- •Allowed
policy.installationvalues:- •
NOT_AVAILABLE - •
AVAILABLE - •
INSTALLED_BY_DEFAULT
- •
- •Allowed
policy.authenticationvalues:- •
ON_INSTALL - •
ON_USE
- •
- •Treat
policy.productsas an override. Omit it unless the user explicitly requests product gating. - •The generated plugin entry shape is:
{
"name": "plugin-name",
"source": {
"source": "local",
"path": "./plugins/plugin-name"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
- •
Use
--forceonly when intentionally replacing an existing marketplace entry for the same plugin name. - •
If
<repo-root>/.agents/plugins/marketplace.jsondoes not exist yet, create it with top-level"name", an"interface"object containing"displayName", and apluginsarray, then add the new entry. - •
For a brand-new marketplace file, the root object should look like:
{
"name": "[TODO: marketplace-name]",
"interface": {
"displayName": "[TODO: Marketplace Display Name]"
},
"plugins": [
{
"name": "plugin-name",
"source": {
"source": "local",
"path": "./plugins/plugin-name"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Productivity"
}
]
}
Required behavior
- •Outer folder name and
plugin.json"name"are always the same normalized plugin name. - •Do not remove required structure; keep
.codex-plugin/plugin.jsonpresent. - •Keep manifest values as placeholders until a human or follow-up step explicitly fills them.
- •If creating files inside an existing plugin path, use
--forceonly when overwrite is intentional. - •Preserve any existing marketplace
interface.displayName. - •When generating marketplace entries, always write
policy.installation,policy.authentication, andcategoryeven if their values are defaults. - •Add
policy.productsonly when the user explicitly asks for that override. - •Keep marketplace
source.pathrelative to repo root as./plugins/<plugin-name>.
Reference to exact spec sample
For the exact canonical sample JSON for both plugin manifests and marketplace entries, use:
- •
references/plugin-json-spec.md
Validation
After editing SKILL.md, run:
python3 <path-to-skill-creator>/scripts/quick_validate.py .agents/skills/plugin-creator