All skills
Skillintermediate

feat: Ship Codex-format plugin manifests alongside Claude manifests

Add Codex-format plugin manifests (`.agents/plugins/marketplace.json` plus per-plugin `.codex-plugin/plugin.json`) to the repo alongside the existing Claude-format manifests, so Codex users can install CE's skills via the native `codex plugin marketplace add EveryInc/compound-engineering-plugin` flow.

Claude Code Knowledge Pack7/10/2026

Overview

feat: Ship Codex-format plugin manifests alongside Claude manifests

Overview

Add Codex-format plugin manifests (.agents/plugins/marketplace.json plus per-plugin .codex-plugin/plugin.json) to the repo alongside the existing Claude-format manifests, so Codex users can install CE's skills via the native codex plugin marketplace add EveryInc/compound-engineering-plugin flow.

Agents are not supported by Codex's native plugin spec, so the existing Bun converter (bunx @every-env/compound-plugin install compound-engineering --to codex) remains required to complete a CE install. To prevent skill double-registration when users run both flows, the Bun converter's --to codex default is changed to agents-only; an opt-in --include-skills flag re-enables the full bundle for standalone installs. The README documents the two-step flow.

Problem Frame

Codex is the only target in CE's installable set still gated on the Bun converter for the baseline (skills) install. Every other tool either has native support (Claude Code, Cursor, Copilot, Droid, Qwen) or has no native install mechanism at all (OpenCode, Pi, Gemini, Kiro). Codex does have a native plugin format — we just never shipped the manifests for it.

Shipping the Codex manifests:

  • Puts Codex in the "native install" tier alongside Copilot/Droid/Qwen for discovery and lifecycle (install/uninstall/update via codex plugin)

  • Does not change the agent install path (native Codex plugin install does not register custom agents per the spec and our empirical test)

  • Costs \~two hand-authored JSON files per plugin plus a small release-infra extension, because the repo already supports dual-format manifests (Claude + Cursor) and adding a third format is a parallel entry, not a new pattern

Requirements Trace

  • R1. codex plugin marketplace add <local-clone> must succeed and register the CE plugin

  • R2. codex plugin install compound-engineering must install CE's skills into the expected Codex skill location

  • R3. Plugin version in .codex-plugin/plugin.json must stay in sync with .claude-plugin/plugin.json automatically on release

  • R4. bun run release:validate must fail if the Codex manifests drift out of sync with the Claude manifests (plugin list mismatch, name mismatch, version mismatch)

  • R5. README documents the Codex native install flow with a followup step for agents

  • R6. No regressions to existing Claude, Cursor, Copilot, Droid, Qwen, or Bun-converter install paths

Scope Boundaries

  • Native Codex plugin install handles skills only (Codex spec does not register custom agents or slash commands). Agents still flow through the Bun converter; the converter's default behavior is changed in Unit 9 so skills are NOT emitted by default, preventing double-registration.

  • Commands are not installed via native Codex plugin install (Codex spec limitation). Only affects the coding-tutor plugin, which ships commands. Coding-tutor users wanting commands run the Bun converter with --include-skills.

  • No single-command hybrid UX (the two-step codex plugin install + bunx ... --to codex flow is documented, not automated). This becomes obsolete when Codex supports custom agents natively — at which point the entire --to codex converter path is deprecated.

  • No logo asset — interface.logo is omitted; can be added in a followup when a branded icon is available

  • No Codex-specific skill frontmatter fields (metadata.priority, metadata.pathPatterns, metadata.bashPatterns) — these are trigger-tuning extensions, not required for registration, and can be added per-skill in followups

  • No empirical test of remote-repo install in this plan. The remote codex plugin marketplace add EveryInc/compound-engineering-plugin flow documented in the README cannot be tested from a feature branch — Codex fetches the default branch of the remote. Remote-install verification is a separate manual step immediately post-merge, before the release tag: clone the merged main, run the remote install command against it, confirm skills register. If the remote path fails, ship a fix-forward PR rather than rolling back. source: { source: "local", path: "./plugins/<name>" } has been empirically verified as the correct schema for both bundled AND remote-cloned marketplaces (see Resolved Open Questions), so the most likely remote-vs-local divergence — the schema — is already de-risked

Deferred to Separate Tasks

  • Hybrid install UX that bundles codex plugin install with the agent followup into a single command: future plan once Codex's native spec is more settled

  • Codex-specific skill metadata tuning (priority, path patterns, bash patterns) for discoverability: evaluate per-skill in followups as use patterns emerge

  • Plugin logo asset design: hand off to design; drop in later

  • Removal of the --to codex Bun converter path entirely once Codex supports custom agents natively; at that point codex plugin install is sufficient on its own

Context & Research

Relevant Code and Patterns

  • .claude-plugin/marketplace.json, .cursor-plugin/marketplace.json — existing dual-format marketplace manifests (Cursor mirrors Claude's schema; Codex will diverge)

  • plugins/compound-engineering/.claude-plugin/plugin.json, .cursor-plugin/plugin.json — existing dual plugin manifests (source of truth for name/description/version/author/homepage/keywords)

  • .github/release-please-config.jsonplugins/compound-engineering and plugins/coding-tutor packages already list extra-files for .claude-plugin/plugin.json and .cursor-plugin/plugin.json; Codex adds a third entry in each

  • .github/.release-please-manifest.json — tracks versions per release-please package; Cursor marketplace (.cursor-plugin) is a separate tracked package, Codex likely does not need its own tracked package since the Codex marketplace spec has no version field (see Key Technical Decisions)

  • src/release/components.ts — declares release components (marketplace, cursor-marketplace, CLI, per-plugin) and their source-of-truth file paths

  • src/release/metadata.ts — sync engine that reads the various marketplace + plugin manifests and cross-checks / updates versions and descriptions

  • src/release/config.ts — validator stubs (currently only checks changelog-path shape); extend here or in metadata.ts for Codex-consistency rules

  • scripts/release/validate.ts — entry point run by bun run release:validate; consumes the above

  • tests/release-components.test.ts, tests/release-config.test.ts, tests/release-metadata.test.ts — existing test coverage for the release infra; extend alongside the code changes

External References

  • Codex plugin docs: developers.openai.com/codex/plugins, developers.openai.com/codex/plugins/build

  • Canonical reference repo: github.com/openai/plugins — confirms .agents/plugins/marketplace.json at repo root, .codex-plugin/plugin.json per plugin

  • Local evidence:

    • ~/.codex/.tmp/bundled-marketplaces/openai-bundled/.agents/plugins/marketplace.json — bundled OpenAI example, minimal shape

    • ~/.codex/.tmp/plugins/plugins/vercel/ — fully-featured plugin with skills; shows "skills": "./skills/" declaration pattern and interface{} block shape

Documented Codex format (worked out from sources above)

.agents/plugins/marketplace.json (repo root; Codex looks here after cloning):

{
  "name": "compound-engineering-plugin",
  "interface": { "displayName": "Compound Engineering" },
  "plugins": [
    {
      "name": "compound-engineering",
      "source": { "source": "local", "path": "./plugins/compound-engineering" },
      "policy": { "installation": "AVAILABLE", "authentication": "ON_INSTALL" },
      "category": "Coding"
    }
  ]
}

plugins/<name>/.codex-plugin/plugin.json:

{
  "name": "...",
  "version": "...",
  "description": "...",
  "author": { "name": "...", "email": "...", "url": "..." },
  "homepage": "...",
  "repository": "...",
  "license": "...",
  "keywords": ["..."],
  "skills": "./skills/",
  "interface": {
    "displayName": "...",
    "shortDescription": "...",
    "longDescription": "...",
    "developerName": "...",
    "category": "Coding",
    "capabilities": ["Interactive", "Read", "Write"],
    "websiteURL": "...",
    "privacyPolicyURL": "...",
    "termsOfServiceURL": "...",
    "defaultPrompt": ["..."],
    "screenshots": []
  }
}

Required fields per docs: name, version, description. All others optional. Native install registers skills (via skills: key), MCP servers (mcpServers:), apps (apps:), hooks (hooks:). Agents, commands, and prompts are not declarable or auto-discovered.

Key Technical Decisions

  • Commit manifests, don't generate. Hand-authored, versioned like source. release-please bumps version in .codex-plugin/plugin.json via extra-files, same mechanism already used for Claude + Cursor.

  • Don't track the Codex marketplace as a release-please package. The Codex marketplace spec (.agents/plugins/marketplace.json) has no version field — unlike the Claude and Cursor marketplaces which have metadata.version. Treat the Codex marketplace as static content; only the per-plugin .codex-plugin/plugin.json version needs automated bumping.

  • Extend src/release/metadata.ts to read the Codex manifests and cross-check them. Mirrors how Cursor manifests were added: read them, cross-reference plugin lists and versions against the Claude source of truth, fail validation on drift.

  • Omit interface.logo for now. Optional per docs; the bundled OpenAI example has one but many listed plugins don't. Ship without, add later when an icon is available.

  • Don't add Codex-specific skill frontmatter extensions. metadata.priority, metadata.pathPatterns, metadata.bashPatterns are trigger-tuning optimizations, not required for registration. CE skills will use their current Claude-compatible frontmatter; Codex will register them with default trigger behavior.

  • coding-tutor still needs a Codex manifest even though native install won't handle its commands. Reason: the marketplace lists both plugins as a unit; omitting coding-tutor from the Codex marketplace would be asymmetric with the Claude marketplace. Native install will successfully install coding-tutor's skills but not its commands — the README's coding-tutor install instructions will note that commands require the Bun converter.

  • Validation failure modes to enforce: missing Codex manifest when Claude manifest exists; plugin list mismatch between .claude-plugin/marketplace.json and .agents/plugins/marketplace.json; name mismatch between paired plugin.json files; version mismatch between paired plugin.json files; declared skills: "./skills/" pointing at a missing directory.

Open Questions

Resolved During Planning

  • Do we need to ship a logo? No — omit the field. Add in a followup when an asset is available.

  • Should skills declare Codex metadata extensions? No — ship with default trigger behavior. Add per-skill tuning in followups if use patterns reveal a need.

  • Is the Codex marketplace a release-please package? No — it has no version field per the Codex spec, so it stays static. Per-plugin .codex-plugin/plugin.json is the only versioned file.

  • Does coding-tutor get a Codex manifest? Yes — marketplace parity with Claude. Native install will register its skills but not its commands; README notes the gap.

  • Are file paths for the skills: declaration plugin-relative or marketplace-relative? Plugin-relative. "skills": "./skills/" in plugins/compound-engineering/.codex-plugin/plugin.json means plugins/compound-engineering/skills/. Confirmed via vercel and github plugin examples.

  • Does the source: "local" marketplace schema work for remote-cloned marketplaces, not just bundled ones? Yes. The openai-curated marketplace (a real-world remote-fetched marketplace Codex clones and caches at ~/.codex/.tmp/plugins/.agents/plugins/marketplace.json) uses the identical source: { source: "local", path: "./plugins/<name>" } schema. "local" refers to the plugin's co-location within the marketplace repo, not "bundled with Codex." Same schema for both.

  • Does Codex's default skill discovery find flat skills/<name>/SKILL.md layouts at CE's depth? Yes. Vercel's reference plugin at ~/.codex/.tmp/plugins/plugins/vercel/skills/ uses the exact layout CE ships — flat subdirectories each containing SKILL.md. CE has 43 skill directories at that depth under plugins/compound-engineering/skills/. Unit 7 includes a count-based assertion to catch partial-discovery regressions.

Deferred to Implementation

  • Exact interface.shortDescription / longDescription copy for each plugin. Use the description from .claude-plugin/plugin.json as the short form; compose a longer version from the plugin's README section or existing marketplace description. Can be refined during implementation.

  • Does codex plugin install succeed against a local clone of this branch? Empirical verification happens during implementation. If the plugin manifest schema is rejected (e.g., a required field we didn't identify from docs), iterate.

  • Does the Codex skills mechanism register CE's skills without modification? Local empirical test during implementation. CE skills use standard Claude frontmatter (name, description); Codex docs say those are the required fields. Expected to work.

Implementation Units

  • Unit 1: Author plugins/compound-engineering/.codex-plugin/plugin.json

Goal: Codex plugin manifest for the primary CE plugin, with skills declared and interface metadata populated.

Requirements: R1, R2

Dependencies: None

Files:

  • Create: plugins/compound-engineering/.codex-plugin/plugin.json

Approach:

  • Read the Claude manifest at plugins/compound-engineering/.claude-plugin/plugin.json for source-of-truth fields (name, version, description, author, homepage, license, keywords).

  • Add Codex-specific fields: skills: "./skills/", and an interface{} block with displayName, shortDescription (reuse description), longDescription (1-2 sentence pitch, can draw from README lead paragraph), developerName (derive from author), category: "Coding", capabilities: ["Interactive", "Read", "Write"], websiteURL: homepage, privacyPolicyURL / termsOfServiceURL (reuse Every's existing policy URLs if available; omit otherwise — optional per docs), defaultPrompt: [] (can leave empty or add 2-3 starter prompts).

  • Omit logo (decided in Key Technical