feat(dist): build and publish per-agent plugin distributions#158
feat(dist): build and publish per-agent plugin distributions#158evanpurkhiser wants to merge 1 commit into
Conversation
b5ce219 to
68ee821
Compare
`main` is the single source of truth for skills and routing metadata, but it is not itself an installable plugin, and Claude Code, Cursor, and Codex each expect the plugin in a different on-disk shape. No plugin ecosystem can consume a zip or release asset; all install from a git ref. So a GitHub Actions workflow builds each agent's distribution from `main` and publishes it to an orphan `dist-<agent>` branch whose root is exactly that agent's plugin, which a marketplace points at as `getsentry/sentry-for-ai@dist-<agent>`. Each agent has a `plugin-src/<agent>/` dir with its manifests, README, and a `build.sh` that assembles the dist tree from shared repo content. Claude and Cursor consume the plugin at the branch root; Codex requires it under `plugins/sentry/` and rejects the `disable-model-invocation` field the skill tree relies on, so its build strips that field and emits a per-skill `agents/openai.yaml` with `policy.allow_implicit_invocation: false` (see `hide-skills.py`). Before publishing, each build runs a `validate.sh` gate: Claude and Cursor manifests are checked against their published JSON Schemas via `check-jsonschema`, and Codex runs OpenAI's `validate_plugin.py`. Claude manifests embed `$schema` for editor autocomplete; Cursor and Codex forbid unknown keys, so theirs supply the schema only at validation time.
| plugin-src/codex/build.sh /tmp/sentry-codex # or plugin-src/claude / plugin-src/cursor | ||
| ``` | ||
|
|
||
| Then install from the built directory: |
There was a problem hiding this comment.
Bug: The README's build example only shows how to build the codex plugin, but subsequent installation steps reference directories for claude and cursor which would not exist.
Severity: LOW
Suggested Fix
Expand the build example to explicitly show the build commands for all three agents (claude, codex, and cursor). Alternatively, move the general instruction To build any target locally, run 'plugin-src/<agent>/build.sh <output-dir>' to before the specific code block to provide necessary context upfront.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: README.md#L107-L110
Potential issue: The "Build it yourself" section in the README.md provides an incomplete
example. It shows the build command `plugin-src/codex/build.sh /tmp/sentry-codex` but
then lists installation steps for Claude, Codex, and Cursor, which expect directories
`/tmp/sentry-claude`, `/tmp/sentry-codex`, and `/tmp/sentry-cursor` to exist. A user
following these instructions literally would encounter 'path does not exist' errors for
the Claude and Cursor plugins, as only the `codex` directory would have been created. A
later note clarifies the general build pattern, but it appears after the misleading
example.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f487ae7. Configure here.
|
|
||
| # Validate the built tree against the agent's schema/validator before | ||
| # it can be published. | ||
| "plugin-src/${AGENT}/validate.sh" "$WORKTREE" |
There was a problem hiding this comment.
Dist publish skips skill tree
Medium Severity
The dist publish job copies SKILL_TREE.md from main without running scripts/build-skill-tree.sh --check. Skill-tree validation runs only on pull requests, so a stale or inconsistent index on main can still be built and pushed to install branches.
Reviewed by Cursor Bugbot for commit f487ae7. Configure here.


What
mainis the single source of truth for skills, but it is not itself an installable plugin. Each assistant needs the plugin in a different shape, so this adds a build that produces a per-agent plugin frommainand publishes each to its own branch.plugin-src/<agent>/holds each agent's source: a flatplugin.jsonandmarketplace.json, a user-facingREADME.md(shipped into the dist), and abuild.shthat assembles that agent's output layout. Shared content (skills/,commands/,assets/, MCP config,SKILL_TREE.md) stays at the repo root..github/workflows/build-dist.ymlruns all three builds on every push tomainand commits each to an orphan branch whose root is that agent's plugin:dist-claude,dist-cursor,dist-codex. The three jobs touch three different branches, so they run in parallel.README.md(with a do-not-edit notice) and aLICENSE..claude-plugin,.cursor-plugin) are no longer at the repo root, somain's root is no longer itself a plugin; every agent is produced only through its build. Note: Anthropic's official marketplace currently points at the repo root, so it would need repointing to@dist-claude.Why
No plugin ecosystem (Claude, Cursor, Codex) can consume a zip or release asset; all of them install from a git ref. Publishing each built plugin to a branch lets a marketplace point at
getsentry/sentry-for-ai@dist-<agent>.Claude and Cursor consume a plugin at the dist branch root, but Codex requires the plugin in a subdirectory and rejects the
disable-model-invocationfield the skill tree relies on. The Codex build moves the plugin underplugins/sentry/, strips that field, and emits a per-skillagents/openai.yamlwithpolicy.allow_implicit_invocation: false, which is Codex's native equivalent. The router skills stay visible and the leaf skills stay hidden, fully bundled, with no skills.sentry.dev dependency.Live preview (built on my fork)
Verified installs from those branches:
Setup needed before this works in this repo
The workflow appends commits to existing orphan branches. Bootstrap them once, then the workflow maintains them:
Follow-ups (not in this PR)