@get-bb/plugin-sdk 0.4.24 → 0.4.27

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.
@@ -7,15 +7,6 @@
7
7
 
8
8
  import { z } from 'zod';
9
9
 
10
- /**
11
- * Core `bb` CLI top-level command names (plus commander's built-in help).
12
- * Core commands win these names; plugin scaffolding rejects them. Maintained
13
- * by hand and checked against the real Commander program by
14
- * apps/cli/src/__tests__/plugin-cli-proxy.test.ts.
15
- *
16
- * "automation" and "connect" are intentionally absent: builtin plugins own
17
- * those top-level commands and the CLI proxies them.
18
- */
19
10
  declare const RESERVED_BB_CLI_COMMANDS: readonly string[];
20
11
 
21
12
  /** Input-form entry: a path, or a path with options. */
@@ -70,22 +61,6 @@ interface ProviderNativeRootsInputLike {
70
61
  readonly project?: readonly ProviderNativeRootInput[];
71
62
  }
72
63
 
73
- /**
74
- * How completely a provider can clone one of its sessions — the single
75
- * vocabulary shared by the provider declaration
76
- * (`bb.providers.register`), the server→daemon
77
- * `bridgeLaunch`, and the bridge's `initialize` handshake.
78
- *
79
- * - `"none"`: sessions cannot be cloned at all.
80
- * - `"tip"`: only the current end of a session can be cloned (ACP
81
- * `session/fork`), so thread fork works but edit-past-message rewind
82
- * cannot.
83
- * - `"checkpoint"`: a session can be recreated at an earlier point, which is
84
- * what edit-past-message rewind needs.
85
- *
86
- * The values are ordered least to most capable: a declaration is a ceiling
87
- * the handshake may narrow but never widen.
88
- */
89
64
  declare const PROVIDER_FORK_VALUES: readonly ["none", "tip", "checkpoint"];
90
65
  type ProviderFork = (typeof PROVIDER_FORK_VALUES)[number];
91
66
 
@@ -62,20 +62,6 @@ declare const availableModelSchema: z.ZodObject<{
62
62
  }, z.core.$strip>;
63
63
  type AvailableModel = z.infer<typeof availableModelSchema>;
64
64
 
65
- /**
66
- * Declarative presentation a bridge attaches to an item at `item.open` (and
67
- * re-states on `item.close`, whose item is the full terminal shape). The
68
- * assembler persists it on the canonical item so the row renders after the
69
- * plugin is uninstalled or upgraded, and so mobile renders every kind without
70
- * plugin code. The same schema as the persisted field
71
- * (`threadEventItemPresentationSchema` in @bb/domain) — one vocabulary, no
72
- * translation.
73
- *
74
- * Optional in grammar v3 while rows persisted before bridges stamped it are
75
- * upgraded at read time; it becomes required together with the
76
- * `legacy-tool-item-backfill` migration that stamps those rows and retires
77
- * that adapter.
78
- */
79
65
  declare const deltaPresentationSchema: z.ZodObject<{
80
66
  detail: z.ZodOptional<z.ZodString>;
81
67
  icon: z.ZodObject<{
@@ -250,30 +236,19 @@ declare const deltaItemShapeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
250
236
  }, z.core.$strip>], "type">;
251
237
  type DeltaItemShape = z.infer<typeof deltaItemShapeSchema>;
252
238
 
253
- /** Where this bridge process may keep files, scoped to the owning plugin. */
254
239
  interface ProviderBridgeContext {
255
- /** The plugin that ships this bridge. */
256
240
  pluginId: string;
257
- /** Persistent, per-plugin, survives daemon restarts and plugin updates. */
258
241
  dataDir: string;
259
- /** This process only; removed when it exits. */
260
242
  tempDir: string;
261
243
  }
262
244
  interface ProviderBridgeDefinition {
263
- /** One decoded stdin line of the Provider Bridge Protocol. */
264
245
  handleLine: (line: string) => void;
265
- /**
266
- * Called once before the first line is read, with the process's
267
- * plugin-scoped directories. Omit it when the bridge keeps no files.
268
- */
269
246
  start?: (context: ProviderBridgeContext) => void;
270
- /** Stdin closed: the runtime is gone and the bridge must shut down. */
271
247
  onClose?: () => void;
272
248
  onSigterm?: () => void;
273
249
  onSigint?: () => void;
274
250
  }
275
251
  interface ProviderBridgeEntry extends ProviderBridgeDefinition {
276
- /** Bumped when the bootstrap↔bridge contract changes incompatibly. */
277
252
  experimental_apiVersion: 1;
278
253
  }
279
254
 
@@ -311,37 +286,19 @@ type ProviderUsageResult = z.infer<typeof providerUsageResultSchema>;
311
286
 
312
287
  declare const experimental_providerBridge: ProviderBridgeEntry;
313
288
 
314
- /**
315
- * What an agent's own dialect knows about keeping it healthy: how a user
316
- * signs in, whether bb can install it, and where its account and usage live.
317
- * ACP standardizes none of it, so a generic bridge can only report whether
318
- * the executable exists — everything richer belongs to the agent, and is
319
- * therefore the dialect's (see `dialect.ts`), never a bb provider id's.
320
- */
321
289
  interface AcpMaintenanceDialect {
322
- /** The shell command that signs the user in. */
323
290
  loginCommand: string;
324
- /** How bb installs or updates the agent, when it can. */
325
291
  installer(): {
326
292
  command: string;
327
293
  args: string[];
328
294
  displayCommand: string;
329
295
  };
330
- /** The signed-in account, or null when the agent is not signed in. */
331
296
  readAccount(): Promise<{
332
297
  email: string | null;
333
298
  } | null>;
334
- /** The agent's usage windows, for the usage surfaces. */
335
299
  readUsage(): Promise<ProviderUsageResult>;
336
300
  }
337
301
 
338
- /**
339
- * Zod schemas for the subset of the Agent Client Protocol (ACP) that BB
340
- * consumes — https://agentclientprotocol.com. The bridge validates agent
341
- * traffic with these before forwarding, and the adapter re-validates the
342
- * `update` payloads it translates into thread events.
343
- */
344
-
345
302
  declare const acpToolKindSchema: z.ZodEnum<{
346
303
  delete: "delete";
347
304
  edit: "edit";
@@ -440,170 +397,53 @@ declare const acpToolCallUpdateEventSchema: z.ZodPipe<z.ZodTransform<unknown, un
440
397
  }, z.core.$loose>>;
441
398
  type AcpToolCallUpdateEvent = z.infer<typeof acpToolCallUpdateEventSchema>;
442
399
 
443
- /**
444
- * ACP tool call → grammar v3 item shape + presentation.
445
- *
446
- * An ACP agent describes a tool call with a native kind enum and a human
447
- * title. The kind maps straight onto the core kinds: `execute` → `command`,
448
- * `edit`/`delete` → `fileChange`, `read` → `fileRead`, `search` → `search`,
449
- * `fetch` → `webFetch`, `think` → `reasoning`; everything else — `other`,
450
- * `move`, an agent that sent no kind — is a generic `tool` whose `tool` slot
451
- * names the kind. The title is never a tool name: it rides
452
- * `presentation.title`.
453
- *
454
- * A core shape has required fields the agent does not always fill (Cursor's
455
- * `read` and `fetch` calls carry an empty `rawInput` and no `locations`). A
456
- * kind whose shape cannot be built honestly stays a generic `tool` that
457
- * presents as its kind ("Reading file" with the agent's title), so a row is
458
- * never a `fileRead` without a path or a `webFetch` without a URL.
459
- *
460
- * The command / file-change decision is `tool-call-operation.ts`'s, which the
461
- * permission mapping shares, so an approval row and its timeline item never
462
- * disagree (#1803).
463
- */
464
-
465
- /** A tool call's item shape plus the presentation that rides its lifecycle. */
466
400
  interface AcpClassifiedToolCall {
467
401
  item: DeltaItemShape;
468
402
  presentation: DeltaPresentation;
469
403
  }
470
404
  interface AcpCommandResult {
471
- /** The process exit code the agent reported; absent when it reported none. */
472
405
  exitCode?: number;
473
- /** The command's output text; absent when the agent reported none. */
474
406
  output?: string;
475
407
  }
476
408
 
