| A private plugin for my team. You keep the source in your own repository and install it from a checkout or a tarball, never from npm. |
Getting started: a plugin from an empty directory |
| Try a plugin from a git checkout. Someone sent you a branch; you want it running in your bb in five minutes and gone in one. |
Getting started: a plugin from an empty directory |
Ship a plugin to npm. You want bb plugin install npm:@acme/bb-plugin-counter to work for people who have never seen your code. |
Getting started: a plugin from an empty directory |
| Add one CLI word and one service to bb without touching bb. The counter is small on purpose; every later page grows it. |
Getting started: a plugin from an empty directory |
Expose my data to agents and humans with one definition. One method() gives you bb ticket list, GET /api/v1/tickets/tickets/list, and sdk.plugins.tickets.tickets.list({}); the next page turns the same method into a tool. |
Services: one definition, every surface |
Receive webhooks. A kind: "custom" method with auth: "none" is a raw HTTP endpoint under your plugin's route prefix, with the body and headers in your hands. |
Services: one definition, every surface |
Call another plugin's service. requires in the manifest plus ctx.inject(contract, range) gives you a typed handle on threads/threads without importing its code. |
Services: one definition, every surface |
Stream a feed. A stream method is SSE over HTTP, NDJSON on the CLI, and for await in the SDK. |
Services: one definition, every surface |
Let agents file a ticket in my tracker. One expose flag plus a presentation; the agent gets tickets_tickets_create with a JSON Schema, a label, and an icon. |
Agent tools and agent configuration |
Inject project rules into every agent. ctx.agents.contributeInstructions(text) appends to the system prompt of every thread, or of one project. |
Agent tools and agent configuration |
Turn a tool off for manager threads. A resolver decides per turn which tools a thread sees; here top-level threads lose tickets_tickets_create and their child threads keep it. |
Agent tools and agent configuration |
Ship a skill with my plugin. contributes.guide puts your prose in the generated bb skill today; contributes.skills ships a SKILL.md directory in the artifact. |
Agent tools and agent configuration |
| Block sends to a frozen thread. The project is archived, or your own policy freezes it, and the send never reaches the executor. |
Commands and interception |
| Add a footer to every prompt. A human or an agent sends a prompt; your text rides along as one more part. |
Commands and interception |
| Post to Slack when a thread goes idle. The trigger is a status transition on the thread row, not a command. |
Commands and interception |
| Auto-archive threads older than N days. A background service runs the sweep once an hour through the bus. |
Commands and interception |
Audit every thread.create. One log line per dispatch, with the actor and the duration. |
Commands and interception |
| Keep an API token out of my code. You hold a reference; the value never passes through your logs or your database. |
Data and settings |
| Remember a per-thread preference. A sort order the user sets on one thread stays on that thread. |
Data and settings |
| Own a table with migrations. Your rows live in your own SQLite file, and the schema evolves with the plugin. |
Data and settings |
| Expose a setting to Settings and to agents. The user edits it in Settings, agents read it through the CLI, and the plugin says "I need configuration" instead of failing. |
Data and settings |
| Show a live dashboard of my rows. It updates when the CLI, an agent, or another browser changes them. |
Realtime |
| Update a badge when a thread changes status. bb's own entity events reach your component the same way. |
Realtime |
| Stream a long job's progress. Each job's frames reach the browser under the job's own key; nothing refetches a list. |
Realtime |
| Listen on the server without polling. Your own events and bb's arrive on one bus. |
Realtime |
Add a button to the sidebar. sidebar.footer is a list slot; every occupant renders. |
UI slots |
Replace bb's thread list. sidebar.body is a single slot, and Original keeps the stock list inside your wrapper. |
UI slots |
Badge only the thread rows that need one. threadList.row.trailing is a list slot filtered with when. |
UI slots |
Paint one kind of timeline row. timeline.row is a keyed slot with one winner per key. |
UI slots |
Let other plugins extend your panel. Declare a child slot with children and they register into it. |
UI slots |
A dashboard page with its own URL. A pane kind plus a route such as /deploy/:releaseId. |
Pages, panes, navigation, and commands |
Open your pane next to a thread. A thread.header.actions button opens it in a new split. |
Pages, panes, navigation, and commands |
A keyboard shortcut for your command. deploy.open bound to Mod+Shift+D by default. |
Pages, panes, navigation, and commands |
A toast when a background job finishes. A query invalidated by the job's wire event drives useToasts. |
Pages, panes, navigation, and commands |
Confirm before a destructive action. The shell's ui-shell/dialogs service asks the question. |
Pages, panes, navigation, and commands |
Render your tool's result as a card. The tool-ui:<pluginId>/<renderer> rung of timeline.row. |
Timeline rows, interactions, and the composer |
A custom row for your provider's events. The <providerId>:<kind> and <pluginId>/<kind> rungs. |
Timeline rows, interactions, and the composer |
Ask the user a structured question. providers/interactions.request on the server plus an interaction.renderer occupant. |
Timeline rows, interactions, and the composer |
A /deploy action in the composer. A composer.plusMenu row and a composer.actions button. |
Timeline rows, interactions, and the composer |
A banner or a submit gate. composer.stack for a branch-behind banner, composer.submit for a gate while a release runs. |
Timeline rows, interactions, and the composer |
Run a linter over the workspace and report. The server half calls a host command, the role spawns eslint in the workspace, and the result comes back typed. |
The host tier |
Read a config file from the repo on demand. A service method answers bb repo config <root> .bbrc from the host that owns the directory. |
The host tier |
Tail a log file and push lines to the server. The role emits a log-line signal per line; the server half receives it through onSignal. |
The host tier |
Run a long job on a remote machine's host. The same command with { hostId } runs on an enrolled host; timeoutMs sets the deadline. |
The host tier |
Run a workspace-local build tool. pnpm exec tsc in the repo's own node_modules, which only the host has. |
The host tier |
A scratch directory per thread. A throwaway root under the role's data dir; env-local/scratch does this, and the example below adds a repo copy. |
Environment providers |
Run threads in a container. A custom handle is the spec's answer, but as built it cannot run a thread (see What you build); mount a local-path root the container shares instead. |
Environment providers |
An environment on a remote host. The same provider runs on any enrolled host once its artifact is ensured there; environments.provision { hostId } picks the host. |
Environment providers |
Isolate experiments from the checkout. A copy that never touches the user's working tree, unlike local-dir. |
Environment providers |
| Add a new coding agent to bb. Any agent with a scriptable interface (a CLI, an SDK, an HTTP stream) becomes a provider users pick in the composer. |
Provider plugins |
Override how your provider's commands render. A keyed timeline.row occupant at acme:command with Original as the fallback. |
Provider plugins |
Report rate limits to the UI. One provider.rateLimits delta plus a provider.error { category: "rate_limit" } when a turn is refused. |
Provider plugins |
Ask the user before the agent runs a command. A blocking interaction/request with a command subject; core auto-denies it under escalation: "deny". |
Provider plugins |
| Unit-test a handler with its real schema. Defaults filled, bad input refused, the mutation reachable as a command and as a tool. |
Testing |
Render a slot component in isolation. The owner props the real owner would pass, and a fake server service behind useService. |
Testing |
Guard the derived surfaces in CI. The CLI word and the agent tool derive from defineService before anyone runs bb plugin build. |
Testing |
Prove a realtime refetch. An event on the socket refetches your defineQuery without a reload. |
Testing |
Call a host command without a process. The machine tier's handler runs over a fake RoleContext. |
Testing |
| Customize a first-party screen. The thread list, the timeline, or the composer, without maintaining a fork of bb. |
Composition, forks, and distribution |
Make my thread list the default. You wrote your own and want it to win sidebar.body on this machine. |
Composition, forks, and distribution |
| Ship an update with a rollback. One command updates an installed plugin; one command puts the old version back. |
Composition, forks, and distribution |
| Flip an experiment or a bundled row. Enable an experiment that ships disabled, or disable a bundled plugin. |
Composition, forks, and distribution |
Boot a development plugin from a patch file. bb-server --patch, as the smoke does. |
Composition, forks, and distribution |
Port custom-instructions. The smallest 0.4 plugin: one RPC, one CLI word, one instructions contribution, one settings section. |
Migrating from 0.4 |
Port keep-awake. A plugin with a host tier: a host entry with one command, a server reconciler, a settings section. |
Migrating from 0.4 |
| Port a plugin with a nav panel. Decide whether to wait for the page slots or ship on a built slot today. |
Migrating from 0.4 |
Know what is deleted outright. Which 0.4 members have no successor, and what to remove from docs/api_to_audit.md. |
Migrating from 0.4 |