Skip to content

feat!: emit Agent Plugins packages from codex and add an agent-plugins target - #38

Merged
steve-calvert-glean merged 3 commits into
mainfrom
feat/agent-plugins-format
Oct 20, 2026
Merged

steve-calvert-glean merged 3 commits into
mainfrom
feat/agent-plugins-format

Conversation

@steve-calvert-glean

Copy link
Copy Markdown
Contributor

Second of three PRs adding Agent Plugins support. Stacked on #37 (the MCP module); review that first. This PR's base is feat/mcp-dialects.

Why

Agent Plugins 1.0 standardizes the plugin package: a closed root plugin.json, skills/, mcp.json, and reverse-domain extension namespaces. It deliberately leaves out marketplaces, hooks, agents, commands, and rules. OpenAI's packaging docs now prefer it for Codex and ChatGPT and keep .codex-plugin/plugin.json only as a compatibility fallback. Copilot/VS Code loads it too, and Cursor loads the skills and MCP parts.

What

  • src/agent-plugins.ts, the package module. Builds the portable manifest, moves client fields under extensions[<namespace>], and validates a package against the spec: closed manifest, plugin name (§5.5), mcp.json (via feat: render MCP config into each target's MCP dialect #37's agent-plugins dialect), and each skill's name per the Agent Skills spec, which must also match its directory. Marketplaces stay on each target, as the spec intends.
  • codex emits packages by default. It writes root plugin.json with OpenAI settings under extensions.com.openai, plus mcp.json, and keeps .agents/plugins/marketplace.json. Existing configs need no changes: authored interface/apps/hooks move under the namespace automatically. format: "legacy" keeps the .codex-plugin layout. validate detects each plugin's layout on disk, the way Codex does.
  • New agent-plugins target. Portable packages only, under plugins/<name>/, with no marketplace (the spec defines none) and no client profile. Including agents/commands/rules/hooks is a config error, and a non-portable manifest field is a build error. install-info reports no install command, with a citation.
  • Target interface. Two optional members: forConfig (picks a definition per target config) and finalizeManifest (runs after the author's manifest override is merged).
  • Conformance. Vendors the official 1.0.0 plugin.schema.json and mcp.schema.json (commit SHA and SHA-256 in tests/fixtures/agent-plugins/SOURCE.md). Codex and agent-plugins output must validate against them via ajv's 2020-12 build, and pluginpack validate must pass on the same output.
  • Docs. README (targets table, an Agent Plugins section with upgrade notes, MCP table, config reference), CONFORMANCE.md, CLAUDE.md, and the authoring skill. ADR 0001 records why there's no dual layout.

Breaking change

The codex target's default output changes from .codex-plugin/plugin.json + .mcp.json to plugin.json + mcp.json. To keep the old layout, set format: "legacy" on the codex target.

Verification

  • npm run check passes (249 tests; 9 new in tests/agent-plugins.test.ts, plus new conformance tests for codex AP, codex legacy, and agent-plugins).
  • Built gleanwork/agent-plugins from a temp copy:
    • claude and cursor output is byte-identical to 0.11.0.
    • codex changes only in layout: .codex-plugin/ and .mcp.json are replaced by plugin.json and mcp.json. interface lands under extensions.com.openai, and the shared Claude-style MCP config converts to valid Agent Plugins mcp.json.
    • Two upgrade blockers surface on purpose, both handled in the follow-up (c): the hand-written overrides/codex/glean/mcp/config.json (cwd: ".") fails the build, and once it's removed, validate rejects the glean_run skill name, which Agent Plugins clients would skip.

Next

(c) in gleanwork/agent-plugins: delete the codex MCP override, decide on the glean_run rename, upgrade to 0.12, and regenerate codex-plugins.

@steve-calvert-glean steve-calvert-glean added breaking Considered a breaking change and removed breaking Considered a breaking change labels Oct 2, 2026
@steve-calvert-glean
steve-calvert-glean force-pushed the feat/agent-plugins-format branch from 9001c2d to 75988e2 Compare October 2, 2026 22:28
steve-calvert-glean added a commit that referenced this pull request Oct 19, 2026
Fixes from a self-review of the #37 + #38 stack.

- F3: validate parsed SKILL.md frontmatter with gray-matter's default
  engines, so a ---js block ran through eval(). A shared parseMatter()
  helper now refuses the js and javascript engines, for every target.
- F13: build could emit a plugin.json that validate rejects (a bad
  extension namespace, extra author fields). placeClientFields now runs
  the same manifest checks and fails the build.
- F6: native dialects kept an Agent Plugins "./server" cwd as a bare
  relative path, which clients resolve against the user's project. It
  now becomes ${<root>}/server, like a ./ command.
- F8: the agent-plugins target dropped scripts/ by default while still
  emitting MCP commands that point into it. scripts is now a default
  component, as it is for codex.
- F1: validate re-rendered mcp.json and kept only render errors, so a
  server without "type" or with "http" passed. It now reports any server
  that is not already in normalized Agent Plugins form.
- F15: add a test for default-format codex output with hooks/.
- F9, F17, F18, F21: README upgrade note covers the MCP build errors,
  the MCP rules list is complete, install-snippet docs name
  agent-plugins, and CLAUDE.md agrees with CONFORMANCE.md on schemas.
Base automatically changed from feat/mcp-dialects to main October 19, 2026 22:48
…s target

Agent Plugins 1.0 standardizes the plugin package: a closed root
plugin.json, skills/, mcp.json, and reverse-domain extension namespaces.
OpenAI now prefers it for Codex and ChatGPT and keeps
.codex-plugin/plugin.json only as a fallback.

- src/agent-plugins.ts: the package module. It builds the portable
  manifest, moves client fields under extensions[<namespace>], and
  validates a package against the spec (closed manifest, plugin name,
  mcp.json, and skill names per the Agent Skills spec).
- codex: emits a package by default (root plugin.json with OpenAI
  settings under extensions.com.openai, plus mcp.json) and keeps
  .agents/plugins/marketplace.json. format: "legacy" keeps the
  .codex-plugin layout; validate detects the layout per plugin.
- agent-plugins: a new standalone target that writes portable packages
  only, with no marketplace and no client profile. Client-only content
  kinds are a config error; non-portable manifest fields are a build
  error.
- Targets can now choose a definition per config (forConfig) and post-
  process the merged manifest (finalizeManifest).
- Vendors the official 1.0.0 schemas (with provenance) as the
  conformance oracle for codex and agent-plugins.

BREAKING CHANGE: the codex target's default output layout changes from
.codex-plugin/plugin.json + .mcp.json to an Agent Plugins package
(plugin.json + mcp.json). Set `format: "legacy"` on the codex target to
keep the previous layout. MCP config and skill names that Agent Plugins
clients would skip now fail build or validate.
Fixes from a self-review of the #37 + #38 stack.

- F3: validate parsed SKILL.md frontmatter with gray-matter's default
  engines, so a ---js block ran through eval(). A shared parseMatter()
  helper now refuses the js and javascript engines, for every target.
- F13: build could emit a plugin.json that validate rejects (a bad
  extension namespace, extra author fields). placeClientFields now runs
  the same manifest checks and fails the build.
- F6: native dialects kept an Agent Plugins "./server" cwd as a bare
  relative path, which clients resolve against the user's project. It
  now becomes ${<root>}/server, like a ./ command.
- F8: the agent-plugins target dropped scripts/ by default while still
  emitting MCP commands that point into it. scripts is now a default
  component, as it is for codex.
- F1: validate re-rendered mcp.json and kept only render errors, so a
  server without "type" or with "http" passed. It now reports any server
  that is not already in normalized Agent Plugins form.
- F15: add a test for default-format codex output with hooks/.
- F9, F17, F18, F21: README upgrade note covers the MCP build errors,
  the MCP rules list is complete, install-snippet docs name
  agent-plugins, and CLAUDE.md agrees with CONFORMANCE.md on schemas.
Resolves the self-review findings that needed a decision.

- F2: findPackages stopped at depth 4, so validate missed a package at
  a valid deeper plugin path. The depth cap is gone; the walk still stops
  at each package and skips node_modules and dot-directories.
- F7: a plugin.json that failed to parse or declared another $schema was
  not treated as a package. Codex then blamed a missing
  .codex-plugin/plugin.json, and the agent-plugins target skipped the
  plugin. Both now validate the root plugin.json and report it.
- F10: the README now says Cursor output drops "type" from stdio and
  HTTP servers, instead of claiming native config is always unchanged.
@steve-calvert-glean
steve-calvert-glean merged commit dd0e064 into main Oct 20, 2026
1 of 3 checks passed
@steve-calvert-glean
steve-calvert-glean deleted the feat/agent-plugins-format branch October 20, 2026 01:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Considered a breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant