Skip to content

portable manifest adapters (GRO-353) - #9

Open
teallarson wants to merge 27 commits into
mainfrom
teal/gro-353-add-codexchatgpt-plugin-hooks-for-telemetry-and-lifecycle
Open

teallarson wants to merge 27 commits into
mainfrom
teal/gro-353-add-codexchatgpt-plugin-hooks-for-telemetry-and-lifecycle

Conversation

@teallarson

@teallarson teallarson commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Linear ticket: GRO-353

What/why

Arcade’s plugin ships one portable core (skills, MCP gateway config, identity) and small per-host “adapter manifests” that tell each client where to find those pieces. Cursor, Claude, and Codex read different files, path styles, and hook formats, so maintaining five copies by hand caused version drift. This PR makes root plugin.json and mcp.json the source of truth, generates the host adapter JSON from them on release, and adds the intended Codex / ChatGPT lifecycle-hook adapter. A manual smoke test found that Codex CLI 0.154.0 does not load hooks from an Agent Plugin root, so the Codex hook path still needs a packaging decision before merge.

For Codex specifically, the plugin still cannot bundle the custom arcade-operator agent role (an OpenAI platform limit). This branch defines SessionStart, UserPromptSubmit, and SubagentStart hooks, but current Codex does not discover them from the portable Agent Plugin package. Claude Code and Cowork get the same three lifecycle hooks from hooks/hooks.json, including SubagentStart for built-in subagents when arcade-operator is not used. Shipping arcade-operator itself remains available on Cursor, Claude Code, and Copilot CLI.

The intended Codex smoke test is: install the branch, trust hooks via /hooks, and confirm session routing guidance appears. The install resolves the skills, MCP config, and generated fallback manifest, but Codex 0.154.0 reports zero installed hooks for SessionStart, UserPromptSubmit, and SubagentStart. The generated adapter manifests do show the product name Arcade instead of the internal id arcade, and the Codex fallback manifest mirrors extensions.com.openai.interface.

Codebase changes

  • Portable core: plugin.json, mcp.json, skills/, and VERSION stay authoritative; scripts/generate-manifests.mjs writes Cursor, Claude, marketplace, and Codex adapter projections, and npm run generate:check fails CI if they drift.
  • Hand-authored hook adapters: Hook event names and matcher syntax differ by host, so hooks.json files stay explicit per client (hooks/hooks.json for Claude lifecycle hooks, clients/cursor/hooks/hooks.json for Cursor session hooks, com.openai/hooks/hooks.json for Codex lifecycle hooks). scripts/check.mjs enforces the split and rejects Codex-only wiring in the Claude manifest.
  • Codex wiring: OpenAI extension in root plugin.json selects com.openai/hooks/hooks.json; .codex-plugin/plugin.json mirrors extensions.com.openai.interface and the hooks path for older loaders. Commands use Codex’s ${PLUGIN_ROOT} variable.
  • Listing metadata: Generated .cursor-plugin/plugin.json keeps top-level displayName: "Arcade". The Codex fallback manifest copies the full interface object from extensions.com.openai.interface, matching the OpenAI plugin contract.
  • Docs and release: Install guides, support matrix, architecture notes, Release Please extra-files, and manifest tests updated; the prior contract/hash inventory layer was removed in favor of generate + validate. README hook counts are checked against docs/support-matrix.capabilities.json.

Additional notes

#10 is already merged into this branch. #11 remains a draft stacked on #9 and should merge after #9. npm run verify passes locally (61 tests), and check, complete, and Cursor Bugbot are green on dd58ed1. Deeper maintainer detail lives in ARCHITECTURE.md (portable contract → generate → validate) and AGENTS.md (hook adapter table).

Manual Codex smoke — blocked (2026-09-17, Codex CLI 0.154.0)

  • Both the cross-client installer and Codex's native marketplace installer resolve this branch successfully.
  • Codex /hooks reports 0 installed and 0 active hooks for SessionStart, UserPromptSubmit, and SubagentStart.
  • A fresh ephemeral codex exec session with hook trust bypassed ran none of the branch's hook commands.
  • The current Codex loader deliberately skips hook sources for Agent Plugin manifests; see loader.rs.
  • Do not merge or request human review until this PR either ships a Codex-native legacy plugin projection or defers the unsupported Codex-hook claim.

Note

Medium Risk
Broad changes to agent routing, auth failure handling, and multi-client manifest generation; incorrect guidance could block legitimate fallbacks, but scope is plugin packaging and prompts rather than credentials or gateway code.

