@get-bb/plugin-sdk 0.4.15 → 0.4.16
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 +3 -3
- package/bundled-types/bb-plugin-sdk-ai-services.d.ts +141 -0
- package/bundled-types/bb-plugin-sdk-app.d.ts +144 -21
- package/bundled-types/bb-plugin-sdk-host.d.ts +479 -2
- package/bundled-types/bb-plugin-sdk-internal-composer-customization-validation.d.ts +10 -1
- package/bundled-types/bb-plugin-sdk-internal-host-policy.d.ts +339 -32
- package/bundled-types/bb-plugin-sdk-internal-plugin-app-collector.d.ts +2 -1
- package/bundled-types/bb-plugin-sdk-provider-bridge-acp.d.ts +807 -0
- package/bundled-types/bb-plugin-sdk-provider-bridge-testing.d.ts +1742 -211
- package/bundled-types/bb-plugin-sdk-provider-bridge.d.ts +2985 -2442
- package/bundled-types/bb-plugin-sdk-testing-app.d.ts +4 -3
- package/bundled-types/bb-plugin-sdk-testing.d.ts +551 -9
- package/bundled-types/bb-plugin-sdk.d.ts +1331 -1350
- package/dist/ai-services.js +91 -0
- package/dist/app.js +2 -2
- package/dist/host.js +14547 -1
- package/dist/internal/composer-customization-validation.js +11 -0
- package/dist/internal/host-policy.js +656 -91
- package/dist/internal/plugin-app-collector.js +58 -14
- package/dist/provider-bridge-acp.js +9753 -0
- package/dist/provider-bridge-testing.js +3355 -1771
- package/dist/provider-bridge-worker-entry.mjs +917 -0
- package/dist/provider-bridge.js +2255 -3718
- package/dist/replay-provider-child.mjs +650 -0
- package/dist/testing/app.js +63 -19
- package/dist/testing/index.js +803 -115
- package/package.json +14 -1
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
// Confused by the API, or need a symbol that isn't here? Clone the BB repo
|
|
6
6
|
// and read the real source: https://github.com/get-bb/bb
|
|
7
7
|
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
|
|
8
10
|
/**
|
|
9
11
|
* Core `bb` CLI top-level command names (plus commander's built-in help).
|
|
10
12
|
* Plugin CLI commands may not shadow these. Maintained by hand and checked
|
|
@@ -16,6 +18,58 @@
|
|
|
16
18
|
*/
|
|
17
19
|
declare const RESERVED_BB_CLI_COMMANDS: readonly string[];
|
|
18
20
|
|
|
21
|
+
/** Input-form entry: a path, or a path with options. */
|
|
22
|
+
declare const providerNativeRootInputSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
23
|
+
ancestors: z.ZodOptional<z.ZodBoolean>;
|
|
24
|
+
namePrefix: z.ZodOptional<z.ZodString>;
|
|
25
|
+
path: z.ZodString;
|
|
26
|
+
recursive: z.ZodOptional<z.ZodBoolean>;
|
|
27
|
+
skipIfManifest: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strict>]>;
|
|
29
|
+
/**
|
|
30
|
+
* One provider-native root as a plugin declares it: a path, or a path with
|
|
31
|
+
* options. `recursive`: the agent scans nested skill directories. `ancestors`
|
|
32
|
+
* (project roots only): scan the same relative directory in every ancestor of
|
|
33
|
+
* the workspace up to the repository root. `namePrefix`: prepended to every
|
|
34
|
+
* name under the root, a vendor plugin's `plugin-name:`; a prefixed root is
|
|
35
|
+
* listed as a plugin root. `skipIfManifest`: a vendor-plugin marker file to
|
|
36
|
+
* skip by.
|
|
37
|
+
*/
|
|
38
|
+
type ProviderNativeRootInput = z.infer<typeof providerNativeRootInputSchema>;
|
|
39
|
+
/**
|
|
40
|
+
* Normalized roots: relative to the host home (`user`) or to the workspace
|
|
41
|
+
* (`project`). The daemon parses this off the wire; the server produces it
|
|
42
|
+
* from a declaration.
|
|
43
|
+
*/
|
|
44
|
+
declare const providerNativeRootsSchema: z.ZodObject<{
|
|
45
|
+
project: z.ZodArray<z.ZodObject<{
|
|
46
|
+
ancestors: z.ZodBoolean;
|
|
47
|
+
namePrefix: z.ZodString;
|
|
48
|
+
path: z.ZodString;
|
|
49
|
+
recursive: z.ZodBoolean;
|
|
50
|
+
skipIfManifest: z.ZodOptional<z.ZodString>;
|
|
51
|
+
}, z.core.$strict>>;
|
|
52
|
+
user: z.ZodArray<z.ZodObject<{
|
|
53
|
+
ancestors: z.ZodBoolean;
|
|
54
|
+
namePrefix: z.ZodString;
|
|
55
|
+
path: z.ZodString;
|
|
56
|
+
recursive: z.ZodBoolean;
|
|
57
|
+
skipIfManifest: z.ZodOptional<z.ZodString>;
|
|
58
|
+
}, z.core.$strict>>;
|
|
59
|
+
}, z.core.$strict>;
|
|
60
|
+
type ProviderNativeRoots = z.infer<typeof providerNativeRootsSchema>;
|
|
61
|
+
/**
|
|
62
|
+
* Provider-native roots as a plugin's frozen declaration holds them: relative
|
|
63
|
+
* to the target host's home (`user`) or to the workspace (`project`). Paths
|
|
64
|
+
* are relative without dot segments, unique per side, at most 32 per side. A
|
|
65
|
+
* root only one host can name — a moved config directory, a settings entry —
|
|
66
|
+
* is the resolver's answer (`resolveNativeRoots`), never a declared root.
|
|
67
|
+
*/
|
|
68
|
+
interface ProviderNativeRootsInputLike {
|
|
69
|
+
readonly user?: readonly ProviderNativeRootInput[];
|
|
70
|
+
readonly project?: readonly ProviderNativeRootInput[];
|
|
71
|
+
}
|
|
72
|
+
|
|
19
73
|
/**
|
|
20
74
|
* How completely a provider can clone one of its sessions — the single
|
|
21
75
|
* vocabulary shared by the provider declaration
|
|
@@ -89,6 +143,11 @@ type PluginSettingDescriptor = {
|
|
|
89
143
|
description?: string;
|
|
90
144
|
/** Stored in a 0600 file under <dataDir>/plugins/<id>/secrets/, never in the db or sent to the frontend. */
|
|
91
145
|
secret?: true;
|
|
146
|
+
/**
|
|
147
|
+
* Render as a multi-line text field; for JSON or lists. Secrets cannot
|
|
148
|
+
* be multi-line.
|
|
149
|
+
*/
|
|
150
|
+
experimental_multiline?: boolean;
|
|
92
151
|
default?: string;
|
|
93
152
|
} | {
|
|
94
153
|
type: "boolean";
|
|
@@ -124,6 +183,45 @@ interface PluginCliExecutionResult {
|
|
|
124
183
|
stderr: string;
|
|
125
184
|
error?: PluginCliOutputLimitError;
|
|
126
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* The row title of a plugin tool call while it is pending and once it
|
|
188
|
+
* settled. Each label is capped at 80 characters and rendered as plain text.
|
|
189
|
+
*/
|
|
190
|
+
interface PluginAgentToolLabels {
|
|
191
|
+
/** Label shown while the tool call is pending. */
|
|
192
|
+
pending: string;
|
|
193
|
+
/** Label shown after the tool call completes successfully. */
|
|
194
|
+
completed: string;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* How calls to a native plugin tool read as a timeline row (grammar v3). Every
|
|
198
|
+
* field is optional at registration: the server fills what the plugin leaves
|
|
199
|
+
* out (a generic `Running <name>` / `Ran <name>` label; the plugin's branding
|
|
200
|
+
* glyph, then `Toolbox`) and hands one complete presentation to the provider
|
|
201
|
+
* bridge with the tool definition.
|
|
202
|
+
*/
|
|
203
|
+
interface PluginAgentToolPresentation {
|
|
204
|
+
/** Row title while the call is pending and once it settled. */
|
|
205
|
+
label?: PluginAgentToolLabels;
|
|
206
|
+
/**
|
|
207
|
+
* A named host glyph (`{ glyph: "Workflow" }`), or one of this plugin's
|
|
208
|
+
* own declared icons by its namespaced glyph (`{ glyph: "<pluginId>/<name>" }`,
|
|
209
|
+
* an entry of the manifest's `bb.branding.experimental_icons` map). A
|
|
210
|
+
* namespaced glyph that names another plugin or an undeclared name rejects
|
|
211
|
+
* the tool registration.
|
|
212
|
+
*/
|
|
213
|
+
icon?: {
|
|
214
|
+
glyph: string;
|
|
215
|
+
};
|
|
216
|
+
/** Low-value rows clients collapse by default (a question a dedicated
|
|
217
|
+
* interaction row already shows, a bookkeeping call). */
|
|
218
|
+
suppress?: boolean;
|
|
219
|
+
/** Accent colour per theme; omitted rows use the neutral row tint. */
|
|
220
|
+
tint?: {
|
|
221
|
+
light: string;
|
|
222
|
+
dark: string;
|
|
223
|
+
};
|
|
224
|
+
}
|
|
127
225
|
/**
|
|
128
226
|
* Permission modes a provider can run a session in — BB's own permission
|
|
129
227
|
* vocabulary, ordered least ("accept-edits") to most ("full") privileged.
|
|
@@ -156,17 +254,6 @@ type PluginProviderComposerAction = "goal" | "plan";
|
|
|
156
254
|
* starting the bridge first.
|
|
157
255
|
*/
|
|
158
256
|
interface PluginProviderCapabilities {
|
|
159
|
-
/** The provider bridge implements the sessionless `provider/health`
|
|
160
|
-
* request. This is host-local readiness, not a network health check. */
|
|
161
|
-
experimental_providerHealth: boolean;
|
|
162
|
-
/** The provider exposes subscription usage through the sessionless
|
|
163
|
-
* `provider/usage` request. False means callers skip the request and usage
|
|
164
|
-
* settings omit the provider. A shared bridge that declares true may still
|
|
165
|
-
* report usage unavailable for one provider id or return no windows. */
|
|
166
|
-
experimental_providerUsage: boolean;
|
|
167
|
-
/** The provider bridge implements `provider/installation/status` and
|
|
168
|
-
* `provider/installation/run` for host-local installation management. */
|
|
169
|
-
experimental_providerInstallation: boolean;
|
|
170
257
|
/** The provider accepts a fast/priority service-tier choice — shows the
|
|
171
258
|
* service-tier toggle in the picker. */
|
|
172
259
|
supportsServiceTier: boolean;
|
|
@@ -246,7 +333,7 @@ interface PluginProviderExtensionKindDeclaration {
|
|
|
246
333
|
}
|
|
247
334
|
/**
|
|
248
335
|
* Per-command context handed to
|
|
249
|
-
* {@link PluginProviderDeclaration.
|
|
336
|
+
* {@link PluginProviderDeclaration.deriveProviderOptions}. The
|
|
250
337
|
* server builds one for every session and turn command it dispatches on a
|
|
251
338
|
* thread of this provider.
|
|
252
339
|
*/
|
|
@@ -272,6 +359,8 @@ interface PluginProviderOptionsContext {
|
|
|
272
359
|
*/
|
|
273
360
|
settings: Readonly<Record<string, PluginSettingValue | undefined>>;
|
|
274
361
|
}
|
|
362
|
+
/** See {@link PluginProviderDeclaration.models}. */
|
|
363
|
+
type PluginProviderModelCatalogScope = "host" | "workspace";
|
|
275
364
|
/**
|
|
276
365
|
* One cold-cache fallback model. The provider's live `model/list` result is
|
|
277
366
|
* the only real model source; this list stands in only while no probe has
|
|
@@ -293,6 +382,24 @@ interface PluginProviderFallbackModel {
|
|
|
293
382
|
/** Exactly one entry in the list is the default. */
|
|
294
383
|
isDefault: boolean;
|
|
295
384
|
}
|
|
385
|
+
/**
|
|
386
|
+
* Which sessionless maintenance requests a provider bridge implements. The
|
|
387
|
+
* server skips the requests a provider does not declare, and clients omit
|
|
388
|
+
* the matching surfaces, without starting the bridge first.
|
|
389
|
+
*/
|
|
390
|
+
interface PluginProviderMaintenance {
|
|
391
|
+
/** `provider/health`: host-local readiness, never a network health check. */
|
|
392
|
+
health?: boolean;
|
|
393
|
+
/** `provider/usage`: subscription usage windows. False means usage settings
|
|
394
|
+
* omit the provider. A shared bridge that declares true may still report
|
|
395
|
+
* usage unavailable for one provider id or return no windows. */
|
|
396
|
+
usage?: boolean;
|
|
397
|
+
/** `provider/installation/status` and `provider/installation/run`:
|
|
398
|
+
* host-local installation management. */
|
|
399
|
+
installation?: boolean;
|
|
400
|
+
}
|
|
401
|
+
/** Provider-native roots as a plugin declares them, one list per side. */
|
|
402
|
+
type PluginProviderNativeRoots = ProviderNativeRootsInputLike;
|
|
296
403
|
/**
|
|
297
404
|
* One provider this plugin contributes to BB's provider registry.
|
|
298
405
|
*
|
|
@@ -303,10 +410,14 @@ interface PluginProviderFallbackModel {
|
|
|
303
410
|
* reload, like every other plugin surface.
|
|
304
411
|
*
|
|
305
412
|
* A declaration owns the provider's static metadata and bridge options. The
|
|
306
|
-
* executable implementation is the plugin's own provider bridge
|
|
307
|
-
* `
|
|
308
|
-
*
|
|
309
|
-
*
|
|
413
|
+
* executable implementation is the plugin's own provider bridge: the
|
|
414
|
+
* `experimental_providerBridge` export of the `bb.host` artifact the manifest
|
|
415
|
+
* names (`PROVIDER_BRIDGE_EXPORT_NAME` in the bridge kit), built into the
|
|
416
|
+
* artifact BB ships to hosts. Declaring a provider in a plugin with no
|
|
417
|
+
* `bb.host` entry is refused, because the picker entry would exist and no
|
|
418
|
+
* turn on it could ever run; a `bb.host` entry whose artifact failed to
|
|
419
|
+
* build still stages the declaration so the provider is listed as
|
|
420
|
+
* unavailable.
|
|
310
421
|
*/
|
|
311
422
|
interface PluginProviderDeclaration {
|
|
312
423
|
/** Stable provider id: 2–64 characters of lowercase letters, digits, and
|
|
@@ -320,11 +431,15 @@ interface PluginProviderDeclaration {
|
|
|
320
431
|
* family — the ACP agents, for example — so clients can group them without
|
|
321
432
|
* parsing a prefix out of the id. Grouping only: no policy keys on it.
|
|
322
433
|
*/
|
|
323
|
-
|
|
434
|
+
family?: string;
|
|
324
435
|
/**
|
|
325
|
-
* Optional picker icon
|
|
326
|
-
*
|
|
327
|
-
*
|
|
436
|
+
* Optional picker icon: a named host glyph (`"Zap"`) or a plugin-relative
|
|
437
|
+
* path starting with `"./"` (`"./icons/agent.svg"`) — the two forms
|
|
438
|
+
* `bb.branding.icon` takes — or, unlike `bb.branding.icon`, one of this
|
|
439
|
+
* plugin's declared icons by its namespaced glyph (`"<pluginId>/<name>"`,
|
|
440
|
+
* an entry of the manifest's `bb.branding.experimental_icons` map; the
|
|
441
|
+
* plugin id must be this plugin's and the name must be declared, else the
|
|
442
|
+
* plugin fails to load). Paths follow the manifest entry-path escape rules
|
|
328
443
|
* — no leading "/", no ".." segments, no backslashes.
|
|
329
444
|
*/
|
|
330
445
|
icon?: string;
|
|
@@ -341,6 +456,11 @@ interface PluginProviderDeclaration {
|
|
|
341
456
|
* bridge reports it installed. Defaults to `"always"`.
|
|
342
457
|
*/
|
|
343
458
|
experimental_visibility?: "always" | "installed";
|
|
459
|
+
/**
|
|
460
|
+
* The sessionless maintenance requests the provider's bridge implements
|
|
461
|
+
* (docs/provider-plugin-api.md §1). Each defaults to false when omitted.
|
|
462
|
+
*/
|
|
463
|
+
maintenance?: PluginProviderMaintenance;
|
|
344
464
|
/** Pre-session capability facts (see the declaration tests on
|
|
345
465
|
* {@link PluginProviderCapabilities}). */
|
|
346
466
|
capabilities: PluginProviderCapabilities;
|
|
@@ -348,27 +468,44 @@ interface PluginProviderDeclaration {
|
|
|
348
468
|
* (the universal skills typeahead is implicit). */
|
|
349
469
|
composerActions: readonly PluginProviderComposerAction[];
|
|
350
470
|
/** Provider copy for core surfaces ({@link PluginProviderStrings}). */
|
|
351
|
-
|
|
471
|
+
strings?: PluginProviderStrings;
|
|
352
472
|
/** Service tiers this provider accepts, as picker options. Non-empty when
|
|
353
473
|
* present, unique ids. The coarse `capabilities.supportsServiceTier` stays
|
|
354
474
|
* until WS2a stabilizes. */
|
|
355
|
-
|
|
475
|
+
serviceTiers?: readonly PluginProviderOptionDescriptor[];
|
|
356
476
|
/** Reasoning levels as picker options with labels, beside the coarse
|
|
357
477
|
* `capabilities.reasoningLevels` ladder (ids only). Non-empty when present,
|
|
358
478
|
* unique ids. WS2a merges the two. */
|
|
359
|
-
|
|
479
|
+
reasoningLevels?: readonly PluginProviderOptionDescriptor[];
|
|
360
480
|
/** Extension kinds this provider's bridge may emit, keyed by local name
|
|
361
481
|
* (`[a-z0-9-]+`). The server validates extension payloads against these
|
|
362
482
|
* schemas at ingest and persists a `provider/unhandled` on a miss. */
|
|
363
|
-
|
|
483
|
+
extensionKinds?: Readonly<Record<string, PluginProviderExtensionKindDeclaration>>;
|
|
364
484
|
/**
|
|
365
485
|
* Cold-cache fallback models ({@link PluginProviderFallbackModel}). The
|
|
366
486
|
* server offers them only while a model probe has not completed or failed
|
|
367
487
|
* transiently; the live `model/list` result always replaces them. Ids must
|
|
368
488
|
* be unique and exactly one entry must be the default.
|
|
369
489
|
*/
|
|
370
|
-
|
|
371
|
-
|
|
490
|
+
models?: {
|
|
491
|
+
/**
|
|
492
|
+
* Optional: a provider that only declares a catalog `scope` needs no
|
|
493
|
+
* fallback list, and an omitted list reads as no fallbacks at all.
|
|
494
|
+
*/
|
|
495
|
+
fallback?: readonly PluginProviderFallbackModel[];
|
|
496
|
+
/**
|
|
497
|
+
* How far one `model/list` answer travels. `"host"` means the catalog is
|
|
498
|
+
* the same everywhere on a machine — the bridge answers from account or
|
|
499
|
+
* agent state and ignores the workspace path — so bb probes once per host
|
|
500
|
+
* and reuses the answer for every environment on it. `"workspace"` (the
|
|
501
|
+
* default) means project configuration can change the answer, so bb
|
|
502
|
+
* probes per workspace and sends the path.
|
|
503
|
+
*
|
|
504
|
+
* Declaring `"host"` wrongly is a stale catalog in a workspace that
|
|
505
|
+
* configured its own models; declaring `"workspace"` wrongly costs a
|
|
506
|
+
* redundant probe. The default is therefore the safe one.
|
|
507
|
+
*/
|
|
508
|
+
scope?: PluginProviderModelCatalogScope;
|
|
372
509
|
};
|
|
373
510
|
/**
|
|
374
511
|
* Daemon environment variables this provider's bridge may read. Provider
|
|
@@ -377,9 +514,38 @@ interface PluginProviderDeclaration {
|
|
|
377
514
|
* and the daemon forwards exactly those variables. Names are
|
|
378
515
|
* `[A-Z_][A-Z0-9_]*`, at most 32.
|
|
379
516
|
*/
|
|
380
|
-
|
|
517
|
+
env?: {
|
|
381
518
|
passthrough: readonly string[];
|
|
382
519
|
};
|
|
520
|
+
/**
|
|
521
|
+
* Directories this provider's agent reads its own skills from, relative to
|
|
522
|
+
* the target host's home directory (`user`) or to the workspace
|
|
523
|
+
* (`project`). An agent with skills of its own — an ACP agent pointed at
|
|
524
|
+
* `.cursor/skills`, say — names them here so bb can list them beside its
|
|
525
|
+
* own; core never guesses a provider's skill layout. Paths are relative
|
|
526
|
+
* and may not contain dot segments; each side holds at most 32 roots. One
|
|
527
|
+
* declaration is global, so a directory only one host can name (an agent's
|
|
528
|
+
* settings-configured skills directory, say) is not declared here but
|
|
529
|
+
* resolved on that host (`experimental_resolvesNativeRoots`).
|
|
530
|
+
*/
|
|
531
|
+
experimental_nativeSkillRoots?: PluginProviderNativeRoots;
|
|
532
|
+
/**
|
|
533
|
+
* Directories this provider's agent reads its own slash commands from —
|
|
534
|
+
* flat directories of `*.md` prompt files (`.claude/commands`, say) — in
|
|
535
|
+
* the same two-sided shape as `experimental_nativeSkillRoots`. bb offers
|
|
536
|
+
* them in the composer beside the agent's skills.
|
|
537
|
+
*/
|
|
538
|
+
experimental_nativeCommandRoots?: PluginProviderNativeRoots;
|
|
539
|
+
/**
|
|
540
|
+
* This plugin's `bb.host` entry implements
|
|
541
|
+
* `experimental_nativeRootsHostContract` (`@get-bb/plugin-sdk/host`): core
|
|
542
|
+
* calls `resolveNativeRoots({ cwd })` on the workspace host when it lists
|
|
543
|
+
* commands or skills, and scans what comes back beside the declared roots.
|
|
544
|
+
* This is where a provider's host-only knowledge goes — a config-moved
|
|
545
|
+
* directory, an installed vendor plugin, a config-file entry — including
|
|
546
|
+
* project-scoped entries, which a global declaration cannot carry.
|
|
547
|
+
*/
|
|
548
|
+
experimental_resolvesNativeRoots?: boolean;
|
|
383
549
|
/**
|
|
384
550
|
* Derive this provider's opaque per-command options. Called synchronously
|
|
385
551
|
* by the server for every session and turn command on a thread of this
|
|
@@ -392,9 +558,30 @@ interface PluginProviderDeclaration {
|
|
|
392
558
|
* a buggy hook cannot silently run a turn with default knobs. Must be fast:
|
|
393
559
|
* it sits on the turn-submit path.
|
|
394
560
|
*/
|
|
395
|
-
|
|
561
|
+
deriveProviderOptions?: (context: PluginProviderOptionsContext) => Readonly<Record<string, JsonValue>>;
|
|
396
562
|
}
|
|
397
563
|
type PluginMentionTrigger = "!" | "#" | "$" | "@" | "~";
|
|
564
|
+
/**
|
|
565
|
+
* What a plugin's AI service does. `inference` answers bb's server-side helper
|
|
566
|
+
* completions (thread titles, commit messages: a prompt and a JSON Schema in,
|
|
567
|
+
* a structured value out); `voice` transcribes recorded speech.
|
|
568
|
+
*/
|
|
569
|
+
type PluginAiServiceKind = "inference" | "voice";
|
|
570
|
+
/**
|
|
571
|
+
* An AI service a plugin offers from its `bb.host` entry, which implements
|
|
572
|
+
* `experimental_aiServicesHostContract` (`@get-bb/plugin-sdk/ai-services`).
|
|
573
|
+
* The user selects it with `BB_INFERENCE` / `BB_TRANSCRIPTION` set to
|
|
574
|
+
* `<id>/<model>`; core calls the plugin's host entry on the primary host with
|
|
575
|
+
* the `id` on every request, so one entry can serve several services.
|
|
576
|
+
*/
|
|
577
|
+
interface PluginAiServiceDeclaration {
|
|
578
|
+
/** The `<serviceId>` segment of the user's setting; stable, lowercase. */
|
|
579
|
+
readonly id: string;
|
|
580
|
+
/** Shown beside the id wherever the setting's options are listed. */
|
|
581
|
+
readonly displayName: string;
|
|
582
|
+
/** Which kinds this service answers; a kind it lacks is not offered. */
|
|
583
|
+
readonly kinds: readonly PluginAiServiceKind[];
|
|
584
|
+
}
|
|
398
585
|
|
|
399
586
|
/**
|
|
400
587
|
* Built-in dynamic tool names plugins may not shadow. Maintained by hand —
|
|
@@ -435,6 +622,61 @@ declare const PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS = 80;
|
|
|
435
622
|
declare const PLUGIN_PROVIDER_PERMISSION_MODE_VALUES: readonly ["accept-edits", "auto", "full"];
|
|
436
623
|
declare const PLUGIN_PROVIDER_REASONING_LEVEL_VALUES: readonly ["none", "low", "medium", "high", "xhigh", "ultracode", "max", "ultra"];
|
|
437
624
|
declare const PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES: readonly ["plan", "goal"];
|
|
625
|
+
/**
|
|
626
|
+
* AI-service ids the server serves itself: `openai` transcription and the
|
|
627
|
+
* builtin inference providers (pi-ai 0.84). A plugin cannot register one —
|
|
628
|
+
* it would capture the user's prompts and audio. This list is the one source
|
|
629
|
+
* for both the fake host and production (`isServerDirectAiServiceId`);
|
|
630
|
+
* apps/server/test/services/plugins/plugin-ai-services.test.ts pins it to
|
|
631
|
+
* pi-ai's provider registry, so a pi-ai bump must move it in the same change.
|
|
632
|
+
*/
|
|
633
|
+
declare const SERVER_DIRECT_AI_SERVICE_IDS: readonly string[];
|
|
634
|
+
/**
|
|
635
|
+
* Validate one `bb.experimental_aiServices.register` declaration the same
|
|
636
|
+
* way in the production host and the fake host. Throws on the first problem;
|
|
637
|
+
* returns a normalized, frozen copy carrying only contract fields.
|
|
638
|
+
*/
|
|
639
|
+
declare function validatePluginAiServiceDeclaration(declaration: PluginAiServiceDeclaration): PluginAiServiceDeclaration;
|
|
640
|
+
/**
|
|
641
|
+
* What an AI service binds to, decided at the
|
|
642
|
+
* `bb.experimental_aiServices.register` call: the plugin's built `bb.host`
|
|
643
|
+
* artifact, or — when the plugin declares an entry that failed to build —
|
|
644
|
+
* nothing yet, with the build problem. An unbound service is staged so the
|
|
645
|
+
* factory completes; the load then fails on that problem before the staged
|
|
646
|
+
* registrations flush, so the service never goes live, while a provider the
|
|
647
|
+
* same factory declared can still be retained as unavailable.
|
|
648
|
+
*/
|
|
649
|
+
type AiServiceHostBinding<THostArtifact> = {
|
|
650
|
+
readonly artifact: THostArtifact;
|
|
651
|
+
readonly problem: null;
|
|
652
|
+
} | {
|
|
653
|
+
readonly artifact: null;
|
|
654
|
+
readonly problem: string;
|
|
655
|
+
};
|
|
656
|
+
/**
|
|
657
|
+
* The refusals a host makes at `bb.experimental_aiServices.register` before
|
|
658
|
+
* it stages the declaration: a reserved server-direct id, and a plugin with
|
|
659
|
+
* no `bb.host` entry for the service to run on. A plugin whose declared
|
|
660
|
+
* entry failed to build is not refused here: the service is staged unbound,
|
|
661
|
+
* carrying the build problem, so the load fails on that problem — the
|
|
662
|
+
* actionable one — after the factory instead of at this call, and a
|
|
663
|
+
* provider the same factory declares is listed as unavailable rather than
|
|
664
|
+
* lost. Returns what the service binds to. The production host and the fake
|
|
665
|
+
* host both call this, so they refuse identically;
|
|
666
|
+
* apps/server/test/services/plugins/plugin-ai-services.test.ts pins the
|
|
667
|
+
* messages.
|
|
668
|
+
*/
|
|
669
|
+
declare function assertAiServiceRegistrable<THostArtifact>(args: {
|
|
670
|
+
id: string;
|
|
671
|
+
/** The plugin's built `bb.host` artifact, or null when it has none. */
|
|
672
|
+
hostArtifact: THostArtifact | null;
|
|
673
|
+
/** Why the artifact is missing when the plugin declared an entry that failed to build. */
|
|
674
|
+
hostArtifactProblem: string | null;
|
|
675
|
+
}): AiServiceHostBinding<THostArtifact>;
|
|
676
|
+
/** The collision a second registration of a live AI-service id raises. */
|
|
677
|
+
declare function aiServiceAlreadyRegisteredMessage(id: string): string;
|
|
678
|
+
/** The collision a second registration of a live provider id raises. */
|
|
679
|
+
declare function providerAlreadyRegisteredMessage(id: string): string;
|
|
438
680
|
/**
|
|
439
681
|
* Validate one `bb.providers.register` declaration. Plugin
|
|
440
682
|
* sources are untyped at runtime, so every field is checked; the production
|
|
@@ -442,9 +684,31 @@ declare const PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES: readonly ["plan", "goal"];
|
|
|
442
684
|
* declarations identically. Throws a descriptive error on the first problem;
|
|
443
685
|
* returns a normalized, deeply frozen copy carrying only contract fields.
|
|
444
686
|
*/
|
|
445
|
-
declare function validatePluginProviderDeclaration(declaration: PluginProviderDeclaration): PluginProviderDeclaration;
|
|
446
687
|
/**
|
|
447
|
-
*
|
|
688
|
+
* A declaration that has been through {@link validatePluginProviderDeclaration}.
|
|
689
|
+
*
|
|
690
|
+
* The validator fills the defaults it owns, so a consumer reads one explicit
|
|
691
|
+
* value rather than re-deciding what an absent field means. Only the fields
|
|
692
|
+
* the validator GUARANTEES are narrowed here; everything else keeps the
|
|
693
|
+
* author-facing shape.
|
|
694
|
+
*/
|
|
695
|
+
type NormalizedPluginProviderDeclaration = Omit<PluginProviderDeclaration, "experimental_nativeCommandRoots" | "experimental_nativeSkillRoots" | "experimental_resolvesNativeRoots"> & {
|
|
696
|
+
readonly experimental_nativeSkillRoots?: ProviderNativeRoots;
|
|
697
|
+
readonly experimental_nativeCommandRoots?: ProviderNativeRoots;
|
|
698
|
+
readonly experimental_resolvesNativeRoots: boolean;
|
|
699
|
+
readonly maintenance: {
|
|
700
|
+
readonly health: boolean;
|
|
701
|
+
readonly usage: boolean;
|
|
702
|
+
readonly installation: boolean;
|
|
703
|
+
};
|
|
704
|
+
readonly models: {
|
|
705
|
+
readonly fallback?: readonly PluginProviderFallbackModel[];
|
|
706
|
+
readonly scope: PluginProviderModelCatalogScope;
|
|
707
|
+
};
|
|
708
|
+
};
|
|
709
|
+
declare function validatePluginProviderDeclaration(declaration: PluginProviderDeclaration): NormalizedPluginProviderDeclaration;
|
|
710
|
+
/**
|
|
711
|
+
* Run a declaration's `deriveProviderOptions` hook for one
|
|
448
712
|
* command and validate its result as a bounded, plain-JSON object — the same
|
|
449
713
|
* rules as `experimental_bridgeOptions`, because the result rides the same
|
|
450
714
|
* wire slot. Shared by the real host and the fake so a hook that works in
|
|
@@ -452,7 +716,7 @@ declare function validatePluginProviderDeclaration(declaration: PluginProviderDe
|
|
|
452
716
|
*/
|
|
453
717
|
declare function deriveValidatedProviderOptions(args: {
|
|
454
718
|
declaration: PluginProviderDeclaration;
|
|
455
|
-
context: Parameters<NonNullable<PluginProviderDeclaration["
|
|
719
|
+
context: Parameters<NonNullable<PluginProviderDeclaration["deriveProviderOptions"]>>[0];
|
|
456
720
|
}): Readonly<Record<string, JsonValue>>;
|
|
457
721
|
declare function isStandardSchema(value: unknown): value is StandardSchemaV1;
|
|
458
722
|
declare function readRpcMethodContract(method: string, value: unknown): PluginRpcMethodContract;
|
|
@@ -465,6 +729,24 @@ declare function isZodSchemaLike(value: unknown): boolean;
|
|
|
465
729
|
* recursive `$ref`, so this is a shared production/fake-host boundary rule.
|
|
466
730
|
*/
|
|
467
731
|
declare function assertNoRecursiveJsonSchemaReferences(schema: unknown, subject: string): void;
|
|
732
|
+
/**
|
|
733
|
+
* Reject the fields a registration never reads. Renamed fields get the
|
|
734
|
+
* message above; any other `experimental_` field is unknown (the same
|
|
735
|
+
* rule configure() output follows in the plugin service). The production
|
|
736
|
+
* host and the fake host both call this before parsing `presentation`, so
|
|
737
|
+
* a registration built against an older SDK fails a plugin's own unit test
|
|
738
|
+
* with the message bb would give it.
|
|
739
|
+
*/
|
|
740
|
+
declare function rejectStaleAgentToolFields(toolName: string, tool: object): void;
|
|
741
|
+
/**
|
|
742
|
+
* The declared shape of `presentation`, copied field by field so
|
|
743
|
+
* a plugin's object cannot smuggle prototypes or extra markup into the
|
|
744
|
+
* persisted row. Labels share the status-label length cap. The production
|
|
745
|
+
* host and the fake host both call this, so a presentation that registers
|
|
746
|
+
* in a plugin unit test registers in bb, and one bb rejects is rejected
|
|
747
|
+
* with the same message.
|
|
748
|
+
*/
|
|
749
|
+
declare function parsePluginAgentToolPresentation(toolName: string, value: unknown): PluginAgentToolPresentation | null;
|
|
468
750
|
/** Compact issue summary from a (possibly foreign-instance) zod error. */
|
|
469
751
|
declare function summarizeParseIssues(error: unknown): string;
|
|
470
752
|
declare function enforcePluginCliOutputLimit(result: Omit<PluginCliExecutionResult, "error">, jsonOutput: boolean): PluginCliExecutionResult;
|
|
@@ -482,5 +764,30 @@ declare function enforcePluginCliOutputLimit(result: Omit<PluginCliExecutionResu
|
|
|
482
764
|
* with cancellation forwarded to the source, so no full-size buffer is made.
|
|
483
765
|
*/
|
|
484
766
|
declare function adoptHttpRouteResponse(value: unknown): Response;
|
|
767
|
+
/**
|
|
768
|
+
* The one rule for a namespaced glyph (`"<pluginId>/<name>"`) wherever a
|
|
769
|
+
* plugin may reference its own declared icons — a tool presentation at
|
|
770
|
+
* `bb.agents.registerTool`, a provider icon at `bb.providers.register`, and a
|
|
771
|
+
* row presentation at ingest: the plugin id must be the emitting plugin's
|
|
772
|
+
* and the name must be in its `bb.branding.experimental_icons` map. The
|
|
773
|
+
* server and the fake plugin host apply it from here, so a registration the
|
|
774
|
+
* fake accepts is one the server accepts.
|
|
775
|
+
*
|
|
776
|
+
* Returns the reason a glyph is refused, always naming the glyph and the
|
|
777
|
+
* plugin, or null when the glyph is acceptable. A host glyph (no `/`) is
|
|
778
|
+
* never refused here: whether the client can draw it is the client's call.
|
|
779
|
+
*/
|
|
780
|
+
declare function undeclaredIconProblem(pluginId: string, declaredIconNames: ReadonlySet<string>, glyph: string): string | null;
|
|
781
|
+
/** `bb.providers.register` refusal for an icon {@link undeclaredIconProblem} rejects. */
|
|
782
|
+
declare function providerIconRefusalMessage(providerId: string, problem: string): string;
|
|
783
|
+
/** `bb.agents.registerTool` refusal for a glyph {@link undeclaredIconProblem} rejects. */
|
|
784
|
+
declare function agentToolIconRefusalMessage(toolName: string, problem: string): string;
|
|
785
|
+
/**
|
|
786
|
+
* `bb.providers.register` refusal for a plugin whose manifest declares no
|
|
787
|
+
* `bb.host` entry: a declaration is metadata, and the bridge it runs on is
|
|
788
|
+
* that entry.
|
|
789
|
+
*/
|
|
790
|
+
declare function providerWithoutBridgeMessage(providerId: string): string;
|
|
485
791
|
|
|
486
|
-
export { AGENT_TOOL_NAME_PATTERN, BACKGROUND_NAME_PATTERN, CLI_COMMAND_NAME_PATTERN, KV_VALUE_MAX_BYTES, MENTION_PROVIDER_ID_PATTERN, PLUGIN_AGENT_DYNAMIC_INSTRUCTIONS_MAX_CHARS, PLUGIN_AGENT_SELECTION_MAX_IDS, PLUGIN_AGENT_STATIC_INSTRUCTIONS_MAX_CHARS, PLUGIN_AGENT_STATUS_LABEL_MAX_CHARS, PLUGIN_AGENT_TOOL_PARAMETERS_MAX_BYTES, PLUGIN_HTTP_METHODS, PLUGIN_MENTION_TRIGGER_VALUES, PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES, PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES, PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS, PLUGIN_PROVIDER_PERMISSION_MODE_VALUES, PLUGIN_PROVIDER_REASONING_LEVEL_VALUES, PROVIDER_ID_PATTERN, RESERVED_AGENT_TOOL_NAMES, RESERVED_BB_CLI_COMMANDS, RPC_METHOD_PATTERN, SETTING_KEY_PATTERN, adoptHttpRouteResponse, assertNoRecursiveJsonSchemaReferences, deriveValidatedProviderOptions, enforcePluginCliOutputLimit, isPluginMentionTrigger, isStandardSchema, isZodSchemaLike, normalizeMentionProviderTriggers, readRpcMethodContract, registerSettingDescriptors, summarizeParseIssues, validatePluginProviderDeclaration, validateSettingsUpdate };
|
|
792
|
+
export { AGENT_TOOL_NAME_PATTERN, BACKGROUND_NAME_PATTERN, CLI_COMMAND_NAME_PATTERN, KV_VALUE_MAX_BYTES, MENTION_PROVIDER_ID_PATTERN, PLUGIN_AGENT_DYNAMIC_INSTRUCTIONS_MAX_CHARS, PLUGIN_AGENT_SELECTION_MAX_IDS, PLUGIN_AGENT_STATIC_INSTRUCTIONS_MAX_CHARS, PLUGIN_AGENT_STATUS_LABEL_MAX_CHARS, PLUGIN_AGENT_TOOL_PARAMETERS_MAX_BYTES, PLUGIN_HTTP_METHODS, PLUGIN_MENTION_TRIGGER_VALUES, PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES, PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES, PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS, PLUGIN_PROVIDER_PERMISSION_MODE_VALUES, PLUGIN_PROVIDER_REASONING_LEVEL_VALUES, PROVIDER_ID_PATTERN, RESERVED_AGENT_TOOL_NAMES, RESERVED_BB_CLI_COMMANDS, RPC_METHOD_PATTERN, SERVER_DIRECT_AI_SERVICE_IDS, SETTING_KEY_PATTERN, adoptHttpRouteResponse, agentToolIconRefusalMessage, aiServiceAlreadyRegisteredMessage, assertAiServiceRegistrable, assertNoRecursiveJsonSchemaReferences, deriveValidatedProviderOptions, enforcePluginCliOutputLimit, isPluginMentionTrigger, isStandardSchema, isZodSchemaLike, normalizeMentionProviderTriggers, parsePluginAgentToolPresentation, providerAlreadyRegisteredMessage, providerIconRefusalMessage, providerWithoutBridgeMessage, readRpcMethodContract, registerSettingDescriptors, rejectStaleAgentToolFields, summarizeParseIssues, undeclaredIconProblem, validatePluginAiServiceDeclaration, validatePluginProviderDeclaration, validateSettingsUpdate };
|
|
793
|
+
export type { AiServiceHostBinding, NormalizedPluginProviderDeclaration };
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// Confused by the API, or need a symbol that isn't here? Clone the BB repo
|
|
6
6
|
// and read the real source: https://github.com/get-bb/bb
|
|
7
7
|
|
|
8
|
-
import { PluginHomepageSectionRegistration, PluginSettingsSectionRegistration, PluginNavPanelRegistration, PluginThreadPanelActionRegistration, PluginNewThreadPanelActionRegistration, ComposerCustomization, PluginPendingInteractionRegistration, PluginSidebarFooterActionRegistration, PluginThreadListRegistration, PluginThreadHeaderActionRegistration, PluginFileOpenerRegistration, PluginSourceCodeRendererRegistration, PluginDiffRendererRegistration, PluginMessageDirectiveRegistration, PluginMessageActionRegistration, PluginCommandPaletteActionRegistration, PluginProviderIconRegistration, PluginContentScriptRegistration, PluginAppDefinition } from '@get-bb/plugin-sdk';
|
|
8
|
+
import { PluginHomepageSectionRegistration, PluginSettingsSectionRegistration, PluginNavPanelRegistration, PluginThreadPanelActionRegistration, PluginNewThreadPanelActionRegistration, ComposerCustomization, PluginPendingInteractionRegistration, PluginSidebarFooterActionRegistration, PluginThreadListRegistration, PluginThreadHeaderActionRegistration, PluginFileOpenerRegistration, PluginSourceCodeRendererRegistration, PluginDiffRendererRegistration, PluginMessageDirectiveRegistration, PluginMessageActionRegistration, PluginCommandPaletteActionRegistration, PluginProviderIconRegistration, PluginTimelineRendererRegistration, PluginContentScriptRegistration, PluginAppDefinition } from '@get-bb/plugin-sdk';
|
|
9
9
|
|
|
10
10
|
/** Validated registrations produced by one plugin app setup execution. */
|
|
11
11
|
interface CollectedPluginAppRegistrations {
|
|
@@ -26,6 +26,7 @@ interface CollectedPluginAppRegistrations {
|
|
|
26
26
|
messageActions: PluginMessageActionRegistration[];
|
|
27
27
|
commandPaletteActions: PluginCommandPaletteActionRegistration[];
|
|
28
28
|
providerIcons: PluginProviderIconRegistration[];
|
|
29
|
+
timelineRenderers: PluginTimelineRendererRegistration[];
|
|
29
30
|
contentScripts: PluginContentScriptRegistration[];
|
|
30
31
|
}
|
|
31
32
|
/**
|