Reference
Draft 1, 2026-08-21. Assembled from @get-bb/plugin-sdk/api.lock.json (the locked surface), the SDK README, the spec sections under next/docs/sections/, the as-built notes in next/docs/stage-2/04-kernel-as-built.md, and the reference plugin next/examples/plugins/hello-slot. Source tree: branch bb/rewrite-bb-app-from-scratch-thr_e2n9n5n7i6 at dc07292bf (local only). The sections were written against 6f3d4592f and updated for the dc07292bf delta listed in §0.7.
0. How to read this document
0.1 Scope
This document describes what a plugin author can import, declare, and call. It does not describe the kernel's internals. Where the spec and the built kernel differ, the built kernel wins; the "As built" column names the deviation (D1–D20, see Appendix A) or the source file.
0.2 Entry points
A plugin imports one package, @get-bb/plugin-sdk, through seven entry points. Each entry runs in one place.
| Entry | Runs in | Section |
|---|---|---|
@get-bb/plugin-sdk (root) |
the core process; same as /server |
§3 |
@get-bb/plugin-sdk/server |
the core process (in-process, or a plugin:<id> worker for marketplace installs) |
§3 |
@get-bb/plugin-sdk/app |
the browser, through the import map | §4, §5 |
@get-bb/plugin-sdk/host |
a host-role child process on a machine | §6 |
@get-bb/plugin-sdk/bridge |
the provider bridge child process; the declaration also loads in core | §7 |
@get-bb/plugin-sdk/contracts |
every tier and the browser; schemas only, no runtime side effects | §2 |
@get-bb/plugin-sdk/testing |
tests only | §9 |
A plugin may also import @bb/ui (the component kit, on the import map) and other plugins' published contracts modules (@get-bb/plugin-<id>/contracts). It imports nothing else from bb.
0.3 Tiers at a glance
(The import and reducers tiers, and the build outputs per tier, are in §1.6.)
| Tier | Manifest key | Default export | Receives |
|---|---|---|---|
| server | bb.server |
definePlugin({ activate(ctx, config), background? }) |
ctx: PluginContext (§3) |
| app | bb.app |
definePluginApp({ setup(app, config) }) |
app: PluginAppApi (§4) |
| host | bb.host |
defineHostEntry({ roles, signals, dispose }) |
RoleContext per role (§6) |
| contracts | bb.contracts |
named exports built with defineService, defineEvent, … |
— (§2) |
| cli | bb.cli |
defineOfflineHandlers({...}) — not built; the entry is spec-only (03 §5.9; Appendix B) |
local files only |
At least one of server, app, host is required. A package with a non-empty provides must set contracts.
0.4 One definition, five surfaces
A service method is defined once with defineService/method. The kernel derives the HTTP route (/api/v1/<pluginId>/<service>/<kebab-method>), the typed SDK call, the bb CLI word, the agent tool (<plugin>_<service>_<method>), and the reference docs from that one definition (§8). Every mutation method is also a command on the bus with an actor, before interceptors, and after listeners (§3.4).
0.5 Conventions
- Signatures are abridged: optional fields carry
?, defaults are shown as= value. - Spec cites are
NN §x.y(section fileNN-*.md). Built cites areD#or a path undernext/packages/.README deviation Nis the numbered entry under "Deviations from the spec" inpackages/plugin-sdk/README.md;kernel-host README deviationlikewise. - Identifiers: plugin ids match
^[a-z0-9][a-z0-9-]{0,63}$(PLUGIN_ID_RE, §1.1); service ids are<pluginId>/<serviceName>; event names are<pluginId>/<name>(kernel events arekernel/<name>); command names are<noun>.<verb>; extension kinds are<pluginId>/<kind>; core kinds are bare snake_case (file_change,web_search). - No member carries an
experimental_prefix. The surface is reviewed throughapi.lock.json; adding or renaming an export edits that file in the same change. - Sentences use present tense and active voice.
0.6 Known open questions for authors
Product decisions this document does not make. Each line names the gap, the fact as built, and what is undecided.
engines.bbandpeer["@bb/ui"]for a 1.0 plugin (§1.2): the core and@bb/uiare0.0.0in the tree (apps/bb-app/package.json,packages/ui/package.json) and hello-slot omits both, so the defaults*apply. The version strings a 1.0 plugin should pin are not decided.- Published dependency ranges (§1.5):
@get-bb/plugin-sdkis1.0.0-next.0(packages/plugin-sdk/package.json),@bb/uihas no published version, and the example usesworkspace:*. The ranges an out-of-tree plugin writes are not decided. target: "host"(§2.2, D5): answers 503service_unavailable. Which release flips D5 is not decided.bb plugin new(§1.7, 01 §3.1): not in@bb/plugin-build. Whether it ships, and with which skeleton, is not decided; §1.5 has the hand-written starter.ctx.hostClientin the product (§3.9, D15): resolved atdc07292bf— core passescreateHostClients(...).clientForto the loader (packages/core/src/core.ts), so a server tier reaches itsrpcrole. The stage-2/04 D15 note predates this commit.
0.7 Changes at dc07292bf (the Stage 2 domain integration)
@get-bb/plugin-sdk/serverexportswithDefaults(def, handlers)(§3.3).contributes.commands.nounsadmits dotted nouns:^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)*$(§1.3).- New kernel services:
kernel/store.eventsAppend,kernel/host-runtime,kernel/bridge-driver;kernel/storegainsqueueGet,projectsGet,environmentsGet,attachmentsGet,threadsByEnvironment(§3.11). EnvironmentProvider.provisionreceivessource: ProjectSource | null; the role answersenv/describe;EnvironmentsPortgainssummarizeanddescribe; provision progress ridesenv.progressnotifications, not a stored event (§6.5).HostView.homeDir: string | nullonkernel/hosts.list|get(§3.11).ctx.hostClientis wired in core (§3.9; supersedes D15).- CLI: a variadic positional of structured items keeps a non-JSON word as a string (§8.4);
bb plugin install <source>has its positional (closes D9's gap). - A
usesre-run is one observable step: teardown and re-activation in one registry batch; a handle follows a same-generation re-provide instead ofstale_handle(§3.3).