@get-bb/plugin-sdk 0.4.29 → 0.4.34

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.
@@ -431,6 +431,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
431
431
  composerCustomizations: [],
432
432
  pendingInteractions: [],
433
433
  sidebarFooterActions: [],
434
+ experimentalSidebarNavigations: [],
434
435
  threadLists: [],
435
436
  threadHeaderActions: [],
436
437
  fileOpeners: [],
@@ -452,6 +453,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
452
453
  composerCustomization: /* @__PURE__ */ new Set(),
453
454
  pendingInteraction: /* @__PURE__ */ new Set(),
454
455
  sidebarFooterAction: /* @__PURE__ */ new Set(),
456
+ sidebarNavigation: /* @__PURE__ */ new Set(),
455
457
  threadList: /* @__PURE__ */ new Set(),
456
458
  threadHeaderAction: /* @__PURE__ */ new Set(),
457
459
  fileOpener: /* @__PURE__ */ new Set(),
@@ -643,6 +645,22 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
643
645
  run: registration.run
644
646
  });
645
647
  },
648
+ experimental_sidebarNavigation(registration) {
649
+ const kind = "slots.experimental_sidebarNavigation";
650
+ const id = requireSlotId(kind, registration?.id);
651
+ requireUniqueId(kind, seenIds.sidebarNavigation, id);
652
+ const description = requireOptionalString(
653
+ kind,
654
+ "description",
655
+ registration.description
656
+ );
657
+ collected.experimentalSidebarNavigations.push({
658
+ id,
659
+ title: requireNonEmptyString(kind, "title", registration.title),
660
+ ...description !== void 0 ? { description } : {},
661
+ component: requireComponent(kind, registration.component)
662
+ });
663
+ },
646
664
  experimental_threadList(registration) {
647
665
  const kind = "slots.experimental_threadList";
648
666
  const id = requireSlotId(kind, registration?.id);
@@ -1713,7 +1731,8 @@ function renderSlot(registration, props, options = {}) {
1713
1731
  inputLockCalls: [],
1714
1732
  quotes: [],
1715
1733
  mentions: [],
1716
- focusCount: 0
1734
+ focusCount: 0,
1735
+ submits: []
1717
1736
  };
1718
1737
  const composerOwnership = { active: true };
1719
1738
  const composer = {
@@ -1768,6 +1787,19 @@ ${block}
1768
1787
  },
1769
1788
  focus() {
1770
1789
  composerLog.focusCount += 1;
1790
+ },
1791
+ async experimental_submit({ sendAt }) {
1792
+ if (!composerOwnership.active) {
1793
+ throw new Error("This composer is no longer active.");
1794
+ }
1795
+ if (composerText.trim() === "") {
1796
+ throw new Error("Type a message before scheduling it.");
1797
+ }
1798
+ if (!Number.isFinite(sendAt) || sendAt <= Date.now()) {
1799
+ throw new Error("Pick a time in the future.");
1800
+ }
1801
+ composerLog.submits.push({ sendAt });
1802
+ commitComposerText("");
1771
1803
  }
1772
1804
  }
1773
1805
  };
@@ -1612,6 +1612,12 @@ function agentToolIconRefusalMessage(toolName, problem) {
1612
1612
  function providerWithoutBridgeMessage(providerId) {
1613
1613
  return `provider "${providerId}" has no bridge to run on: this plugin declares no "bb.host" entry in its manifest`;
1614
1614
  }
1615
+ function storePluginHook(records, hook, handler) {
1616
+ records[hook] = handler;
1617
+ }
1618
+ function pluginHookAlreadyRegisteredMessage(hook) {
1619
+ return `a "${hook}" hook handler is already registered by this plugin`;
1620
+ }
1615
1621
 
1616
1622
  // src/testing/fake-sdk.ts
1617
1623
  function withSpawnAttribution(pluginId, args) {
@@ -2538,6 +2544,7 @@ function createFakePluginHostInternal(options, sharedState) {
2538
2544
  });
2539
2545
  }
2540
2546
  };
2547
+ let requestedDrains = 0;
2541
2548
  const needsConfigurationMessages = [];