Overview
This PR makes root plugin.json and mcp.json the portable source of truth and adds scripts/generate-manifests.mjs so Cursor, Claude, marketplace, Codex listing fallback, client MCP adapters, and com.github.copilot/agents/arcade-operator.agent.md stay in sync via npm run generate / generate:check. Root plugin.json gains extensions.com.openai.interface; generated .codex-plugin/plugin.json mirrors it for legacy loaders—Codex lifecycle hooks are explicitly not shipped (documented upstream blocker; hook work parked on another branch).

Claude gets a third lifecycle hook (SubagentStart + subagent-start.mjs, wider SessionStart matchers, 5s timeouts). Cursor session hooks pick up the same timeout. Shared routing guidance, arcade-operator, try-arcade, and the Cursor rule now treat gateway needsAuth vs missing/failing MCP separately and forbid substituting other connectors (including Cursor’s plugin-arcade-arcade namespace).

CI collapses to npm run verify with JSON Schema contracts for host adapters, hook stdout/manifest smoke tests, docs/support-matrix.capabilities.json, and Codex/Cursor adapter checks; install docs and ARCHITECTURE.md / AGENTS.md describe the generate→validate model.

Reviewed by Cursor Bugbot for commit afd2e87. Bugbot is set up for automated code reviews on this repo. Configure here.

teallarson and others added 2 commits September 15, 2026 11:02
Wire the Codex adapter manifest and SubagentStart hook so Codex installs load the same routing hooks as Claude Code, with install and trust docs updated.

Co-authored-by: Cursor <cursoragent@cursor.com>
Expand subagent guidance to the full routing marker set, add invalid-stdin fallback parity with session-start, and enforce marker coverage in CI.

Co-authored-by: Cursor <cursoragent@cursor.com>
teallarson and others added 2 commits September 15, 2026 11:13
Wire skills into the Codex adapter manifest, clarify which clients run each hook event, simplify subagent-start stdin handling, and lock the broad SubagentStart matcher in tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Adopt the review template from ArcadeAI/monorepo #4127 so new pull requests open with What/why, Codebase changes, and Additional notes sections.

Co-authored-by: Cursor <cursoragent@cursor.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread hooks/hooks.json
@teallarson
teallarson marked this pull request as draft September 15, 2026 15:32
@teallarson
teallarson removed the request for review from kamath September 15, 2026 15:32
Split Codex lifecycle hooks into clients/codex/hooks/hooks.json so Claude Code no longer loads SubagentStart, and enforce the per-client manifest pattern in check.mjs and ARCHITECTURE.

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson

Copy link
Copy Markdown
Contributor Author

@BugBot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread .codex-plugin/plugin.json Outdated
Comment thread .codex-plugin/plugin.json Outdated
Codex auto-discovers hooks/hooks.json but ignores .codex-plugin hook arrays when the Agent Plugins root manifest is present. Move SubagentStart into com.openai/hooks/hooks.json with PLUGIN_ROOT, add clear to SessionStart, and drop the unreachable clients/codex adapter.

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson

Copy link
Copy Markdown
Contributor Author

@BugBot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread .codex-plugin/plugin.json Outdated
Declare com.openai/hooks/hooks.json alongside hooks/hooks.json in .codex-plugin so Codex registers SubagentStart without adding it to the Claude manifest.

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson

Copy link
Copy Markdown
Contributor Author

@BugBot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Single contract file now drives all host manifests, inventory digests,
and identity metadata. Generator runs in verify via generate:check;
version bumps regenerate manifests instead of patching five files by hand.

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson teallarson changed the title Add Codex/ChatGPT plugin hooks for lifecycle events Add Codex hooks and contract-driven manifest generation (GRO-353) Sep 15, 2026
Codex plugins cannot bundle custom agent roles yet; point users at
try-arcade and SubagentStart routing instead of a manual TOML install step.

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson

Copy link
Copy Markdown
Contributor Author

@BugBot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Extend inventory.json with hook_manifests digests so generate:check
catches drift on hooks/hooks.json and per-host adapter manifests.

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson

Copy link
Copy Markdown
Contributor Author

@BugBot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Cursor-only .cursor/rules/hooks-adapters.mdc does not reach Claude Code or
Codex contributors. AGENTS.md is the cross-host maintainer entry point.

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson teallarson changed the title Add Codex hooks and contract-driven manifest generation (GRO-353) Add Codex hooks and portable manifest adapters (GRO-353) Sep 15, 2026
@teallarson
teallarson marked this pull request as ready for review September 15, 2026 20:41
teallarson and others added 2 commits September 15, 2026 16:45
The portable manifest generator dropped listing fields when the contract
stack was removed. Codex and Cursor now show "Arcade" again, matching the
Claude marketplace listing.

