@get-bb/plugin-sdk 0.5.15 → 0.5.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/bundled-types/bb-plugin-sdk-app.d.ts +261 -25
- package/bundled-types/bb-plugin-sdk-internal-host-policy.d.ts +72 -60
- package/bundled-types/bb-plugin-sdk-provider-bridge.d.ts +1 -0
- package/bundled-types/bb-plugin-sdk-testing-app.d.ts +14 -11
- package/bundled-types/bb-plugin-sdk-testing.d.ts +2 -4
- package/bundled-types/bb-plugin-sdk.d.ts +319 -43
- package/dist/app.js +140 -44
- package/dist/host.js +2 -535
- package/dist/internal/host-policy.js +29 -77
- package/dist/provider-bridge-acp.js +24 -2
- package/dist/provider-bridge-testing.js +2 -1
- package/dist/provider-bridge.js +4 -506
- package/dist/testing/app.js +15 -0
- package/dist/testing/index.js +39 -83
- package/package.json +2 -7
- package/bundled-types/bb-plugin-sdk-ai-services.d.ts +0 -141
- package/dist/ai-services.js +0 -95
|
@@ -1677,26 +1677,71 @@ interface PluginMentionProviderRegistration {
|
|
|
1677
1677
|
experimental_images?: readonly ExperimentalPluginMentionImage[];
|
|
1678
1678
|
}>;
|
|
1679
1679
|
}
|
|
1680
|
+
/** Options for one `complete` call. */
|
|
1681
|
+
interface PluginAiCompleteOptions {
|
|
1682
|
+
/**
|
|
1683
|
+
* Aborted when bb stops waiting: the task timed out (5 seconds for titles
|
|
1684
|
+
* and commit messages) or the request was cancelled. Pass it to `fetch`.
|
|
1685
|
+
*/
|
|
1686
|
+
readonly signal: AbortSignal;
|
|
1687
|
+
}
|
|
1688
|
+
/** Options for one `transcribe` call. */
|
|
1689
|
+
interface PluginAiTranscribeOptions {
|
|
1690
|
+
/** Aborted when bb stops waiting (10 seconds) or the request was cancelled. */
|
|
1691
|
+
readonly signal: AbortSignal;
|
|
1692
|
+
/**
|
|
1693
|
+
* Vocabulary the speaker is likely to use (names, identifiers), for
|
|
1694
|
+
* services that accept a transcription prompt; `null` when there is none.
|
|
1695
|
+
*/
|
|
1696
|
+
readonly hint: string | null;
|
|
1697
|
+
}
|
|
1680
1698
|
/**
|
|
1681
|
-
*
|
|
1682
|
-
*
|
|
1683
|
-
*
|
|
1699
|
+
* Whether a service can answer right now. `message` is shown to the user
|
|
1700
|
+
* beside the service ("Sign in to your bb account") and should say how to
|
|
1701
|
+
* make it ready.
|
|
1684
1702
|
*/
|
|
1685
|
-
type
|
|
1703
|
+
type PluginAiServiceStatus = {
|
|
1704
|
+
readonly ready: true;
|
|
1705
|
+
} | {
|
|
1706
|
+
readonly ready: false;
|
|
1707
|
+
readonly message: string;
|
|
1708
|
+
};
|
|
1686
1709
|
/**
|
|
1687
|
-
* An AI service
|
|
1688
|
-
* `
|
|
1689
|
-
*
|
|
1690
|
-
*
|
|
1691
|
-
*
|
|
1710
|
+
* An AI service bb can use for its helper tasks: thread titles and commit
|
|
1711
|
+
* messages (`complete`) and voice input (`transcribe`). The user picks a
|
|
1712
|
+
* service per task in Settings → AI services or with
|
|
1713
|
+
* `bb settings ai-services set`. The functions run in the plugin's server
|
|
1714
|
+
* process; a plugin that needs host-local state (a login file, a local model)
|
|
1715
|
+
* reaches its own `bb.host` entry through `bb.hosts.experimental_client`.
|
|
1716
|
+
*
|
|
1717
|
+
* bb owns the prompts and cleans up replies (think blocks, quotes, labels,
|
|
1718
|
+
* extra lines), so a service returns the model's text as-is. The plugin owns
|
|
1719
|
+
* everything behind the function: which model, which API, any retries.
|
|
1720
|
+
* Failure is a rejected promise.
|
|
1692
1721
|
*/
|
|
1693
1722
|
interface PluginAiServiceDeclaration {
|
|
1694
|
-
/**
|
|
1723
|
+
/**
|
|
1724
|
+
* Stable, lowercase id, unique within this plugin. bb identifies a service
|
|
1725
|
+
* by plugin id and service id, so another plugin may use the same id.
|
|
1726
|
+
* `automatic` and `off` are reserved.
|
|
1727
|
+
*/
|
|
1695
1728
|
readonly id: string;
|
|
1696
|
-
/** Shown
|
|
1729
|
+
/** Shown in the picker; 1-64 characters. */
|
|
1697
1730
|
readonly displayName: string;
|
|
1698
|
-
/**
|
|
1699
|
-
|
|
1731
|
+
/**
|
|
1732
|
+
* Answer one prompt with plain text. Offered for thread titles and commit
|
|
1733
|
+
* messages. Declare `complete`, `transcribe`, or both.
|
|
1734
|
+
*/
|
|
1735
|
+
readonly complete?: (prompt: string, options: PluginAiCompleteOptions) => Promise<string>;
|
|
1736
|
+
/** Transcribe recorded speech to text. Offered for voice input. */
|
|
1737
|
+
readonly transcribe?: (audio: File, options: PluginAiTranscribeOptions) => Promise<string>;
|
|
1738
|
+
/**
|
|
1739
|
+
* Report whether the service can answer. bb calls it for the picker's
|
|
1740
|
+
* status line and to decide whether Automatic skips the service and
|
|
1741
|
+
* whether the microphone shows; results are cached for a few seconds.
|
|
1742
|
+
* Omit it when the service is always ready.
|
|
1743
|
+
*/
|
|
1744
|
+
readonly status?: () => Promise<PluginAiServiceStatus>;
|
|
1700
1745
|
}
|
|
1701
1746
|
|
|
1702
1747
|
declare function pluginCliCollisionWarning(pluginId: string, commandName: string): string | null;
|
|
@@ -1733,57 +1778,24 @@ declare const PLUGIN_PROVIDER_PERMISSION_MODE_VALUES: readonly ["accept-edits",
|
|
|
1733
1778
|
declare const PLUGIN_PROVIDER_REASONING_LEVEL_VALUES: readonly ["none", "low", "medium", "high", "xhigh", "ultracode", "max", "ultra"];
|
|
1734
1779
|
declare const PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES: readonly ["plan", "goal"];
|
|
1735
1780
|
/**
|
|
1736
|
-
*
|
|
1737
|
-
*
|
|
1738
|
-
*
|
|
1739
|
-
* for both the fake host and production (`isServerDirectAiServiceId`);
|
|
1740
|
-
* apps/server/test/services/plugins/plugin-ai-services.test.ts pins it to
|
|
1741
|
-
* pi-ai's provider registry, so a pi-ai bump must move it in the same change.
|
|
1781
|
+
* A validated `bb.experimental_aiServices.register` declaration. Absent
|
|
1782
|
+
* functions are `null` so hosts never have to distinguish missing from
|
|
1783
|
+
* undefined.
|
|
1742
1784
|
*/
|
|
1743
|
-
|
|
1785
|
+
interface NormalizedPluginAiService {
|
|
1786
|
+
readonly id: string;
|
|
1787
|
+
readonly displayName: string;
|
|
1788
|
+
readonly complete: NonNullable<PluginAiServiceDeclaration["complete"]> | null;
|
|
1789
|
+
readonly transcribe: NonNullable<PluginAiServiceDeclaration["transcribe"]> | null;
|
|
1790
|
+
readonly status: NonNullable<PluginAiServiceDeclaration["status"]> | null;
|
|
1791
|
+
}
|
|
1744
1792
|
/**
|
|
1745
1793
|
* Validate one `bb.experimental_aiServices.register` declaration the same
|
|
1746
1794
|
* way in the production host and the fake host. Throws on the first problem;
|
|
1747
1795
|
* returns a normalized, frozen copy carrying only contract fields.
|
|
1748
1796
|
*/
|
|
1749
|
-
declare function validatePluginAiServiceDeclaration(declaration: PluginAiServiceDeclaration):
|
|
1750
|
-
/**
|
|
1751
|
-
* What an AI service binds to, decided at the
|
|
1752
|
-
* `bb.experimental_aiServices.register` call: the plugin's built `bb.host`
|
|
1753
|
-
* artifact, or — when the plugin declares an entry that failed to build —
|
|
1754
|
-
* nothing yet, with the build problem. An unbound service is staged so the
|
|
1755
|
-
* factory completes; the load then fails on that problem before the staged
|
|
1756
|
-
* registrations flush, so the service never goes live, while a provider the
|
|
1757
|
-
* same factory declared can still be retained as unavailable.
|
|
1758
|
-
*/
|
|
1759
|
-
type AiServiceHostBinding<THostArtifact> = {
|
|
1760
|
-
readonly artifact: THostArtifact;
|
|
1761
|
-
readonly problem: null;
|
|
1762
|
-
} | {
|
|
1763
|
-
readonly artifact: null;
|
|
1764
|
-
readonly problem: string;
|
|
1765
|
-
};
|
|
1766
|
-
/**
|
|
1767
|
-
* The refusals a host makes at `bb.experimental_aiServices.register` before
|
|
1768
|
-
* it stages the declaration: a reserved server-direct id, and a plugin with
|
|
1769
|
-
* no `bb.host` entry for the service to run on. A plugin whose declared
|
|
1770
|
-
* entry failed to build is not refused here: the service is staged unbound,
|
|
1771
|
-
* carrying the build problem, so the load fails on that problem — the
|
|
1772
|
-
* actionable one — after the factory instead of at this call, and a
|
|
1773
|
-
* provider the same factory declares is listed as unavailable rather than
|
|
1774
|
-
* lost. Returns what the service binds to. The production host and the fake
|
|
1775
|
-
* host both call this, so they refuse identically;
|
|
1776
|
-
* apps/server/test/services/plugins/plugin-ai-services.test.ts pins the
|
|
1777
|
-
* messages.
|
|
1778
|
-
*/
|
|
1779
|
-
declare function assertAiServiceRegistrable<THostArtifact>(args: {
|
|
1780
|
-
id: string;
|
|
1781
|
-
/** The plugin's built `bb.host` artifact, or null when it has none. */
|
|
1782
|
-
hostArtifact: THostArtifact | null;
|
|
1783
|
-
/** Why the artifact is missing when the plugin declared an entry that failed to build. */
|
|
1784
|
-
hostArtifactProblem: string | null;
|
|
1785
|
-
}): AiServiceHostBinding<THostArtifact>;
|
|
1786
|
-
/** The collision a second registration of a live AI-service id raises. */
|
|
1797
|
+
declare function validatePluginAiServiceDeclaration(declaration: PluginAiServiceDeclaration): NormalizedPluginAiService;
|
|
1798
|
+
/** The collision a plugin's second registration of one AI-service id raises. */
|
|
1787
1799
|
declare function aiServiceAlreadyRegisteredMessage(id: string): string;
|
|
1788
1800
|
/** The collision a second registration of a live provider id raises. */
|
|
1789
1801
|
declare function providerAlreadyRegisteredMessage(id: string): string;
|
|
@@ -2069,5 +2081,5 @@ declare function normalizePluginAgentConfiguration(args: {
|
|
|
2069
2081
|
declare function validateRpcValue(schema: StandardSchemaV1, value: unknown, phase: "input" | "output", fail: (error: PluginRpcError) => never): Promise<unknown>;
|
|
2070
2082
|
declare function normalizeRpcJsonResult(value: unknown, fail: (error: PluginRpcError) => never): JsonValue;
|
|
2071
2083
|
|
|
2072
|
-
export { ENVIRONMENT_PROVIDER_DESCRIPTION_MAX_CHARS, ENVIRONMENT_PROVIDER_DISPLAY_NAME_MAX_CHARS, ENVIRONMENT_PROVIDER_ID_PATTERN, ENVIRONMENT_PROVIDER_REQUIREMENT_NAMES, KV_VALUE_MAX_BYTES, MACHINE_PROVIDER_DESCRIPTION_MAX_CHARS, PLUGIN_AGENT_STATUS_LABEL_MAX_CHARS, PLUGIN_MENTION_TRIGGER_VALUES, PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES, PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES, PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS, PLUGIN_PROVIDER_ENV_MAX_ENTRIES, PLUGIN_PROVIDER_ENV_NAME_PATTERN, PLUGIN_PROVIDER_PERMISSION_MODE_VALUES, PLUGIN_PROVIDER_REASONING_LEVEL_VALUES, PROVIDER_ID_PATTERN, RESERVED_AGENT_TOOL_NAMES, RESERVED_BB_CLI_COMMANDS,
|
|
2073
|
-
export type {
|
|
2084
|
+
export { ENVIRONMENT_PROVIDER_DESCRIPTION_MAX_CHARS, ENVIRONMENT_PROVIDER_DISPLAY_NAME_MAX_CHARS, ENVIRONMENT_PROVIDER_ID_PATTERN, ENVIRONMENT_PROVIDER_REQUIREMENT_NAMES, KV_VALUE_MAX_BYTES, MACHINE_PROVIDER_DESCRIPTION_MAX_CHARS, PLUGIN_AGENT_STATUS_LABEL_MAX_CHARS, PLUGIN_MENTION_TRIGGER_VALUES, PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES, PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES, PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS, PLUGIN_PROVIDER_ENV_MAX_ENTRIES, PLUGIN_PROVIDER_ENV_NAME_PATTERN, PLUGIN_PROVIDER_PERMISSION_MODE_VALUES, PLUGIN_PROVIDER_REASONING_LEVEL_VALUES, PROVIDER_ID_PATTERN, RESERVED_AGENT_TOOL_NAMES, RESERVED_BB_CLI_COMMANDS, SETTING_KEY_PATTERN, adoptHttpRouteResponse, aiServiceAlreadyRegisteredMessage, coerceStoredPluginSettingValue, deriveValidatedProviderOptions, enforcePluginCliOutputLimit, environmentCompositionSchema, isPluginMentionTrigger, isStandardSchema, normalizeAgentToolRegistration, normalizeCliRegistration, normalizeHttpRouteRegistration, normalizeInteractionRequest, normalizeMentionProviderRegistration, normalizePluginAgentConfiguration, normalizeRealtimePayload, normalizeRpcJsonResult, normalizeRpcRegistration, normalizeWebSocketRouteRegistration, parsePluginRowPresentation, pluginCliCollisionWarning, pluginHookAlreadyRegisteredMessage, providerAlreadyRegisteredMessage, providerIconRefusalMessage, providerWithoutBridgeMessage, publishRpcMethod, readRpcPublicationOptions, registerSettingDescriptors, runPluginStorageMigrations, storePluginHook, summarizeStandardIssues, undeclaredIconProblem, validateBackgroundServiceRegistration, validatePluginAiServiceDeclaration, validatePluginEnvironmentProviderDeclaration, validatePluginMachineProviderDeclaration, validatePluginProviderDeclaration, validatePluginProviderEnvEntries, validateProviderEnvContribution, validateRpcValue, validateScheduleRegistration, validateServerAccessProviderDeclaration, validateSettingsUpdate };
|
|
2085
|
+
export type { NormalizedPluginAiService, NormalizedPluginEnvironmentComposition, NormalizedPluginEnvironmentProvider, NormalizedPluginEnvironmentProviderRequirements, NormalizedPluginInteractionRequest, NormalizedPluginMachineProvider, NormalizedPluginProviderDeclaration };
|
|
@@ -1657,6 +1657,7 @@ declare const BRIDGE_JSON_RPC_ERRORS: {
|
|
|
1657
1657
|
readonly NO_ACTIVE_TURN: -32001;
|
|
1658
1658
|
readonly SESSION_NOT_RESTORABLE: -32002;
|
|
1659
1659
|
readonly FORK_CHECKPOINT_UNSUPPORTED: -32003;
|
|
1660
|
+
readonly MISSING_EXECUTABLE: -32004;
|
|
1660
1661
|
};
|
|
1661
1662
|
declare const providerRecoveryHintSchema: z.ZodObject<{
|
|
1662
1663
|
kind: z.ZodEnum<{
|
|
@@ -35,11 +35,11 @@ type CollectedPluginProviderIconRegistration = Omit<PluginProviderIconRegistrati
|
|
|
35
35
|
*
|
|
36
36
|
* - {@link installTestPluginRuntime} fills `globalThis.__bbPluginRuntime.
|
|
37
37
|
* pluginSdkApp` with a test implementation of the `@get-bb/plugin-sdk/app`
|
|
38
|
-
* surface (the same seam `bb plugin build` shims to the real app).
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* {@link loadPluginApp}
|
|
42
|
-
*
|
|
38
|
+
* surface (the same seam `bb plugin build` shims to the real app). The
|
|
39
|
+
* `@get-bb/plugin-sdk/app` exports look the runtime up when they are called
|
|
40
|
+
* or rendered, so import order does not matter: install the runtime any time
|
|
41
|
+
* before the first hook runs ({@link loadPluginApp} and {@link renderSlot}
|
|
42
|
+
* install it for you).
|
|
43
43
|
* - {@link loadPluginApp} runs the definition's setup against a validating
|
|
44
44
|
* collector (ported from the BB app's interpreter, same error messages)
|
|
45
45
|
* and returns the typed slot registrations.
|
|
@@ -161,9 +161,11 @@ interface SidebarNavigationCall {
|
|
|
161
161
|
openInSplit?: boolean;
|
|
162
162
|
}
|
|
163
163
|
/**
|
|
164
|
-
* Install the test runtime at `globalThis.__bbPluginRuntime.pluginSdkApp
|
|
165
|
-
*
|
|
166
|
-
*
|
|
164
|
+
* Install the test runtime at `globalThis.__bbPluginRuntime.pluginSdkApp`,
|
|
165
|
+
* plus the React the `@get-bb/plugin-sdk/app` components render through.
|
|
166
|
+
* Idempotent per module instance. Call it before the first SDK hook runs or
|
|
167
|
+
* SDK component renders; when the plugin's modules are imported does not
|
|
168
|
+
* matter.
|
|
167
169
|
*/
|
|
168
170
|
declare function installTestPluginRuntime(): void;
|
|
169
171
|
interface CapturedPluginApp {
|
|
@@ -200,9 +202,8 @@ type PluginAppModule = {
|
|
|
200
202
|
type PluginAppSource = PluginAppDefinition | PluginAppModule | (() => Promise<PluginAppDefinition | PluginAppModule>);
|
|
201
203
|
/**
|
|
202
204
|
* Install the test runtime, resolve the plugin app definition, and capture
|
|
203
|
-
* its slot registrations. Pass
|
|
204
|
-
*
|
|
205
|
-
* would bind `definePluginApp` before the installer runs.
|
|
205
|
+
* its slot registrations. Pass the imported module, its default export, or a
|
|
206
|
+
* thunk (`() => import("../app.tsx")`).
|
|
206
207
|
*/
|
|
207
208
|
declare function loadPluginApp(source: PluginAppSource): Promise<CapturedPluginApp>;
|
|
208
209
|
interface ContentScriptTestMountOptions {
|
|
@@ -256,6 +257,8 @@ interface RenderSlotOptions<Contract extends PluginRpcContract = PluginRpcContra
|
|
|
256
257
|
projectId?: string | null;
|
|
257
258
|
threadId?: string | null;
|
|
258
259
|
};
|
|
260
|
+
/** `experimental_usePluginId()` value; defaults to `test-plugin`. */
|
|
261
|
+
pluginId?: string;
|
|
259
262
|
/** Initial `useRealtimeConnectionState()` value; defaults to `connected`. */
|
|
260
263
|
realtimeConnectionState?: PluginRealtimeConnectionState;
|
|
261
264
|
/** Initial state for this render's isolated composer scope and view. */
|
|
@@ -1371,10 +1371,8 @@ interface CreateFakePluginHostOptions {
|
|
|
1371
1371
|
sharedPortTunnelIdentities?: Record<string, PluginSharedPortTunnelIdentity>;
|
|
1372
1372
|
/**
|
|
1373
1373
|
* Whether the plugin's manifest declares a `bb.host` entry. Production
|
|
1374
|
-
* refuses `bb.providers.register` (the provider would have no
|
|
1375
|
-
* run on)
|
|
1376
|
-
* nothing to run on) without one; the fake applies the same rules.
|
|
1377
|
-
* Defaults to true.
|
|
1374
|
+
* refuses `bb.providers.register` without one (the provider would have no
|
|
1375
|
+
* bridge to run on); the fake applies the same rule. Defaults to true.
|
|
1378
1376
|
*/
|
|
1379
1377
|
experimental_hostEntry?: boolean;
|
|
1380
1378
|
/**
|