Skip to content

Support multi-plugin repositories with a collection manifest #1097

Description

@galligan

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions