Providers

bb.providers owns provider choice, the provider bridge protocol, and shared provider host control.

Purpose

The plugin gives each provider ID one replaceable implementation. It gives consumers one registry for models, health, usage, and maintenance.

The plugin also owns the typed server-to-host bridge. Provider plugins translate their native agent protocol into this common protocol.

The kernel still owns host transport and process isolation. bb.providers owns provider sessions, request control, recovery, and maintenance above those kernel ports.

Built-in provider plugins

The built-in provider plugins use the same contracts as all other provider plugins.

Plugin ID Provider implementation
bb.claude-code Claude Code
bb.codex Codex
bb.pi Pi
bb.acp The ACP family: Cursor, Pi ACP, and do.computer

Each plugin claims bb.providers.provider, keyed by provider ID. Each plugin supplies its own keyed bb.providers.bridge host-role implementation and bridge artifacts.

These plugins have no special privilege. A marketplace provider claims the same contract and uses the same winner rules.

A fork claims the same keys and enters the normal winner selection. A provider plugin fork follows the same rules as any other plugin fork.

Surfaces

ID kind replaceable props contract sketch notes
None This plugin declares no app surface. Threads owns provider controls in the composer. Settings owns provider maintenance pages.

Services

ID kind replaceable contract notes
bb.providers single yes ProvidersService The first-party implementation is the default provider.
bb.providers.provider keyed by provider ID yes Provider The current claimant supplies one provider ID. Each key has its own winner and fallback.

bb.providers

This service is the registry and control plane. Read methods use the current winner for each provider key.

Method Result Notes
list(query?) ProviderRecord[] Lists visible provider keys and winner state.
get(providerId) ProviderRecord | null Reads one provider key without a host call.
resolve(providerId) Provider Returns the live keyed provider handle.
watch(listener) Unsubscribe Reports add, change, winner, health, and removal events.
models(providerId, context) ModelCatalog Uses the host cache and the declaration fallback list.
health(providerId, context) ProviderHealth Runs a sessionless health request.
usage(providerId, context) ProviderUsage Reads provider account limits.
installationStatus(providerId, context) ProviderInstallationStatus Reads the CLI state and available action.
runInstallation(providerId, context, action) ProviderInstallationRunResult Runs one declared install or update action.
export interface ProvidersService {
  list(query?: ProviderListQuery): Promise<readonly ProviderRecord[]>;
  get(providerId: string): Promise<ProviderRecord | null>;
  resolve(providerId: string): Promise<Provider>;
  watch(listener: (event: ProviderRegistryEvent) => void): Unsubscribe;
  models(providerId: string, context: ProviderHostContext): Promise<ModelCatalog>;
  health(providerId: string, context: ProviderHostContext): Promise<ProviderHealth>;
  usage(providerId: string, context: ProviderHostContext): Promise<ProviderUsage>;
  installationStatus(
    providerId: string,
    context: ProviderHostContext,
  ): Promise<ProviderInstallationStatus>;
  runInstallation(
    providerId: string,
    context: ProviderHostContext,
    action: "install" | "update",
  ): Promise<ProviderInstallationRunResult>;
}

export interface ProviderRecord {
  providerId: string;
  declaration: ProviderDeclaration;
  winner: { pluginId: string; generation: number; isDefault: boolean };
  claimants: readonly { pluginId: string; version: string; state: ProviderClaimState }[];
  availability: "ready" | "unavailable" | "degraded" | "failed";
  lastFailure?: ProviderFailure;
}

export type ProviderRegistryEvent =
  | { kind: "added" | "changed"; record: ProviderRecord }
  | { kind: "winner-changed"; providerId: string; previousPluginId: string; record: ProviderRecord }
  | { kind: "removed"; providerId: string }
  | { kind: "health-changed"; providerId: string; health: ProviderHealth };

A keyed winner change uses the backend replacement transaction. The candidate must become ready before cutover.

The runtime drains old calls to a deadline. It then restarts required dependents in graph order.

The first claim for a new key must declare itself as that key's default. A later replacement claim cannot change this fallback.

bb.providers.provider

Each claim implements one provider ID. The declaration is static, but the methods can use settings and host state.

Method Result Notes
declaration() ProviderDeclaration Returns the claim data from contract.json.
deriveOptions(context) JsonObject Derives per-command bridge options.
models(context) ModelCatalog Returns a live catalog or the fallback catalog.
health(context) ProviderHealth Uses the bridge only when the declaration enables health.
usage(context) ProviderUsage Uses the bridge only when the declaration enables usage.
installationStatus(context) ProviderInstallationStatus Uses shared maintenance probes.
runInstallation(context, action) ProviderInstallationRunResult Uses a declared command and verification rule.
resolveNativeRoots(context) ProviderResolvedNativeRoots Resolves host-specific skill and command roots.
openSession(context) ProviderSession Opens one supervised bridge session.
export interface Provider {
  declaration(): ProviderDeclaration;
  deriveOptions(context: ProviderOptionsContext): Promise<JsonObject>;
  models(context: ProviderHostContext): Promise<ModelCatalog>;
  health(context: ProviderHostContext): Promise<ProviderHealth>;
  usage(context: ProviderHostContext): Promise<ProviderUsage>;
  installationStatus(context: ProviderHostContext): Promise<ProviderInstallationStatus>;
  runInstallation(
    context: ProviderHostContext,
    action: "install" | "update",
  ): Promise<ProviderInstallationRunResult>;
  resolveNativeRoots(context: NativeRootsContext): Promise<ProviderResolvedNativeRoots>;
  openSession(context: ProviderSessionContext): Promise<ProviderSession>;
}

export interface ProviderSession {
  start(input: ThreadStartRequest): Promise<ThreadIdentityResult>;
  resume(input: ThreadResumeRequest): Promise<ThreadIdentityResult>;
  fork(input: ThreadForkRequest): Promise<ThreadIdentityResult>;
  stop(input: ThreadStopRequest): Promise<void>;
  discard(input: ThreadIdentityRequest): Promise<void>;
  archive(input: ThreadIdentityRequest): Promise<void>;
  unarchive(input: ThreadIdentityRequest): Promise<void>;
  setName(input: ThreadNameSetRequest): Promise<void>;
  clearGoal(input: ThreadIdentityRequest): Promise<void>;
  startTurn(input: TurnStartRequest): Promise<void>;
  steerTurn(input: TurnSteerRequest): Promise<void>;
  configureSkills(input: SkillsConfigureRequest): Promise<void>;
  close(): Promise<void>;
}

Provider declaration

The contract uses the liked 1.0 declaration shape. It makes static choices reviewable before code starts.

export interface ProviderDeclaration {
  id: string;
  displayName: string;
  family?: string;
  icon?: string;
  visibility: "always" | "installed";
  capabilities: ProviderCapabilities;
  composerActions: readonly ("plan" | "goal")[];
  strings?: ProviderStrings;
  serviceTiers?: readonly ProviderOption[];
  reasoningLevels?: readonly ProviderOption[];
  maintenance?: ProviderMaintenance;
  extensionKinds?: Readonly<Record<string, ProviderExtensionKind>>;
  models?: {
    fallback?: readonly ProviderFallbackModel[];
    scope?: "host" | "workspace";
  };
  env?: { passthrough: readonly string[] };
  bridgeOptions?: JsonObject;
  nativeRoots?: {
    skills?: readonly ProviderNativeRoot[];
    commands?: readonly ProviderNativeRoot[];
    resolveOnHost?: boolean;
  };
}

export interface ProviderCapabilities {
  supportsServiceTier: boolean;
  supportsNativeUserQuestion: boolean;
  fork: "none" | "thread" | "checkpoint";
  supportsManualCompaction: boolean;
  supportsThreadArchive: boolean;
  supportsThreadRename: boolean;
  permissionModes: readonly ("accept-edits" | "auto" | "full")[];
  reasoningLevels: readonly string[];
}

