Shape: Plugin

A Claude plugin ships as a versioned bundle that lands in the Claude marketplace via a release branch rather than via a deploy to a running server. The branch IS the release artifact: you tag a version, the marketplace fetches it. You do not have a "staging URL" or a "production URL" in the conventional sense; the channel reads from the branch.

When this shape applies

  • You author a Claude plugin (or any artifact whose release surface IS a git branch).
  • No deployable environment exists -- the marketplace pulls from main (or a release tag), and that is the entire release pipeline.
  • You want /gaia-publish to drive the release, not /gaia-deploy (which would HALT on the kind gate -- there is nothing to deploy to).

project-config.yaml

The two load-bearing pieces are environments[].kind: branch-only and the distribution: block pointing at channel: claude-marketplace. The kind discriminator tells /gaia-help and /gaia-deploy that this environment is published, not deployed.

environments:
  - id: marketplace
    name: Claude Marketplace
    kind: branch-only
    branch: main

distribution:
  channel: claude-marketplace
  registry: https://anthropic.com/marketplace
  manifest: plugin.json
  release_workflow: gaia-release.yml

The manifest field MUST point at plugin.json -- that is the version-bearing file the marketplace reads. The release_workflow field MUST resolve to a workflow file under .github/workflows/ that publishes the artifact on tag push.

Phase 5 routing

When you run /gaia-help, the Phase 5 router reads environments[*].kind + the presence of distribution:. With kind: branch-only and a distribution: block, the router emits publish-primary and suggests /gaia-publish as the primary release command. It does NOT suggest /gaia-deploy -- that command refuses non-deployable kinds with the use /gaia-publish instead guidance.

CI overlays

Generated workflows live at .github/workflows/gaia-*.yml (the gaia- prefix contract). If you need custom jobs or steps, add overlay files alongside:

# .github/workflows/gaia-ci.user-jobs.yml
jobs:
  publish-changelog:
    runs-on: ubuntu-latest
    steps:
      - run: echo "publish CHANGELOG.md to marketplace metadata"

The stitching engine merges your user-jobs.yml jobs into the managed jobs: map at /gaia-config-ci --regenerate time. Protected job names (e.g., bats-tests, commitlint) cannot be overridden -- the protected-jobs assertion refuses any user-job with a colliding name.

Publish to claude-marketplace

Once /gaia-config-validate passes, run:

/gaia-publish

The orchestrator reads distribution.channel: claude-marketplace, dispatches the publish-claude-marketplace adapter, and posts the release. The adapter reads distribution.manifest for the version (from plugin.json) and distribution.release_workflow for the CI workflow that actually publishes.

You'll know it worked when

  • /gaia-config-validate exits 0 with no migration WARNING.
  • /gaia-help suggests /gaia-publish as the Phase 5 primary action.
  • /gaia-deploy HALTs with environment 'marketplace' is kind: branch-only -- use /gaia-publish instead.
  • A successful /gaia-publish run posts the release to the marketplace and the version in plugin.json matches the tag pushed by release_workflow.