2542
2549
  const status = {
2543
2550
  needsConfiguration(message) {
@@ -2569,7 +2576,13 @@ function createFakePluginHostInternal(options, sharedState) {
2569
2576
  "thread.idle": [],
2570
2577
  "thread.failed": [],
2571
2578
  "thread.archived": [],
2572
- "thread.deleted": []
2579
+ "thread.deleted": [],
2580
+ "message.queued": [],
2581
+ "message.dispatched": [],
2582
+ "turn.failed": []
2583
+ };
2584
+ const hooks = {
2585
+ "message.dispatch": null
2573
2586
  };
2574
2587
  const disposeHooks = [];
2575
2588
  const serviceControllers = [];
@@ -2787,6 +2800,18 @@ function createFakePluginHostInternal(options, sharedState) {
2787
2800
  return registerProviderDeclaration(declaration);
2788
2801
  }
2789
2802
  };
2803
+ const experimental_hooks = {
2804
+ on(hook, handler) {
2805
+ if (hooks[hook] !== null) {
2806
+ throw new Error(pluginHookAlreadyRegisteredMessage(hook));
2807
+ }
2808
+ storePluginHook(hooks, hook, handler);
2809
+ },
2810
+ async recheck(_hook) {
2811
+ assertLive();
2812
+ requestedDrains += 1;
2813
+ }
2814
+ };
2790
2815
  const bb = {
2791
2816
  pluginId,
2792
2817
  log,
@@ -2801,6 +2826,7 @@ function createFakePluginHostInternal(options, sharedState) {
2801
2826
  providers,
2802
2827
  ui,
2803
2828
  events,
2829
+ experimental_hooks,
2804
2830
  status,
2805
2831
  server,
2806
2832
  hosts,
@@ -2858,6 +2884,9 @@ function createFakePluginHostInternal(options, sharedState) {
2858
2884
  logEntries,
2859
2885
  realtimeSignals,
2860
2886
  needsConfigurationMessages,
2887
+ get recheckCount() {
2888
+ return requestedDrains;
2889
+ },
2861
2890
  sharedPortDeclarations,
2862
2891
  experimental_hostRpcCalls: hostRpcCalls,
2863
2892
  sdk: sdkHarness,
@@ -2886,9 +2915,15 @@ function createFakePluginHostInternal(options, sharedState) {
2886
2915
  "thread.idle": threadEventHandlers["thread.idle"].length,
2887
2916
  "thread.failed": threadEventHandlers["thread.failed"].length,
2888
2917
  "thread.archived": threadEventHandlers["thread.archived"].length,
2889
- "thread.deleted": threadEventHandlers["thread.deleted"].length
2918
+ "thread.deleted": threadEventHandlers["thread.deleted"].length,
2919
+ "message.queued": threadEventHandlers["message.queued"].length,
2920
+ "message.dispatched": threadEventHandlers["message.dispatched"].length,
2921
+ "turn.failed": threadEventHandlers["turn.failed"].length
2890
2922
  };
2891
2923
  },
2924
+ get hooks() {
2925
+ return { ...hooks };
2926
+ },
2892
2927
  mentionProviders,
2893
2928
  providerRegistrations,
2894
2929
  aiServiceRegistrations
@@ -3195,6 +3230,43 @@ function makeThreadResponse(overrides = {}) {
3195
3230
  runtime: { displayStatus: "idle", hostReconnectGraceExpiresAt: null },
3196
3231
  activeBackgroundAgentCount: 0,
3197
3232
  canSpawnChild: true,
3233
+ queuedMessageCount: 0,
3234
+ ...overrides
3235
+ };
3236
+ }
3237
+ function makeQueueEntry(overrides = {}) {
3238
+ return {
3239
+ id: "queued_1",
3240
+ threadId: "thread-1",
3241
+ content: [{ type: "text", text: "Queued turn", mentions: [] }],
3242
+ model: "test-model",
3243
+ reasoningLevel: "medium",
3244
+ permissionMode: "auto",
3245
+ serviceTier: "default",
3246
+ groupWithNext: false,
3247
+ sendAt: null,
3248
+ waitingOn: {
3249
+ kind: "plugin",
3250
+ pluginId: "test-plugin",
3251
+ reason: "Waiting"
3252
+ },
3253
+ failureReason: null,
3254
+ payload: { kind: "inline" },
3255
+ editable: true,
3256
+ createdAt: 0,
3257
+ updatedAt: 0,
3258
+ ...overrides
3259
+ };
3260
+ }
3261
+ function makeTurnFailedEvent(overrides = {}) {
3262
+ return {
3263
+ threadId: "thread-1",
3264
+ requestId: "creq_2222222222",
3265
+ turnId: "turn-1",
3266
+ errorInfo: null,
3267
+ inputAccepted: true,
3268
+ rateLimits: null,
3269
+ attemptNumber: 1,
3198
3270
  ...overrides
3199
3271
  };
3200
3272
  }
@@ -3299,5 +3371,7 @@ export {
3299
3371
  createFakePluginHost,
3300
3372
  createFakeSdk,
3301
3373
  scanPublicSdkOnly as experimental_scanPublicSdkOnly,
3302
- makeThreadResponse
3374
+ makeQueueEntry,
3375
+ makeThreadResponse,
3376
+ makeTurnFailedEvent
3303
3377
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@get-bb/plugin-sdk",
3
- "version": "0.4.29",
3
+ "version": "0.4.34",
4
4
  "homepage": "https://github.com/get-bb/bb#readme",
5
5
  "bugs": {
6
6
  "url": "https://github.com/get-bb/bb/issues"