export interface ProviderStrings {
  signInHint: string;
  expiredHint: string;
  installUrl: string;
  brandPrefix?: string;
  planModeCopy?: string;
  iconTint?: { light: string; dark: string };
}

export interface ProviderOptionsContext {
  threadId: string;
  projectId: string;
  model: string;
  permissionMode: "accept-edits" | "auto" | "full";
  promptMode?: "plan";
  settings: Readonly<Record<string, string | boolean | undefined>>;
}

export interface ProviderFallbackModel {
  id: string;
  displayName: string;
  description: string;
  supportedReasoningEfforts: readonly {
    reasoningEffort: string;
    description: string;
  }[];
  defaultReasoningEffort: string;
  isDefault: boolean;
}

export interface ProviderOption {
  id: string;
  label: string;
  description?: string;
}

export interface ProviderExtensionKind {
  item?: StandardSchemaV1;
  state?: StandardSchemaV1;
}

export interface ProviderNativeRoot {
  id: string;
  path: string;
}

The build checks each extension item and state schema. The runtime rejects an undeclared extension kind.

Bridge protocol

bb.providers.bridge uses newline-delimited JSON-RPC 2.0. The handshake selects a thread-delta grammar in the supported range.

The public module is @bb/providers/bridge. It contains schemas, types, a bridge factory, and a conformance kit.

Transport and entry

export interface ProviderBridgeEntry {
  apiVersion: 1;
  definition: ProviderBridgeDefinition;
}

export interface ProviderBridgeDefinition {
  start?(context: ProviderBridgeContext): void | Promise<void>;
  handleLine(line: string): void;
  onClose?(): void | Promise<void>;
  onSigterm?(): void | Promise<void>;
  onSigint?(): void | Promise<void>;
}

export interface ProviderBridgeContext {
  pluginId: string;
  providerId: string;
  dataDir: string;
  tempDir: string;
  signal: AbortSignal;
}

export function defineProviderBridge(
  definition: ProviderBridgeDefinition,
): ProviderBridgeEntry;

One line has a 64 MiB limit. An overflow closes the bridge with a protocol error.

Handshake

Method Direction Input Output
initialize runtime to bridge protocol version, client data, grammar range protocol version and BridgeCapabilities
export interface BridgeCapabilities {
  sessionRestore: boolean;
  threadArchive: boolean;
  threadRename: boolean;
  threadGoalClear: boolean;
  fork: "none" | "thread" | "checkpoint";
  approvalEnforcedBy: "runtime" | "provider";
  grammarVersions: readonly [minimum: number, maximum: number];
  steerMode: "inject" | "queue";
  skills: { configure: boolean };
}

The runtime chooses the highest common grammar. A bridge cannot report a capability wider than its static declaration.

Runtime requests

Method Input Output Gate
model/list { cwd? } available and selected-only models live catalog
provider/health host context and options ProviderHealth maintenance.health
provider/usage provider ID, host context, options ProviderUsage maintenance.usage
provider/installation/status provider ID, host context, requirement ProviderInstallationStatus maintenance.installation
provider/installation/run provider ID, host context, action ProviderInstallationRunResult maintenance.installation
thread/start thread, workspace, tools, options, initial input ThreadIdentityResult always
thread/resume thread and provider thread identity ThreadIdentityResult sessionRestore
thread/fork source identity and optional checkpoint ThreadIdentityResult fork
thread/stop intent and active turn {} always
thread/discard thread identity {} always
thread/name/set thread identity and title {} threadRename
thread/archive thread identity {} threadArchive
thread/unarchive thread identity {} threadArchive
thread/goal/clear thread identity {} threadGoalClear
turn/start input, client request ID, options {} always
turn/steer expected turn, input, request ID, options {} steerMode
skills/configure normalized roots and skill descriptions {} skills.configure
export interface BridgeExecutionOptions {
  model?: string;
  serviceTier?: string;
  reasoningLevel?: string;
  promptMode?: "plan";
  instructions?: string;
  envVars?: Readonly<Record<string, string>>;
  providerOptions?: JsonObject;
}

Bridge requests and notifications

The bridge can request one tool call or one user interaction. The shared request service tracks both request types.

Method Direction Contract
item/tool/call bridge to runtime Tool name, call ID, arguments, and thread identity.
interaction/request bridge to runtime A typed approval, question, secret, or open interaction.
thread/identity bridge notification Maps a bb thread to a provider thread.
session/replaced bridge notification Reports a new session and possible context loss.
provider/raw bridge notification Preserves unknown or noise data.
provider/recovery bridge notification Gives typed recovery advice.
error bridge notification Reports an unscoped bridge error.
thread/delta bridge notification Sends ordered normalized deltas.
export type PendingInteractionPayload =
  | ApprovalInteraction
  | QuestionInteraction
  | SecretInteraction
  | OpenInteraction;

export interface SecretInteraction {
  kind: "secret";
  requestKey: string;
  title: string;
  prompt: string;
  secretName: string;
}

export type PendingInteractionResolution =
  | { kind: "approval"; decision: "allow_once" | "allow_for_session" | "deny" }
  | { kind: "answer"; answers: readonly string[] }
  | { kind: "secret"; stored: boolean }
  | { kind: "submitted"; data: JsonValue }
  | { kind: "interrupted"; reason: string };

The secret value never enters a delta or a server log. The kernel secrets port stores it.

Thread deltas

A thread/delta notification contains one ordered ThreadDelta[]. Each item event uses a stable DeltaItemKey.

export interface DeltaItemKey {
  providerItemId?: string;
  channel?: string;
  parentRef?: string;
}

export type DeltaItem =
  | CommandItem | FileChangeItem | ToolItem | CompactionItem
  | AgentMessageItem | ReasoningItem | PlanItem
  | WebSearchItem | WebFetchItem | ImageViewItem
  | BackgroundTaskItem | FileReadItem | SearchItem
  | DelegationItem | PlanStepsItem | ExtensionItem;

export type ThreadDelta =
  | InputAcceptedDelta | InputProviderDelta
  | TurnOpenDelta | TurnBoundaryDelta | TurnDiffDelta
  | ItemOpenDelta | ItemCloseDelta | ItemProgressDelta
  | TextDelta | TextCloseDelta | OutputDelta | CommandOutputSnapshotDelta
  | UsageDelta | ContextWindowDelta | ContextCompactedDelta | ContextClearedDelta
  | ThreadStartedDelta | ThreadIdentityDelta | ThreadNameDelta
  | ExtensionStateDelta | ProviderRateLimitsDelta | ProviderErrorDelta
  | ProviderModelFallbackDelta | ProviderWarningDelta | UnhandledDelta
  | SessionEndedDelta | SessionResetDelta;
Delta kind Required data Effect
input.accepted client request and optional provider turn Confirms accepted input.
input.provider text and optional parent Adds provider-side input.
turn.open provider turn and parent Opens a turn.
turn.boundary status, error, checkpoint, turn Settles or changes a turn.
item.open key, full item, presentation Opens an item.
item.close key, status, full item, result Settles an item.
item.progress key, message or snapshot Updates progress.
item.textDelta key, text channel, text Adds streamed text.
item.textClose key, text channel, optional final text Closes streamed text.
item.outputDelta key, output channel, text Adds command or file output.
command.outputSnapshot key and full output Replaces command output.
usage last and total usage Updates token usage.
contextWindow used size and estimate flag Updates context use.
context.compacted turn reference Reports compaction.
context.cleared kind only Reports cleared context.
turn.diff diff and turn reference Adds a turn diff.
thread.started kind only Reports provider thread start.
thread.identity provider thread ID Updates identity.
thread.name name Updates the provider name.
extension.state extension kind and payload Updates extension state.
provider.rateLimits normalized rate-limit state Updates limits.
provider.error message, category, retry data Reports a provider failure.
provider.modelFallback model pair, reason, message Reports model fallback.
provider.warning summary, details, category Reports a warning.
unhandled raw event and coverage data Preserves unmapped data.
session.ended kind only Ends the session.
session.reset kind only Resets the session state.