Co-authored-by: Cursor <cursoragent@cursor.com>
* Stop agent fallback when Arcade gateway needs auth.

Add gateway-auth guardrails across try-arcade, arcade-operator, routing
guidance, and the Cursor rule, plus a beforeSubmitPrompt hook so Cursor
gets the same per-turn reminder Claude already has.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Use host-agnostic auth wording in shared session context.

SESSION_CONTEXT is injected into both Cursor and Claude SessionStart hooks;
referring to Cursor only sent Claude users to the wrong place.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Remove Cursor beforeSubmitPrompt hook that cannot inject context.

Cursor's beforeSubmitPrompt only allows or blocks prompts; additional_context
is ignored. Per-turn needsAuth guidance stays on the always-apply arcade rule.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Extend needsAuth guardrails to subagent routing context.

Rebase onto GRO-353 so SUBAGENT_CONTEXT includes the same no-substitute
auth block as session and prompt guidance, keeping CI marker checks green.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: distinguish auth from gateway failures

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson
teallarson requested a review from kamath September 16, 2026 22:03
teallarson and others added 3 commits September 17, 2026 10:03
Align Codex SessionStart with fork, vendored Codex I/O schemas, adapter manifest validation, support-matrix capabilities data, and verify:codex/cursor gates so client wiring drift fails CI before review.

Co-authored-by: Cursor <cursoragent@cursor.com>
Wire Claude SubagentStart, rename commands to arcade-* slugs, expose Codex
listing metadata via extensions.com.openai.interface, and sync support matrix
with machine-readable capabilities plus generated Cursor repository field.

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson

Copy link
Copy Markdown
Contributor Author

@BugBot review

1 similar comment
@teallarson

Copy link
Copy Markdown
Contributor Author

@BugBot review

@teallarson

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Keep polling when Bugbot returns neutral due to a push race so the gate
waits for a fresh review instead of failing immediately.

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread .github/workflows/check.yml Outdated
teallarson and others added 5 commits September 17, 2026 11:30
Skip routing injection when agent_type is arcade-operator, wire the full
local verify gate into GitHub Actions, and add hook contract coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
Parse Bugbot check-run JSON with jq so multiline summaries survive, and
treat neutral runs that report no issues as pass for the complete job.

Co-authored-by: Cursor <cursoragent@cursor.com>
Run wired Codex, Claude, and Cursor hook commands with substituted plugin-root tokens in verify, and ignore docs/research/ so audit notes stay local.

Co-authored-by: Cursor <cursoragent@cursor.com>
Document Codex plugin add and @arcade skill invocation, native Claude marketplace paths, reliable Cursor local install, and corrected VS Code and Copilot hook notes.

Co-authored-by: Cursor <cursoragent@cursor.com>
…view.

Align adapter schemas with parseVersion suffix support, copy extensions.com.openai.interface into the Codex fallback manifest, guard README hook counts in CI, and dedupe the verify chain.

Co-authored-by: Cursor <cursoragent@cursor.com>
@teallarson

Copy link
Copy Markdown
Contributor Author

@BugBot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 71e7b19. Configure here.

Comment thread .github/workflows/check.yml
teallarson and others added 3 commits September 17, 2026 14:47
The plugins CLI (v1.3.4) rejects --target copilot. Valid slug is
github-copilot. Align README and copilot install guide with measured CLI behavior.

Co-authored-by: Teal Larson <LARSON.TEAL@GMAIL.COM>
Codex 0.154.0 skips plugin hooks for Agent Plugin packages
(openai/codex#39895). Park the full Codex hook adapter on branch
cursor/park-codex-hooks-gro-353-f8ad and merge the rest of GRO-353 now.

This branch keeps manifest generation, Claude/Cursor lifecycle hooks,
Copilot operator projection, and extensions.com.openai.interface listing
metadata. Docs and support matrix no longer claim Codex hooks are active.
Use @arcade and bundled skills for Codex routing until upstream fixes the
loader gap.

Co-authored-by: Teal Larson <LARSON.TEAL@GMAIL.COM>
@teallarson teallarson changed the title Add Codex hooks and portable manifest adapters (GRO-353) portable manifest adapters (GRO-353) Sep 17, 2026
Incorporate binary repro from Codex 0.154.0: manifest parsing works for
extensions.com.openai and .codex-plugin fallback, but loader.rs discards
hook_sources for AgentPlugin format. Document #37027 as the introducing
change and note we do not ship the $schema-removal workaround.

Co-authored-by: Teal Larson <LARSON.TEAL@GMAIL.COM>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants