@get-bb/plugin-sdk 0.4.99 → 0.4.101

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.
@@ -855,6 +855,23 @@ interface ExperimentalAppOverlayRegistration {
855
855
  id: string;
856
856
  component: ComponentType<ExperimentalAppOverlayProps>;
857
857
  }
858
+ /**
859
+ * A name the host resolves to a glyph, in this order: a name any plugin
860
+ * registered with `app.experimental_icons.register()`, then a built-in BB icon
861
+ * name (`"Zap"`), then a namespaced `"<pluginId>/<name>"` glyph naming an
862
+ * entry of that plugin's manifest `bb.branding.experimental_icons` map. A
863
+ * registration therefore shadows a built-in, and either shadows a declared
864
+ * icon of the same name. Names that resolve to none of the three fall back to
865
+ * the surface's generic icon.
866
+ *
867
+ * Declared icons and registrations are one vocabulary here: the same name
868
+ * works in `experimental_Icon`, in every field below, and — for a declared
869
+ * icon — in the tool, provider and bridge-row declarations that accept one.
870
+ * Declared icons need no frontend bundle and survive the plugin being stopped;
871
+ * registrations can be any React component but live only while the plugin's
872
+ * app bundle is loaded.
873
+ */
874
+ type BbIconName = string;
858
875
  /**
859
876
  * Owner-defined validator for a fixed tab's transient target. The host first
860
877
  * verifies that the value is JSON-safe, then calls this validator before
@@ -879,8 +896,7 @@ type ExperimentalPluginFixedTabReference<Target extends JsonValue$1 = never> = {
879
896
  /** A fixed tab declared by a plugin nav panel. */