477
- /**
478
- * Per-agent dialects: the vendor side channels of an ACP agent.
479
- *
480
- * The ACP wire schema (`wire.ts`) parses only the protocol. What an agent
481
- * puts beside the protocol is a dialect: grok stamps `_meta["x.ai/tool"]` on
482
- * every tool event, Cursor reports its sub-agents through a vendor JSON-RPC
483
- * request (`cursor/task`) that the protocol has no place for. A dialect is a
484
- * small, per-agent module that reads those channels and answers the few
485
- * questions the shared translator asks. The shared schema never learns a
486
- * vendor key, and a dialect never changes what a protocol field means.
487
- *
488
- * Version 1 of the protocol has no sub-agent concept at all (`session/fork`
489
- * is unstable and unrelated), so every delegation an ACP agent reports is
490
- * vendor-specific and belongs here rather than in the classifier.
491
- *
492
- * The dialect is selected per session from the agent's launch command. An
493
- * agent with no dialect of its own gets the generic one, which answers
494
- * nothing and leaves every decision to the protocol fields.
495
- */
496
-
497
- /**
498
- * The programmatic identity of a tool call, when the agent reports one
499
- * outside the protocol's unstable `name` field: the tool's own name and, for
500
- * an agent that sends the `kind` late (grok puts it on the first update, a
501
- * few milliseconds after the `tool_call`), the kind at open, so the opened
502
- * shape and the closed shape agree.
503
- */
504
409
  interface AcpToolIdentity {
505
410
  name?: string;
506
411
  kind?: AcpToolKind;
507
412
  }
508
- /** What a dialect learned about a sub-agent the agent launched. */
509
413
  interface AcpDelegationReport {
510
- /** The tool call the delegation belongs to. */
511
414
  toolCallId: string;
512
- /** The child's provider-native id. */
513
415
  childRef: string;
514
- /** The row headline: what the sub-agent was asked to do. */
515
416
  label: string;
516
- /** A sub-agent type or model the row can name, when the agent says. */
517
417
  detail?: string;
518
418
  }
519
419
  interface AcpDialect {
520
- /** Stable id, for logs and tests. */
521
420
  readonly id: string;
522
- /**
523
- * The tool identity a tool_call / tool_call_update carries in the agent's
524
- * side channel, if any. The translator fills an absent protocol `name` and
525
- * `kind` from it; a protocol value always wins over the dialect's.
526
- */
527
421
  toolIdentity?(event: AcpToolCallUpdateEvent): AcpToolIdentity | undefined;
528
- /**
529
- * The agent's own classification of a tool call, when its side channel
530
- * says something the protocol fields cannot. Returning `undefined` leaves
531
- * the shared classifier in charge — which is the normal answer.
532
- */
533
422
  classifyToolCall?(event: AcpToolCallUpdateEvent): AcpClassifiedToolCall | undefined;
534
- /**
535
- * A command result carried in the agent's non-standard rawOutput shape.
536
- * Returning `undefined` leaves the shared ACP result parser in charge.
537
- */
538
423
  commandResult?(event: AcpToolCallUpdateEvent): AcpCommandResult | undefined;
539
- /**
540
- * A command event with the agent's non-standard result fields normalized
541
- * into the shared ACP result shapes. The hook runs only after the call has
542
- * classified as a command; existing shared result fields must win.
543
- */
544
424
  normalizeCommandEvent?(event: AcpToolCallUpdateEvent): AcpToolCallUpdateEvent;
545
- /**
546
- * A vendor JSON-RPC request the agent sends to the client. A dialect that
547
- * answers one returns the JSON-RPC result to reply with (`{}` is a valid
548
- * acknowledgement) and, optionally, what the request reported. A request
549
- * no dialect claims stays an unsupported method.
550
- */
551
425
  handleClientRequest?(method: string, params: unknown): AcpClientRequestOutcome | undefined;
552
- /**
553
- * How bb keeps this agent healthy: sign-in, installation, account and
554
- * usage. ACP standardizes none of it, so an agent without one reports only
555
- * whether its executable exists.
556
- */
557
426
  maintenance?: AcpMaintenanceDialect;
558
427
  }
559
428
  interface AcpClientRequestOutcome {
560
- /** The JSON-RPC result the bridge replies with. */
561
429
  result: Record<string, unknown>;
562
- /** A sub-agent the request reported, if it reported one. */
563
430
  delegation?: AcpDelegationReport;
564
431
  }
565
432
 