Item close events repeat the full item. This rule makes event replay independent from bridge memory.

The grammar accepts text channels agentMessage, reasoningSummary, reasoningText, and plan. It accepts output channels command and fileChange.

Unknown events use ProviderRawEvent. A coverage value of noise permits a drop after diagnostics.

Item contracts

All item variants have a type field. An extension item also has a declared schema.

Item type Main data
command Command, work directory, output, exit code, status, and approval state.
fileChange Path, add or update or delete kind, move path, diff, old text, and new text.
tool Tool name, call ID, arguments, result, status, and presentation.
compaction Cause, status, and optional summary.
agentMessage Assistant text and status.
reasoning Summary text, detail text, and status.
plan Plan text and status.
webSearch Query, sources, and status.
webFetch URL, title, result, and status.
imageView Path or URL, detail, and status.
backgroundTask Family, task type, description, status, usage, output file, summary, and error.
fileRead Path and optional command.
search Mode, query, path, and optional command.
delegation Child reference, label, background flag, and summary.
planSteps Ordered steps and optional explanation.
extension Declared extension kind and validated JSON payload.
export interface DeltaFileChange {
  path: string;
  kind: "add" | "update" | "delete";
  movePath?: string;
  diff?: string;
  oldText?: string;
  newText?: string;
}

export interface BackgroundTaskItem {
  type: "backgroundTask";
  familyId: string;
  taskType: string;
  description: string;
  status: string;
  taskStatus: string;
  skipTranscript: boolean;
  workflowName?: string;
  workflow?: JsonValue;
  usage?: ProviderTokenUsage;
  summary?: string;
  error?: string;
  outputFile?: string;
}

export interface DelegationItem {
  type: "delegation";
  childRef: string;
  label: string;
  background: boolean;
  summary?: string;
}

export interface PlanStepsItem {
  type: "planSteps";
  steps: readonly ThreadPlanStep[];
  explanation?: string;
}

export interface ExtensionItem {
  type: "extension";
  kind: string;
  payload: JsonValue;
}

Maintenance, health, and usage

export interface ProviderMaintenance {
  health?: boolean;
  usage?: boolean;
  installation?: boolean;
}

export interface ProviderHealth {
  status: "ok" | "not_installed" | "unauthenticated" | "expired" | "unsupported" | "error";
  statusMessage?: string;
  accountEmail?: string;
  planLabel?: string;
  installedVersion?: string;
  minimumSupportedVersion?: string;
  canInstall: boolean;
  canUpdate: boolean;
  loginCommand?: string;
}

export type ProviderUsage =
  | { status: "ok"; accountEmail?: string; planLabel?: string; windows: readonly ProviderUsageWindow[] }
  | { status: "not_installed" | "unauthenticated" | "expired" }
  | { status: "error"; message: string; accountEmail?: string; planLabel?: string };

export interface ProviderUsageWindow {
  label: string;
  usedPercent: number;
  resetsAt: string | null;
  cost?: { usedUsdCents: number; limitUsdCents: number };
}

export interface ProviderInstallationStatus {
  executableName: string;
  executablePath: string | null;
  installed: boolean;
  installSource: "npm-global" | "path" | "download" | "unknown";
  currentVersion: string | null;
  latestVersion: string | null;
  minimumSupportedVersion: string | null;
  npmPackageName?: string;
  npmGlobalPackageVersion?: string | null;
  installAction?: ProviderInstallationAction;
  needsUpdate: boolean;
  versionUnsupported: boolean;
}

export interface ProviderInstallationCommand {
  command: string;
  args: readonly string[];
  displayCommand: string;
}

export interface ProviderInstallationAction {
  kind: "install" | "update";
  label: "Install" | "Update";
  command: ProviderInstallationCommand;
}

export type ProviderInstallationVerification =
  | { kind: "installed" }
  | { kind: "version_changed"; previousVersion: string | null }
  | { kind: "version_at_least"; version: string };

export type ProviderInstallationRunResult =
  | { available: false; message: string }
  | {
      available: true;
      command: ProviderInstallationCommand;
      verification: ProviderInstallationVerification;
    };

An install run returns the exact command and a verification rule. Shared maintenance code verifies the result after execution.

Recovery and errors

export type ProviderRecoveryKind =
  | "restart-process"
  | "resume-fresh"
  | "reauthenticate"
  | "reinstall"
  | "none";

export interface ProviderRecoveryHint {
  kind: ProviderRecoveryKind;
  message: string;
  retryable: boolean;
}

export const BRIDGE_JSON_RPC_ERRORS = {
  INVALID_PARAMS: -32602,
  METHOD_NOT_FOUND: -32601,
  BRIDGE_ERROR: -32000,
  NO_ACTIVE_TURN: -32001,
  SESSION_NOT_RESTORABLE: -32002,
  FORK_CHECKPOINT_UNSUPPORTED: -32003,
} as const;

The supervisor rejects pending requests when a process exits. It records the recovery hint with the provider and session state.

Protocol runtime utilities

The bridge module provides a small runtime above the host services. Provider adapters do not write their own JSON-RPC loop.

Area Exact contract
JSON-RPC messages JsonRpcMessage, ProviderInboundRequest, ProviderRuntimeEvent, and command plans.
JSON-RPC output send, sendResult, sendError, and recovery-aware request dispatch.
Line input A bounded line reader with overflow and close callbacks.
Tool calls Request and response codecs, content blocks, image decode, and one pending-call tracker.
Interactions A decoder and one pending-request tracker with process-scope rejection.
Raw events Parse, describe, and classify each event as normalized, noise, or unknown.
Child environment Remove bridge-only values before a provider process starts.
Record mode Store bounded child input and output records through the supervisor.
export interface ProviderRequestClient {
  request<T>(method: string, params: JsonValue, options?: { signal?: AbortSignal }): Promise<T>;
  notify(method: string, params: JsonValue): void;
  handleResponse(response: BridgeJsonRpcResponse): boolean;
  rejectAll(message: string): void;
}

export interface ProviderVisibilityMetadata<TRawEvent> {
  parseRawEvent(input: unknown): TRawEvent | null;
  describeParsedRawEvent(event: TRawEvent): ProviderRawEventDescription;
  describeRawEvent(input: unknown): ProviderRawEventDescription;
}

Exports

Module Exports
@bb/providers/contracts bbProviders, bbProvider, all server interfaces, and provider declaration schemas.
@bb/providers/app useProviders, ProviderIcon, ProviderDirectoryState
@bb/providers/bridge Bridge entry factory, protocol schemas, deltas, items, interactions, maintenance types, and JSON-RPC helpers.
@bb/providers/bridge/testing Memory transport, conformance runner, protocol fixtures, and transcript checks.
@bb/providers/host Host role tokens, supervisor clients, request clients, maintenance helpers, and native-root helpers.
@bb/providers/bridge/acp Experimental ACP probe, launch, bridge, and presentation helpers.

Direct imports select exact code. Service and host-role tokens follow the current winner.

export interface ProviderDirectoryState {
  status: "loading" | "ready" | "error";
  providers: readonly ProviderRecord[];
}

export function useProviders(): ProviderDirectoryState;

export interface ProviderIconProps {
  providerId: string;
  className?: string;
}

export const ProviderIcon: ComponentType<ProviderIconProps>;

The provider declaration supplies its icon data. A plugin can export an exact React icon module when the declared asset cannot represent its mark. The 2.0 API drops the global experimental_providerIcon registration slot.

Host roles

