agent-plugin-porter
v0.2.0
Published
Port Claude Code plugins into Codex and Agy/Gemini-compatible local plugin packages.
Maintainers
Readme
Agent Plugin Porter
agent-plugin-porter ports Claude Code plugin sources into local packages for
other agent runtimes.
The default output is a cross-runtime plugin repo:
- Codex CLI/App compatible:
.codex-plugin/plugin.jsonplus a local.agents/plugins/marketplace.json. - Agy-compatible: root
plugin.json. - Gemini-compatible:
gemini-extension.jsonplusGEMINI.md.
Legacy split targets remain available for target-specific testing:
codexwrites a Codex marketplace package underdist/codex/.agywrites an Agy/Gemini-compatible local package underdist/agy/.claudeis opt-in and writes Claude plugin metadata only when requested.
The first real fixture is Anthropic's official claude-md-management plugin.
Existing completed ports such as agent-skills/skills/simplify are reference
examples, not input targets.
Install
After the first public npm release:
npm install -g agent-plugin-porter
agent-plugin-porter --helpOr run a published version without installing it globally:
npx -y agent-plugin-porter@latest --helpUntil the npm package exists, use the local checkout:
npm ci
npm test
npm run lint
npm run build
npm run cli -- <command>Port One Plugin
Use a local Claude Code plugin cache path:
npm run build
npm run cli -- port \
/Users/karlchow/.claude/plugins/cache/claude-plugins-official/claude-md-management/1.0.0 \
--out ./distUse an official GitHub tree URL:
npm run build
npm run cli -- port \
https://github.com/anthropics/claude-plugins-official/tree/main/plugins/claude-md-management \
--out ./distGenerated output:
dist/
├── repo/
│ └── claude-md-management/
│ ├── .agents/plugins/marketplace.json
│ ├── .codex-plugin/plugin.json
│ ├── GEMINI.md
│ ├── commands/revise-claude-md.md
│ ├── gemini-extension.json
│ ├── plugin.json
│ └── skills/claude-md-improver/SKILL.md
└── reports/
└── claude-md-management.port-report.jsonThe repo output follows the same multi-harness layout used by
obra/superpowers: shared plugin content
at the repository root, platform manifests beside it, and runtime-specific
marketplace or context files only where a runtime needs them.
Include Claude Plugin Metadata
Claude plugin metadata is opt-in:
npm run cli -- port \
/Users/karlchow/.claude/plugins/cache/claude-plugins-official/claude-md-management/1.0.0 \
--targets repo,claude \
--out ./distThis adds:
dist/repo/claude-md-management/.claude-plugin/plugin.json
dist/repo/claude-md-management/.claude-plugin/marketplace.jsonUse --targets claude only when you specifically want a split Claude package at
dist/claude/<plugin-name>/.
Legacy Split Targets
Use split targets when you need the older per-runtime artifacts:
npm run cli -- port \
/Users/karlchow/.claude/plugins/cache/claude-plugins-official/claude-md-management/1.0.0 \
--targets codex,agy \
--out ./distGenerated split output:
dist/
├── agy/
│ └── claude-md-management/
│ ├── .claude-plugin/plugin.json
│ ├── commands/revise-claude-md.md
│ ├── plugin.json
│ └── skills/claude-md-improver/SKILL.md
├── codex/
│ ├── .agents/plugins/marketplace.json
│ └── plugins/claude-md-management/
│ ├── .codex-plugin/plugin.json
│ ├── commands/revise-claude-md.md
│ └── skills/claude-md-improver/SKILL.md
└── reports/
└── claude-md-management.port-report.jsonInventory And Batch Port
Inventory a local plugin cache or cloned official repo:
npm run cli -- inventory \
/Users/karlchow/.claude/plugins/cache/claude-plugins-official \
--out ./dist/reports/official-inventory.jsonPort selected plugins from the inventory:
npm run cli -- port-batch \
--manifest ./dist/reports/official-inventory.json \
--include claude-md-management \
--out ./distThe inventory command also accepts a GitHub repo URL. For GitHub sources, the
repo is cloned into a local .source-cache under the output directory so the
inventory paths remain usable by later port-batch commands.
npm run cli -- inventory \
https://github.com/anthropics/claude-plugins-official \
--out ./dist/reports/official-inventory.jsonInstall Generated Repo Output
The default repo output is written to:
dist/repo/claude-md-managementFor Codex, register the generated repo as a local marketplace and install the plugin from that marketplace:
codex plugin marketplace add ./dist/repo/claude-md-management
codex plugin marketplace upgrade
codex plugin add claude-md-management@claude-md-management
codex plugin listFor Agy:
agy plugin validate dist/repo/claude-md-management
agy plugin install dist/repo/claude-md-management
agy plugin listFor Gemini CLI legacy extensions:
gemini extensions validate dist/repo/claude-md-management
gemini extensions install dist/repo/claude-md-management
gemini extensions listInstall Legacy Split Codex Output Locally
After --targets codex,agy, copy one generated Codex plugin into the personal
marketplace:
npm run cli -- install-codex-personal \
--plugin claude-md-management \
--from ./dist/codexThis copies:
dist/codex/plugins/claude-md-management -> ~/plugins/claude-md-managementand updates:
~/.agents/plugins/marketplace.jsonThen install from Codex:
codex plugin add claude-md-management@personal
codex plugin listFor a non-default marketplace or sandboxed test, pass explicit paths:
npm run cli -- install-codex-personal \
--plugin claude-md-management \
--from ./dist/codex \
--marketplace /tmp/porter-home/.agents/plugins/marketplace.json \
--plugins-dir /tmp/porter-home/pluginsVerify Codex Loading
Structural checks:
jq -r '.skills' dist/repo/claude-md-management/.codex-plugin/plugin.json
jq -r '.plugins[0].source.path' dist/repo/claude-md-management/.agents/plugins/marketplace.json
find dist/repo/claude-md-management/skills -maxdepth 3 -type f | sortRuntime checks:
plugin/read pluginName="claude-md-management"
skills/list forceReload=trueExpected active skill name:
claude-md-management:claude-md-improverVerify Agy/Gemini Loading
The default package is written to:
dist/repo/claude-md-managementUse the local Agy CLI if available:
agy plugin validate dist/repo/claude-md-management
agy plugin install dist/repo/claude-md-management
agy plugin listUse Gemini CLI legacy extension commands if available:
gemini extensions validate dist/repo/claude-md-management
gemini extensions install dist/repo/claude-md-management
gemini extensions listReports
Each port writes:
dist/reports/<plugin-name>.port-report.jsonThe report distinguishes mechanical compatibility from semantic
portability. For example, claude-md-management is loadable in Codex, but the
skill still targets CLAUDE.md, not Codex-native AGENTS.md hygiene. The
report preserves that as a semantic warning. Claude command prompt files are
copied into generated packages for source completeness, but remain listed under
manual components until an explicit target-native command conversion exists.
Always review:
jq '.manualComponents,.semanticWarnings' dist/reports/<plugin-name>.port-report.jsonSuccessful target discovery does not erase manual components. Claude commands,
hooks, subagents, MCP configuration, and CLAUDE.md-specific workflows remain
manual or semantic-warning surfaces unless this CLI has an explicit,
target-specific adapter for them.
Publish-Ready Repo
To publish the default generated repo to GitHub, push this folder as the repository root:
dist/repo/<plugin-name>/.agents/plugins/marketplace.json
dist/repo/<plugin-name>/.codex-plugin/plugin.json
dist/repo/<plugin-name>/gemini-extension.json
dist/repo/<plugin-name>/GEMINI.md
dist/repo/<plugin-name>/plugin.json
dist/repo/<plugin-name>/skills/<skill-name>/SKILL.mdThen add the repository in Codex:
codex plugin marketplace add owner/repo --ref main
codex plugin marketplace upgrade
codex plugin add claude-md-management@claude-md-managementDevelopment
npm ci
npm test
npm run lint
npm run buildCI runs the same verification commands on push and pull requests:
npm ci
npm test
npm run lint
npm run buildPublishing The CLI
Do not publish from an unaudited dirty tree or from an unverified build. The package metadata currently assumes the GitHub home is:
https://github.com/karlorz/agent-plugin-porterCreate that repository before the first public release, or update
repository, bugs, and homepage in package.json to match the actual
GitHub repository.
Before every publish:
npm ci
npm test
npm run lint
npm run build
npm pack --dry-run
npm view agent-plugin-porter version || trueInspect the npm pack --dry-run file list. It should include package.json,
README.md, LICENSE, and compiled runtime files under build/src/. It should
not include src/, test/, dist/, generated port output, source caches, or
compiled test files.
First publish usually needs an npm account login or an automation token:
npm login
npm publishFor a prerelease channel:
npm publish --tag betaIf the package is renamed to a public scoped package, publish with explicit public access:
npm publish --access publicFor provenance after the npm package exists and GitHub trusted publishing is configured:
npm publish --provenanceTrusted publishing is normally configured from npm package settings after the
package exists. Add a publish workflow only after choosing the release trigger
and authentication model: either an NPM_TOKEN secret or OIDC trusted
publishing with id-token: write.