880
897
  type PluginFixedTabRegistration<Target extends JsonValue$1 = never> = ExperimentalPluginFixedTabReference<Target> & {
881
898
  title: string;
882
- /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
883
- icon: string;
899
+ icon: BbIconName;
884
900
  component: ComponentType<PluginNavPanelProps>;
885
901
  /** `flush` lets the component own padding and scrolling. */
886
902
  layout?: "flush" | "padded";
@@ -891,8 +907,7 @@ interface PluginNavPanelRegistration {
891
907
  /** Unique within the plugin; letters, digits, `-`, `_`. */
892
908
  id: string;
893
909
  title: string;
894
- /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
895
- icon: string;
910
+ icon: BbIconName;
896
911
  /** URL segment under `/plugins/<pluginId>/`; letters, digits, `-`, `_`. */
897
912
  path: string;
898
913
  component: ComponentType<PluginNavPanelProps>;
@@ -975,10 +990,10 @@ interface PluginThreadPanelActionRegistration {
975
990
  /** Label of the action row in the panel's new-tab launcher. */
976
991
  title: string;
977
992
  /**
978
- * Icon hint (BB icon name) used when the plugin ships no logo; the
979
- * launcher row and opened tabs prefer the plugin's logo.
993
+ * Drawn only when the manifest declares no `bb.branding.icon`; the launcher
994
+ * row and opened tabs prefer that over this hint.
980
995
  */
981
- icon?: string;
996
+ icon?: BbIconName;
982
997
  /** Rendered inside every panel tab this action opens. */
983
998
  component: ComponentType<PluginThreadPanelProps>;
984
999
  /**
@@ -1015,8 +1030,8 @@ interface PluginNewThreadPanelActionRegistration {
1015
1030
  id: string;
1016
1031
  /** Label of the action row in the panel's new-tab launcher. */
1017
1032
  title: string;
1018
- /** Icon hint (BB icon name) used when the plugin ships no logo. */
1019
- icon?: string;
1033
+ /** Drawn only when the manifest declares no `bb.branding.icon`. */
1034
+ icon?: BbIconName;
1020
1035
  /** Rendered inside every panel tab this action opens. */
1021
1036
  component: ComponentType<PluginNewThreadPanelProps>;
1022
1037
  /** Host framing; matches `threadPanelAction`. */
@@ -1060,8 +1075,8 @@ interface PluginSidebarFooterActionRegistration {
1060
1075
  id: string;
1061
1076
  /** Tooltip and accessible label for the icon button. */
1062
1077
  title: string;
1063
- /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
1064
- icon: string;
1078
+ /** Drawn only when the manifest declares no `bb.branding.icon`. */
1079
+ icon: BbIconName;
1065
1080
  /**
1066
1081
  * Runs when the user activates the action (e.g. call `openSettings()`,
1067
1082
  * open a panel via other surfaces, toast). Errors (sync or async) are
@@ -1080,8 +1095,7 @@ interface ExperimentalSidebarFooterItemBase {
1080
1095
  id: string;
1081
1096
  /** Tooltip and accessible label for the host-rendered icon button. */
1082
1097
  label: string;
1083
- /** BB icon-name hint; unknown names fall back to a generic icon. */
1084
- icon: string;
1098
+ icon: BbIconName;
1085
1099
  }
1086
1100
  /** A sidebar-footer item that runs a callback when activated. */
1087
1101
  interface ExperimentalSidebarFooterActionRegistration extends ExperimentalSidebarFooterItemBase {
@@ -1558,8 +1572,7 @@ interface PluginMessageActionRegistration {
1558
1572
  id: string;
1559
1573
  /** Tooltip / menu label for the action. */
1560
1574
  title: string;
1561
- /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
1562
- icon?: string;
1575
+ icon?: BbIconName;
1563
1576
  /**
1564
1577
  * Runs when the user activates the action. Errors (sync or async) are
1565
1578
  * contained and logged; they never break the timeline.
@@ -1990,6 +2003,11 @@ interface ExperimentalProviderIconProps {
1990
2003
  "aria-hidden"?: boolean | "false" | "true";
1991
2004
  "aria-label"?: string;
1992
2005
  }
2006
+ /**
2007
+ * An app icon registered by a plugin. The registry is app-wide: a registered
2008
+ * name is usable wherever a `BbIconName` is — `experimental_Icon`, and every
2009
+ * host-rendered surface that takes one — by this plugin or any other.
2010
+ */
1993
2011
  interface ExperimentalIconRegistration {
1994
2012
  /** Shared app name. Namespacing is recommended, but not required. */
1995
2013
  name: string;
@@ -2000,10 +2018,11 @@ interface ExperimentalIconRegistration {
2000
2018
  }
2001
2019
  interface ExperimentalAppIcons {
2002
2020
  /**
2003
- * Add or override an app icon during setup. Returns nothing; the host
2004
- * replaces registrations on reload and removes them on unload. Duplicate
2005
- * names within a plugin reject setup. Between plugins, the first plugin id
2006
- * in lexical order wins, independent of bundle load order.
2021
+ * Add or override an app icon during setup. A registered name shadows a
2022
+ * built-in of the same name. Returns nothing; the host replaces
2023
+ * registrations on reload and removes them on unload. Duplicate names within
2024
+ * a plugin reject setup. Between plugins, the first plugin id in lexical
2025
+ * order wins, independent of bundle load order.
2007
2026
  */
2008
2027
  register(registration: ExperimentalIconRegistration): void;
2009
2028
  }
@@ -2088,8 +2107,8 @@ interface ComposerCustomization {
2088
2107
  interface ComposerPlusMenuItem {
2089
2108
  id: string;
2090
2109
  label: string;
2091
- /** BB icon name; unknown names fall back to the generic plugin icon. */
2092
- icon?: string;
2110
+ /** Drawn only when the manifest declares no `bb.branding.icon`. */
2111
+ icon?: BbIconName;
2093
2112
  /** Accessible description for the host-rendered row. */
2094
2113
  description?: string;
2095
2114
  disabled?: boolean | ((view: ComposerView) => boolean);
@@ -2142,8 +2161,11 @@ interface PluginComposerTextEffect {
2142
2161
  }
2143
2162
  /** Host-rendered status that temporarily replaces a thread's draft glyph. */
2144
2163
  interface PluginComposerThreadRowStatus {
2145
- /** BB icon-name hint; unknown names fall back to the generic plugin icon. */
2146
- icon: string;
2164
+ /**
2165
+ * Always drawn as given: unlike the plugin-badged surfaces, this one has no
2166
+ * preference for the plugin's own `bb.branding.icon`.
2167
+ */
2168
+ icon: BbIconName;
2147
2169
  /** Accessible label for the status glyph. */
2148
2170
  label: string;
2149
2171
  /**
@@ -2276,8 +2298,7 @@ interface ThreadChatMessageAction {
2276
2298
  id: string;
2277
2299
  /** Tooltip / menu label for the action. */
2278
2300
  title: string;
2279
- /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
2280
- icon?: string;
2301
+ icon?: BbIconName;
2281
2302
  /**
2282
2303
  * Message roles the action applies to. Omitted = both user and assistant
2283
2304
  * messages.
@@ -300,6 +300,21 @@ type CallerExecutionInputSource = z.infer<typeof callerExecutionInputSourceSchem
300
300
  declare const PROVIDER_FORK_VALUES: readonly ["none", "tip", "checkpoint"];
301
301
  type ProviderFork = (typeof PROVIDER_FORK_VALUES)[number];
302
302
 
303
+ declare const threadTurnInitiatorSchema: z.ZodEnum<{
304
+ agent: "agent";
305
+ system: "system";
306
+ user: "user";
307
+ }>;
308
+ type ThreadTurnInitiator = z.infer<typeof threadTurnInitiatorSchema>;
309
+
310
+ declare const threadCreateOriginSchema: z.ZodEnum<{
311
+ app: "app";
312
+ cli: "cli";
313
+ plugin: "plugin";
314
+ sdk: "sdk";
315
+ }>;
316
+ type ThreadCreateOrigin = z.infer<typeof threadCreateOriginSchema>;
317
+
303
318
  declare const threadQueuedMessageSchema: z.ZodObject<{
304
319
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
305
320
  mentions: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -394,6 +409,13 @@ declare const threadQueuedMessageSchema: z.ZodObject<{
394
409
  user: "user";
395
410
  }>;
396
411
  model: z.ZodString;
412
+ origin: z.ZodNullable<z.ZodEnum<{
413
+ app: "app";
414
+ cli: "cli";
415
+ plugin: "plugin";
416
+ sdk: "sdk";
417
+ }>>;
418
+ originPluginId: z.ZodNullable<z.ZodString>;
397
419
  payload: z.ZodDiscriminatedUnion<[z.ZodObject<{
398
420
  kind: z.ZodLiteral<"inline">;
399
421
  }, z.core.$strip>, z.ZodObject<{
@@ -448,22 +470,7 @@ declare const threadQueuedMessageSchema: z.ZodObject<{
448
470
  }, z.core.$strip>;
449
471
  type ThreadQueuedMessage = z.infer<typeof threadQueuedMessageSchema>;
450
472
 
451
- declare const threadCreateOriginSchema: z.ZodEnum<{
452
- app: "app";
453
- cli: "cli";
454
- plugin: "plugin";
455
- sdk: "sdk";
456
- }>;
457
- type ThreadCreateOrigin = z.infer<typeof threadCreateOriginSchema>;
458
473
  type ExecutionInputFieldSource = CallerExecutionInputSource;
459
- declare const startedOnBehalfOfSchema: z.ZodObject<{
460
- initiator: z.ZodEnum<{
461
- agent: "agent";
462
- system: "system";
463
- }>;
464
- senderThreadId: z.ZodString;
465
- }, z.core.$strip>;
466
- type StartedOnBehalfOf = z.infer<typeof startedOnBehalfOfSchema>;
467
474
  declare const threadResponseSchema: z.ZodObject<{
468
475
  activeBackgroundAgentCount: z.ZodNumber;
469
476
  archivedAt: z.ZodNullable<z.ZodNumber>;
@@ -1016,8 +1023,26 @@ interface MessageDispatchHookContext {
1016
1023
  /** Whether this attempt starts a turn or joins a running one. */
1017
1024
  attempt: PluginDispatchAttemptKind;
1018
1025
  /**
1019
- * The queued row this attempt is re-trying, or null when the attempt is
1020
- * inline and no row has ever existed for it.
1026
+ * The author category shared by this dispatch's messages: `user`, `agent`,
1027
+ * or `system`. `mixed` means the queued messages have different categories.
1028
+ * Different agents still share the `agent` category; read `queuedMessages`
1029
+ * for each message's author. `mixed` is a hook summary, not a turn initiator.
1030
+ */
1031
+ initiator: ThreadTurnInitiator | "mixed";
1032
+ /**
1033
+ * The thread that sent every message in this dispatch: a thread id, null
1034
+ * when none of them has a sender, or the literal `"mixed"` when the rows
1035
+ * disagree. A thread-start names its requesting thread; a message a human
1036
+ * typed and a core-driven retry have no sender. Null therefore still means
1037
+ * "nobody sent this" rather than "bb could not tell", so a handler may key
1038
+ * a human-versus-agent policy on it; `queuedMessages` names each row's own
1039
+ * sender. Thread ids are prefixed, so no id collides with `"mixed"`.
1040
+ */
1041
+ senderThreadId: string | "mixed" | null;
1042
+ /**
1043
+ * All queued rows this attempt is re-trying, in dispatch order. Empty for
1044
+ * an inline attempt. Each row retains its own content, author, and origin; `input`
1045
+ * contains their combined input, and the hook decides for the whole group.
1021
1046
  *
1022
1047
  * This is how a hook tells a fresh send from a re-attempt of something it
1023
1048
  * already decided about — the replacement for the old
@@ -1025,7 +1050,7 @@ interface MessageDispatchHookContext {
1025
1050
  * should treat the two identically; a hook that logs should not
1026
1051
  * double-count.
1027
1052
  */
1028
- queuedMessage: ThreadQueuedMessage | null;
1053
+ queuedMessages: ThreadQueuedMessage[];
1029
1054
  /**
1030
1055
  * Opaque JSON supplied by a plugin through the composer's
1031
1056
  * `experimental_submit`, paired with that plugin's id. Null for ordinary
@@ -1036,10 +1061,15 @@ interface MessageDispatchHookContext {
1036
1061
  pluginId: string;
1037
1062
  data: JsonValue;
1038
1063
  } | null;
1039
- /** How the dispatch was requested; null for internal/core-driven sends. */
1040
- origin: ThreadCreateOrigin | null;
1041
- originPluginId: string | null;
1042
- startedOnBehalfOf: StartedOnBehalfOf | null;
1064
+ /**
1065
+ * How the dispatch was requested; null for internal/core-driven sends, which
1066
+ * includes every follow-up, steer and retry. Persisted with the queued row,
1067
+ * so a drained re-attempt reads what its first attempt read. For a grouped
1068
+ * dispatch, each field is its shared value or `"mixed"` when rows differ,
1069
+ * including a value versus null. Each queued row exposes its own origin.
1070
+ */
1071
+ origin: ThreadCreateOrigin | "mixed" | null;
1072
+ originPluginId: string | "mixed" | null;
1043
1073
  parentThreadId: string | null;
1044
1074
  }
1045
1075
  /**
@@ -1549,6 +1579,12 @@ interface PluginMentionItem {
1549
1579
  id: string;
1550
1580
  title: string;
1551
1581
  subtitle?: string;
1582
+ /**
1583
+ * BB icon name: a built-in name, or a name the plugin's app bundle
1584
+ * registered with `app.experimental_icons.register()`. The row prefers the
1585
+ * plugin's own branding icon when it ships one; unknown names fall back to
1586
+ * the generic plugin icon.
1587
+ */
1552
1588
  icon?: string;
1553
1589
  }
1554
1590
  /** Agent-only image context resolved with a plugin mention. */
@@ -1402,7 +1402,7 @@ type PluginAgentConfigurationContextOverrides = {
1402
1402
  };
1403
1403
  origin?: Partial<PluginAgentConfigurationContext["origin"]>;
1404
1404
  };
1405
- type MessageDispatchHookContextOverrides = Omit<Partial<MessageDispatchHookContext>, "environment" | "executionSources" | "host" | "input" | "project" | "queuedMessage" | "requestedExecution" | "thread"> & {
1405
+ type MessageDispatchHookContextOverrides = Omit<Partial<MessageDispatchHookContext>, "environment" | "executionSources" | "host" | "input" | "project" | "queuedMessages" | "requestedExecution" | "thread"> & {
1406
1406
  thread?: Partial<MessageDispatchHookContext["thread"]>;
1407
1407
  project?: Partial<MessageDispatchHookContext["project"]>;
1408
1408
  environment?: Partial<NonNullable<MessageDispatchHookContext["environment"]>> | null;
@@ -1410,7 +1410,7 @@ type MessageDispatchHookContextOverrides = Omit<Partial<MessageDispatchHookConte
1410
1410
  input?: Partial<MessageDispatchHookContext["input"]>;
1411
1411
  requestedExecution?: Partial<MessageDispatchHookContext["requestedExecution"]>;
1412
1412
  executionSources?: Partial<MessageDispatchHookContext["executionSources"]>;
1413
- queuedMessage?: Partial<NonNullable<MessageDispatchHookContext["queuedMessage"]>> | null;
1413
+ queuedMessages?: Partial<MessageDispatchHookContext["queuedMessages"][number]>[];
1414
1414
  };
1415
1415
  /**
1416
1416
  * A complete, deterministic host response for faking `bb.sdk.hosts.list()`
@@ -98,7 +98,7 @@ declare const appSettingsUpdateSchema: z$1.ZodUnion<readonly [z$1.ZodObject<{
98
98
  }, z$1.core.$strict>]>;
99
99
  type AppSettingsUpdate = z$1.infer<typeof appSettingsUpdateSchema>;
100
100
 
101
- declare const UI_PREFERENCE_KEYS: readonly ["sidebar.organizationMode", "sidebar.chronologicalSort", "sidebar.sortDirection", "sidebar.sectionOrder", "sidebar.manualSectionOrder", "sidebar.machineSectionOrder", "sidebar.collapsedSections", "sidebar.collapsedProjects", "sidebar.collapsedThreads", "sidebar.collapsedEnvironments", "sidebar.collapsedThreadSections", "sidebar.collapsedMachines", "sidebar.footerOrder", "sidebar.hiddenFooterItems", "sidebar.pluginPanelOrder", "sidebar.visiblePluginPanels", "sidebar.navigationProvider", "sidebar.threadListProvider"];
101
+ declare const UI_PREFERENCE_KEYS: readonly ["sidebar.organizationMode", "sidebar.threadGrouping.environment", "sidebar.chronologicalSort", "sidebar.sortDirection", "sidebar.sectionOrder", "sidebar.manualSectionOrder", "sidebar.machineSectionOrder", "sidebar.collapsedSections", "sidebar.collapsedProjects", "sidebar.collapsedThreads", "sidebar.collapsedEnvironments", "sidebar.collapsedThreadSections", "sidebar.collapsedMachines", "sidebar.footerOrder", "sidebar.hiddenFooterItems", "sidebar.pluginPanelOrder", "sidebar.visiblePluginPanels", "sidebar.navigationProvider", "sidebar.threadListProvider"];
102
102
  type UiPreferenceKey = (typeof UI_PREFERENCE_KEYS)[number];
103
103
  interface UiPreferenceDefinition<Schema extends z$1.ZodTypeAny = z$1.ZodTypeAny> {
104
104
  schema: Schema;
@@ -111,6 +111,7 @@ declare const uiPreferenceDefinitions: {
111
111
  machine: "machine";
112
112
  project: "project";
113
113
  }>>;
114
+ readonly "sidebar.threadGrouping.environment": UiPreferenceDefinition<z$1.ZodUnion<readonly [z$1.ZodLiteral<"auto">, z$1.ZodBoolean]>>;
114
115
  readonly "sidebar.chronologicalSort": UiPreferenceDefinition<z$1.ZodEnum<{
115
116
  alpha: "alpha";
116
117
  created: "created";
@@ -4084,6 +4085,21 @@ type ThreadEventRow = {
4084
4085
  [TType in ThreadEventType]: ThreadEventRowOfType<TType>;
4085
4086
  }[ThreadEventType];
4086
4087
 
4088
+ declare const threadTurnInitiatorSchema: z$1.ZodEnum<{
4089
+ agent: "agent";
4090
+ system: "system";
4091
+ user: "user";
4092
+ }>;
4093
+ type ThreadTurnInitiator = z$1.infer<typeof threadTurnInitiatorSchema>;
4094
+
4095
+ declare const threadCreateOriginSchema: z$1.ZodEnum<{
4096
+ app: "app";
4097
+ cli: "cli";
4098
+ plugin: "plugin";
4099
+ sdk: "sdk";
4100
+ }>;
4101
+ type ThreadCreateOrigin = z$1.infer<typeof threadCreateOriginSchema>;
4102
+
4087
4103
  declare const threadStatusSchema: z$1.ZodEnum<{
4088
4104
  active: "active";
4089
4105
  error: "error";
@@ -4203,6 +4219,13 @@ declare const threadQueuedMessageSchema: z$1.ZodObject<{
4203
4219
  user: "user";
4204
4220
  }>;
4205
4221
  model: z$1.ZodString;
4222
+ origin: z$1.ZodNullable<z$1.ZodEnum<{
4223
+ app: "app";
4224
+ cli: "cli";
4225
+ plugin: "plugin";
4226
+ sdk: "sdk";
4227
+ }>>;
4228
+ originPluginId: z$1.ZodNullable<z$1.ZodString>;
4206
4229
  payload: z$1.ZodDiscriminatedUnion<[z$1.ZodObject<{
4207
4230
  kind: z$1.ZodLiteral<"inline">;
4208
4231
  }, z$1.core.$strip>, z$1.ZodObject<{
@@ -11480,13 +11503,6 @@ interface TimelineTurnRow extends TimelineRowBase {
11480
11503
  type TimelineSourceRow = TimelineConversationRow | TimelineWorkRow | TimelineSystemRow;
11481
11504
  type TimelineRow = TimelineSourceRow | TimelineTurnRow;
11482
11505
 
11483
- declare const threadCreateOriginSchema: z$1.ZodEnum<{
11484
- app: "app";
11485
- cli: "cli";
11486
- plugin: "plugin";
11487
- sdk: "sdk";
11488
- }>;
11489
- type ThreadCreateOrigin = z$1.infer<typeof threadCreateOriginSchema>;
11490
11506
  type ExecutionInputFieldSource = CallerExecutionInputSource;
11491
11507
  declare const createExecutionInputSourcesSchema: z$1.ZodObject<{
11492
11508
  model: z$1.ZodOptional<z$1.ZodEnum<{
@@ -11511,14 +11527,6 @@ declare const createExecutionInputSourcesSchema: z$1.ZodObject<{
11511
11527
  }>>;
11512
11528
  }, z$1.core.$strict>;
11513
11529
  type CreateExecutionInputSources = z$1.infer<typeof createExecutionInputSourcesSchema>;
11514
- declare const startedOnBehalfOfSchema: z$1.ZodObject<{
11515
- initiator: z$1.ZodEnum<{
11516
- agent: "agent";
11517
- system: "system";
11518
- }>;
11519
- senderThreadId: z$1.ZodString;
11520
- }, z$1.core.$strip>;
11521
- type StartedOnBehalfOf = z$1.infer<typeof startedOnBehalfOfSchema>;
11522
11530
  declare const createThreadRequestSchema: z$1.ZodObject<{
11523
11531
  environment: z$1.ZodDiscriminatedUnion<[z$1.ZodObject<{
11524
11532
  environmentId: z$1.ZodString;
@@ -12196,6 +12204,13 @@ declare const sendMessageResponseSchema: z$1.ZodDiscriminatedUnion<[z$1.ZodObjec
12196
12204
  user: "user";
12197
12205
  }>;
12198
12206
  model: z$1.ZodString;
12207
+ origin: z$1.ZodNullable<z$1.ZodEnum<{
12208
+ app: "app";
12209
+ cli: "cli";
12210
+ plugin: "plugin";
12211
+ sdk: "sdk";
12212
+ }>>;
12213
+ originPluginId: z$1.ZodNullable<z$1.ZodString>;
12199
12214
  payload: z$1.ZodDiscriminatedUnion<[z$1.ZodObject<{
12200
12215
  kind: z$1.ZodLiteral<"inline">;
12201
12216
  }, z$1.core.$strip>, z$1.ZodObject<{
@@ -12751,6 +12766,13 @@ declare const sendQueuedMessageResponseSchema: z$1.ZodDiscriminatedUnion<[z$1.Zo
12751
12766
  user: "user";
12752
12767
  }>;
12753
12768
  model: z$1.ZodString;
12769
+ origin: z$1.ZodNullable<z$1.ZodEnum<{
12770
+ app: "app";
12771
+ cli: "cli";
12772
+ plugin: "plugin";
12773
+ sdk: "sdk";
12774
+ }>>;
12775
+ originPluginId: z$1.ZodNullable<z$1.ZodString>;
12754
12776
  payload: z$1.ZodDiscriminatedUnion<[z$1.ZodObject<{
12755
12777
  kind: z$1.ZodLiteral<"inline">;
12756
12778
  }, z$1.core.$strip>, z$1.ZodObject<{
@@ -13645,6 +13667,13 @@ declare const threadQueuedMessageListResponseSchema: z$1.ZodArray<z$1.ZodObject<
13645
13667
  user: "user";
13646
13668
  }>;
13647
13669
  model: z$1.ZodString;
13670
+ origin: z$1.ZodNullable<z$1.ZodEnum<{
13671
+ app: "app";
13672
+ cli: "cli";
13673
+ plugin: "plugin";
13674
+ sdk: "sdk";
13675
+ }>>;
13676
+ originPluginId: z$1.ZodNullable<z$1.ZodString>;
13648
13677
  payload: z$1.ZodDiscriminatedUnion<[z$1.ZodObject<{
13649
13678
  kind: z$1.ZodLiteral<"inline">;
13650
13679
  }, z$1.core.$strip>, z$1.ZodObject<{
@@ -15386,6 +15415,23 @@ interface ExperimentalAppOverlayRegistration {
15386
15415
  id: string;
15387
15416
  component: ComponentType<ExperimentalAppOverlayProps>;
15388
15417
  }
15418
+ /**
15419
+ * A name the host resolves to a glyph, in this order: a name any plugin
15420
+ * registered with `app.experimental_icons.register()`, then a built-in BB icon
15421
+ * name (`"Zap"`), then a namespaced `"<pluginId>/<name>"` glyph naming an
15422
+ * entry of that plugin's manifest `bb.branding.experimental_icons` map. A
15423
+ * registration therefore shadows a built-in, and either shadows a declared
15424
+ * icon of the same name. Names that resolve to none of the three fall back to
15425
+ * the surface's generic icon.
15426
+ *
15427
+ * Declared icons and registrations are one vocabulary here: the same name
15428
+ * works in `experimental_Icon`, in every field below, and — for a declared
15429
+ * icon — in the tool, provider and bridge-row declarations that accept one.
15430
+ * Declared icons need no frontend bundle and survive the plugin being stopped;
15431
+ * registrations can be any React component but live only while the plugin's
15432
+ * app bundle is loaded.
15433
+ */
15434
+ type BbIconName = string;
15389
15435
  /**
15390
15436
  * Owner-defined validator for a fixed tab's transient target. The host first
15391
15437
  * verifies that the value is JSON-safe, then calls this validator before
@@ -15410,8 +15456,7 @@ type ExperimentalPluginFixedTabReference<Target extends JsonValue = never> = {
15410
15456
  /** A fixed tab declared by a plugin nav panel. */
15411
15457
  type PluginFixedTabRegistration<Target extends JsonValue = never> = ExperimentalPluginFixedTabReference<Target> & {
15412
15458
  title: string;
15413
- /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
15414
- icon: string;
15459
+ icon: BbIconName;
15415
15460
  component: ComponentType<PluginNavPanelProps>;
15416
15461
  /** `flush` lets the component own padding and scrolling. */
15417
15462
  layout?: "flush" | "padded";
@@ -15422,8 +15467,7 @@ interface PluginNavPanelRegistration {
15422
15467
  /** Unique within the plugin; letters, digits, `-`, `_`. */
15423
15468
  id: string;
15424
15469
  title: string;
15425
- /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
15426
- icon: string;
15470
+ icon: BbIconName;
15427
15471
  /** URL segment under `/plugins/<pluginId>/`; letters, digits, `-`, `_`. */
15428
15472
  path: string;
15429
15473
  component: ComponentType<PluginNavPanelProps>;
@@ -15506,10 +15550,10 @@ interface PluginThreadPanelActionRegistration {
15506
15550
  /** Label of the action row in the panel's new-tab launcher. */
15507
15551
  title: string;
15508
15552
  /**
15509
- * Icon hint (BB icon name) used when the plugin ships no logo; the
15510
- * launcher row and opened tabs prefer the plugin's logo.
15553
+ * Drawn only when the manifest declares no `bb.branding.icon`; the launcher
15554
+ * row and opened tabs prefer that over this hint.
15511
15555
  */
15512
- icon?: string;
15556
+ icon?: BbIconName;
15513
15557
  /** Rendered inside every panel tab this action opens. */
15514
15558
  component: ComponentType<PluginThreadPanelProps>;
15515
15559
  /**
@@ -15546,8 +15590,8 @@ interface PluginNewThreadPanelActionRegistration {
15546
15590
  id: string;
15547
15591
  /** Label of the action row in the panel's new-tab launcher. */
15548
15592
  title: string;
15549
- /** Icon hint (BB icon name) used when the plugin ships no logo. */
15550
- icon?: string;
15593
+ /** Drawn only when the manifest declares no `bb.branding.icon`. */
15594
+ icon?: BbIconName;
15551
15595
  /** Rendered inside every panel tab this action opens. */
15552
15596
  component: ComponentType<PluginNewThreadPanelProps>;
15553
15597
  /** Host framing; matches `threadPanelAction`. */
@@ -15591,8 +15635,8 @@ interface PluginSidebarFooterActionRegistration {
15591
15635
  id: string;
15592
15636
  /** Tooltip and accessible label for the icon button. */
15593
15637
  title: string;
15594
- /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
15595
- icon: string;
15638
+ /** Drawn only when the manifest declares no `bb.branding.icon`. */
15639
+ icon: BbIconName;
15596
15640
  /**
15597
15641
  * Runs when the user activates the action (e.g. call `openSettings()`,
15598
15642
  * open a panel via other surfaces, toast). Errors (sync or async) are
@@ -15611,8 +15655,7 @@ interface ExperimentalSidebarFooterItemBase {
15611
15655
  id: string;
15612
15656
  /** Tooltip and accessible label for the host-rendered icon button. */
15613
15657
  label: string;
15614
- /** BB icon-name hint; unknown names fall back to a generic icon. */
15615
- icon: string;
15658
+ icon: BbIconName;
15616
15659
  }
15617
15660
  /** A sidebar-footer item that runs a callback when activated. */
15618
15661
  interface ExperimentalSidebarFooterActionRegistration extends ExperimentalSidebarFooterItemBase {
@@ -16089,8 +16132,7 @@ interface PluginMessageActionRegistration {
16089
16132
  id: string;
16090
16133
  /** Tooltip / menu label for the action. */
16091
16134
  title: string;
16092
- /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
16093
- icon?: string;
16135
+ icon?: BbIconName;
16094
16136
  /**
16095
16137
  * Runs when the user activates the action. Errors (sync or async) are
16096
16138
  * contained and logged; they never break the timeline.
@@ -16521,6 +16563,11 @@ interface ExperimentalProviderIconProps {
16521
16563
  "aria-hidden"?: boolean | "false" | "true";
16522
16564
  "aria-label"?: string;
16523
16565
  }
16566
+ /**
16567
+ * An app icon registered by a plugin. The registry is app-wide: a registered
16568
+ * name is usable wherever a `BbIconName` is — `experimental_Icon`, and every
16569
+ * host-rendered surface that takes one — by this plugin or any other.
16570
+ */
16524
16571
  interface ExperimentalIconRegistration {
16525
16572
  /** Shared app name. Namespacing is recommended, but not required. */
16526
16573
  name: string;
@@ -16531,10 +16578,11 @@ interface ExperimentalIconRegistration {
16531
16578
  }
16532
16579
  interface ExperimentalAppIcons {
16533
16580
  /**
16534
- * Add or override an app icon during setup. Returns nothing; the host
16535
- * replaces registrations on reload and removes them on unload. Duplicate
16536
- * names within a plugin reject setup. Between plugins, the first plugin id
16537
- * in lexical order wins, independent of bundle load order.
16581
+ * Add or override an app icon during setup. A registered name shadows a
16582
+ * built-in of the same name. Returns nothing; the host replaces
16583
+ * registrations on reload and removes them on unload. Duplicate names within
16584
+ * a plugin reject setup. Between plugins, the first plugin id in lexical
16585
+ * order wins, independent of bundle load order.
16538
16586
  */
16539
16587
  register(registration: ExperimentalIconRegistration): void;
16540
16588
  }
@@ -16619,8 +16667,8 @@ interface ComposerCustomization {
16619
16667
  interface ComposerPlusMenuItem {
16620
16668
  id: string;
16621
16669
  label: string;
16622
- /** BB icon name; unknown names fall back to the generic plugin icon. */
16623
- icon?: string;
16670
+ /** Drawn only when the manifest declares no `bb.branding.icon`. */
16671
+ icon?: BbIconName;
16624
16672
  /** Accessible description for the host-rendered row. */
16625
16673
  description?: string;
16626
16674
  disabled?: boolean | ((view: ComposerView) => boolean);
@@ -16673,8 +16721,11 @@ interface PluginComposerTextEffect {
16673
16721
  }
16674
16722
  /** Host-rendered status that temporarily replaces a thread's draft glyph. */
16675
16723
  interface PluginComposerThreadRowStatus {
16676
- /** BB icon-name hint; unknown names fall back to the generic plugin icon. */
16677
- icon: string;
16724
+ /**
16725
+ * Always drawn as given: unlike the plugin-badged surfaces, this one has no
16726
+ * preference for the plugin's own `bb.branding.icon`.
16727
+ */
16728
+ icon: BbIconName;
16678
16729
  /** Accessible label for the status glyph. */
16679
16730
  label: string;
16680
16731
  /**
@@ -16807,8 +16858,7 @@ interface ThreadChatMessageAction {
16807
16858
  id: string;
16808
16859
  /** Tooltip / menu label for the action. */
16809
16860
  title: string;
16810
- /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
16811
- icon?: string;
16861
+ icon?: BbIconName;
16812
16862
  /**
16813
16863
  * Message roles the action applies to. Omitted = both user and assistant
16814
16864
  * messages.
@@ -19751,8 +19801,26 @@ interface MessageDispatchHookContext {
19751
19801
  /** Whether this attempt starts a turn or joins a running one. */
19752
19802
  attempt: PluginDispatchAttemptKind;
19753
19803
  /**
19754
- * The queued row this attempt is re-trying, or null when the attempt is
19755
- * inline and no row has ever existed for it.
19804
+ * The author category shared by this dispatch's messages: `user`, `agent`,
19805
+ * or `system`. `mixed` means the queued messages have different categories.
19806
+ * Different agents still share the `agent` category; read `queuedMessages`
19807
+ * for each message's author. `mixed` is a hook summary, not a turn initiator.
19808
+ */
19809
+ initiator: ThreadTurnInitiator | "mixed";
19810
+ /**
19811
+ * The thread that sent every message in this dispatch: a thread id, null
19812
+ * when none of them has a sender, or the literal `"mixed"` when the rows
19813
+ * disagree. A thread-start names its requesting thread; a message a human
19814
+ * typed and a core-driven retry have no sender. Null therefore still means
19815
+ * "nobody sent this" rather than "bb could not tell", so a handler may key
19816
+ * a human-versus-agent policy on it; `queuedMessages` names each row's own
19817
+ * sender. Thread ids are prefixed, so no id collides with `"mixed"`.
19818
+ */
19819
+ senderThreadId: string | "mixed" | null;
19820
+ /**
19821
+ * All queued rows this attempt is re-trying, in dispatch order. Empty for
19822
+ * an inline attempt. Each row retains its own content, author, and origin; `input`
19823
+ * contains their combined input, and the hook decides for the whole group.
19756
19824
  *
19757
19825
  * This is how a hook tells a fresh send from a re-attempt of something it
19758
19826
  * already decided about — the replacement for the old
@@ -19760,7 +19828,7 @@ interface MessageDispatchHookContext {
19760
19828
  * should treat the two identically; a hook that logs should not
19761
19829
  * double-count.
19762
19830
  */
19763
- queuedMessage: ThreadQueuedMessage | null;
19831
+ queuedMessages: ThreadQueuedMessage[];
19764
19832
  /**
19765
19833
  * Opaque JSON supplied by a plugin through the composer's
19766
19834
  * `experimental_submit`, paired with that plugin's id. Null for ordinary
@@ -19771,10 +19839,15 @@ interface MessageDispatchHookContext {
19771
19839
  pluginId: string;
19772
19840
  data: JsonValue;
19773
19841
  } | null;
19774
- /** How the dispatch was requested; null for internal/core-driven sends. */
19775
- origin: ThreadCreateOrigin | null;
19776
- originPluginId: string | null;
19777
- startedOnBehalfOf: StartedOnBehalfOf | null;
19842
+ /**
19843
+ * How the dispatch was requested; null for internal/core-driven sends, which
19844
+ * includes every follow-up, steer and retry. Persisted with the queued row,
19845
+ * so a drained re-attempt reads what its first attempt read. For a grouped
19846
+ * dispatch, each field is its shared value or `"mixed"` when rows differ,
19847
+ * including a value versus null. Each queued row exposes its own origin.
19848
+ */
19849
+ origin: ThreadCreateOrigin | "mixed" | null;
19850
+ originPluginId: string | "mixed" | null;
19778
19851
  parentThreadId: string | null;
19779
19852
  }
19780
19853
  /**
@@ -20661,6 +20734,12 @@ interface PluginMentionItem {
20661
20734
  id: string;
20662
20735
  title: string;
20663
20736
  subtitle?: string;
20737
+ /**
20738
+ * BB icon name: a built-in name, or a name the plugin's app bundle
20739
+ * registered with `app.experimental_icons.register()`. The row prefers the
20740
+ * plugin's own branding icon when it ships one; unknown names fall back to
20741
+ * the generic plugin icon.
20742
+ */
20664
20743
  icon?: string;
20665
20744
  }
20666
20745
  /** Agent-only image context resolved with a plugin mention. */
@@ -4340,11 +4340,12 @@ function makeMessageDispatchHookContext(overrides = {}) {
4340
4340
  permissionMode: null
4341
4341
  },
4342
4342
  attempt: "start-turn",
4343
- queuedMessage: null,
4343
+ initiator: "user",
4344
+ senderThreadId: null,
4345
+ queuedMessages: [],
4344
4346
  experimental_submission: null,
4345
4347
  origin: null,
4346
4348
  originPluginId: null,
4347
- startedOnBehalfOf: null,
4348
4349
  parentThreadId: null,
4349
4350
  environmentIntent: null
4350
4351
  };
@@ -4401,15 +4402,16 @@ function makeMessageDispatchHookContext(overrides = {}) {
4401
4402
  ...context.executionSources,
4402
4403
  ...overrides.executionSources
4403
4404
  },
4404
- queuedMessage: overrides.queuedMessage === void 0 ? context.queuedMessage : overrides.queuedMessage === null ? null : makeQueueEntry({
4405
- threadId: thread.id,
4406
- ...overrides.queuedMessage
4407
- })
4405
+ queuedMessages: (overrides.queuedMessages ?? context.queuedMessages).map(
4406
+ (message) => makeQueueEntry({ threadId: thread.id, ...message })
4407
+ )
4408
4408
  };
4409
4409
  }
4410
4410
  function makeQueueEntry(overrides = {}) {
4411
4411
  return {
4412
4412
  id: "queued_1",
4413
+ origin: null,
4414
+ originPluginId: null,
4413
4415
  initiator: "user",
4414
4416
  senderThreadId: null,
4415
4417
  threadId: "thread-1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@get-bb/plugin-sdk",
3
- "version": "0.4.99",
3
+ "version": "0.4.101",
4
4
  "homepage": "https://github.com/get-bb/bb#readme",
5
5
  "bugs": {
6
6
  "url": "https://github.com/get-bb/bb/issues"