566
- /**
567
- * What one installed ACP agent can actually do (Q21).
568
- *
569
- * A provider declaration states its capabilities before any agent has spoken,
570
- * so bb declared one answer for every ACP agent and got them wrong: the ACP
571
- * tier offered `session/fork` for five agents, of which the two bb has since
572
- * read the wire for support none of it. A declaration above what the agent
573
- * answers is not a missing feature — the bridge refuses the fork only after
574
- * bb created the fork thread, so the thread dies on start (get-bb/bb#1833).
575
- *
576
- * The agent already reports the truth: `initialize` returns
577
- * `agentCapabilities`. This probe asks it. It runs on the host, because the
578
- * agent is a host-local executable, and it is deliberately cheap and
579
- * disposable: spawn, initialize, read the reply, kill. It never starts a
580
- * session and never prompts.
581
- */
582
-
583
433
  interface AcpAgentProbeRequest {
584
434
  command: string;
585
435
  args: readonly string[];
586
- /** Extra environment the agent's launch spec asks for. */
587
436
  env?: Record<string, string>;
588
- /** Where to run the probe; the agent may refuse to start without one. */
589
437
  cwd: string;
590
438
  timeoutMs?: number;
591
439
  }
592
- /** What the agent said about itself, or why bb could not ask. */
593
440
  type AcpAgentProbe = {
594
441
  reachable: true;
595
- /** The agent implements the unstable `session/fork`. */
596
442
  fork: boolean;
597
443
  } | {
598
444
  reachable: false;
599
445
  reason: string;
600
446
  };
601
- /**
602
- * Ask one agent what it supports. Never throws: an agent that is missing,
603
- * broken, or too slow is a `reachable: false` answer with the reason, which
604
- * the caller reports as "bb could not verify this agent" rather than as a
605
- * capability.
606
- */
607
447
  declare function probeAcpAgent(request: AcpAgentProbeRequest): Promise<AcpAgentProbe>;
608
448
  declare const acpAgentProbeSchema: z.ZodType<AcpAgentProbe>;
609
449
 
@@ -717,48 +557,8 @@ declare const acpLaunchSpecSchema: z.ZodObject<{
717
557
  }, z.core.$strict>;
718
558
  type AcpLaunchSpec = z.infer<typeof acpLaunchSpecSchema>;
719
559
 
720
- /**
721
- * Agent CLI model catalog.
722
- *
723
- * Cursor's `cursor-agent --list-models` prints one
724
- * `id - Display Name` line per model,
725
- * OpenCode's `opencode models` prints one bare id per line, and Grok's
726
- * `grok models` prints a bulleted list. These ids can encode reasoning effort:
727
- * `gpt-5.3-codex-low`, bare `gpt-5.3-codex` for medium, `gpt-5.5-extra-high`
728
- * as an alternate xhigh spelling, with an optional `-fast` service tail after
729
- * the effort token (`gpt-5.3-codex-low-fast`). This module groups those raw
730
- * variants into bb model families so the picker offers one clean entry per
731
- * family with selectable reasoning efforts, and resolves a (family, effort,
732
- * serviceTier) selection back to the exact raw id at session launch — by table
733
- * lookup, never string synthesis, because effort spellings vary per family.
734
- *
735
- * The `-fast` tail is a service tier, not a separate model: both the normal
736
- * and fast raw ids for a given effort collapse into one family, and the bb
737
- * "Fast mode" toggle (serviceTier) selects between them at launch.
738
- *
739
- * Cursor's "thinking" marker (appearing as an infix `…-thinking-medium` or a
740
- * suffix `…-medium-thinking` / `…-thinking`) is folded into the reasoning
741
- * ladder too: thinking variants keep their effort, and the model's
742
- * non-thinking variants collapse onto a single "none" (thinking-off) level at
743
- * the bottom of the ladder. So one "Opus 4.8" entry offers None, Low … Max
744
- * instead of separate "Opus 4.8" and "Opus 4.8 Thinking" rows. An explicit
745
- * `-none` effort id (e.g. `gpt-5.5-none`) is the same "none" level.
746
- *
747
- * Display names are stripped of noise the picker renders elsewhere or doesn't
748
- * need — the per-model effort word and "Thinking" marker (reasoning has its
749
- * own control), the redundant `1M` context tag, the `(NO ZDR)` data-retention
750
- * marker, and Cursor's own `(default)`/`(current)` annotations.
751
- */
752
-
753
560
  interface AgentModelCatalog {
754
561
  models: AvailableModel[];
755
- /**
756
- * Exact raw agent id for the family identified by its default-variant id
757
- * (`AvailableModel.id`) at the given effort and service tier. Picks the
758
- * `-fast` id when `serviceTier` is "fast" and the family has one, otherwise
759
- * the normal id. `reasoningLevel` omitted falls back to the family's default
760
- * effort. Returns undefined when the family or requested effort is unknown.
761
- */
762
562
  resolveVariant(args: {
763
563
  model: string;
764
564
  reasoningLevel?: ReasoningLevel;