mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat(skills): default plugin creator to personal share flow (#22221)
## Summary Plugin creation now defaults to the personal marketplace path and ends with a readable handoff back into Codex after a marketplace-backed scaffold. Before this change, `plugin-creator` centered repo-local marketplace updates and did not clearly guide the agent to return the user to the created plugin afterward. This PR updates the bundled system skill so marketplace-backed scaffolds default to `~/plugins/<plugin-name>` plus `~/.agents/plugins/marketplace.json`, ask for user intent only when an existing repo marketplace makes personal vs team scope ambiguous, and end with named Markdown deeplinks labeled `View <plugin-name>` and `Share <plugin-name>`. ## What changed - default marketplace-backed creation to the personal plugin location - document the explicit repo/team override path for codebases that should own the plugin entry - ask personal vs team only when the current Git repo already has `.agents/plugins/marketplace.json` and the user has not stated scope - require named Markdown deeplinks after marketplace-backed creation so the final response returns the user to the exact plugin cleanly - keep the deeplink targets precise with real absolute `marketplacePath` and normalized `pluginName` values - align the bundled prompt, scaffold help text, and marketplace reference spec with the new default ## Testing Tests: targeted skill validation, Python compile checks, personal-default scaffold smoke, repo-override scaffold smoke, and whitespace checks.
This commit is contained in:
committed by
GitHub
Unverified
parent
ed5944ba1d
commit
fd24c00b0b
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: plugin-creator
|
||||
description: Create and scaffold plugin directories for Codex with a required `.codex-plugin/plugin.json`, optional plugin folders/files, and baseline placeholders you can edit before publishing or testing. Use when Codex needs to create a new local plugin, add optional plugin structure, or generate or update repo-root `.agents/plugins/marketplace.json` entries for plugin ordering and availability metadata.
|
||||
description: Create and scaffold plugin directories for Codex with a required `.codex-plugin/plugin.json`, optional plugin folders/files, and baseline placeholders you can edit before publishing or testing. Use when Codex needs to create a new personal plugin, add optional plugin structure, or generate or update personal or repo-root `.agents/plugins/marketplace.json` entries for plugin ordering and availability metadata.
|
||||
---
|
||||
|
||||
# Plugin Creator
|
||||
@@ -13,32 +13,36 @@ description: Create and scaffold plugin directories for Codex with a required `.
|
||||
# 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>.
|
||||
# By default creates in ~/plugins/<plugin-name>.
|
||||
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py <plugin-name>
|
||||
```
|
||||
|
||||
2. Open `<plugin-path>/.codex-plugin/plugin.json` and replace `[TODO: ...]` placeholders.
|
||||
|
||||
3. Generate or update the repo marketplace entry when the plugin should appear in Codex UI ordering:
|
||||
3. Generate or update the personal marketplace entry when the plugin should appear in Codex UI ordering:
|
||||
|
||||
```bash
|
||||
# marketplace.json always lives at <repo-root>/.agents/plugins/marketplace.json
|
||||
# Personal marketplace entries default to ~/.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:
|
||||
If the current Git repo already has `.agents/plugins/marketplace.json` and the user has not said
|
||||
whether the plugin is personal or shared with their team, ask before generating a marketplace entry.
|
||||
When they choose the repo marketplace, use:
|
||||
|
||||
```bash
|
||||
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin \
|
||||
--path ~/plugins \
|
||||
--marketplace-path ~/.agents/plugins/marketplace.json \
|
||||
--path ./plugins \
|
||||
--marketplace-path ./.agents/plugins/marketplace.json \
|
||||
--with-marketplace
|
||||
```
|
||||
|
||||
4. Generate/adjust optional companion folders as needed:
|
||||
|
||||
```bash
|
||||
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin --path <parent-plugin-directory> \
|
||||
python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin \
|
||||
--path <parent-plugin-directory> \
|
||||
--marketplace-path <marketplace-json-path> \
|
||||
--with-skills --with-hooks --with-scripts --with-assets --with-mcp --with-apps --with-marketplace
|
||||
```
|
||||
|
||||
@@ -46,11 +50,14 @@ python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin -
|
||||
|
||||
## 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.
|
||||
- Default marketplace-backed scaffolds are personal: `~/plugins/<plugin-name>/` plus
|
||||
`~/.agents/plugins/marketplace.json`.
|
||||
- If the current Git repo already has `.agents/plugins/marketplace.json` and the user has not said
|
||||
personal vs team, ask which marketplace to update before generating a marketplace entry.
|
||||
- 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 `interface` section.
|
||||
- Creates or updates `<repo-root>/.agents/plugins/marketplace.json` when `--with-marketplace` is set.
|
||||
- Creates or updates the selected marketplace when `--with-marketplace` is set.
|
||||
- If the marketplace file does not exist yet, seed top-level `name` plus `interface.displayName` placeholders before adding the first plugin entry.
|
||||
- `<plugin-name>` is normalized using skill-creator naming rules:
|
||||
- `My Plugin` → `my-plugin`
|
||||
@@ -67,9 +74,8 @@ python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin -
|
||||
|
||||
## Marketplace workflow
|
||||
|
||||
- `marketplace.json` always 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.json` plus `./plugins/<plugin-name>`.
|
||||
- Personal plugins use `~/.agents/plugins/marketplace.json`.
|
||||
- Repo/team plugins use `<repo-root>/.agents/plugins/marketplace.json`.
|
||||
- Marketplace root metadata supports top-level `name` plus optional `interface.displayName`.
|
||||
- Treat plugin order in `plugins[]` as render order in Codex. Append new entries unless a user explicitly asks to reorder the list.
|
||||
- `displayName` belongs inside the marketplace `interface` object, not individual `plugins[]` entries.
|
||||
@@ -107,7 +113,7 @@ python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin -
|
||||
```
|
||||
|
||||
- Use `--force` only when intentionally replacing an existing marketplace entry for the same plugin name.
|
||||
- If `<repo-root>/.agents/plugins/marketplace.json` does not exist yet, create it with top-level `"name"`, an `"interface"` object containing `"displayName"`, and a `plugins` array, then add the new entry.
|
||||
- If the selected marketplace file does not exist yet, create it with top-level `"name"`, an `"interface"` object containing `"displayName"`, and a `plugins` array, then add the new entry.
|
||||
|
||||
- For a brand-new marketplace file, the root object should look like:
|
||||
|
||||
@@ -143,7 +149,16 @@ python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin -
|
||||
- Preserve any existing marketplace `interface.displayName`.
|
||||
- When generating marketplace entries, always write `policy.installation`, `policy.authentication`, and `category` even if their values are defaults.
|
||||
- Add `policy.products` only when the user explicitly asks for that override.
|
||||
- Keep marketplace `source.path` relative to repo root as `./plugins/<plugin-name>`.
|
||||
- Keep marketplace `source.path` relative to the selected marketplace root as `./plugins/<plugin-name>`.
|
||||
- When the workflow created or updated a marketplace-backed plugin, end the final user-facing
|
||||
response with these two Markdown links, in this order, and do not add any text after them:
|
||||
- `[View <normalized plugin name>](codex://plugins/view-local?marketplacePath=<absolute marketplace.json path>&pluginName=<normalized plugin name>)`
|
||||
- `[Share <normalized plugin name>](codex://plugins/share-local?marketplacePath=<absolute marketplace.json path>&pluginName=<normalized plugin name>)`
|
||||
- Replace the link-label placeholder and both deeplink placeholders with the real normalized plugin
|
||||
name plus the real absolute marketplace path from the scaffolded plugin. URL-encode query
|
||||
parameter values when needed.
|
||||
- Do not emit the `View <normalized plugin name>` or `Share <normalized plugin name>` links when no marketplace entry was
|
||||
created or updated.
|
||||
|
||||
## Reference to exact spec sample
|
||||
|
||||
|
||||
@@ -99,8 +99,8 @@
|
||||
|
||||
`marketplace.json` depends on where the plugin should live:
|
||||
|
||||
- Repo plugin: `<repo-root>/.agents/plugins/marketplace.json`
|
||||
- Local plugin: `~/.agents/plugins/marketplace.json`
|
||||
- Personal plugin: `~/.agents/plugins/marketplace.json`
|
||||
- Repo/team plugin: `<repo-root>/.agents/plugins/marketplace.json`
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -143,9 +143,9 @@
|
||||
- `source` (`object`): Plugin source descriptor.
|
||||
- `source` (`string`): Use `local` for this repo workflow.
|
||||
- `path` (`string`): Relative plugin path based on the marketplace root.
|
||||
- Repo plugin: `./plugins/<plugin-name>`
|
||||
- Local plugin in `~/.agents/plugins/marketplace.json`: `./plugins/<plugin-name>`
|
||||
- The same relative path convention is used for both repo-rooted and home-rooted marketplaces.
|
||||
- Personal plugin in `~/.agents/plugins/marketplace.json`: `./plugins/<plugin-name>`
|
||||
- Repo/team plugin: `./plugins/<plugin-name>`
|
||||
- The same relative path convention is used for both personal and repo/team marketplaces.
|
||||
- Example: with `~/.agents/plugins/marketplace.json`, `./plugins/<plugin-name>` resolves to `~/plugins/<plugin-name>`.
|
||||
- `policy` (`object`): Marketplace policy block. Always include it.
|
||||
- `installation` (`string`): Availability policy.
|
||||
@@ -165,6 +165,9 @@
|
||||
- Treat `policy.products` as an override and omit it unless explicitly requested.
|
||||
- Append new entries unless the user explicitly requests reordering.
|
||||
- Replace an existing entry for the same plugin only when overwrite is intentional.
|
||||
- Choose marketplace location to match the plugin destination:
|
||||
- Repo plugin: `<repo-root>/.agents/plugins/marketplace.json`
|
||||
- Local plugin: `~/.agents/plugins/marketplace.json`
|
||||
- Default new plugin creation to the personal marketplace.
|
||||
- If the current Git repo already has `.agents/plugins/marketplace.json` and the user has not said
|
||||
personal or team, ask which marketplace to update before creating the entry.
|
||||
- Choose marketplace location to match the selected destination:
|
||||
- Personal plugin: `~/.agents/plugins/marketplace.json`
|
||||
- Repo/team plugin: `<repo-root>/.agents/plugins/marketplace.json`
|
||||
|
||||
@@ -11,8 +11,8 @@ from typing import Any
|
||||
|
||||
|
||||
MAX_PLUGIN_NAME_LENGTH = 64
|
||||
DEFAULT_PLUGIN_PARENT = Path.cwd() / "plugins"
|
||||
DEFAULT_MARKETPLACE_PATH = Path.cwd() / ".agents" / "plugins" / "marketplace.json"
|
||||
DEFAULT_PLUGIN_PARENT = Path.home() / "plugins"
|
||||
DEFAULT_MARKETPLACE_PATH = Path.home() / ".agents" / "plugins" / "marketplace.json"
|
||||
DEFAULT_INSTALL_POLICY = "AVAILABLE"
|
||||
DEFAULT_AUTH_POLICY = "ON_INSTALL"
|
||||
DEFAULT_CATEGORY = "Productivity"
|
||||
@@ -192,8 +192,8 @@ def parse_args() -> argparse.Namespace:
|
||||
"--path",
|
||||
default=str(DEFAULT_PLUGIN_PARENT),
|
||||
help=(
|
||||
"Parent directory for plugin creation (defaults to <cwd>/plugins). "
|
||||
"When using a home-rooted marketplace, use <home>/plugins."
|
||||
"Parent directory for plugin creation (defaults to <home>/plugins). "
|
||||
"Use <repo>/plugins when creating a repo/team plugin."
|
||||
),
|
||||
)
|
||||
parser.add_argument("--with-skills", action="store_true", help="Create skills/ directory")
|
||||
@@ -206,7 +206,7 @@ def parse_args() -> argparse.Namespace:
|
||||
"--with-marketplace",
|
||||
action="store_true",
|
||||
help=(
|
||||
"Create or update <cwd>/.agents/plugins/marketplace.json. "
|
||||
"Create or update <home>/.agents/plugins/marketplace.json by default. "
|
||||
"Marketplace entries always point to ./plugins/<plugin-name> relative to the "
|
||||
"marketplace root."
|
||||
),
|
||||
@@ -215,8 +215,8 @@ def parse_args() -> argparse.Namespace:
|
||||
"--marketplace-path",
|
||||
default=str(DEFAULT_MARKETPLACE_PATH),
|
||||
help=(
|
||||
"Path to marketplace.json (defaults to <cwd>/.agents/plugins/marketplace.json). "
|
||||
"For a home-rooted marketplace, use <home>/.agents/plugins/marketplace.json."
|
||||
"Path to marketplace.json (defaults to <home>/.agents/plugins/marketplace.json). "
|
||||
"Use <repo>/.agents/plugins/marketplace.json for a repo/team plugin."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
|
||||
Reference in New Issue
Block a user