@get-bb/plugin-sdk 0.4.22 → 0.4.24

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.
@@ -410,15 +410,14 @@ interface PluginThreadListProps {
410
410
  /** True on phone-width viewports and coarse pointers. */
411
411
  isCompactViewport: boolean;
412
412
  /**
413
- * Call after the user opens a thread. It closes the mobile sidebar drawer,
414
- * and it clears the host search field on every viewport. Always call it, or
415
- * the sidebar stays in search mode after the thread opens.
413
+ * Call after the user opens a thread. It closes the mobile sidebar drawer.
416
414
  */
417
415
  onNavigate: () => void;
418
416
  /**
419
- * The host search field's current text, or "" when the field is closed.
420
- * The host owns that field, so a plugin list filters by this rather than
421
- * shipping a second search box.
417
+ * Compatibility value for the former sidebar search field. BB now searches
418
+ * threads in the quick palette, so the host always supplies "".
419
+ *
420
+ * @deprecated The quick palette owns thread search. Ignore this value.
422
421
  */
423
422
  searchQuery: string;
424
423
  /**
@@ -1163,7 +1162,7 @@ interface PluginSidebarThreadSplit {
1163
1162
  * leaving the user with no sidebar.
1164
1163
  *
1165
1164
  * The plugin gets the scrolling list and nothing else. The New-thread button,
1166
- * the search field, the plugin nav rows, and the footer stay host-rendered in
1165
+ * the search action, the plugin nav rows, and the footer stay host-rendered in
1167
1166
  * every sidebar — they are shared surfaces (other plugins live in two of
1168
1167
  * them), and a replaced list must not be able to remove them.
1169
1168
  */
@@ -4716,8 +4716,8 @@ interface ReplayRecordingOptions {
4716
4716
  */
4717
4717
  orderTimeoutMs?: number;
4718
4718
  /**
4719
- * Quiet period after the last request before a non-exact replay is closed.
4720
- * An exact current-lane replay waits for every planned event instead.
4719
+ * Quiet period after the last bridge output before the replay is closed.
4720
+ * An exact current-lane replay first waits for every planned event.
4721
4721
  */
4722
4722
  settleMs?: number;
4723
4723
  /**
@@ -12351,15 +12351,14 @@ interface PluginThreadListProps {
12351
12351
  /** True on phone-width viewports and coarse pointers. */
12352
12352
  isCompactViewport: boolean;
12353
12353
  /**
12354
- * Call after the user opens a thread. It closes the mobile sidebar drawer,
12355
- * and it clears the host search field on every viewport. Always call it, or
12356
- * the sidebar stays in search mode after the thread opens.
12354
+ * Call after the user opens a thread. It closes the mobile sidebar drawer.
12357
12355
  */
12358
12356
  onNavigate: () => void;
12359
12357
  /**
12360
- * The host search field's current text, or "" when the field is closed.
12361
- * The host owns that field, so a plugin list filters by this rather than
12362
- * shipping a second search box.
12358
+ * Compatibility value for the former sidebar search field. BB now searches
12359
+ * threads in the quick palette, so the host always supplies "".
12360
+ *
12361
+ * @deprecated The quick palette owns thread search. Ignore this value.
12363
12362
  */
12364
12363
  searchQuery: string;
12365
12364
  /**
@@ -13104,7 +13103,7 @@ interface PluginSidebarThreadSplit {
13104
13103
  * leaving the user with no sidebar.
13105
13104
  *
13106
13105
  * The plugin gets the scrolling list and nothing else. The New-thread button,
13107
- * the search field, the plugin nav rows, and the footer stay host-rendered in
13106
+ * the search action, the plugin nav rows, and the footer stay host-rendered in
13108
13107
  * every sidebar — they are shared surfaces (other plugins live in two of
13109
13108
  * them), and a replaced list must not be able to remove them.
13110
13109
  */
@@ -7253,9 +7253,25 @@ function buildAcpModelListParams(launchSpec, options) {
7253
7253
  ...launchSpec.nativeReasoning !== void 0 ? { nativeReasoning: launchSpec.nativeReasoning } : {}
7254
7254
  };
7255
7255
  }
7256
- function cursorParameterizedModelId(model) {
7256
+ var CURSOR_LEGACY_FAMILY_SELECTIONS = {
7257
+ "claude-4-sonnet": { modelId: "claude-sonnet-4" },
7258
+ "claude-4.5-opus": { modelId: "claude-opus-4-5" },
7259
+ "claude-4.5-sonnet": { modelId: "claude-sonnet-4-5" },
7260
+ "claude-4.6-opus": { modelId: "claude-opus-4-6" },
7261
+ "claude-4.6-sonnet": { modelId: "claude-sonnet-4-6" },
7262
+ "gemini-3.6-flash-minimal": {
7263
+ modelId: "gemini-3.6-flash",
7264
+ reasoningLevel: "low"
7265
+ },
7266
+ "gpt-5.1-codex-max": { modelId: "gpt-5.1" }
7267
+ };
7268
+ function cursorParameterizedSelection(model, reasoningLevel) {
7257
7269
  const familyId = model === "auto" ? "default" : agentModelFamilyId(model);
7258
- return familyId.startsWith("cursor-") ? familyId.slice("cursor-".length) : familyId;
7270
+ const bareFamilyId = familyId.startsWith("cursor-") ? familyId.slice("cursor-".length) : familyId;
7271
+ const selection = CURSOR_LEGACY_FAMILY_SELECTIONS[bareFamilyId] ?? {
7272
+ modelId: bareFamilyId
7273
+ };
7274
+ return selection.reasoningLevel !== void 0 || reasoningLevel === void 0 ? selection : { ...selection, reasoningLevel };
7259
7275
  }
7260
7276
  function buildAcpModelSelectionParam(launchSpec, options, parameterizedModelPicker, dialectId) {
7261
7277
  const model = options.model;
@@ -7264,10 +7280,13 @@ function buildAcpModelSelectionParam(launchSpec, options, parameterizedModelPick
7264
7280
  return {};
7265
7281
  }
7266
7282
  if (parameterizedModelPicker || !listCommand || !launchSpec.modelCli?.selectFlag) {
7283
+ const modelSelection = parameterizedModelPicker && dialectId === "cursor" ? cursorParameterizedSelection(model, options.reasoningLevel) : {
7284
+ modelId: model,
7285
+ ...options.reasoningLevel !== void 0 ? { reasoningLevel: options.reasoningLevel } : {}
7286
+ };
7267
7287
  return {
7268
7288
  modelSelection: {
7269
- modelId: parameterizedModelPicker && dialectId === "cursor" ? cursorParameterizedModelId(model) : model,
7270
- ...options.reasoningLevel !== void 0 ? { reasoningLevel: options.reasoningLevel } : {},
7289
+ ...modelSelection,
7271
7290
  ...parameterizedModelPicker && options.serviceTier !== void 0 ? { serviceTier: options.serviceTier } : {}
7272
7291
  }
7273
7292
  };
@@ -7395,6 +7414,7 @@ function createAcpAgentConnection(options) {
7395
7414
  const stderrChunks = [];
7396
7415
  let nextRequestId = 1;
7397
7416
  let exited = false;
7417
+ let stopping = false;
7398
7418
  function rejectAllPending(error) {
7399
7419
  for (const [, request] of pending) {
7400
7420
  request.reject(error);
@@ -7416,6 +7436,9 @@ function createAcpAgentConnection(options) {
7416
7436
  options.onExit({ code: null, signal: null, stderrTail });
7417
7437
  }
7418
7438
  function writeLine(message) {
7439
+ if (stopping) {
7440
+ return;
7441
+ }
7419
7442
  const stdin = child.stdin;
7420
7443
  if (!stdin || stdin.destroyed || !stdin.writable) {
7421
7444
  closeForAgentStdin(new Error("stdin is not writable"));
@@ -7427,6 +7450,10 @@ function createAcpAgentConnection(options) {
7427
7450
  if (!isClosedAgentStdinError(error)) {
7428
7451
  throw error;
7429
7452
  }
7453
+ if (stopping) {
7454
+ child.kill("SIGKILL");
7455
+ return;
7456
+ }
7430
7457
  closeForAgentStdin(error);
7431
7458
  });
7432
7459
  if (child.stdout) {
@@ -7524,10 +7551,10 @@ function createAcpAgentConnection(options) {
7524
7551
  });
7525
7552
  return {
7526
7553
  get exited() {
7527
- return exited;
7554
+ return stopping || exited;
7528
7555
  },
7529
7556
  request({ method, params, resultSchema }) {
7530
- if (exited) {
7557
+ if (stopping || exited) {
7531
7558
  return Promise.reject(
7532
7559
  new AcpAgentExitedError(
7533
7560
  `ACP agent "${options.command}" is not running`
@@ -7556,15 +7583,21 @@ function createAcpAgentConnection(options) {
7556
7583
  });
7557
7584
  },
7558
7585
  notify(method, params) {
7559
- if (exited) {
7586
+ if (stopping || exited) {
7560
7587
  return;
7561
7588
  }
7562
7589
  writeLine({ jsonrpc: "2.0", method, params });
7563
7590
  },
7564
7591
  kill() {
7565
- if (exited) {
7592
+ if (stopping || exited) {
7566
7593
  return;
7567
7594
  }
7595
+ stopping = true;
7596
+ rejectAllPending(
7597
+ new AcpAgentExitedError(
7598
+ `ACP agent "${options.command}" is not running`
7599
+ )
7600
+ );
7568
7601
  child.kill("SIGTERM");
7569
7602
  }
7570
7603
  };
@@ -7111,9 +7111,8 @@ async function replayRecording(options) {
7111
7111
  `all ${plannedEventCount} planned events before closing the bridge`,
7112
7112
  () => events.length >= plannedEventCount
7113
7113
  );
7114
- } else {
7115
- await waitFor("the stream to settle", () => Date.now() - lastOutputAt >= settleMs);
7116
7114
  }
7115
+ await waitFor("the stream to settle", () => Date.now() - lastOutputAt >= settleMs);
7117
7116
  child.stdin?.end();
7118
7117
  const exitCode = await Promise.race([
7119
7118
  exited,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@get-bb/plugin-sdk",
3
- "version": "0.4.22",
3
+ "version": "0.4.24",
4
4
  "homepage": "https://github.com/get-bb/bb#readme",
5
5
  "bugs": {
6
6
  "url": "https://github.com/get-bb/bb/issues"