@get-bb/plugin-sdk 0.4.101 → 0.4.106

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.
@@ -1631,10 +1631,6 @@ interface PluginCommandRegistration {
1631
1631
  */
1632
1632
  run(context: PluginCommandContext): void | Promise<void>;
1633
1633
  }
1634
- /** @deprecated Use PluginCommandContext. */
1635
- type PluginCommandPaletteActionContext = PluginCommandContext;
1636
- /** @deprecated Use PluginCommandRegistration. */
1637
- type PluginCommandPaletteActionRegistration = PluginCommandRegistration;
1638
1634
  /** Registers commands for bb's command palette. */
1639
1635
  interface PluginAppCommands {
1640
1636
  /** Register a command. IDs are unique within this plugin, including legacy slot registrations. */
@@ -2272,6 +2268,82 @@ interface PluginComposerApi {
2272
2268
  * Experimental: see docs/api_to_audit.md.
2273
2269
  */
2274
2270
  experimental_submit(options: ExperimentalComposerSubmitOptions): Promise<void>;
2271
+ /**
2272
+ * Set this composer's pickers as if each value had been picked by hand.
2273
+ *
2274
+ * Every field is optional. An omitted field is left alone. A field this
2275
+ * composer has no picker for is ignored rather than rejected: a thread
2276
+ * composer has no project or environment; a provider without service tiers
2277
+ * has no tier; a fork draft locks its project, provider and environment.
2278
+ * Values travel through the same paths the pickers use, so in the
2279
+ * new-thread composer they become the remembered defaults for the next
2280
+ * thread and are reported as the user's explicit choices, and in a thread
2281
+ * composer a provider change starts the same handoff the picker starts:
2282
+ * the handoff block is prepended to the draft and the next send creates a
2283
+ * new thread. A same-provider model change in a thread does not start a
2284
+ * handoff, exactly like the picker.
2285
+ *
2286
+ * In the new-thread composer the project is switched first and awaited
2287
+ * (attachments are copied to the new project), then the environment and
2288
+ * machine are applied to the new project, then provider, model, reasoning
2289
+ * level, service tier and permission mode. A provider change reloads the
2290
+ * model catalog before the model and reasoning level are applied to it.
2291
+ * Because the project switch remounts plugin surfaces, the returned
2292
+ * promise is owned by the composer and still resolves after the calling
2293
+ * component has unmounted.
2294
+ *
2295
+ * Resolves with the composer's own selection once it has settled: the
2296
+ * applied values have committed and the model catalog for the selected
2297
+ * provider and machine has finished loading, so model, reasoning level and
2298
+ * permission mode have reconciled against it. The catalog wait is bounded;
2299
+ * if it has not finished after 15 seconds the promise resolves with the
2300
+ * selection as it stands. The result carries only the fields this composer
2301
+ * has, so a missing key means "no such picker here" and a value that
2302
+ * differs from the one passed was reconciled (a reasoning level the model
2303
+ * does not support, a permission mode above the machine's ceiling, a model
2304
+ * the provider does not list). A provider the composer does not list is
2305
+ * ignored together with the model and reasoning level meant for it, so the
2306
+ * stored provider preference never names something the picker could not
2307
+ * have chosen. `environment` is absent while the composer
2308
+ * has no submittable environment; `providerId` and `model` are absent
2309
+ * while nothing is selected; `serviceTier` is present only when the
2310
+ * selected provider has tiers and one is chosen.
2311
+ *
2312
+ * Rejects, with a message safe to show to the user, in a composer with no
2313
+ * pickers at all (a queued-message editor, a side chat, a plugin surface
2314
+ * mounted outside any composer), when the calling surface is no longer
2315
+ * active, and when a value is not a known reasoning level, service tier or
2316
+ * permission mode.
2317
+ *
2318
+ * Experimental: see docs/api_to_audit.md.
2319
+ */
2320
+ experimental_setSelection(selection: ExperimentalComposerSelection): Promise<ExperimentalComposerSelection>;
2321
+ }
2322
+ /**
2323
+ * Picker values for `experimental_setSelection`, and the shape it resolves
2324
+ * with. Field names match `NewThreadRequest` and the `default*` props of
2325
+ * `experimental_NewThreadComposer`, so one routed decision can feed the
2326
+ * composer, the embedded composer and `bb.sdk.threads.spawn` alike.
2327
+ */
2328
+ interface ExperimentalComposerSelection {
2329
+ /** New-thread composers only. BB's personal-project id means "Don't work in a project". */
2330
+ projectId?: string;
2331
+ /**
2332
+ * New-thread composers only. `{ type: "project-default" }` and a `host`
2333
+ * environment without a `hostId` seed nothing and are ignored. Provider
2334
+ * `inputs` are not applied; the provider's own inputs control keeps its
2335
+ * value, and the result reports what the composer would submit.
2336
+ */
2337
+ environment?: CreateThreadEnvironmentArgs;
2338
+ /** A provider the composer does not list is ignored, and `model` and `reasoningLevel` with it. */
2339
+ providerId?: string;
2340
+ /** Applied only when the composer ends up on the requested provider (or none was requested). */
2341
+ model?: string;
2342
+ /** Applied only when the composer ends up on the requested provider (or none was requested). */
2343
+ reasoningLevel?: ReasoningLevel;
2344
+ /** Ignored by a provider with no service tiers. */
2345
+ serviceTier?: ServiceTier;
2346
+ permissionMode?: PermissionMode;
2275
2347
  }
2276
2348
  /**
2277
2349
  * What `experimental_submit` does differently from pressing Enter.
@@ -2398,9 +2470,8 @@ interface ExperimentalProviderModelPickerProps {
2398
2470
  /**
2399
2471
  * Props of the host-owned `experimental_BranchPicker` component — bb's branch
2400
2472
  * picker bundled with its branch-options loading for the given host and
2401
- * project, the control bb's own New Thread composer renders as "Branch from".
2402
- * The host owns fetching, searching, and refreshing the branch list; the
2403
- * caller owns only the selection.
2473
+ * project. The host owns fetching, searching, and refreshing the branch list;
2474
+ * the caller owns the selection and its meaning.
2404
2475
  */
2405
2476
  interface BranchPickerProps {
2406
2477
  /**
@@ -2411,21 +2482,21 @@ interface BranchPickerProps {
2411
2482
  /** The project whose source on `hostId` is listed; null disables loading. */
2412
2483
  projectId: string | null;
2413
2484
  /**
2414
- * The selected branch name, or null when no branch is chosen (the host
2415
- * shows its placeholder and the consumer falls back to its own default).
2485
+ * The selected branch name, or null when no branch is chosen. A null value
2486
+ * shows the placeholder without selecting or implying a default branch.
2416
2487
  */
2417
2488
  value: string | null;
2418
2489
  /** Called with the picked branch name, or null when the pick is cleared. */
2419
2490
  onChange(next: string | null): void;
2420
2491
  /**
2421
- * Text placed before the branch on the trigger, e.g. "Base:". Omitted, the
2422
- * trigger is the branch alone.
2492
+ * Text placed before the branch on the trigger and used as the menu heading,
2493
+ * e.g. "Compare with:". Omitted, the trigger is the branch alone and the menu
2494
+ * uses the neutral "Branches" heading.
2423
2495
  */
2424
2496
  label?: string;
2425
2497
  /**
2426
- * The trigger while nothing is picked. Omitted, the host shows the resolved
2427
- * default worktree base branch muted, or a neutral `default` placeholder
2428
- * when the base cannot be resolved.
2498
+ * The complete trigger text while nothing is picked, without the label
2499
+ * prefix. Defaults to "Select branch".
2429
2500
  */
2430
2501
  placeholder?: string;
2431
2502
  /** Render the current selection without allowing changes. */
@@ -2952,4 +3023,4 @@ declare const experimental_useProviders: () => PluginProvidersState;
2952
3023
  declare const experimental_useCodeTheme: () => PluginCodeThemeState;
2953
3024
 
2954
3025
  export { Markdown, ThreadChat, UrlLink, definePluginApp, experimental_BranchPicker, experimental_Diff, experimental_FileLink, experimental_Icon, experimental_NewThreadComposer, experimental_PermissionModePicker, experimental_ProviderIcon, experimental_ProviderModelPicker, experimental_SourceCode, experimental_useAppPanel, experimental_useBranches, experimental_useCheckoutState, experimental_useCodeTheme, experimental_useFixedTabTarget, experimental_useProviders, experimental_useSidebarThreadActions, experimental_useSidebarThreadPullRequest, experimental_useSidebarThreadSplit, experimental_useSidebarThreads, useBbContext, useBbNavigate, useComposer, useComposerView, useRealtime, useRealtimeConnectionState, useRpc, useSettings };
2955
- export type { BbContext, BbNavigate, BranchPickerProps, BranchesState, CheckoutState, CodeOverflowMode, ComposerCustomization, ComposerPlusMenuItem, ComposerRichTextSpec, ComposerStructuredDraft, ComposerView, DiffProps, DiffViewMode, ExperimentalAppIcons, ExperimentalAppOverlayProps, ExperimentalAppOverlayRegistration, ExperimentalAppPanel, ExperimentalAppPanelSurface, ExperimentalComposerSubmitOptions, ExperimentalDiffFileContent, ExperimentalDiffFullFileContents, ExperimentalFileLinkProps, ExperimentalFileLocation, ExperimentalFileOpenOptions, ExperimentalFixedTabTargetContract, ExperimentalFixedTabTargetState, ExperimentalIconProps, ExperimentalIconRegistration, ExperimentalLiveFileTarget, ExperimentalOpenFixedTabOptions, ExperimentalPermissionModePickerProps, ExperimentalPluginBrowserPage, ExperimentalPluginBrowserPageEvaluateOptions, ExperimentalPluginBrowserPageWorld, ExperimentalPluginBrowserToolbarActionProps, ExperimentalPluginBrowserToolbarActionRegistration, ExperimentalPluginFixedTabReference, ExperimentalProviderIconProps, ExperimentalProviderModelPickerProps, ExperimentalProviderModelPickerRouting, ExperimentalProviderModelPickerValue, ExperimentalSidebarFooter, ExperimentalSidebarFooterActionContext, ExperimentalSidebarFooterActionRegistration, ExperimentalSidebarFooterDisclosureController, ExperimentalSidebarFooterDisclosureProps, ExperimentalSidebarFooterDisclosureRegistration, ExperimentalSidebarFooterItemBase, ExperimentalSidebarFooterItemRegistration, ExperimentalSidebarNavigationAction, ExperimentalSidebarNavigationActivationOptions, ExperimentalSidebarNavigationIcon, ExperimentalSidebarNavigationItem, ExperimentalSidebarNavigationProps, ExperimentalSidebarNavigationRegistration, ExperimentalSidebarNavigationShortcut, JsonValue$1 as JsonValue, MarkdownProps, NewThreadComposerProps, NewThreadRequest, PluginAppBuilder, PluginAppCommands, PluginAppComposer, PluginAppContentScripts, PluginAppDefinition, PluginAppSetup, PluginAppSlots, PluginCodeThemeData, PluginCodeThemeState, PluginCodeThemeTokenRule, PluginCommandContext, PluginCommandPaletteActionContext, PluginCommandPaletteActionRegistration, PluginCommandRegistration, PluginCommandShortcut, PluginComposerApi, PluginComposerMention, PluginComposerScope, PluginComposerTextEffect, PluginComposerThreadRowStatus, PluginContentScriptContext, PluginContentScriptDisposer, PluginContentScriptRegistration, PluginDiffRendererProps, PluginDiffRendererRegistration, PluginEnvironmentProviderInputsChange, PluginEnvironmentProviderInputsProps, PluginEnvironmentProviderInputsRegistration, PluginFileOpenerProps, PluginFileOpenerRegistration, PluginFileOpenerSource, PluginFixedTabDeclaration, PluginFixedTabRegistration, PluginHomepageSectionProps, PluginHomepageSectionRegistration, PluginMachineProviderInputsChange, PluginMachineProviderInputsProps, PluginMachineProviderInputsRegistration, PluginMessageActionContext, PluginMessageActionRegistration, PluginMessageDirectiveMessage, PluginMessageDirectiveOpenWorkspaceFile, PluginMessageDirectiveProps, PluginMessageDirectiveRegistration, PluginNavPanelProps, PluginNavPanelRegistration, PluginNewThreadPanelActionContext, PluginNewThreadPanelActionRegistration, PluginNewThreadPanelProps, PluginPanelActionOpenOptions, PluginPendingInteractionProps, PluginPendingInteractionRegistration, PluginPendingInteractionView, PluginProviderIconRegistration, PluginProvidersState, PluginRealtimeConnectionState, PluginRpcCallArgs, PluginRpcClient, PluginRpcContract, PluginRpcError, PluginRpcErrorCode, PluginRpcHandlers, PluginRpcIssuePathSegment, PluginRpcMethodContract, PluginRpcResult, PluginRpcValidationIssue, PluginSdkApp, PluginSettingsSectionProps, PluginSettingsSectionRegistration, PluginSettingsState, PluginSidebarFooterActionContext, PluginSidebarFooterActionProps, PluginSidebarFooterActionRegistration, PluginSidebarProject, PluginSidebarPullRequest, PluginSidebarSplitPane, PluginSidebarThread, PluginSidebarThreadActions, PluginSidebarThreadActivity, PluginSidebarThreadIndicator, PluginSidebarThreadPullRequestState, PluginSidebarThreadSplit, PluginSidebarThreadsState, PluginSourceCodeRendererProps, PluginSourceCodeRendererRegistration, PluginTargetedPanelActionOpenOptions, PluginThreadHeaderActionProps, PluginThreadHeaderActionRegistration, PluginThreadListProps, PluginThreadListRegistration, PluginThreadPanelActionContext, PluginThreadPanelActionRegistration, PluginThreadPanelProps, PluginTimelineRendererProps, PluginTimelineRendererRegistration, PluginTimelineRendererRow, PluginTimelineRowPresentation, PluginTimelineRowStatus, ReadonlyJsonValue, SourceCodeLineRange, SourceCodeProps, StandardSchemaV1, StandardSchemaV1InferInput, StandardSchemaV1InferOutput, StandardSchemaV1Issue, StandardSchemaV1Result, ThreadChatMessageAction, ThreadChatMessageReference, ThreadChatProps, UrlLinkProps, UseBranchesArgs, UseCheckoutStateArgs };
3026
+ export type { BbContext, BbNavigate, BranchPickerProps, BranchesState, CheckoutState, CodeOverflowMode, ComposerCustomization, ComposerPlusMenuItem, ComposerRichTextSpec, ComposerStructuredDraft, ComposerView, DiffProps, DiffViewMode, ExperimentalAppIcons, ExperimentalAppOverlayProps, ExperimentalAppOverlayRegistration, ExperimentalAppPanel, ExperimentalAppPanelSurface, ExperimentalComposerSelection, ExperimentalComposerSubmitOptions, ExperimentalDiffFileContent, ExperimentalDiffFullFileContents, ExperimentalFileLinkProps, ExperimentalFileLocation, ExperimentalFileOpenOptions, ExperimentalFixedTabTargetContract, ExperimentalFixedTabTargetState, ExperimentalIconProps, ExperimentalIconRegistration, ExperimentalLiveFileTarget, ExperimentalOpenFixedTabOptions, ExperimentalPermissionModePickerProps, ExperimentalPluginBrowserPage, ExperimentalPluginBrowserPageEvaluateOptions, ExperimentalPluginBrowserPageWorld, ExperimentalPluginBrowserToolbarActionProps, ExperimentalPluginBrowserToolbarActionRegistration, ExperimentalPluginFixedTabReference, ExperimentalProviderIconProps, ExperimentalProviderModelPickerProps, ExperimentalProviderModelPickerRouting, ExperimentalProviderModelPickerValue, ExperimentalSidebarFooter, ExperimentalSidebarFooterActionContext, ExperimentalSidebarFooterActionRegistration, ExperimentalSidebarFooterDisclosureController, ExperimentalSidebarFooterDisclosureProps, ExperimentalSidebarFooterDisclosureRegistration, ExperimentalSidebarFooterItemBase, ExperimentalSidebarFooterItemRegistration, ExperimentalSidebarNavigationAction, ExperimentalSidebarNavigationActivationOptions, ExperimentalSidebarNavigationIcon, ExperimentalSidebarNavigationItem, ExperimentalSidebarNavigationProps, ExperimentalSidebarNavigationRegistration, ExperimentalSidebarNavigationShortcut, JsonValue$1 as JsonValue, MarkdownProps, NewThreadComposerProps, NewThreadRequest, PluginAppBuilder, PluginAppCommands, PluginAppComposer, PluginAppContentScripts, PluginAppDefinition, PluginAppSetup, PluginAppSlots, PluginCodeThemeData, PluginCodeThemeState, PluginCodeThemeTokenRule, PluginCommandContext, PluginCommandRegistration, PluginCommandShortcut, PluginComposerApi, PluginComposerMention, PluginComposerScope, PluginComposerTextEffect, PluginComposerThreadRowStatus, PluginContentScriptContext, PluginContentScriptDisposer, PluginContentScriptRegistration, PluginDiffRendererProps, PluginDiffRendererRegistration, PluginEnvironmentProviderInputsChange, PluginEnvironmentProviderInputsProps, PluginEnvironmentProviderInputsRegistration, PluginFileOpenerProps, PluginFileOpenerRegistration, PluginFileOpenerSource, PluginFixedTabDeclaration, PluginFixedTabRegistration, PluginHomepageSectionProps, PluginHomepageSectionRegistration, PluginMachineProviderInputsChange, PluginMachineProviderInputsProps, PluginMachineProviderInputsRegistration, PluginMessageActionContext, PluginMessageActionRegistration, PluginMessageDirectiveMessage, PluginMessageDirectiveOpenWorkspaceFile, PluginMessageDirectiveProps, PluginMessageDirectiveRegistration, PluginNavPanelProps, PluginNavPanelRegistration, PluginNewThreadPanelActionContext, PluginNewThreadPanelActionRegistration, PluginNewThreadPanelProps, PluginPanelActionOpenOptions, PluginPendingInteractionProps, PluginPendingInteractionRegistration, PluginPendingInteractionView, PluginProviderIconRegistration, PluginProvidersState, PluginRealtimeConnectionState, PluginRpcCallArgs, PluginRpcClient, PluginRpcContract, PluginRpcError, PluginRpcErrorCode, PluginRpcHandlers, PluginRpcIssuePathSegment, PluginRpcMethodContract, PluginRpcResult, PluginRpcValidationIssue, PluginSdkApp, PluginSettingsSectionProps, PluginSettingsSectionRegistration, PluginSettingsState, PluginSidebarFooterActionContext, PluginSidebarFooterActionProps, PluginSidebarFooterActionRegistration, PluginSidebarProject, PluginSidebarPullRequest, PluginSidebarSplitPane, PluginSidebarThread, PluginSidebarThreadActions, PluginSidebarThreadActivity, PluginSidebarThreadIndicator, PluginSidebarThreadPullRequestState, PluginSidebarThreadSplit, PluginSidebarThreadsState, PluginSourceCodeRendererProps, PluginSourceCodeRendererRegistration, PluginTargetedPanelActionOpenOptions, PluginThreadHeaderActionProps, PluginThreadHeaderActionRegistration, PluginThreadListProps, PluginThreadListRegistration, PluginThreadPanelActionContext, PluginThreadPanelActionRegistration, PluginThreadPanelProps, PluginTimelineRendererProps, PluginTimelineRendererRegistration, PluginTimelineRendererRow, PluginTimelineRowPresentation, PluginTimelineRowStatus, ReadonlyJsonValue, SourceCodeLineRange, SourceCodeProps, StandardSchemaV1, StandardSchemaV1InferInput, StandardSchemaV1InferOutput, StandardSchemaV1Issue, StandardSchemaV1Result, ThreadChatMessageAction, ThreadChatMessageReference, ThreadChatProps, UrlLinkProps, UseBranchesArgs, UseCheckoutStateArgs };
@@ -292,6 +292,8 @@ interface PluginEnvironmentProviderDefinition<R extends PluginEnvironmentProvide
292
292
  /** Experimental per-machine availability, probed in the background for pickers and again at thread creation: see docs/api_to_audit.md. */
293
293
  availability?(context: PluginEnvironmentProviderAvailabilityContext): PluginEnvironmentProviderAvailability | Promise<PluginEnvironmentProviderAvailability>;
294
294
  validate?(context: PluginEnvironmentProviderValidateContext<R, S>): PluginEnvironmentValidateDecision | Promise<PluginEnvironmentValidateDecision>;
295
+ /** Pure path selection from parsed inputs. Core reuses a recorded environment on the selected host before calling create; null requests normal creation. */
296
+ experimental_existingPath?(inputs: InputsValue<S>): string | null;
295
297
  create(context: PluginEnvironmentProviderCreateContext<R, S>): Promise<PluginEnvironmentProviderCreateResult>;
296
298
  remove(context: PluginEnvironmentProviderRemoveContext): Promise<PluginEnvironmentProviderRemoveResult>;
297
299
  }
@@ -630,6 +630,8 @@ interface PluginEnvironmentProviderDefinition<R extends PluginEnvironmentProvide
630
630
  /** Experimental per-machine availability, probed in the background for pickers and again at thread creation: see docs/api_to_audit.md. */
631
631
  availability?(context: PluginEnvironmentProviderAvailabilityContext): PluginEnvironmentProviderAvailability | Promise<PluginEnvironmentProviderAvailability>;
632
632
  validate?(context: PluginEnvironmentProviderValidateContext<R, S>): PluginEnvironmentValidateDecision | Promise<PluginEnvironmentValidateDecision>;
633
+ /** Pure path selection from parsed inputs. Core reuses a recorded environment on the selected host before calling create; null requests normal creation. */
634
+ experimental_existingPath?(inputs: InputsValue$1<S>): string | null;
633
635
  create(context: PluginEnvironmentProviderCreateContext<R, S>): Promise<PluginEnvironmentProviderCreateResult>;
634
636
  remove(context: PluginEnvironmentProviderRemoveContext): Promise<PluginEnvironmentProviderRemoveResult>;
635
637
  }
