Problem
A bb plugin package manifest describes exactly one plugin, and a direct git: install currently treats the repository root as that plugin's root. This effectively requires either:
- one repository per plugin, or
- publishing every plugin package to npm before it can be installed remotely.
That is awkward for teams that develop several related plugins in one Bun/npm/pnpm workspace alongside shared tooling, docs, fixtures, and design apps.
Claude Code marketplaces provide useful prior art: a repository-level .claude-plugin/marketplace.json lists multiple independently installable plugins and points each entry at a relative directory within the repository.
Proposal
Support an optional repository-level bb plugin collection manifest, for example .bb/plugins.json:
{
"$schema": "https://getbb.dev/schemas/plugins.schema.json",
"schemaVersion": 1,
"name": "galligan-bb-plugins",
"plugins": [
{
"name": "agent-sidebar",
"source": "./plugins/agent-sidebar"
},
{
"name": "gitbutler-status",
"source": "./plugins/gitbutler-status"
}
]
}
Each source directory would remain a complete, ordinary bb plugin package with its own package.json and bb manifest. The repository manifest is only an index; it should not duplicate or override the package manifest's identity, compatibility, branding, or entry points.
A possible CLI shape:
bb plugin install git:https://github.com/galligan/bb-workbench.git@main --plugin agent-sidebar
The exact command syntax is open for discussion. A lower-level --subdirectory plugins/agent-sidebar option could provide the underlying primitive, while --plugin resolves a named entry from the repository manifest.
Expected behavior
- One Git or local repository can contain multiple independently installable plugins.
- Installation selects one plugin rather than enabling the whole collection.
- Relative sources resolve from the repository root.
- Each selected directory is validated using the existing plugin package-manifest rules.
- Installed provenance retains the repository URL, requested ref, resolved commit, and plugin subdirectory so
outdated, update, rollback, and status continue to work.
- A repository/commit is cloned or cached once when practical, even if several plugins from it are installed.
- Private repositories continue to use the existing Git credential flow.
- Local development works with the same collection manifest as remote Git installation.
Safety requirements
- Reject absolute paths, empty paths,
.. traversal, and symlinks that resolve outside the checked-out repository.
- Reject duplicate collection entry names and conflicting plugin IDs.
- Do not allow collection metadata to weaken
engines.bb, engines.bbPluginSdk, artifact metadata, or existing managed-install validation.
- A broken entry should fail independently without invalidating already-installed sibling plugins.
npm compatibility
This should complement, not replace, the existing npm installation path:
bb plugin install npm:bb-plugin-agent-sidebar@^1.0.0
Monorepos should still be able to publish individual workspace packages to npm. The repository manifest would mainly improve Git/local distribution, discovery, and development before or without npm publication.
Implementation note
The plugin persistence/update model already carries a Git subdirectory field, while direct Git installs currently record the subdirectory as null. That appears to provide some groundwork for retaining subdirectory provenance.
Acceptance criteria
- Document and validate a versioned repository-manifest schema.
- Install a named plugin whose package lives below the repository root.
- Add coverage for local paths, Git refs/commits, update checks, rollback, private-source behavior, and path traversal/symlink escapes.
- Document how repository collections relate to standalone Git packages, npm packages, and bb's official bundled plugin catalog.
Prior art
Claude Code's repository marketplace manifest supports a plugins array with relative source paths, an optional shared pluginRoot, and dedicated Git-subdirectory sources:
https://code.claude.com/docs/en/plugin-marketplaces
Problem
A bb plugin package manifest describes exactly one plugin, and a direct
git:install currently treats the repository root as that plugin's root. This effectively requires either:That is awkward for teams that develop several related plugins in one Bun/npm/pnpm workspace alongside shared tooling, docs, fixtures, and design apps.
Claude Code marketplaces provide useful prior art: a repository-level
.claude-plugin/marketplace.jsonlists multiple independently installable plugins and points each entry at a relative directory within the repository.Proposal
Support an optional repository-level bb plugin collection manifest, for example
.bb/plugins.json:{ "$schema": "https://getbb.dev/schemas/plugins.schema.json", "schemaVersion": 1, "name": "galligan-bb-plugins", "plugins": [ { "name": "agent-sidebar", "source": "./plugins/agent-sidebar" }, { "name": "gitbutler-status", "source": "./plugins/gitbutler-status" } ] }Each
sourcedirectory would remain a complete, ordinary bb plugin package with its ownpackage.jsonandbbmanifest. The repository manifest is only an index; it should not duplicate or override the package manifest's identity, compatibility, branding, or entry points.A possible CLI shape:
The exact command syntax is open for discussion. A lower-level
--subdirectory plugins/agent-sidebaroption could provide the underlying primitive, while--pluginresolves a named entry from the repository manifest.Expected behavior
outdated,update, rollback, and status continue to work.Safety requirements
..traversal, and symlinks that resolve outside the checked-out repository.engines.bb,engines.bbPluginSdk, artifact metadata, or existing managed-install validation.npm compatibility
This should complement, not replace, the existing npm installation path:
Monorepos should still be able to publish individual workspace packages to npm. The repository manifest would mainly improve Git/local distribution, discovery, and development before or without npm publication.
Implementation note
The plugin persistence/update model already carries a Git subdirectory field, while direct Git installs currently record the subdirectory as
null. That appears to provide some groundwork for retaining subdirectory provenance.Acceptance criteria
Prior art
Claude Code's repository marketplace manifest supports a
pluginsarray with relativesourcepaths, an optional sharedpluginRoot, and dedicated Git-subdirectory sources:https://code.claude.com/docs/en/plugin-marketplaces