Repo layout

July 16, 2026 · View on GitHub

This repo is a static, single-plugin catalog — repo root is the browse plugin, one plugin per repo. No application code, no build step. The plugin is CLI-only (a SKILL.md that shells out to a real CLI) — no MCP config, so there's no API key to embed in this public, git-pinned repo.

If Browserbase ever needs a second distinct plugin, it belongs in its own dedicated repo — not nested inside this one. A nested plugins/<name>/ layout breaks third-party tools (e.g. Hermes Agent's skill "tap") that scan for skills/ at repo root by convention.

Layout

.
├── .claude-plugin/marketplace.json      # Claude Code marketplace (source: ".")
├── .claude-plugin/plugin.json           # Claude Code plugin manifest
├── .codex-plugin/plugin.json            # Codex plugin
├── .cursor-plugin/marketplace.json      # Cursor marketplace (source: ".", repo validator reads this)
├── .cursor-plugin/plugin.json           # Cursor plugin manifest
├── .agents/plugins/marketplace.json     # Generic .agents marketplace (path: ".")
├── .grok-plugin/plugin.json             # Grok plugin
├── gemini-extension.json                # Gemini CLI extension
├── GEMINI.md                            # Gemini context file (CLI-only, no mcpServers)
├── plugin.json                          # Open Plugin spec manifest (vendor-neutral, e.g. `npx plugins add`)
├── assets/logo.svg
├── skills/browse/SKILL.md               # YAML frontmatter: name + description
└── scripts/
    ├── validate-template.mjs            # run by CI and locally, see "Validate" below
    ├── gemini-sync.mjs                  # shared logic: derive GEMINI.md's expected content from SKILL.md
    ├── sync-gemini.mjs                  # regenerates GEMINI.md; --check fails without writing
    ├── version-sync.mjs                 # shared logic: reads the version every manifest must match
    └── sync-version.mjs                 # propagates plugin.json's version to the others; --check fails without writing

Every per-format plugin.json's "skills" and "logo" fields are relative to repo root (./skills/, assets/logo.svg), and every root marketplace file's "source"/"path" is ".". The root plugin.json is a separate, vendor-neutral manifest (Open Plugin spec v1.0.0); it doesn't replace or override any per-client manifest and only needs updating when the plugin's name, version, or metadata changes.

Updating the skill

  • skills/browse/SKILL.md — YAML frontmatter must include name and description; allowed-tools: Bash and instructions for shelling out to browse. This is a manual copy of the canonical stagehand/packages/cli/skills/browse/SKILL.md — edit there and re-copy here. Automated copy-on-release sync is tracked in stagehand#2330.
  • GEMINI.md — Gemini's extension format has no way to reference an external skill file, so it carries the same instructions as SKILL.md's body, verbatim. After editing skills/browse/SKILL.md, run node scripts/sync-gemini.mjs to regenerate GEMINI.md. CI fails if the two drift out of sync.
  • assets/logo.svg — the marketplace display logo.

Bumping the version

plugin.json's version tracks this repo's own release tags (v0.1.0, v0.2.0, ...), the same as the git tags already used for GitHub Releases. The published Cursor marketplace listing is built by release.yml, which only runs on a tag push — merging to main alone doesn't update it. plugin.json is the single source of truth for the other four: .claude-plugin/plugin.json, .cursor-plugin/plugin.json, .grok-plugin/plugin.json, and gemini-extension.json must all match it exactly.

To cut a release, bump plugin.json's version and run:

node scripts/sync-version.mjs

CI fails if any of the five drift out of sync. Once that PR merges to main, a second CI job (tag-release, in .github/workflows/validate.yml) detects the version change and pushes the matching vX.Y.Z tag automatically — no one runs git tag by hand. That tag push is what triggers release.yml to actually validate, package, and publish the release. If plugin.json's version didn't change on a given push to main, or a tag for that version already exists, tag-release is a no-op.

Validate

node scripts/validate-template.mjs

Fix all reported errors before committing. This also runs in CI on every pull request and on pushes to main (.github/workflows/validate.yml).

Common pitfalls

  • Plugin name not kebab-case, or not matching a marketplace entry name.
  • Missing .cursor-plugin/plugin.json at repo root.
  • Missing frontmatter keys (name, description) in SKILL.md.
  • Broken relative paths for logo or skills in a manifest.
  • A marketplace source/path pointing at anything other than "." — this repo has no nested plugin folder anymore.
  • Editing skills/browse/SKILL.md without running node scripts/sync-gemini.mjs afterward — CI fails if GEMINI.md drifts out of sync.
  • Bumping plugin.json's version without running node scripts/sync-version.mjs afterward — CI fails if the other manifests drift out of sync.