@@ -1107,6 +1109,23 @@ interface PluginCliContext {
1107
1109
  /** Aborted when the invoking CLI HTTP request disconnects. */
1108
1110
  signal?: AbortSignal;
1109
1111
  }
1112
+ /**
1113
+ * What a submitted form leaves in the thread timeline, chosen by the plugin.
1114
+ * bb never stores the form's payload or the submitted value; it stores only
1115
+ * this description, so a plugin decides what the transcript keeps.
1116
+ */
1117
+ interface PluginInteractionDescription {
1118
+ /** Row title once submitted; defaults to the presentation's completed label. */
1119
+ title?: string;
1120
+ /** Short Markdown for the expanded row. */
1121
+ detail?: string;
1122
+ /**
1123
+ * Persisted with the row and handed to this plugin's
1124
+ * `experimental_timelineRenderer` registered for `"<pluginId>/<rendererId>"`.
1125
+ * Omit anything the transcript must not keep.
1126
+ */
1127
+ payload?: JsonValue;
1128
+ }
1110
1129
  interface PluginInteractionRequest {
1111
1130
  threadId: string;
1112
1131
  rendererId: string;
@@ -1114,6 +1133,19 @@ interface PluginInteractionRequest {
1114
1133
  payload: JsonValue;
1115
1134
  /** Defaults to ten minutes; capped at one hour. */
1116
1135
  timeoutMs?: number;
1136
+ /**
1137
+ * How the form reads as a timeline row while it waits and once it settles,
1138
+ * in the same shape as a native tool's presentation. bb fills what is left
1139
+ * out: "Waiting for <title>" / "Submitted <title>" and the plugin's glyph.
1140
+ */
1141
+ presentation?: PluginRowPresentation;
1142
+ /**
1143
+ * Called once with the submitted value, before the waiting `requestInput`
1144
+ * promise resolves; never for a cancellation, which bb titles itself. Its
1145
+ * return is persisted on the row. A throw or a slow return leaves the row
1146
+ * with its completed label and nothing more.
1147
+ */
1148
+ describeSubmission?(value: JsonValue): PluginInteractionDescription | Promise<PluginInteractionDescription>;
1117
1149
  }
1118
1150
  interface PluginCliResult {
1119
1151
  exitCode: number;
@@ -1144,6 +1176,15 @@ interface PluginCliRegistration {
1144
1176
  /** Subcommand metadata rendered in help and the plugin-commands skill
1145
1177
  * without executing plugin code. Parsing argv is plugin-owned. */
1146
1178
  commands?: PluginCliCommandInfo[];
1179
+ /**
1180
+ * Set when `run` answers `--help` / `-h` itself, at every level, without
1181
+ * executing a command. The `bb` CLI then forwards help requests to the
1182
+ * plugin instead of printing the one-line `usage` from `commands`.
1183
+ * `defineCli` sets it. Leave it unset for a hand-written `run`:
1184
+ * the host cannot know that such a parser will not act on the other
1185
+ * arguments.
1186
+ */
1187
+ rendersHelp?: boolean;
1147
1188
  run(argv: string[], ctx: PluginCliContext): PluginCliResult | Promise<PluginCliResult>;
1148
1189
  }
1149
1190
  /** Per-turn context handed to bb.agents context providers (design §4.4). */
@@ -1164,30 +1205,37 @@ type PluginAgentToolResult = string | {
1164
1205
  interface PluginAgentToolContext {
1165
1206
  threadId: string;
1166
1207
  projectId: string;
1167
- /** The tool-call request's abort signal (aborts if the daemon round-trip
1168
- * is torn down mid-call). */
1208
+ /**
1209
+ * Aborts when the tool-call request is cancelled, the thread is stopped or
1210
+ * deleted, or this plugin is disposed. Opening a form with `bb.ui.requestInput`
1211
+ * detaches the call from its request: the agent receives a waiting notice,
1212
+ * and request cancellation no longer aborts this signal. The tool's eventual
1213
+ * result is delivered as a system message (success steers a running turn or
1214
+ * starts a new one; an `isError` result only steers). Thread stop/delete and
1215
+ * plugin disposal still abort the signal after detachment.
1216
+ */
1169
1217
  signal: AbortSignal;
1170
1218
  }
1171
1219
  /**
1172
- * The row title of a plugin tool call while it is pending and once it
1220
+ * The title of a plugin-owned timeline row while it is pending and once it
1173
1221
  * settled. Each label is capped at 80 characters and rendered as plain text.
1174
1222
  */
1175
- interface PluginAgentToolLabels {
1176
- /** Label shown while the tool call is pending. */
1223
+ interface PluginRowLabels {
1224
+ /** Label shown while the row is pending. */
1177
1225
  pending: string;
1178
- /** Label shown after the tool call completes successfully. */
1226
+ /** Label shown after the row completes successfully. */
1179
1227
  completed: string;
1180
1228
  }
1181
1229
  /**
1182
- * How calls to a native plugin tool read as a timeline row (grammar v3). Every
1183
- * field is optional at registration: the server fills what the plugin leaves
1184
- * out (a generic `Running <name>` / `Ran <name>` label; the plugin's branding
1185
- * glyph, then `Toolbox`) and hands one complete presentation to the provider
1186
- * bridge with the tool definition.
1230
+ * How something a plugin owns reads as a timeline row (grammar v3): a native
1231
+ * tool's calls, or the row a `bb.ui.requestInput` form leaves behind. Every
1232
+ * field is optional: the server fills what the plugin leaves out (a generic
1233
+ * label; the plugin's branding glyph, then `Toolbox`) and hands one complete
1234
+ * presentation to whatever renders the row.
1187
1235
  */
1188
- interface PluginAgentToolPresentation {
1189
- /** Row title while the call is pending and once it settled. */
1190
- label?: PluginAgentToolLabels;
1236
+ interface PluginRowPresentation {
1237
+ /** Row title while the row is pending and once it settled. */
1238
+ label?: PluginRowLabels;
1191
1239
  /**
1192
1240
  * A named host glyph (`{ glyph: "Workflow" }`), or one of this plugin's
1193
1241
  * own declared icons by its namespaced glyph (`{ glyph: "<pluginId>/<name>" }`,
@@ -1801,7 +1849,7 @@ declare function publishRpcMethod(method: string, contract: PluginRpcMethodContr
1801
1849
  * in a plugin unit test registers in bb, and one bb rejects is rejected
1802
1850
  * with the same message.
1803
1851
  */
1804
- declare function parsePluginAgentToolPresentation(toolName: string, value: unknown): PluginAgentToolPresentation | null;
1852
+ declare function parsePluginRowPresentation(subject: string, value: unknown): PluginRowPresentation | null;
1805
1853
  /** Compact issue summary from a (possibly foreign-instance) zod error. */
1806
1854
  declare function summarizeStandardIssues(issues: readonly StandardSchemaV1Issue[]): string;
1807
1855
  declare function enforcePluginCliOutputLimit(result: Omit<PluginCliExecutionResult, "error">, jsonOutput: boolean): PluginCliExecutionResult;
@@ -1885,6 +1933,7 @@ interface NormalizedPluginEnvironmentProvider {
1885
1933
  inputsJsonSchema: JsonValue | null;
1886
1934
  availability: NonNullable<PluginEnvironmentProviderDeclaration["availability"]> | null;
1887
1935
  validate: NonNullable<PluginEnvironmentProviderDeclaration["validate"]> | null;
1936
+ experimental_existingPath: NonNullable<PluginEnvironmentProviderDeclaration["experimental_existingPath"]> | null;
1888
1937
  create: PluginEnvironmentProviderDeclaration["create"];
1889
1938
  remove: PluginEnvironmentProviderDeclaration["remove"];
1890
1939
  policy: PluginEnvironmentProviderPolicy;
@@ -1955,6 +2004,7 @@ declare function normalizeCliRegistration(registration: PluginCliRegistration, a
1955
2004
  name: string;
1956
2005
  summary: string;
1957
2006
  commands: PluginCliCommandInfo[];
2007
+ rendersHelp: boolean;
1958
2008
  run: PluginCliRegistration["run"];
1959
2009
  };
1960
2010
  type AgentToolExecute = (params: unknown, ctx: PluginAgentToolContext) => PluginAgentToolResult | Promise<PluginAgentToolResult>;
@@ -1972,14 +2022,14 @@ declare function normalizeAgentToolRegistration(args: {
1972
2022
  name: string;
1973
2023
  description: string;
1974
2024
  instructions?: string;
1975
- presentation?: PluginAgentToolPresentation;
2025
+ presentation?: PluginRowPresentation;
1976
2026
  parameters: unknown;
1977
2027
  execute(params: never, ctx: PluginAgentToolContext): PluginAgentToolResult | Promise<PluginAgentToolResult>;
1978
2028
  };
1979
2029
  }): {
1980
2030
  name: string;
1981
2031
  description: string;
1982
- presentation: PluginAgentToolPresentation | null;
2032
+ presentation: PluginRowPresentation | null;
1983
2033
  instructions: string | null;
1984
2034
  inputSchema: unknown;
1985
2035
  parse: AgentToolParse;
@@ -1994,13 +2044,16 @@ declare function normalizeMentionProviderRegistration(provider: PluginMentionPro
1994
2044
  search: PluginMentionProviderRegistration["search"];
1995
2045
  resolve: PluginMentionProviderRegistration["resolve"];
1996
2046
  };
1997
- declare function normalizeInteractionRequest(request: PluginInteractionRequest): {
2047
+ interface NormalizedPluginInteractionRequest {
1998
2048
  threadId: string;
1999
2049
  rendererId: string;
2000
2050
  title: string;
2001
2051
  payload: JsonValue;
2002
2052
  timeoutMs: number;
2003
- };
2053
+ presentation: PluginRowPresentation | null;
2054
+ describeSubmission: NonNullable<PluginInteractionRequest["describeSubmission"]> | null;
2055
+ }
2056
+ declare function normalizeInteractionRequest(request: PluginInteractionRequest): NormalizedPluginInteractionRequest;
2004
2057
  declare function validateProviderEnvContribution(label: "provider environment contribution" | "provider environment health contribution", providerId: string, resolve: unknown, registered: ReadonlyMap<string, unknown>): void;
2005
2058
  declare function normalizePluginAgentConfiguration(args: {
2006
2059
  knownSkillIds: ReadonlySet<string>;
@@ -2016,5 +2069,5 @@ declare function normalizePluginAgentConfiguration(args: {
2016
2069
  declare function validateRpcValue(schema: StandardSchemaV1, value: unknown, phase: "input" | "output", fail: (error: PluginRpcError) => never): Promise<unknown>;
2017
2070
  declare function normalizeRpcJsonResult(value: unknown, fail: (error: PluginRpcError) => never): JsonValue;
2018
2071
 
2019
- export { ENVIRONMENT_PROVIDER_DESCRIPTION_MAX_CHARS, ENVIRONMENT_PROVIDER_DISPLAY_NAME_MAX_CHARS, ENVIRONMENT_PROVIDER_ID_PATTERN, ENVIRONMENT_PROVIDER_REQUIREMENT_NAMES, KV_VALUE_MAX_BYTES, MACHINE_PROVIDER_DESCRIPTION_MAX_CHARS, PLUGIN_AGENT_STATUS_LABEL_MAX_CHARS, PLUGIN_MENTION_TRIGGER_VALUES, PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES, PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES, PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS, PLUGIN_PROVIDER_ENV_MAX_ENTRIES, PLUGIN_PROVIDER_ENV_NAME_PATTERN, PLUGIN_PROVIDER_PERMISSION_MODE_VALUES, PLUGIN_PROVIDER_REASONING_LEVEL_VALUES, PROVIDER_ID_PATTERN, RESERVED_AGENT_TOOL_NAMES, RESERVED_BB_CLI_COMMANDS, SERVER_DIRECT_AI_SERVICE_IDS, SETTING_KEY_PATTERN, adoptHttpRouteResponse, aiServiceAlreadyRegisteredMessage, assertAiServiceRegistrable, coerceStoredPluginSettingValue, deriveValidatedProviderOptions, enforcePluginCliOutputLimit, environmentCompositionSchema, isPluginMentionTrigger, isStandardSchema, normalizeAgentToolRegistration, normalizeCliRegistration, normalizeHttpRouteRegistration, normalizeInteractionRequest, normalizeMentionProviderRegistration, normalizePluginAgentConfiguration, normalizeRealtimePayload, normalizeRpcJsonResult, normalizeRpcRegistration, normalizeWebSocketRouteRegistration, parsePluginAgentToolPresentation, pluginCliCollisionWarning, pluginHookAlreadyRegisteredMessage, providerAlreadyRegisteredMessage, providerIconRefusalMessage, providerWithoutBridgeMessage, publishRpcMethod, readRpcPublicationOptions, registerSettingDescriptors, runPluginStorageMigrations, storePluginHook, summarizeStandardIssues, undeclaredIconProblem, validateBackgroundServiceRegistration, validatePluginAiServiceDeclaration, validatePluginEnvironmentProviderDeclaration, validatePluginMachineProviderDeclaration, validatePluginProviderDeclaration, validatePluginProviderEnvEntries, validateProviderEnvContribution, validateRpcValue, validateScheduleRegistration, validateServerAccessProviderDeclaration, validateSettingsUpdate };
2020
- export type { AiServiceHostBinding, NormalizedPluginEnvironmentComposition, NormalizedPluginEnvironmentProvider, NormalizedPluginEnvironmentProviderRequirements, NormalizedPluginMachineProvider, NormalizedPluginProviderDeclaration };
2072
+ export { ENVIRONMENT_PROVIDER_DESCRIPTION_MAX_CHARS, ENVIRONMENT_PROVIDER_DISPLAY_NAME_MAX_CHARS, ENVIRONMENT_PROVIDER_ID_PATTERN, ENVIRONMENT_PROVIDER_REQUIREMENT_NAMES, KV_VALUE_MAX_BYTES, MACHINE_PROVIDER_DESCRIPTION_MAX_CHARS, PLUGIN_AGENT_STATUS_LABEL_MAX_CHARS, PLUGIN_MENTION_TRIGGER_VALUES, PLUGIN_PROVIDER_BRIDGE_OPTIONS_MAX_BYTES, PLUGIN_PROVIDER_COMPOSER_ACTION_VALUES, PLUGIN_PROVIDER_DISPLAY_NAME_MAX_CHARS, PLUGIN_PROVIDER_ENV_MAX_ENTRIES, PLUGIN_PROVIDER_ENV_NAME_PATTERN, PLUGIN_PROVIDER_PERMISSION_MODE_VALUES, PLUGIN_PROVIDER_REASONING_LEVEL_VALUES, PROVIDER_ID_PATTERN, RESERVED_AGENT_TOOL_NAMES, RESERVED_BB_CLI_COMMANDS, SERVER_DIRECT_AI_SERVICE_IDS, SETTING_KEY_PATTERN, adoptHttpRouteResponse, aiServiceAlreadyRegisteredMessage, assertAiServiceRegistrable, coerceStoredPluginSettingValue, deriveValidatedProviderOptions, enforcePluginCliOutputLimit, environmentCompositionSchema, isPluginMentionTrigger, isStandardSchema, normalizeAgentToolRegistration, normalizeCliRegistration, normalizeHttpRouteRegistration, normalizeInteractionRequest, normalizeMentionProviderRegistration, normalizePluginAgentConfiguration, normalizeRealtimePayload, normalizeRpcJsonResult, normalizeRpcRegistration, normalizeWebSocketRouteRegistration, parsePluginRowPresentation, pluginCliCollisionWarning, pluginHookAlreadyRegisteredMessage, providerAlreadyRegisteredMessage, providerIconRefusalMessage, providerWithoutBridgeMessage, publishRpcMethod, readRpcPublicationOptions, registerSettingDescriptors, runPluginStorageMigrations, storePluginHook, summarizeStandardIssues, undeclaredIconProblem, validateBackgroundServiceRegistration, validatePluginAiServiceDeclaration, validatePluginEnvironmentProviderDeclaration, validatePluginMachineProviderDeclaration, validatePluginProviderDeclaration, validatePluginProviderEnvEntries, validateProviderEnvContribution, validateRpcValue, validateScheduleRegistration, validateServerAccessProviderDeclaration, validateSettingsUpdate };
2073
+ export type { AiServiceHostBinding, NormalizedPluginEnvironmentComposition, NormalizedPluginEnvironmentProvider, NormalizedPluginEnvironmentProviderRequirements, NormalizedPluginInteractionRequest, NormalizedPluginMachineProvider, NormalizedPluginProviderDeclaration };
@@ -3589,6 +3589,7 @@ declare const threadEventSchema: z.ZodPipe<z.ZodUnknown, z.ZodUnion<readonly [z.
3589
3589
  "child-outcome-batch": "child-outcome-batch";
3590
3590
  "ownership-assigned": "ownership-assigned";
3591
3591
  "ownership-removed": "ownership-removed";
3592
+ "tool-result-delivered": "tool-result-delivered";
3592
3593
  unlabeled: "unlabeled";
3593
3594
  }>>;
3594
3595
  systemMessageSubject: z.ZodOptional<z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -3598,6 +3599,10 @@ declare const threadEventSchema: z.ZodPipe<z.ZodUnknown, z.ZodUnion<readonly [z.
3598
3599
  }, z.core.$strip>, z.ZodObject<{
3599
3600
  count: z.ZodNumber;
3600
3601
  kind: z.ZodLiteral<"thread-batch">;
3602
+ }, z.core.$strip>, z.ZodObject<{
3603
+ kind: z.ZodLiteral<"tool-call">;
3604
+ suppress: z.ZodBoolean;
3605
+ toolName: z.ZodString;
3601
3606
  }, z.core.$strip>], "kind">>>;
3602
3607
  target: z.ZodDiscriminatedUnion<[z.ZodObject<{
3603
3608
  kind: z.ZodLiteral<"thread-start">;
@@ -3851,9 +3856,39 @@ declare const threadEventSchema: z.ZodPipe<z.ZodUnknown, z.ZodUnion<readonly [z.
3851
3856
  }, z.core.$strip>;
3852
3857
  payload: z.ZodObject<{
3853
3858
  kind: z.ZodLiteral<"plugin">;
3859
+ presentation: z.ZodOptional<z.ZodObject<{
3860
+ badge: z.ZodOptional<z.ZodObject<{
3861
+ glyph: z.ZodString;
3862
+ hint: z.ZodString;
3863
+ label: z.ZodString;
3864
+ tone: z.ZodEnum<{
3865
+ destructive: "destructive";
3866
+ neutral: "neutral";
3867
+ }>;
3868
+ }, z.core.$strip>>;
3869
+ detail: z.ZodOptional<z.ZodString>;
3870
+ icon: z.ZodObject<{
3871
+ glyph: z.ZodString;
3872
+ }, z.core.$strip>;
3873
+ label: z.ZodObject<{
3874
+ completed: z.ZodString;
3875
+ pending: z.ZodString;
3876
+ }, z.core.$strip>;
3877
+ suppress: z.ZodOptional<z.ZodBoolean>;
3878
+ tint: z.ZodOptional<z.ZodObject<{
3879
+ dark: z.ZodString;
3880
+ light: z.ZodString;
3881
+ }, z.core.$strip>>;
3882
+ title: z.ZodOptional<z.ZodString>;
3883
+ }, z.core.$strip>>;
3854
3884
  title: z.ZodString;
3855
3885
  }, z.core.$strip>;
3856
3886
  resolution: z.ZodNullable<z.ZodObject<{
3887
+ description: z.ZodOptional<z.ZodObject<{
3888
+ detail: z.ZodOptional<z.ZodString>;
3889
+ payload: z.ZodOptional<z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>>;
3890
+ title: z.ZodOptional<z.ZodString>;
3891
+ }, z.core.$strip>>;
3857
3892
  kind: z.ZodLiteral<"plugin_submitted">;
3858
3893
  }, z.core.$strip>>;
3859
3894
  status: z.ZodEnum<{
@@ -798,6 +798,31 @@ type UserQuestionPendingInteractionPayload = z.infer<typeof userQuestionPendingI
798
798
  declare const pluginPendingInteractionPayloadSchema: z.ZodObject<{
799
799
  data: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
800
800
  kind: z.ZodLiteral<"plugin">;
801
+ presentation: z.ZodOptional<z.ZodObject<{
802
+ badge: z.ZodOptional<z.ZodObject<{
803
+ glyph: z.ZodString;
804
+ hint: z.ZodString;
805
+ label: z.ZodString;
806
+ tone: z.ZodEnum<{
807
+ destructive: "destructive";
808
+ neutral: "neutral";
809
+ }>;
810
+ }, z.core.$strip>>;
811
+ detail: z.ZodOptional<z.ZodString>;
812
+ icon: z.ZodObject<{
813
+ glyph: z.ZodString;
814
+ }, z.core.$strip>;
815
+ label: z.ZodObject<{
816
+ completed: z.ZodString;
817
+ pending: z.ZodString;
818
+ }, z.core.$strip>;
819
+ suppress: z.ZodOptional<z.ZodBoolean>;
820
+ tint: z.ZodOptional<z.ZodObject<{
821
+ dark: z.ZodString;
822
+ light: z.ZodString;
823
+ }, z.core.$strip>>;
824
+ title: z.ZodOptional<z.ZodString>;
825
+ }, z.core.$strip>>;
801
826
  title: z.ZodString;
802
827
  }, z.core.$strip>;
803
828
  type PluginPendingInteractionPayload = z.infer<typeof pluginPendingInteractionPayloadSchema>;
@@ -1010,6 +1035,11 @@ declare const pendingInteractionResolutionSchema: z.ZodUnion<readonly [z.ZodDisc
1010
1035
  }, z.core.$strip>>;
1011
1036
  kind: z.ZodLiteral<"user_answer">;
1012
1037
  }, z.core.$strip>, z.ZodObject<{
1038
+ description: z.ZodOptional<z.ZodObject<{
1039
+ detail: z.ZodOptional<z.ZodString>;
1040
+ payload: z.ZodOptional<z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>>;
1041
+ title: z.ZodOptional<z.ZodString>;
1042
+ }, z.core.$strip>>;
1013
1043
  kind: z.ZodLiteral<"plugin_submitted">;
1014
1044
  }, z.core.$strip>, z.ZodObject<{
1015
1045
  kind: z.ZodLiteral<"request_answer">;
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { ReactNode, ComponentType } from 'react';
9
9
  import { RenderResult } from '@testing-library/react';
10
- import { ExperimentalSidebarFooterItemRegistration, PluginProviderIconRegistration, PluginHomepageSectionRegistration, PluginSettingsSectionRegistration, ExperimentalAppOverlayRegistration, PluginNavPanelRegistration, PluginThreadPanelActionRegistration, PluginNewThreadPanelActionRegistration, ComposerCustomization, PluginPendingInteractionRegistration, PluginSidebarFooterActionRegistration, ExperimentalSidebarNavigationRegistration, PluginThreadListRegistration, PluginThreadHeaderActionRegistration, ExperimentalPluginBrowserToolbarActionRegistration, PluginFileOpenerRegistration, PluginSourceCodeRendererRegistration, PluginDiffRendererRegistration, PluginMessageDirectiveRegistration, PluginMessageActionRegistration, ExperimentalIconRegistration, PluginTimelineRendererRegistration, PluginEnvironmentProviderInputsRegistration, PluginMachineProviderInputsRegistration, PluginContentScriptRegistration, PluginComposerScope, PluginComposerTextEffect, PluginComposerMention, ExperimentalComposerSubmitOptions, PluginComposerThreadRowStatus, ExperimentalOpenFixedTabOptions, JsonValue, BbNavigate, ExperimentalFileOpenOptions, PluginAppDefinition, PluginRpcContract, StandardSchemaV1InferInput, PluginRpcResult, PluginRealtimeConnectionState, PluginSidebarThreadsState, PluginProvidersState, PluginCodeThemeState, BranchesState, CheckoutState, PluginSidebarPullRequest, PluginSidebarThreadActions } from '@get-bb/plugin-sdk';
10
+ import { ExperimentalSidebarFooterItemRegistration, PluginProviderIconRegistration, PluginHomepageSectionRegistration, PluginSettingsSectionRegistration, ExperimentalAppOverlayRegistration, PluginNavPanelRegistration, PluginThreadPanelActionRegistration, PluginNewThreadPanelActionRegistration, ComposerCustomization, PluginPendingInteractionRegistration, PluginSidebarFooterActionRegistration, ExperimentalSidebarNavigationRegistration, PluginThreadListRegistration, PluginThreadHeaderActionRegistration, ExperimentalPluginBrowserToolbarActionRegistration, PluginFileOpenerRegistration, PluginSourceCodeRendererRegistration, PluginDiffRendererRegistration, PluginMessageDirectiveRegistration, PluginMessageActionRegistration, ExperimentalIconRegistration, PluginTimelineRendererRegistration, PluginEnvironmentProviderInputsRegistration, PluginMachineProviderInputsRegistration, PluginContentScriptRegistration, PluginComposerScope, PluginComposerTextEffect, PluginComposerMention, ExperimentalComposerSubmitOptions, ExperimentalComposerSelection, PluginComposerThreadRowStatus, ExperimentalOpenFixedTabOptions, JsonValue, BbNavigate, ExperimentalFileOpenOptions, PluginAppDefinition, PluginRpcContract, StandardSchemaV1InferInput, PluginRpcResult, PluginRealtimeConnectionState, PluginSidebarThreadsState, PluginProvidersState, PluginCodeThemeState, BranchesState, CheckoutState, PluginSidebarPullRequest, PluginSidebarThreadActions } from '@get-bb/plugin-sdk';
11
11
 
12
12
  type ExperimentalSidebarFooterCommandKind = "close" | "open" | "toggle";
13
13
  interface ExperimentalSidebarFooterRuntimeSnapshot {
@@ -116,6 +116,14 @@ interface ComposerLog {
116
116
  * draft — enough to assert what a picker scheduled and that it tidied up.
117
117
  */
118
118
  submits: ExperimentalComposerSubmitOptions[];
119
+ /**
120
+ * Every `experimental_setSelection` the harness composer accepted, in
121
+ * order. The harness has no pickers of its own, so it records the request
122
+ * and echoes it back as the settled selection, minus the fields the
123
+ * composer's scope has no picker for (a thread has no project or
124
+ * environment). Queued-message and side-chat scopes reject, as the app does.
125
+ */
126
+ selections: ExperimentalComposerSelection[];
119
127
  }
120
128
  /** One recorded `experimental_useSidebarThreadActions()` call. */
121
129
  interface SidebarActionCall {
@@ -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 { StandardSchemaV1 as StandardSchemaV1$1, StandardSchemaV1InferOutput, PluginMachineValidateDecision, JsonValue as JsonValue$2, PluginEnvironmentProviderRequirements as PluginEnvironmentProviderRequirements$1, PluginEnvironmentValidateDecision, BbPluginApi, PluginSettingValue as PluginSettingValue$1, PluginSharedPortTunnelIdentity, PluginAgentToolPresentation, PluginAgentToolContext, PluginAgentToolResult, PluginCliCommandInfo, PluginCliContext, PluginCliResult, PluginHttpAuthMode, PluginHttpHandler, PluginMentionTrigger, PluginMentionSearchContext, PluginMentionItem, PluginMentionProviderRegistration, PluginCliExecutionResult, PluginThreadEventName, PluginThreadEventPayloads, PluginAgentConfigurationContext, ExperimentalPluginProviderEnvContext, ExperimentalPluginProviderEnvEntry, ExperimentalPluginProviderEnvHealthContext, ExperimentalPluginProviderEnvHealth, PluginSettingDescriptors, ExperimentalPluginWebSocketHandler, PluginAgentConfiguration, PluginHookName, PluginHookHandler, PluginAiServiceDeclaration, PluginInteractionRequest, MessageDispatchHookContext } from '@get-bb/plugin-sdk';
8
+ import { StandardSchemaV1 as StandardSchemaV1$1, StandardSchemaV1InferOutput, PluginMachineValidateDecision, JsonValue as JsonValue$2, PluginEnvironmentProviderRequirements as PluginEnvironmentProviderRequirements$1, PluginEnvironmentValidateDecision, BbPluginApi, PluginSettingValue as PluginSettingValue$1, PluginSharedPortTunnelIdentity, PluginRowPresentation, PluginAgentToolContext, PluginAgentToolResult, PluginCliCommandInfo, PluginCliContext, PluginCliResult, PluginHttpAuthMode, PluginHttpHandler, PluginMentionTrigger, PluginMentionSearchContext, PluginMentionItem, PluginMentionProviderRegistration, PluginCliExecutionResult, PluginThreadEventName, PluginThreadEventPayloads, PluginAgentConfigurationContext, ExperimentalPluginProviderEnvContext, ExperimentalPluginProviderEnvEntry, ExperimentalPluginProviderEnvHealthContext, ExperimentalPluginProviderEnvHealth, PluginSettingDescriptors, ExperimentalPluginWebSocketHandler, PluginAgentConfiguration, PluginHookName, PluginHookHandler, PluginAiServiceDeclaration, PluginInteractionRequest, MessageDispatchHookContext } from '@get-bb/plugin-sdk';
9
9
  import { z } from 'zod';
10
10
 
11
11
  type PluginMachineProviderResource = Exclude<JsonValue$2, null>;
@@ -423,6 +423,8 @@ interface PluginEnvironmentProviderDefinition<R extends PluginEnvironmentProvide
423
423
  /** Experimental per-machine availability, probed in the background for pickers and again at thread creation: see docs/api_to_audit.md. */
424
424
  availability?(context: PluginEnvironmentProviderAvailabilityContext): PluginEnvironmentProviderAvailability | Promise<PluginEnvironmentProviderAvailability>;
425
425
  validate?(context: PluginEnvironmentProviderValidateContext<R, S>): PluginEnvironmentValidateDecision | Promise<PluginEnvironmentValidateDecision>;
426
+ /** Pure path selection from parsed inputs. Core reuses a recorded environment on the selected host before calling create; null requests normal creation. */
427
+ experimental_existingPath?(inputs: InputsValue<S>): string | null;
426
428
  create(context: PluginEnvironmentProviderCreateContext<R, S>): Promise<PluginEnvironmentProviderCreateResult>;
427
429
  remove(context: PluginEnvironmentProviderRemoveContext): Promise<PluginEnvironmentProviderRemoveResult>;
428
430
  }
@@ -980,6 +982,7 @@ interface NormalizedPluginEnvironmentProvider {
980
982
  inputsJsonSchema: JsonValue | null;
981
983
  availability: NonNullable<PluginEnvironmentProviderDeclaration["availability"]> | null;
982
984
  validate: NonNullable<PluginEnvironmentProviderDeclaration["validate"]> | null;
985
+ experimental_existingPath: NonNullable<PluginEnvironmentProviderDeclaration["experimental_existingPath"]> | null;
983
986
  create: PluginEnvironmentProviderDeclaration["create"];
984
987
  remove: PluginEnvironmentProviderDeclaration["remove"];
985
988
  policy: PluginEnvironmentProviderPolicy;
@@ -1126,11 +1129,11 @@ interface FakeAgentToolRecord {
1126
1129
  instructions: string | null;
1127
1130
  /**
1128
1131
  * The plugin's declared row presentation, null when it declared none.
1129
- * Parsed by the shared `parsePluginAgentToolPresentation`, so the record
1132
+ * Parsed by the shared `parsePluginRowPresentation`, so the record
1130
1133
  * holds exactly what the production host stores and a presentation bb
1131
1134
  * rejects is rejected here with the same message.
1132
1135
  */
1133
- presentation: PluginAgentToolPresentation | null;
1136
+ presentation: PluginRowPresentation | null;
1134
1137
  /** JSON-schema object the host would send providers. */
1135
1138
  inputSchema: unknown;
1136
1139
  parse(input: unknown): {