ID kind replaceable role contract notes
bb.providers.bridge keyed by provider ID yes ProviderBridgeRole The public provider service depends on this private role.
bb.providers.nativeRoots keyed by provider ID yes ProviderNativeRootsRole The provider claim can omit this role when roots are static.
export interface ProviderBridgeRole {
  initialize(input: InitializeRequest): Promise<InitializeResult>;
  request<M extends RuntimeBridgeMethod>(
    method: M,
    input: RuntimeBridgeInput<M>,
    options?: { signal?: AbortSignal },
  ): Promise<RuntimeBridgeOutput<M>>;
  toolResult(requestId: string | number, result: BridgeToolCallResult): Promise<void>;
  interactionResult(
    requestId: string | number,
    result: PendingInteractionResolution,
  ): Promise<void>;
  events(listener: (event: ProviderBridgeEvent) => void): Unsubscribe;
  close(reason: string): Promise<void>;
}

export interface ProviderNativeRootsRole {
  resolve(input: { providerId: string; cwd: string | null }): Promise<ProviderResolvedNativeRoots>;
}

The manifest joins both claims by the same provider key. The inspector shows the server generation and host generation in one record.

Shared provider host services

Provider roles use these services. They do not implement process and request control again.

ID kind replaceable purpose
bb.providers.host.supervisor single no Owns provider processes, sessions, exit policy, leases, and transcript records.
bb.providers.host.requests single no Owns pending JSON-RPC requests, timeouts, tool calls, and interactions.
bb.providers.host.maintenance single no Owns executable probes, versions, install commands, and verification.
bb.providers.host.declarations single no Reconciles dynamic provider declarations and native roots.
export interface ProviderHostSupervisor {
  spawn(spec: ProviderLaunchSpec): Promise<ProviderProcess>;
  attach(identity: ProviderProcessIdentity): Promise<ProviderProcess>;
  getSession(scope: ProviderSessionScope): ProviderSupervisedSession | null;
  closeSession(scope: ProviderSessionScope, reason: string): Promise<void>;
  closeAll(providerId: string, reason: string): Promise<void>;
  childEnv(input: NodeJS.ProcessEnv, session: Readonly<Record<string, string>>): NodeJS.ProcessEnv;
  recordChildIo(scope: ProviderSessionScope, record: ProviderChildIoRecord): Promise<void>;
  retainWorker(scope: ProviderSessionScope): ProviderWorkerLease;
}

export interface ProviderHostRequests {
  createClient(process: ProviderProcess, options: ProviderRequestOptions): ProviderRequestClient;
  decodeResponse(input: unknown): BridgeJsonRpcResponse | null;
  decodeToolResult(input: unknown): DecodedBridgeToolResult;
  buildToolContent(input: ToolResultInput): readonly BridgeToolCallContent[];
  failScope(scope: ProviderSessionScope, message: string): void;
}

export interface ProviderHostMaintenance {
  resolveExecutable(command: string): Promise<string | null>;
  commandOutput(command: string, args: readonly string[]): Promise<string | null>;
  versionFrom(value: string | null): string | null;
  readCliVersion(command: string): Promise<string | null>;
  compareVersions(left: string, right: string): number;
  npmCommand(): string;
  formatCommand(command: string, args: readonly string[]): string;
  npmInstall(npmPackage: string): ProviderInstallationCommand;
  npmLatest(npmPackage: string): Promise<string | null>;
  npmProbe(npmPackage: string): Promise<NpmGlobalPackageProbe>;
  installSource(input: InstallSourceInput): ProviderInstallationSource;
  installationVerification(
    status: Pick<ProviderInstallationStatus, "currentVersion" | "latestVersion">,
    action: "install" | "update",
  ): ProviderInstallationVerification;
  downloadedInstaller(url: string): ProviderInstallationCommand;
  clampPercent(value: number): number;
}

export interface ProviderHostDeclarations {
  apply(source: string, declarations: readonly ProviderDeclaration[]): Promise<DeclarationDiff>;
  removeSource(source: string): Promise<void>;
  snapshot(): readonly ProviderDeclaration[];
  watch(listener: (diff: DeclarationDiff) => void): Unsubscribe;
  filterNativeRoots(input: ProviderResolvedNativeRootsInput): FilteredNativeRoots;
}

The supervisor gives every session one process identity. It applies timeouts, aborts, exit rejection, and kill escalation.

The declaration service applies one atomic diff. ACP does not need disposer maps or declaration polls in its server half.

Experimental host adapters

The host module exports experimental_resolveClaudePluginRoots and experimental_resolveVendorPluginRoots. Both return normalized native roots.

The ACP module exports these experimental helpers:

  • experimental_acpAgentProbeSchema
  • experimental_acpLaunchSpecSchema
  • experimental_acpProviderBridge
  • experimental_probeAcpAgent
  • experimental_toolPresentation

These exports keep the experimental stability marker. They use the stable bridge and supervisor contracts underneath.

Example

This provider claims one server key and one host-role key. The user can choose another claimant for acme.

{
  "id": "acme.provider",
  "version": "2.0.0",
  "claims": [
    { "service": "bb.providers.provider", "version": "^1", "key": "acme", "default": true },
    { "hostRole": "bb.providers.bridge", "version": "^1", "key": "acme", "default": true }
  ],
  "requires": [{ "service": "bb.providers", "range": "^1" }],
  "artifacts": {
    "server": "./dist/server.js",
    "host": "./dist/host.js"
  }
}
// server.ts
import { defineServerPlugin } from "@get-bb/plugin/server";
import { bbProvider } from "@bb/providers/contracts";
import { declaration } from "./declaration.js";

export default defineServerPlugin((api) => {
  api.services.provide(bbProvider, {
    declaration: () => declaration,
    deriveOptions: async ({ settings }) => ({ apiBase: settings.apiBase ?? null }),
    models: (context) => api.host.roles.call("bb.providers.bridge", "model/list", context),
    health: (context) => api.host.roles.call("bb.providers.bridge", "provider/health", context),
    usage: (context) => api.host.roles.call("bb.providers.bridge", "provider/usage", context),
    installationStatus: (context) => api.host.roles.call("bb.providers.bridge", "provider/installation/status", context),
    runInstallation: (context, action) => api.host.roles.call("bb.providers.bridge", "provider/installation/run", { ...context, action }),
    resolveNativeRoots: (context) => api.host.roles.call("bb.providers.nativeRoots", "resolve", context),
    openSession: (context) => api.host.roles.session("bb.providers.bridge", context),
  }, { key: "acme" });
});
// host.ts
import { defineHostPlugin } from "@get-bb/plugin/host";
import { bbProviderBridgeRole, bbProviderHostSupervisor } from "@bb/providers/host";
import { createAcmeBridge } from "./acme-bridge.js";

export default defineHostPlugin(async (api) => {
  const supervisor = await api.services.use(bbProviderHostSupervisor);
  api.hostRoles.provide(
    bbProviderBridgeRole,
    createAcmeBridge({ supervisor, declaration }),
    { key: "acme" },
  );
});

The runtime stages both halves before it changes the winner. A failed host candidate cannot remove the current acme provider.

Covers

