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 includenameanddescription;allowed-tools: Bashand instructions for shelling out tobrowse. This is a manual copy of the canonicalstagehand/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 asSKILL.md's body, verbatim. After editingskills/browse/SKILL.md, runnode scripts/sync-gemini.mjsto regenerateGEMINI.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
namenot kebab-case, or not matching a marketplace entry name. - Missing
.cursor-plugin/plugin.jsonat repo root. - Missing frontmatter keys (
name,description) inSKILL.md. - Broken relative paths for
logoorskillsin a manifest. - A marketplace
source/pathpointing at anything other than"."— this repo has no nested plugin folder anymore. - Editing
skills/browse/SKILL.mdwithout runningnode scripts/sync-gemini.mjsafterward — CI fails ifGEMINI.mddrifts out of sync. - Bumping
plugin.json'sversionwithout runningnode scripts/sync-version.mjsafterward — CI fails if the other manifests drift out of sync.