old item ID new contract/verb note
server.providers bb.providers.provider contract The keyed contract replaces the registration namespace.
server.providers.register api.services.provide(bbProvider, implementation, { key }) The factory scope supplies automatic cleanup.
server.providers.declaration bb.providers.provider: ProviderDeclaration The static declaration remains part of contract.json.
server.providers.capabilities bb.providers.provider: ProviderCapabilities
server.providers.maintenance bb.providers.provider: ProviderMaintenance
server.providers.strings bb.providers.provider: ProviderStrings
server.providers.optionsContext bb.providers.provider: ProviderOptionsContext
server.providers.declaration.id bb.providers.provider: ProviderDeclaration.id
server.providers.declaration.displayName bb.providers.provider: ProviderDeclaration.displayName
server.providers.declaration.family bb.providers.provider: ProviderDeclaration.family
server.providers.declaration.icon bb.providers.provider: ProviderDeclaration.icon
server.providers.declaration.experimental_bridgeOptions bb.providers.provider: ProviderDeclaration.bridgeOptions The stable declaration field replaces the experimental field.
server.providers.declaration.experimental_visibility bb.providers.provider: ProviderDeclaration.visibility The stable declaration field replaces the experimental field.
server.providers.declaration.maintenance bb.providers.provider: ProviderDeclaration.maintenance
server.providers.declaration.capabilities bb.providers.provider: ProviderDeclaration.capabilities
server.providers.declaration.composerActions bb.providers.provider: ProviderDeclaration.composerActions
server.providers.declaration.strings bb.providers.provider: ProviderDeclaration.strings
server.providers.declaration.serviceTiers bb.providers.provider: ProviderDeclaration.serviceTiers
server.providers.declaration.reasoningLevels bb.providers.provider: ProviderDeclaration.reasoningLevels
server.providers.declaration.extensionKinds bb.providers.provider: ProviderDeclaration.extensionKinds
server.providers.declaration.models bb.providers.provider: ProviderDeclaration.models
server.providers.declaration.env bb.providers.provider: ProviderDeclaration.env
server.providers.declaration.experimental_nativeSkillRoots bb.providers.provider: ProviderDeclaration.nativeRoots.skills The stable native-roots object replaces the experimental field.
server.providers.declaration.experimental_nativeCommandRoots bb.providers.provider: ProviderDeclaration.nativeRoots.commands The stable native-roots object replaces the experimental field.
server.providers.declaration.experimental_resolvesNativeRoots bb.providers.provider: ProviderDeclaration.nativeRoots.resolveOnHost The stable native-roots object replaces the experimental field.
server.providers.declaration.deriveProviderOptions bb.providers.provider: Provider.deriveOptions() Behavior moves from declaration data to the provider service.
server.providers.capabilities.permissionModes bb.providers.provider: ProviderCapabilities.permissionModes
server.providers.capabilities.reasoningLevels bb.providers.provider: ProviderCapabilities.reasoningLevels
server.providers.maintenance.health bb.providers.provider: ProviderMaintenance.health
server.providers.maintenance.usage bb.providers.provider: ProviderMaintenance.usage
server.providers.maintenance.installation bb.providers.provider: ProviderMaintenance.installation
server.providers.optionDescriptor bb.providers.provider: ProviderOption
server.providers.extensionKind bb.providers.provider: ProviderExtensionKind
server.providers.fallbackModel bb.providers.provider: ProviderFallbackModel
server.providers.fallbackModel.supportedReasoningEfforts bb.providers.provider: ProviderFallbackModel.supportedReasoningEfforts
server.providers.fallbackModel.defaultReasoningEffort bb.providers.provider: ProviderFallbackModel.defaultReasoningEffort
server.providers.fallbackModel.isDefault bb.providers.provider: ProviderFallbackModel.isDefault
server.providers.capabilities.supportsServiceTier bb.providers.provider: ProviderCapabilities.supportsServiceTier
server.providers.capabilities.supportsNativeUserQuestion bb.providers.provider: ProviderCapabilities.supportsNativeUserQuestion
server.providers.capabilities.fork bb.providers.provider: ProviderCapabilities.fork
server.providers.capabilities.supportsManualCompaction bb.providers.provider: ProviderCapabilities.supportsManualCompaction
server.providers.capabilities.supportsThreadArchive bb.providers.provider: ProviderCapabilities.supportsThreadArchive
server.providers.capabilities.supportsThreadRename bb.providers.provider: ProviderCapabilities.supportsThreadRename
server.providers.strings.signInHint bb.providers.provider: ProviderStrings.signInHint
server.providers.strings.expiredHint bb.providers.provider: ProviderStrings.expiredHint
server.providers.strings.installUrl bb.providers.provider: ProviderStrings.installUrl
server.providers.strings.brandPrefix bb.providers.provider: ProviderStrings.brandPrefix
server.providers.strings.planModeCopy bb.providers.provider: ProviderStrings.planModeCopy
server.providers.strings.iconTint bb.providers.provider: ProviderStrings.iconTint
server.providers.optionDescriptor.id bb.providers.provider: ProviderOption.id
server.providers.optionDescriptor.label bb.providers.provider: ProviderOption.label
server.providers.optionDescriptor.description bb.providers.provider: ProviderOption.description
server.providers.extensionKind.item bb.providers.provider: ProviderExtensionKind.item
server.providers.extensionKind.state bb.providers.provider: ProviderExtensionKind.state
server.providers.optionsContext.threadId bb.providers.provider: ProviderOptionsContext.threadId
server.providers.optionsContext.projectId bb.providers.provider: ProviderOptionsContext.projectId
server.providers.optionsContext.model bb.providers.provider: ProviderOptionsContext.model
server.providers.optionsContext.permissionMode bb.providers.provider: ProviderOptionsContext.permissionMode
server.providers.optionsContext.promptMode bb.providers.provider: ProviderOptionsContext.promptMode
server.providers.optionsContext.settings bb.providers.provider: ProviderOptionsContext.settings
server.providers.fallbackModel.id bb.providers.provider: ProviderFallbackModel.id
server.providers.fallbackModel.displayName bb.providers.provider: ProviderFallbackModel.displayName
server.providers.fallbackModel.description bb.providers.provider: ProviderFallbackModel.description
server.providers.models.fallback bb.providers.provider: ProviderDeclaration.models.fallback
server.providers.models.scope bb.providers.provider: ProviderDeclaration.models.scope
server.providers.env.passthrough bb.providers.provider: ProviderDeclaration.env.passthrough
bridge.entry bb.providers.bridge host role: ProviderBridgeEntry
bridge.exportName dropped The bb.providers.bridge host-role claim replaces the magic experimental_providerBridge export.
bridge.context bb.providers.bridge host role: ProviderBridgeContext
bridge.definition bb.providers.bridge host role: ProviderBridgeDefinition
bridge.definition.handleLine bb.providers.bridge host role: ProviderBridgeDefinition.handleLine
bridge.definition.start bb.providers.bridge host role: ProviderBridgeDefinition.start
bridge.definition.onClose bb.providers.bridge host role: ProviderBridgeDefinition.onClose
bridge.definition.onSigterm bb.providers.bridge host role: ProviderBridgeDefinition.onSigterm
bridge.definition.onSigint bb.providers.bridge host role: ProviderBridgeDefinition.onSigint
bridge.define @bb/providers/bridge: defineProviderBridge()
bridge.parseEntry bb.providers.bridge host-role loader validation The loader validates contract.json before role start.
bridge.protocol.version @bb/providers/bridge: BRIDGE_PROTOCOL_VERSION
bridge.protocol.grammarV2 @bb/providers/bridge: delta grammar version 2 Kept for negotiated compatibility.
bridge.protocol.grammarV3 @bb/providers/bridge: delta grammar version 3 Kept for negotiated compatibility.
bridge.handshake.initialize @bb/providers/bridge: handshake.initialize
bridge.handshake.capabilities @bb/providers/bridge: handshake.capabilities
bridge.handshake.grammarVersions @bb/providers/bridge: handshake.grammarVersions
bridge.handshake.steerMode @bb/providers/bridge: handshake.steerMode
bridge.handshake.negotiateGrammar @bb/providers/bridge: handshake.negotiateGrammar
bridge.request.methods @bb/providers/bridge: RUNTIME_BRIDGE_METHODS
bridge.request.modelList bb.providers.bridge host role: modelList Runtime request handlers use this message contract.
bridge.request.providerHealth bb.providers.bridge host role: providerHealth Runtime request handlers use this message contract.
bridge.request.providerUsage bb.providers.bridge host role: providerUsage Runtime request handlers use this message contract.
bridge.request.installStatus bb.providers.bridge host role: installStatus Runtime request handlers use this message contract.
bridge.request.installRun bb.providers.bridge host role: installRun Runtime request handlers use this message contract.
bridge.request.threadStart bb.providers.bridge host role: threadStart Runtime request handlers use this message contract.
bridge.request.threadResume bb.providers.bridge host role: threadResume Runtime request handlers use this message contract.
bridge.request.threadFork bb.providers.bridge host role: threadFork Runtime request handlers use this message contract.
bridge.request.threadStop bb.providers.bridge host role: threadStop Runtime request handlers use this message contract.
bridge.request.threadLifecycle bb.providers.bridge host role: threadLifecycle Runtime request handlers use this message contract.
bridge.request.threadNameSet bb.providers.bridge host role: threadNameSet Runtime request handlers use this message contract.
bridge.request.turnStart bb.providers.bridge host role: turnStart Runtime request handlers use this message contract.
bridge.request.turnSteer bb.providers.bridge host role: turnSteer Runtime request handlers use this message contract.
bridge.request.skillsConfigure bb.providers.bridge host role: skillsConfigure Runtime request handlers use this message contract.
bridge.request.executionOptions @bb/providers/bridge: BridgeExecutionOptions The type applies to thread and turn requests.
bridge.notification.methods @bb/providers/bridge: BRIDGE_NOTIFICATION_METHODS
bridge.notification.threadIdentity bb.providers.bridge host role: notify.threadIdentity
bridge.notification.sessionReplaced bb.providers.bridge host role: notify.sessionReplaced
bridge.notification.providerRaw bb.providers.bridge host role: notify.providerRaw
bridge.notification.recovery bb.providers.bridge host role: notify.recovery
bridge.notification.error bb.providers.bridge host role: notify.error
bridge.inbound.methods @bb/providers/bridge: BRIDGE_RUNTIME_REQUEST_METHODS
bridge.inbound.toolCall bb.providers.host.requests: toolCall The shared request service tracks the response.
bridge.inbound.interaction bb.providers.host.requests: interaction The shared request service tracks the response.
bridge.delta.method @bb/providers/bridge: THREAD_DELTA_NOTIFICATION_METHOD
bridge.delta.notification bb.providers.bridge host role: thread/delta notification
bridge.delta.itemKey @bb/providers/bridge: DeltaItemKey
bridge.delta.item @bb/providers/bridge: DeltaItem
bridge.delta.itemTypes @bb/providers/bridge: DeltaItem["type"]
bridge.delta.fileChange @bb/providers/bridge: DeltaFileChange
bridge.delta.backgroundTask @bb/providers/bridge: BackgroundTaskItem
bridge.delta.fileRead @bb/providers/bridge: FileReadItem
bridge.delta.search @bb/providers/bridge: SearchItem
bridge.delta.delegation @bb/providers/bridge: DelegationItem
bridge.delta.planSteps @bb/providers/bridge: PlanStepsItem
bridge.delta.extension @bb/providers/bridge: ExtensionItem
bridge.delta.progress @bb/providers/bridge: DeltaProgressSnapshot
bridge.delta.textChannel @bb/providers/bridge: DeltaTextChannel
bridge.delta.outputChannel @bb/providers/bridge: DeltaOutputChannel
bridge.delta.noTurnFallback @bb/providers/bridge: DeltaNoTurnFallback
bridge.delta.kinds @bb/providers/bridge: ThreadDelta union The union keeps all normalized delta kinds.
bridge.recovery.hint @bb/providers/bridge: ProviderRecoveryHint
bridge.error.data @bb/providers/bridge: BridgeError.data
bridge.error.codes @bb/providers/bridge: BRIDGE_JSON_RPC_ERRORS
bridge.maintenance.health @bb/providers/bridge: ProviderHealth
bridge.maintenance.usage @bb/providers/bridge: ProviderUsage
bridge.maintenance.window @bb/providers/bridge: ProviderUsageWindow
bridge.maintenance.installStatus @bb/providers/bridge: ProviderInstallationStatus
bridge.maintenance.installAction @bb/providers/bridge: ProviderInstallationAction
bridge.maintenance.command @bb/providers/bridge: ProviderInstallationCommand
bridge.maintenance.verification @bb/providers/bridge: ProviderInstallationVerification
bridge.maintenance.runResult @bb/providers/bridge: ProviderInstallationRunResult
bridge.toolCall.request @bb/providers/bridge: BridgeToolCall.request
bridge.toolCall.response @bb/providers/bridge: BridgeToolCall.response
bridge.toolCall.decodeResponse bb.providers.host.requests: decodeResponse The shared host service owns pending tool calls.
bridge.toolCall.content @bb/providers/bridge: BridgeToolCall.content
bridge.toolCall.image @bb/providers/bridge: BridgeToolCall.image
bridge.toolCall.decodePayload bb.providers.host.requests: decodePayload The shared host service owns pending tool calls.
bridge.toolCall.buildContent bb.providers.host.requests: buildContent The shared host service owns pending tool calls.
bridge.toolCall.tracker bb.providers.host.requests: tracker The shared host service owns pending tool calls.
bridge.toolCall.tracker.forward bb.providers.host.requests: tracker.forward The shared host service owns pending tool calls.
bridge.toolCall.tracker.handle bb.providers.host.requests: tracker.handle The shared host service owns pending tool calls.
bridge.toolCall.tracker.resolve bb.providers.host.requests: tracker.resolve The shared host service owns pending tool calls.
bridge.toolCall.tracker.create bb.providers.host.requests: tracker.create The shared host service owns pending tool calls.
bridge.jsonrpc.message @bb/providers/bridge: JsonRpc.message The bridge runtime owns transport decoding.
bridge.jsonrpc.inboundRequest @bb/providers/bridge: JsonRpc.inboundRequest The bridge runtime owns transport decoding.
bridge.jsonrpc.runtimeEvent @bb/providers/bridge: JsonRpc.runtimeEvent The bridge runtime owns transport decoding.
bridge.jsonrpc.requestPlan @bb/providers/bridge: JsonRpc.requestPlan The bridge runtime owns transport decoding.
bridge.jsonrpc.noopPlan @bb/providers/bridge: JsonRpc.noopPlan The bridge runtime owns transport decoding.
bridge.jsonrpc.commandPlan @bb/providers/bridge: JsonRpc.commandPlan The bridge runtime owns transport decoding.
bridge.jsonrpc.postInitialize @bb/providers/bridge: JsonRpc.postInitialize The bridge runtime owns transport decoding.
bridge.jsonrpc.decodedToolCall @bb/providers/bridge: JsonRpc.decodedToolCall The bridge runtime owns transport decoding.
bridge.jsonrpc.decodedInteraction @bb/providers/bridge: JsonRpc.decodedInteraction The bridge runtime owns transport decoding.
bridge.jsonrpc.decodeToolCall @bb/providers/bridge: JsonRpc.decodeToolCall The bridge runtime owns transport decoding.
bridge.io.create bb.providers.host.requests: transport.create The shared request service owns JSON-RPC output.
bridge.io.lineHandler bb.providers.host.requests: transport.lineHandler The shared request service owns JSON-RPC output.
bridge.io.runRequest bb.providers.host.requests: transport.runRequest The shared request service owns JSON-RPC output.
bridge.io.sendError bb.providers.host.requests: transport.sendError The shared request service owns JSON-RPC output.
bridge.io.recoveryError bb.providers.host.requests: transport.recoveryError The shared request service owns JSON-RPC output.
bridge.lines.maxBytes bb.providers.host.supervisor: MAX_BRIDGE_LINE_BYTES
bridge.lines.read bb.providers.host.supervisor: readBoundedLines()
bridge.lines.args @bb/providers/host: BoundedLineReaderOptions
bridge.env.withoutRuntime bb.providers.host.supervisor: childEnv() The shared supervisor removes runtime-only environment values.
bridge.visibility.metadata @bb/providers/bridge: ProviderVisibility.metadata
bridge.visibility.create @bb/providers/bridge: ProviderVisibility.create
bridge.visibility.coverage @bb/providers/bridge: ProviderVisibility.coverage
bridge.visibility.description @bb/providers/bridge: ProviderVisibility.description
bridge.maintenance.resolveExecutable bb.providers.host.maintenance: resolveExecutable() The shared host service removes provider-local probe code.
bridge.maintenance.commandOutput bb.providers.host.maintenance: commandOutput() The shared host service removes provider-local probe code.
bridge.maintenance.versionFrom bb.providers.host.maintenance: versionFrom() The shared host service removes provider-local probe code.
bridge.maintenance.readCliVersion bb.providers.host.maintenance: readCliVersion() The shared host service removes provider-local probe code.
bridge.maintenance.compareVersions bb.providers.host.maintenance: compareVersions() The shared host service removes provider-local probe code.
bridge.maintenance.npmCommand bb.providers.host.maintenance: npmCommand() The shared host service removes provider-local probe code.
bridge.maintenance.formatCommand bb.providers.host.maintenance: formatCommand() The shared host service removes provider-local probe code.
bridge.maintenance.npmInstall bb.providers.host.maintenance: npmInstall() The shared host service removes provider-local probe code.
bridge.maintenance.npmLatest bb.providers.host.maintenance: npmLatest() The shared host service removes provider-local probe code.
bridge.maintenance.npmProbe bb.providers.host.maintenance: npmProbe() The shared host service removes provider-local probe code.
bridge.maintenance.npmProbeType @bb/providers/host: NpmGlobalPackageProbe
bridge.maintenance.installSource bb.providers.host.maintenance: installSource() The shared host service removes provider-local probe code.
bridge.maintenance.installationVerification bb.providers.host.maintenance: installationVerification() The shared host service removes provider-local probe code.
bridge.maintenance.downloadedInstaller bb.providers.host.maintenance: downloadedInstaller() The shared host service removes provider-local probe code.
bridge.maintenance.clampPercent bb.providers.host.maintenance: clampPercent() The shared host service removes provider-local probe code.
bridge.request.threadDiscard bb.providers.bridge host role: threadDiscard Runtime request handlers use this message contract.
bridge.request.threadArchive bb.providers.bridge host role: threadArchive Runtime request handlers use this message contract.
bridge.request.threadUnarchive bb.providers.bridge host role: threadUnarchive Runtime request handlers use this message contract.
bridge.request.threadGoalClear bb.providers.bridge host role: threadGoalClear Runtime request handlers use this message contract.
bridge.delta.inputAccepted @bb/providers/bridge: ThreadDelta.inputAccepted
bridge.delta.inputProvider @bb/providers/bridge: ThreadDelta.inputProvider
bridge.delta.turnOpen @bb/providers/bridge: ThreadDelta.turnOpen
bridge.delta.turnBoundary @bb/providers/bridge: ThreadDelta.turnBoundary
bridge.delta.itemOpen @bb/providers/bridge: ThreadDelta.itemOpen
bridge.delta.itemClose @bb/providers/bridge: ThreadDelta.itemClose
bridge.delta.itemProgress @bb/providers/bridge: ThreadDelta.itemProgress
bridge.delta.textDelta @bb/providers/bridge: ThreadDelta.textDelta
bridge.delta.textClose @bb/providers/bridge: ThreadDelta.textClose
bridge.delta.outputDelta @bb/providers/bridge: ThreadDelta.outputDelta
bridge.delta.commandSnapshot @bb/providers/bridge: ThreadDelta.commandSnapshot
bridge.delta.usage @bb/providers/bridge: ThreadDelta.usage
bridge.delta.contextWindow @bb/providers/bridge: ThreadDelta.contextWindow
bridge.delta.contextCompacted @bb/providers/bridge: ThreadDelta.contextCompacted
bridge.delta.contextCleared @bb/providers/bridge: ThreadDelta.contextCleared
bridge.delta.turnDiff @bb/providers/bridge: ThreadDelta.turnDiff
bridge.delta.threadStarted @bb/providers/bridge: ThreadDelta.threadStarted
bridge.delta.threadIdentity @bb/providers/bridge: ThreadDelta.threadIdentity
bridge.delta.threadName @bb/providers/bridge: ThreadDelta.threadName
bridge.delta.extensionState @bb/providers/bridge: ThreadDelta.extensionState
bridge.delta.rateLimits @bb/providers/bridge: ThreadDelta.rateLimits
bridge.delta.providerError @bb/providers/bridge: ThreadDelta.providerError
bridge.delta.modelFallback @bb/providers/bridge: ThreadDelta.modelFallback
bridge.delta.warning @bb/providers/bridge: ThreadDelta.warning
bridge.delta.unhandled @bb/providers/bridge: ThreadDelta.unhandled
bridge.delta.sessionEnded @bb/providers/bridge: ThreadDelta.sessionEnded
bridge.delta.sessionReset @bb/providers/bridge: ThreadDelta.sessionReset
bridge.execution.model @bb/providers/bridge: BridgeExecutionOptions.model
bridge.execution.serviceTier @bb/providers/bridge: BridgeExecutionOptions.serviceTier
bridge.execution.reasoningLevel @bb/providers/bridge: BridgeExecutionOptions.reasoningLevel
bridge.execution.promptMode @bb/providers/bridge: BridgeExecutionOptions.promptMode
bridge.execution.instructions @bb/providers/bridge: BridgeExecutionOptions.instructions
bridge.execution.envVars @bb/providers/bridge: BridgeExecutionOptions.envVars
bridge.execution.providerOptions @bb/providers/bridge: BridgeExecutionOptions.providerOptions
bridge.handshake.capabilities.sessionRestore @bb/providers/bridge: handshake.capabilities.sessionRestore
bridge.handshake.capabilities.threadArchive @bb/providers/bridge: handshake.capabilities.threadArchive
bridge.handshake.capabilities.threadRename @bb/providers/bridge: handshake.capabilities.threadRename
bridge.handshake.capabilities.threadGoalClear @bb/providers/bridge: handshake.capabilities.threadGoalClear
bridge.handshake.capabilities.fork @bb/providers/bridge: handshake.capabilities.fork
bridge.handshake.capabilities.approvalEnforcedBy @bb/providers/bridge: handshake.capabilities.approvalEnforcedBy
bridge.handshake.capabilities.grammarVersions @bb/providers/bridge: handshake.capabilities.grammarVersions
bridge.handshake.capabilities.steerMode @bb/providers/bridge: handshake.capabilities.steerMode
bridge.handshake.capabilities.skills @bb/providers/bridge: handshake.capabilities.skills
host.provider.declaration bb.providers.provider: ProviderDeclaration The server and host use one declaration type.
host.provider.declaration.id bb.providers.provider: ProviderDeclaration.id
host.provider.declaration.displayName bb.providers.provider: ProviderDeclaration.displayName
host.provider.declaration.family bb.providers.provider: ProviderDeclaration.family
host.provider.declaration.icon bb.providers.provider: ProviderDeclaration.icon
host.provider.declaration.capabilities bb.providers.provider: ProviderDeclaration.capabilities
host.provider.declaration.composerActions bb.providers.provider: ProviderDeclaration.composerActions
host.provider.declaration.experimental_bridgeOptions bb.providers.provider: ProviderDeclaration.bridgeOptions The stable declaration field replaces the experimental field.
host.provider.declaration.experimental_visibility bb.providers.provider: ProviderDeclaration.visibility The stable declaration field replaces the experimental field.
host.provider.declaration.maintenance bb.providers.provider: ProviderDeclaration.maintenance
host.provider.declaration.strings bb.providers.provider: ProviderDeclaration.strings
host.provider.declaration.serviceTiers bb.providers.provider: ProviderDeclaration.serviceTiers
host.provider.declaration.reasoningLevels bb.providers.provider: ProviderDeclaration.reasoningLevels
host.provider.declaration.extensionKinds bb.providers.provider: ProviderDeclaration.extensionKinds
host.provider.declaration.models bb.providers.provider: ProviderDeclaration.models
host.provider.declaration.env bb.providers.provider: ProviderDeclaration.env
host.provider.declaration.nativeSkillRoots bb.providers.provider: ProviderDeclaration.nativeRoots.skills The native-roots object holds static skill roots.
host.provider.declaration.nativeCommandRoots bb.providers.provider: ProviderDeclaration.nativeRoots.commands The native-roots object holds static command roots.
host.provider.declaration.resolvesNativeRoots bb.providers.provider: ProviderDeclaration.nativeRoots.resolveOnHost The provider can claim the bb.providers.nativeRoots host role.
host.provider.declaration.deriveOptions bb.providers.provider: Provider.deriveOptions() Behavior moves from declaration data to the provider service.
host.provider.capabilities bb.providers.provider: ProviderCapabilities
host.provider.strings bb.providers.provider: ProviderStrings
host.provider.option bb.providers.provider: ProviderOption
host.provider.extensionKind bb.providers.provider: ProviderExtensionKind
host.provider.optionsContext bb.providers.provider: ProviderOptionsContext
host.provider.fallbackModel bb.providers.provider: ProviderFallbackModel
host.provider.maintenance bb.providers.provider: ProviderMaintenance
host.provider.capabilities.supportsServiceTier bb.providers.provider: ProviderCapabilities.supportsServiceTier
host.provider.capabilities.supportsNativeUserQuestion bb.providers.provider: ProviderCapabilities.supportsNativeUserQuestion
host.provider.capabilities.fork bb.providers.provider: ProviderCapabilities.fork
host.provider.capabilities.supportsManualCompaction bb.providers.provider: ProviderCapabilities.supportsManualCompaction
host.provider.capabilities.supportsThreadArchive bb.providers.provider: ProviderCapabilities.supportsThreadArchive
host.provider.capabilities.supportsThreadRename bb.providers.provider: ProviderCapabilities.supportsThreadRename
host.provider.capabilities.permissionModes bb.providers.provider: ProviderCapabilities.permissionModes
host.provider.capabilities.reasoningLevels bb.providers.provider: ProviderCapabilities.reasoningLevels
host.provider.strings.signInHint bb.providers.provider: ProviderStrings.signInHint
host.provider.strings.expiredHint bb.providers.provider: ProviderStrings.expiredHint
host.provider.strings.installUrl bb.providers.provider: ProviderStrings.installUrl
host.provider.strings.brandPrefix bb.providers.provider: ProviderStrings.brandPrefix
host.provider.strings.planModeCopy bb.providers.provider: ProviderStrings.planModeCopy
host.provider.strings.iconTint bb.providers.provider: ProviderStrings.iconTint
host.provider.option.id bb.providers.provider: ProviderOption.id
host.provider.option.label bb.providers.provider: ProviderOption.label
host.provider.option.description bb.providers.provider: ProviderOption.description
host.provider.extensionKind.item bb.providers.provider: ProviderExtensionKind.item
host.provider.extensionKind.state bb.providers.provider: ProviderExtensionKind.state
host.provider.optionsContext.settings bb.providers.provider: ProviderOptionsContext.settings
host.provider.fallbackModel.id bb.providers.provider: ProviderFallbackModel.id
host.provider.fallbackModel.displayName bb.providers.provider: ProviderFallbackModel.displayName
host.provider.fallbackModel.description bb.providers.provider: ProviderFallbackModel.description
host.provider.fallbackModel.supportedReasoningEfforts bb.providers.provider: ProviderFallbackModel.supportedReasoningEfforts
host.provider.fallbackModel.defaultReasoningEffort bb.providers.provider: ProviderFallbackModel.defaultReasoningEffort
host.provider.fallbackModel.isDefault bb.providers.provider: ProviderFallbackModel.isDefault
host.provider.maintenance.health bb.providers.provider: ProviderMaintenance.health
host.provider.maintenance.usage bb.providers.provider: ProviderMaintenance.usage
host.provider.maintenance.installation bb.providers.provider: ProviderMaintenance.installation
bridge.experimental_acpAgentProbeSchema @bb/providers/bridge/acp: experimental_acpAgentProbeSchema The export stays experimental.
bridge.experimental_acpLaunchSpecSchema @bb/providers/bridge/acp: experimental_acpLaunchSpecSchema The export stays experimental.
bridge.experimental_acpProviderBridge @bb/providers/bridge/acp: experimental_acpProviderBridge The adapter uses the stable bridge role.
bridge.experimental_buildBridgeToolCallContent bb.providers.host.requests: buildToolContent() The shared request service replaces the experimental helper.
bridge.experimental_probeAcpAgent @bb/providers/bridge/acp: experimental_probeAcpAgent() The export stays experimental.
bridge.experimental_recordProviderChildIo bb.providers.host.supervisor: recordChildIo() The shared supervisor owns transcript records.
bridge.experimental_toolPresentation @bb/providers/bridge/acp: experimental_toolPresentation The ACP presentation adapter stays experimental.
bridge.interaction.secretRequest @bb/providers/bridge: SecretInteraction The kernel secrets port stores the submitted value.
bridge.providerRawEventSchema @bb/providers/bridge: providerRawEventSchema
bridge.threadDelta @bb/providers/bridge: ThreadDelta and threadDeltaSchema
host.context.experimental_retainWorker bb.providers.host.supervisor: retainWorker() The shared supervisor owns worker leases.
host.experimental_nativeRootsHostContract bb.providers.nativeRoots host role The keyed role replaces the experimental host contract.
host.experimental_providerBridge bb.providers.bridge host role The keyed host-role claim replaces the magic export.
host.experimental_resolveClaudePluginRoots @bb/providers/host: experimental_resolveClaudePluginRoots() The vendor adapter stays experimental.
host.experimental_resolveVendorPluginRoots @bb/providers/host: experimental_resolveVendorPluginRoots() The vendor adapter stays experimental.
app.contracts.PluginProviderIconRegistration ProviderDeclaration.icon or exact app export Provider identity data replaces the global icon slot.
app.contracts.PluginProviderIconRegistration.icon ProviderDeclaration.icon A plugin can also export an exact React icon module.
app.contracts.PluginProviderIconRegistration.providerId ProviderDeclaration.id The provider key identifies the icon owner.
app.contracts.PluginProvidersState @bb/providers/app: ProviderDirectoryState The state reports directory status and provider records.
app.hooks.experimental_useProviders @bb/providers/app: useProviders() The stable hook reads the active provider directory.
app.slots.experimental_providerIcon dropped Declare icon data or export an exact provider icon component.
host.nativeRoots.answer bb.providers.nativeRoots: ProviderNativeRootsRole.resolve() input The role call carries the validated resolver answer.
host.nativeRoots.contract bb.providers.nativeRoots host role The keyed role replaces the experimental contract.
host.nativeRoots.dropped FilteredNativeRoots.dropped Validation still reports each removed root.
host.nativeRoots.filter bb.providers.host.declarations: filterNativeRoots() The shared host service validates and limits roots.
host.nativeRoots.filtered FilteredNativeRoots The result keeps accepted roots and validation reports.
host.nativeRoots.input ProviderResolvedNativeRootsInput The input keeps provider and workspace context.
host.nativeRoots.output ProviderResolvedNativeRoots The output keeps normalized skill and command roots.
host.nativeRoots.resolve bb.providers.nativeRoots: resolve() The keyed host role resolves host-specific roots.
host.providers.namespace bb.providers.provider keyed service The service token replaces the host registration namespace.
host.providers.register api.services.provide(bbProvider.key()) The factory scope owns provider cleanup.
server.sdk.providers bb.providers service The named service replaces the broad SDK area.
server.sdk.providers.list bb.providers service: list() The service returns the active provider directory.
server.sdk.providers.models bb.providers service: models() The service resolves models through the provider winner.
server.sdk.system.executionOptions bb.providers service: models() execution catalog The provider catalog owns execution choices.
server.sdk.system.providerStates bb.providers service: list() and watch() Provider records carry availability and winner state.
server.sdk.system.usageLimits bb.providers service: usage() The selected provider reports account limits.