@get-bb/plugin-sdk 0.4.6 → 0.4.9

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.
@@ -17,7 +17,7 @@ interface PluginRpcValidationIssue {
17
17
  path?: PluginRpcIssuePathSegment[];
18
18
  }
19
19
  /** Stable wire error categories for plugin RPC. */
20
- type PluginRpcErrorCode = "invalid_json" | "invalid_input" | "handler_error" | "invalid_output" | "non_json_result" | "unknown_method";
20
+ type PluginRpcErrorCode = "handler_error" | "invalid_input" | "invalid_json" | "invalid_output" | "non_json_result" | "unknown_method";
21
21
  /** Structured RPC failure returned as `{ ok: false, error }`. */
22
22
  interface PluginRpcError {
23
23
  code: PluginRpcErrorCode;
@@ -67,14 +67,14 @@ type PluginRpcCallArgs<Method extends PluginRpcMethodContract> = null extends Pl
67
67
  type PluginRpcResult<Method extends PluginRpcMethodContract> = StandardSchemaV1InferOutput<Method["output"]>;
68
68
 
69
69
  declare const reasoningLevelSchema: z.ZodEnum<{
70
- none: "none";
71
- low: "low";
72
- medium: "medium";
73
70
  high: "high";
74
- xhigh: "xhigh";
75
- ultracode: "ultracode";
71
+ low: "low";
76
72
  max: "max";
73
+ medium: "medium";
74
+ none: "none";
77
75
  ultra: "ultra";
76
+ ultracode: "ultracode";
77
+ xhigh: "xhigh";
78
78
  }>;
79
79
  type ReasoningLevel = z.infer<typeof reasoningLevelSchema>;
80
80
  declare const serviceTierSchema: z.ZodEnum<{
@@ -83,118 +83,118 @@ declare const serviceTierSchema: z.ZodEnum<{
83
83
  }>;
84
84
  type ServiceTier = z.infer<typeof serviceTierSchema>;
85
85
  declare const permissionModeSchema: z.ZodEnum<{
86
- full: "full";
87
- auto: "auto";
88
86
  "accept-edits": "accept-edits";
87
+ auto: "auto";
88
+ full: "full";
89
89
  }>;
90
90
  type PermissionMode = z.infer<typeof permissionModeSchema>;
91
91
  declare const promptInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
92
- visibility: z.ZodOptional<z.ZodEnum<{
93
- "agent-only": "agent-only";
94
- }>>;
95
- type: z.ZodLiteral<"text">;
96
- text: z.ZodString;
97
92
  mentions: z.ZodDefault<z.ZodArray<z.ZodObject<{
98
- start: z.ZodNumber;
99
93
  end: z.ZodNumber;
100
94
  resource: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodDiscriminatedUnion<[z.ZodObject<{
101
95
  kind: z.ZodLiteral<"thread">;
102
- threadId: z.ZodString;
103
- projectId: z.ZodOptional<z.ZodString>;
104
96
  label: z.ZodString;
97
+ projectId: z.ZodOptional<z.ZodString>;
98
+ threadId: z.ZodString;
105
99
  }, z.core.$strip>, z.ZodObject<{
106
100
  kind: z.ZodLiteral<"project">;
107
- projectId: z.ZodString;
108
101
  label: z.ZodString;
102
+ projectId: z.ZodString;
109
103
  }, z.core.$strip>, z.ZodObject<{
110
104
  kind: z.ZodLiteral<"section">;
111
- sectionId: z.ZodString;
112
105
  label: z.ZodString;
106
+ sectionId: z.ZodString;
113
107
  }, z.core.$strip>, z.ZodObject<{
114
- kind: z.ZodLiteral<"path">;
115
- source: z.ZodEnum<{
116
- workspace: "workspace";
117
- "thread-storage": "thread-storage";
118
- }>;
119
108
  entryKind: z.ZodEnum<{
120
- file: "file";
121
109
  directory: "directory";
110
+ file: "file";
122
111
  }>;
123
- path: z.ZodString;
112
+ kind: z.ZodLiteral<"path">;
124
113
  label: z.ZodString;
114
+ path: z.ZodString;
115
+ source: z.ZodEnum<{
116
+ "thread-storage": "thread-storage";
117
+ workspace: "workspace";
118
+ }>;
125
119
  }, z.core.$strip>, z.ZodObject<{
120
+ argumentHint: z.ZodNullable<z.ZodString>;
126
121
  kind: z.ZodLiteral<"command">;
127
- trigger: z.ZodEnum<{
128
- "/": "/";
129
- }>;
122
+ label: z.ZodString;
130
123
  name: z.ZodString;
124
+ origin: z.ZodEnum<{
125
+ builtin: "builtin";
126
+ project: "project";
127
+ user: "user";
128
+ }>;
131
129
  source: z.ZodEnum<{
132
130
  command: "command";
133
131
  skill: "skill";
134
132
  }>;
135
- origin: z.ZodEnum<{
136
- user: "user";
137
- project: "project";
138
- builtin: "builtin";
133
+ trigger: z.ZodEnum<{
134
+ "/": "/";
139
135
  }>;
140
- label: z.ZodString;
141
- argumentHint: z.ZodNullable<z.ZodString>;
142
136
  }, z.core.$strip>, z.ZodObject<{
143
- kind: z.ZodLiteral<"plugin">;
144
- pluginId: z.ZodString;
145
137
  icon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
146
138
  itemId: z.ZodString;
139
+ kind: z.ZodLiteral<"plugin">;
147
140
  label: z.ZodString;
141
+ pluginId: z.ZodString;
148
142
  }, z.core.$strip>], "kind">>;
143
+ start: z.ZodNumber;
149
144
  }, z.core.$strip>>>;
150
- }, z.core.$strip>, z.ZodObject<{
145
+ text: z.ZodString;
146
+ type: z.ZodLiteral<"text">;
151
147
  visibility: z.ZodOptional<z.ZodEnum<{
152
148
  "agent-only": "agent-only";
153
149
  }>>;
150
+ }, z.core.$strip>, z.ZodObject<{
154
151
  type: z.ZodLiteral<"image">;
155
152
  url: z.ZodString;
156
- }, z.core.$strip>, z.ZodObject<{
157
153
  visibility: z.ZodOptional<z.ZodEnum<{
158
154
  "agent-only": "agent-only";
159
155
  }>>;
160
- type: z.ZodLiteral<"localImage">;
161
- path: z.ZodString;
162
156
  }, z.core.$strip>, z.ZodObject<{
157
+ path: z.ZodString;
158
+ type: z.ZodLiteral<"localImage">;
163
159
  visibility: z.ZodOptional<z.ZodEnum<{
164
160
  "agent-only": "agent-only";
165
161
  }>>;
166
- type: z.ZodLiteral<"localFile">;
167
- path: z.ZodString;
162
+ }, z.core.$strip>, z.ZodObject<{
163
+ mimeType: z.ZodOptional<z.ZodString>;
168
164
  name: z.ZodOptional<z.ZodString>;
165
+ path: z.ZodString;
169
166
  sizeBytes: z.ZodOptional<z.ZodNumber>;
170
- mimeType: z.ZodOptional<z.ZodString>;
167
+ type: z.ZodLiteral<"localFile">;
168
+ visibility: z.ZodOptional<z.ZodEnum<{
169
+ "agent-only": "agent-only";
170
+ }>>;
171
171
  }, z.core.$strip>], "type">;
172
172
  type PromptInput = z.infer<typeof promptInputSchema>;
173
173
 
174
174
  declare const createThreadEnvironmentArgsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
175
- type: z.ZodLiteral<"reuse">;
176
175
  environmentId: z.ZodString;
176
+ type: z.ZodLiteral<"reuse">;
177
177
  }, z.core.$strip>, z.ZodObject<{
178
- type: z.ZodLiteral<"host">;
179
178
  hostId: z.ZodOptional<z.ZodString>;
179
+ type: z.ZodLiteral<"host">;
180
180
  workspace: z.ZodDiscriminatedUnion<[z.ZodObject<{
181
- type: z.ZodLiteral<"unmanaged">;
182
- path: z.ZodNullable<z.ZodString>;
183
181
  branch: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
184
182
  kind: z.ZodLiteral<"existing">;
185
183
  name: z.ZodString;
186
184
  }, z.core.$strict>, z.ZodObject<{
187
- kind: z.ZodLiteral<"new">;
188
185
  baseBranch: z.ZodString;
186
+ kind: z.ZodLiteral<"new">;
189
187
  }, z.core.$strict>], "kind">>;
188
+ path: z.ZodNullable<z.ZodString>;
189
+ type: z.ZodLiteral<"unmanaged">;
190
190
  }, z.core.$strip>, z.ZodObject<{
191
- type: z.ZodLiteral<"managed-worktree">;
192
191
  baseBranch: z.ZodDiscriminatedUnion<[z.ZodObject<{
193
192
  kind: z.ZodLiteral<"named">;
194
193
  name: z.ZodString;
195
194
  }, z.core.$strip>, z.ZodObject<{
196
195
  kind: z.ZodLiteral<"default">;
197
196
  }, z.core.$strip>], "kind">;
197
+ type: z.ZodLiteral<"managed-worktree">;
198
198
  }, z.core.$strip>, z.ZodObject<{
199
199
  type: z.ZodLiteral<"personal">;
200
200
  }, z.core.$strip>], "type">;
@@ -204,25 +204,25 @@ declare const createThreadEnvironmentArgsSchema: z.ZodDiscriminatedUnion<[z.ZodO
204
204
  type CreateThreadEnvironmentArgs = z.infer<typeof createThreadEnvironmentArgsSchema>;
205
205
 
206
206
  declare const createExecutionInputSourcesSchema: z.ZodObject<{
207
- providerId: z.ZodOptional<z.ZodEnum<{
208
- explicit: "explicit";
209
- "client-preference": "client-preference";
210
- }>>;
211
207
  model: z.ZodOptional<z.ZodEnum<{
212
- explicit: "explicit";
213
208
  "client-preference": "client-preference";
209
+ explicit: "explicit";
214
210
  }>>;
215
- serviceTier: z.ZodOptional<z.ZodEnum<{
211
+ permissionMode: z.ZodOptional<z.ZodEnum<{
212
+ "client-preference": "client-preference";
216
213
  explicit: "explicit";
214
+ }>>;
215
+ providerId: z.ZodOptional<z.ZodEnum<{
217
216
  "client-preference": "client-preference";
217
+ explicit: "explicit";
218
218
  }>>;
219
219
  reasoningLevel: z.ZodOptional<z.ZodEnum<{
220
- explicit: "explicit";
221
220
  "client-preference": "client-preference";
222
- }>>;
223
- permissionMode: z.ZodOptional<z.ZodEnum<{
224
221
  explicit: "explicit";
222
+ }>>;
223
+ serviceTier: z.ZodOptional<z.ZodEnum<{
225
224
  "client-preference": "client-preference";
225
+ explicit: "explicit";
226
226
  }>>;
227
227
  }, z.core.$strict>;
228
228
  type CreateExecutionInputSources = z.infer<typeof createExecutionInputSourcesSchema>;
@@ -337,6 +337,13 @@ interface PluginThreadListProps {
337
337
  * shipping a second search box.
338
338
  */
339
339
  searchQuery: string;
340
+ /**
341
+ * BB's thread list, bound to this sidebar instance. Render it to delegate
342
+ * conditionally without re-entering plugin replacement resolution.
343
+ *
344
+ * @experimental Audit before relying on this as a stable contract.
345
+ */
346
+ experimental_Original: ComponentType;
340
347
  }
341
348
  /**
342
349
  * Props passed to an `experimental_threadHeaderAction` component, rendered in
@@ -365,7 +372,7 @@ interface PluginThreadHeaderActionProps {
365
372
  * are absolute on the thread's host.
366
373
  */
367
374
  interface PluginFileOpenerSource {
368
- kind: "workspace" | "host" | "thread-storage";
375
+ kind: "host" | "thread-storage" | "workspace";
369
376
  threadId: string | null;
370
377
  environmentId: string | null;
371
378
  projectId: string | null;
@@ -374,6 +381,103 @@ interface PluginFileOpenerSource {
374
381
  interface PluginFileOpenerProps {
375
382
  path: string;
376
383
  source: PluginFileOpenerSource;
384
+ /**
385
+ * BB's file preview, bound to this file. Render it to delegate conditionally
386
+ * without re-entering plugin replacement resolution.
387
+ *
388
+ * @experimental Audit before relying on this as a stable contract.
389
+ */
390
+ experimental_Original: ComponentType;
391
+ }
392
+ /** How a code line longer than the viewport is presented. */
393
+ type CodeOverflowMode = "scroll" | "wrap";
394
+ /** How a diff presents its two sides. */
395
+ type DiffViewMode = "split" | "unified";
396
+ /** A 1-based, inclusive line range. */
397
+ interface SourceCodeLineRange {
398
+ start: number;
399
+ end: number;
400
+ }
401
+ /**
402
+ * Props of the host-owned `experimental_SourceCode` component — BB's source
403
+ * viewer. The host owns syntax highlighting, gutters, wrapping, line-selection
404
+ * presentation, and the live BB code theme; the caller owns loading the text
405
+ * and any surrounding chrome.
406
+ */
407
+ interface SourceCodeProps {
408
+ /** The complete source text to render. */
409
+ content: string;
410
+ /** File path or name. Drives language detection and the a11y label. */
411
+ path: string;
412
+ /** Long-line presentation. Defaults to `"scroll"`. */
413
+ overflow?: CodeOverflowMode;
414
+ /**
415
+ * Lines to highlight and scroll into view (1-based, inclusive). Defaults to
416
+ * `null` — nothing highlighted.
417
+ */
418
+ highlightedLines?: SourceCodeLineRange | null;
419
+ /** Applied to the renderer's root element. */
420
+ className?: string;
421
+ }
422
+ /**
423
+ * Props of the host-owned `experimental_Diff` component — BB's diff viewer.
424
+ * The host owns patch normalization (a patch without a `diff --git` header is
425
+ * completed from `path`), syntax highlighting, unified/split presentation,
426
+ * gutters, line-selection presentation, and the live BB code theme. Content
427
+ * that cannot be parsed as a patch degrades to plain monospace text.
428
+ */
429
+ interface DiffProps {
430
+ /** Unified patch text for exactly ONE file. */
431
+ patch: string;
432
+ /**
433
+ * The file the patch applies to. Used to complete a patch that arrives
434
+ * without a `diff --git` header (GitHub's REST patches, single `@@` hunks)
435
+ * and for language detection.
436
+ */
437
+ path: string;
438
+ /** Side-by-side or inline. Defaults to `"unified"`. */
439
+ view?: DiffViewMode;
440
+ /** Long-line presentation. Defaults to `"scroll"`. */
441
+ overflow?: CodeOverflowMode;
442
+ /** Whether the gutter shows line numbers. Defaults to `true`. */
443
+ showLineNumbers?: boolean;
444
+ /** Applied to the renderer's root element. */
445
+ className?: string;
446
+ }
447
+ /**
448
+ * Props passed to an `experimental_sourceCodeRenderer` component. Every value
449
+ * is already resolved — the replacement never re-applies a host default.
450
+ */
451
+ interface PluginSourceCodeRendererProps {
452
+ content: string;
453
+ path: string;
454
+ overflow: CodeOverflowMode;
455
+ highlightedLines: SourceCodeLineRange | null;
456
+ /**
457
+ * BB's source renderer, bound to this request. Render it to delegate
458
+ * conditionally without re-entering plugin replacement resolution.
459
+ *
460
+ * @experimental Audit before relying on this as a stable contract.
461
+ */
462
+ experimental_Original: ComponentType;
463
+ }
464
+ /**
465
+ * Props passed to an `experimental_diffRenderer` component. `patch` is always
466
+ * a complete single-file unified patch, whatever shape the caller supplied.
467
+ */
468
+ interface PluginDiffRendererProps {
469
+ patch: string;
470
+ path: string;
471
+ view: DiffViewMode;
472
+ overflow: CodeOverflowMode;
473
+ showLineNumbers: boolean;
474
+ /**
475
+ * BB's diff renderer, bound to this request. Render it to delegate
476
+ * conditionally without re-entering plugin replacement resolution.
477
+ *
478
+ * @experimental Audit before relying on this as a stable contract.
479
+ */
480
+ experimental_Original: ComponentType;
377
481
  }
378
482
  /**
379
483
  * Message context passed to a `messageDirective` component — the assistant
@@ -434,6 +538,25 @@ interface PluginNavPanelRegistration {
434
538
  /** URL segment under `/plugins/<pluginId>/`; letters, digits, `-`, `_`. */
435
539
  path: string;
436
540
  component: ComponentType<PluginNavPanelProps>;
541
+ /**
542
+ * Ordered, non-closable tabs shown in this page's host-owned right panel.
543
+ * BB owns selection and persistence and always includes its native Browser
544
+ * and Terminal tools beside them. Components mount only while their tab is
545
+ * active and the panel is open, and receive the same `subPath` as the page
546
+ * component.
547
+ *
548
+ * Experimental: see docs/api_to_audit.md.
549
+ */
550
+ experimental_fixedTabs?: readonly {
551
+ /** Unique within this nav panel; letters, digits, `-`, `_`. */
552
+ id: string;
553
+ title: string;
554
+ /** Icon hint (BB icon name); unknown names fall back to a generic icon. */
555
+ icon: string;
556
+ component: ComponentType<PluginNavPanelProps>;
557
+ /** `flush` lets the component own padding and scrolling. */
558
+ layout?: "flush" | "padded";
559
+ }[];
437
560
  /**
438
561
  * Optional presentational component rendered at the trailing edge of this
439
562
  * panel's sidebar row. It receives no props so it can own a narrow live
@@ -453,6 +576,22 @@ interface PluginNavPanelRegistration {
453
576
  */
454
577
  headerContent?: ComponentType<PluginNavPanelProps>;
455
578
  }
579
+ /**
580
+ * What a plugin action passes when it asks the host to open one of its panel
581
+ * tabs. Shared by every `openPanel` entry point so a plugin registering more
582
+ * than one kind of action can write a single open routine;
583
+ * `PluginTargetedPanelActionOpenOptions` adds the `actionId` a caller
584
+ * outside a panel action must pass to name the panel it wants.
585
+ */
586
+ interface PluginPanelActionOpenOptions {
587
+ /** Tab label. Default: the action's `title`. */
588
+ title?: string;
589
+ /**
590
+ * Persisted with the tab and handed to the component as its `params` prop.
591
+ * Must be a JSON value; anything else is a declined open.
592
+ */
593
+ params?: JsonValue;
594
+ }
456
595
  /**
457
596
  * Context handed to a `threadPanelAction`'s `run`.
458
597
  *
@@ -470,11 +609,15 @@ interface PluginThreadPanelActionContext {
470
609
  * identical to an already-open tab of this action focuses that tab
471
610
  * (updating its title) instead of duplicating it. May be called more than
472
611
  * once (different params ⇒ multiple tabs) or not at all.
612
+ *
613
+ * Returns true when the host accepted the open; false when it declined —
614
+ * from this launcher, only a `params` that is not a JSON value. The true /
615
+ * false contract is shared with `messageAction`'s `openPanel` and
616
+ * `useBbNavigate().openThreadPanel` (which decline for more reasons) so one
617
+ * open routine can serve every action kind. A decline is never thrown: the
618
+ * host logs it and reports it here.
473
619
  */
474
- openPanel(options?: {
475
- title?: string;
476
- params?: JsonValue;
477
- }): void;
620
+ openPanel(options?: PluginPanelActionOpenOptions): boolean;
478
621
  }
479
622
  interface PluginThreadPanelActionRegistration {
480
623
  /** Unique within the plugin; letters, digits, `-`, `_`. */
@@ -496,7 +639,7 @@ interface PluginThreadPanelActionRegistration {
496
639
  * app-like content that manages its own layout, such as
497
640
  * `ThreadChat`.
498
641
  */
499
- layout?: "padded" | "flush";
642
+ layout?: "flush" | "padded";
500
643
  /**
501
644
  * Runs when the user activates the action: call your RPC methods, show a
502
645
  * toast, and/or open panel tabs via `context.openPanel`. Omitted =
@@ -511,13 +654,10 @@ interface PluginNewThreadPanelActionContext {
511
654
  projectId: string | null;
512
655
  /**
513
656
  * Open a tab in the root New thread screen's side panel rendering this
514
- * action's `component`. The title, params, deduplication, and error
515
- * semantics match `threadPanelAction`.
657
+ * action's `component`. The title, params, deduplication, return value, and
658
+ * error semantics match `threadPanelAction`.
516
659
  */
517
- openPanel(options?: {
518
- title?: string;
519
- params?: JsonValue;
520
- }): void;
660
+ openPanel(options?: PluginPanelActionOpenOptions): boolean;
521
661
  }
522
662
  /** Registration for the root New thread screen's panel Actions list. */
523
663
  interface PluginNewThreadPanelActionRegistration {
@@ -530,7 +670,7 @@ interface PluginNewThreadPanelActionRegistration {
530
670
  /** Rendered inside every panel tab this action opens. */
531
671
  component: ComponentType<PluginNewThreadPanelProps>;
532
672
  /** Host framing; matches `threadPanelAction`. */
533
- layout?: "padded" | "flush";
673
+ layout?: "flush" | "padded";
534
674
  /**
535
675
  * Runs when the user activates the action. Omitted = immediately open a
536
676
  * panel tab with defaults. Errors are contained and logged.
@@ -582,12 +722,12 @@ interface PluginSidebarFooterActionRegistration {
582
722
  * cannot. A thread holding a draft reports whatever it would report without
583
723
  * one.
584
724
  */
585
- type PluginSidebarThreadIndicator = "unread-error" | "waiting-for-input" | "working-draft" | "workflow" | "background-agent" | "background-command" | "plan-mode" | "goal" | "runtime" | "draft" | "unread-success" | "none";
725
+ type PluginSidebarThreadIndicator = "background-agent" | "background-command" | "draft" | "goal" | "none" | "plan-mode" | "runtime" | "unread-error" | "unread-success" | "waiting-for-input" | "workflow" | "working-draft";
586
726
  /**
587
727
  * How a thread's environment presents its workspace: a worktree bb manages,
588
728
  * a worktree the user manages, or anything else (a plain checkout).
589
729
  */
590
- type PluginSidebarWorkspaceKind = "managed-worktree" | "unmanaged-worktree" | "other";
730
+ type PluginSidebarWorkspaceKind = "managed-worktree" | "other" | "unmanaged-worktree";
591
731
  /** Live work counts on a thread. All zero means nothing is running. */
592
732
  interface PluginSidebarThreadActivity {
593
733
  workflows: number;
@@ -661,8 +801,8 @@ interface PluginSidebarPullRequest {
661
801
  number: number;
662
802
  title: string;
663
803
  url: string;
664
- state: "draft" | "open" | "merged" | "closed";
665
- attention: "checks_failed" | "checks_pending" | "changes_requested" | "review_requested" | "conflicts" | "blocked" | "draft" | "ready_to_merge" | "merged" | "closed" | "none";
804
+ state: "closed" | "draft" | "merged" | "open";
805
+ attention: "blocked" | "changes_requested" | "checks_failed" | "checks_pending" | "closed" | "conflicts" | "draft" | "merged" | "none" | "ready_to_merge" | "review_requested";
666
806
  }
667
807
  interface PluginSidebarThreadPullRequestState {
668
808
  /** True while the first lookup for this thread's environment is in flight. */
@@ -682,7 +822,7 @@ interface PluginSidebarProject {
682
822
  isPersonal: boolean;
683
823
  }
684
824
  interface PluginSidebarThreadsState {
685
- status: "loading" | "ready" | "error";
825
+ status: "error" | "loading" | "ready";
686
826
  threads: readonly PluginSidebarThread[];
687
827
  projects: readonly PluginSidebarProject[];
688
828
  }
@@ -794,10 +934,13 @@ interface PluginSidebarThreadSplit {
794
934
  * Replace the sidebar's thread list with a plugin component.
795
935
  *
796
936
  * Unlike every other slot, this one is EXCLUSIVE: two lists cannot share one
797
- * scroll area. The built-in list stays the default; the user picks a provider
798
- * in Settings Appearance, stored per client. A provider that is uninstalled,
799
- * disabled, or crashing falls back to the built-in list rather than leaving
800
- * the user with no sidebar.
937
+ * scroll area. Registering activates the replacement while the plugin is
938
+ * enabled. If multiple plugins register one, the first in deterministic slot
939
+ * order is active by default; removing it reveals the next. The user can pin
940
+ * BB's list or a specific provider under Settings → Appearance. A plugin can
941
+ * also use its own setting and render `experimental_Original` conditionally.
942
+ * An absent or crashing replacement falls back to BB's list rather than
943
+ * leaving the user with no sidebar.
801
944
  *
802
945
  * The plugin gets the scrolling list and nothing else. The New-thread button,
803
946
  * the search field, the plugin nav rows, and the footer stay host-rendered in
@@ -807,20 +950,21 @@ interface PluginSidebarThreadSplit {
807
950
  interface PluginThreadListRegistration {
808
951
  /** Unique within the plugin; letters, digits, `-`, `_`. */
809
952
  id: string;
810
- /** Label in the Settings → Appearance Sidebar picker. */
953
+ /** Label shown in Settings → Appearance and capability details. */
811
954
  title: string;
812
- /** Optional one-line description under the title in that picker. */
955
+ /** Optional one-line description shown with the provider choice. */
813
956
  description?: string;
814
957
  component: ComponentType<PluginThreadListProps>;
815
958
  }
816
959
  /**
817
- * Register this plugin as a viewer/editor for file extensions. The user
818
- * picks (and can set as default) an opener per extension via the file tab's
819
- * "Open with" menu; matching files opened in the panel then render
820
- * `component` in a plugin tab instead of the built-in preview. Applies to
821
- * working-tree, host, and thread-storage files never to git-ref snapshots
822
- * (diff views always use the built-in preview). The built-in preview stays
823
- * one menu click away, and a missing/disabled opener falls back to it.
960
+ * Register this plugin as a viewer/editor for file extensions. By default,
961
+ * matching files render the first applicable opener in deterministic slot
962
+ * order. The user can pin BB's preview or a specific opener per extension
963
+ * under Settings Files. The file tab's "Open with" menu can override that
964
+ * choice for one open. A plugin can also use its own setting and render
965
+ * `experimental_Original` conditionally. Applies to working-tree, host, and
966
+ * thread-storage files never to git-ref snapshots (diff views always use
967
+ * BB's preview).
824
968
  */
825
969
  interface PluginFileOpenerRegistration {
826
970
  /** Unique within the plugin; letters, digits, `-`, `_`. */
@@ -831,6 +975,41 @@ interface PluginFileOpenerRegistration {
831
975
  extensions: readonly string[];
832
976
  component: ComponentType<PluginFileOpenerProps>;
833
977
  }
978
+ /**
979
+ * Replace BB's source-code renderer everywhere it renders supplied source
980
+ * text — the native file preview and every plugin that calls
981
+ * `experimental_SourceCode`. Like `experimental_threadList` this slot is
982
+ * **exclusive**: one renderer at a time. Registering activates it while the
983
+ * plugin is enabled; if several are registered the first in deterministic slot
984
+ * order wins. A missing, disabled, or crashing replacement falls back to BB's
985
+ * renderer, and a replacement can render `experimental_Original` to delegate
986
+ * per call (behind its own setting, by language, by size — whatever it needs).
987
+ */
988
+ interface PluginSourceCodeRendererRegistration {
989
+ /** Unique within the plugin; letters, digits, `-`, `_`. */
990
+ id: string;
991
+ /** Label shown in capability details. */
992
+ title: string;
993
+ /** Optional one-line description shown with the provider choice. */
994
+ description?: string;
995
+ component: ComponentType<PluginSourceCodeRendererProps>;
996
+ }
997
+ /**
998
+ * Replace BB's diff renderer everywhere it renders supplied diff content — the
999
+ * timeline file diffs, the environment diff panel's text bodies, and every
1000
+ * plugin that calls `experimental_Diff`. Exclusive, with the same activation,
1001
+ * fallback, and `experimental_Original` delegation rules as
1002
+ * {@link PluginSourceCodeRendererRegistration}.
1003
+ */
1004
+ interface PluginDiffRendererRegistration {
1005
+ /** Unique within the plugin; letters, digits, `-`, `_`. */
1006
+ id: string;
1007
+ /** Label shown in capability details. */
1008
+ title: string;
1009
+ /** Optional one-line description shown with the provider choice. */
1010
+ description?: string;
1011
+ component: ComponentType<PluginDiffRendererProps>;
1012
+ }
834
1013
  /**
835
1014
  * Register a leaf message directive rendered inside assistant (and nested
836
1015
  * agent) message Markdown. `id` is the directive name: `inline-vis` matches
@@ -851,16 +1030,20 @@ interface PluginMessageDirectiveRegistration {
851
1030
  interface ThreadChatMessageReference {
852
1031
  id: string;
853
1032
  threadId: string;
854
- role: "user" | "assistant";
1033
+ role: "assistant" | "user";
855
1034
  /** Visible text of the message. */
856
1035
  text: string;
857
1036
  sourceSeqEnd: number;
858
1037
  }
859
- interface PluginMessageActionThreadPanelOptions {
1038
+ /**
1039
+ * What a caller that is *not* itself a panel action passes to open one — a
1040
+ * `messageAction`'s `run`, or any component via `useBbNavigate()`. A panel
1041
+ * action opening its own tab is already the target, so it passes the bare
1042
+ * {@link PluginPanelActionOpenOptions} instead.
1043
+ */
1044
+ interface PluginTargetedPanelActionOpenOptions extends PluginPanelActionOpenOptions {
860
1045
  /** A `threadPanelAction` id registered by this same plugin. */
861
1046
  actionId: string;
862
- title?: string;
863
- params?: JsonValue;
864
1047
  }
865
1048
  /** Context handed to a `messageAction`'s `run`. */
866
1049
  interface PluginMessageActionContext {
@@ -875,11 +1058,15 @@ interface PluginMessageActionContext {
875
1058
  /**
876
1059
  * Open one of this plugin's `threadPanelAction` components in the current
877
1060
  * thread's side panel — the registration-callback equivalent of
878
- * `useBbNavigate().openThreadPanel`. Returns true when the host
879
- * accepted (the action id exists and the surface has a panel); false
880
- * otherwise.
1061
+ * `useBbNavigate().openThreadPanel`.
1062
+ *
1063
+ * Returns true when the host accepted the open; false when it declined —
1064
+ * `params` was not a JSON value, the action id names no `threadPanelAction`
1065
+ * of this plugin, or the surface has no side panel (only the main thread
1066
+ * view does; a `ThreadChat` embedded in a plugin panel does not). A decline
1067
+ * is never thrown: the host logs it and reports it here.
881
1068
  */
882
- openPanel(options: PluginMessageActionThreadPanelOptions): boolean;
1069
+ openPanel(options: PluginTargetedPanelActionOpenOptions): boolean;
883
1070
  }
884
1071
  /**
885
1072
  * An action on chat messages: an icon button in the per-message action bar
@@ -900,6 +1087,32 @@ interface PluginMessageActionRegistration {
900
1087
  */
901
1088
  run(context: PluginMessageActionContext): void | Promise<void>;
902
1089
  }
1090
+ /**
1091
+ * Supply the inline React mark bb draws for one agent provider.
1092
+ *
1093
+ * A manifest `branding.icon` (or a provider's `logoUrl`) is fetched and drawn
1094
+ * through `<img>`, a separate document where `currentColor` resolves to black
1095
+ * — invisible on dark themes and unreachable from app CSS. A component is
1096
+ * rendered inline, so it inherits the app's theme colors and the host's sizing
1097
+ * classes. Register a static color logo as a file and a theme-aware mark here.
1098
+ *
1099
+ * The host passes only `className` (sizing plus the provider's color class);
1100
+ * the component must render an inline SVG (or other inline markup) and must
1101
+ * not fetch. One registration per provider id per plugin; when two plugins
1102
+ * claim the same provider id the host keeps the first by plugin id and warns.
1103
+ */
1104
+ interface PluginProviderIconRegistration {
1105
+ /**
1106
+ * The provider this mark is for — the id bb knows the provider by (the
1107
+ * provider declaration's id, e.g. `codex` or `acp-cursor`), not the plugin
1108
+ * id. Letters, digits, `-`, `_`.
1109
+ */
1110
+ providerId: string;
1111
+ /** Inline, theme-aware mark. Receives the host's sizing/color className. */
1112
+ icon: ComponentType<{
1113
+ className?: string;
1114
+ }>;
1115
+ }
903
1116
  interface PluginAppSlots {
904
1117
  homepageSection(registration: PluginHomepageSectionRegistration): void;
905
1118
  settingsSection(registration: PluginSettingsSectionRegistration): void;
@@ -930,8 +1143,27 @@ interface PluginAppSlots {
930
1143
  */
931
1144
  experimental_threadHeaderAction(registration: PluginThreadHeaderActionRegistration): void;
932
1145
  fileOpener(registration: PluginFileOpenerRegistration): void;
1146
+ /**
1147
+ * Replace BB's source-code renderer (see
1148
+ * {@link PluginSourceCodeRendererRegistration}). Experimental: see
1149
+ * docs/api_to_audit.md.
1150
+ */
1151
+ experimental_sourceCodeRenderer(registration: PluginSourceCodeRendererRegistration): void;
1152
+ /**
1153
+ * Replace BB's diff renderer (see
1154
+ * {@link PluginDiffRendererRegistration}). Experimental: see
1155
+ * docs/api_to_audit.md.
1156
+ */
1157
+ experimental_diffRenderer(registration: PluginDiffRendererRegistration): void;
933
1158
  messageDirective(registration: PluginMessageDirectiveRegistration): void;
934
1159
  messageAction(registration: PluginMessageActionRegistration): void;
1160
+ /**
1161
+ * Draw one agent provider's icon with an inline React component instead of
1162
+ * its `<img>`-rendered logo file (see
1163
+ * {@link PluginProviderIconRegistration}). Experimental: see
1164
+ * docs/api_to_audit.md.
1165
+ */
1166
+ experimental_providerIcon(registration: PluginProviderIconRegistration): void;
935
1167
  }
936
1168
  interface PluginAppComposer {
937
1169
  customize(registration: ComposerCustomization): void;
@@ -1010,7 +1242,7 @@ interface PluginSettingsState {
1010
1242
  isLoading: boolean;
1011
1243
  }
1012
1244
  /** State of the app's shared realtime connection to the bb server. */
1013
- type PluginRealtimeConnectionState = "connecting" | "connected" | "reconnecting";
1245
+ type PluginRealtimeConnectionState = "connected" | "connecting" | "reconnecting";
1014
1246
  /** Where `useComposer()` writes. */
1015
1247
  type PluginComposerScope = {
1016
1248
  kind: "thread";
@@ -1043,7 +1275,7 @@ interface ComposerCustomization {
1043
1275
  banners?: readonly {
1044
1276
  id: string;
1045
1277
  /** Host chrome around the banner. Defaults to `"card"`. */
1046
- chrome?: "card" | "bare";
1278
+ chrome?: "bare" | "card";
1047
1279
  component: ComponentType;
1048
1280
  }[];
1049
1281
  plusMenu?: readonly ComposerPlusMenuItem[];
@@ -1066,7 +1298,7 @@ interface ComposerPlusMenuItem {
1066
1298
  /** Reactive read-side of the composer a plugin surface is mounted in. */
1067
1299
  interface ComposerView {
1068
1300
  scope: PluginComposerScope;
1069
- layout: "expanded" | "compact" | "zen";
1301
+ layout: "compact" | "expanded" | "zen";
1070
1302
  draft: {
1071
1303
  text: string;
1072
1304
  isEmpty: boolean;
@@ -1116,7 +1348,7 @@ interface PluginComposerThreadRowStatus {
1116
1348
  * shimmers; terminal `success` and `error` tones are static. Defaults to the
1117
1349
  * neutral tone.
1118
1350
  */
1119
- tone?: "default" | "running" | "success" | "error";
1351
+ tone?: "default" | "error" | "running" | "success";
1120
1352
  }
1121
1353
  /** An @-mention pill bound to one of the calling plugin's mention providers. */
1122
1354
  interface PluginComposerMention {
@@ -1197,7 +1429,7 @@ interface ThreadChatMessageAction {
1197
1429
  * Message roles the action applies to. Omitted = both user and assistant
1198
1430
  * messages.
1199
1431
  */
1200
- roles?: readonly ("user" | "assistant")[];
1432
+ roles?: readonly ("assistant" | "user")[];
1201
1433
  /**
1202
1434
  * Runs when the user activates the action. Errors (sync or async) are
1203
1435
  * contained and logged; they never break the timeline.
@@ -1220,7 +1452,7 @@ interface ThreadChatProps {
1220
1452
  * "compact" is the side-panel presentation; "timeline" renders the
1221
1453
  * transcript without a composer.
1222
1454
  */
1223
- variant?: "full" | "compact" | "timeline";
1455
+ variant?: "compact" | "full" | "timeline";
1224
1456
  /**
1225
1457
  * "contained" (default) fills and scrolls inside a bounded parent;
1226
1458
  * "document" grows with its content and defers scrolling to the page.
@@ -1236,7 +1468,7 @@ interface ThreadChatProps {
1236
1468
  * lower permissions for this thread independently of the thread it was
1237
1469
  * forked from. Ignored by `variant: "timeline"` (no composer).
1238
1470
  */
1239
- permissionPolicy?: "inherit" | "editable";
1471
+ permissionPolicy?: "editable" | "inherit";
1240
1472
  className?: string;
1241
1473
  /** Rendered above the conversation, scrolling with it. */
1242
1474
  leadingContent?: ReactNode;
@@ -1260,6 +1492,13 @@ interface ThreadChatProps {
1260
1492
  * composer props.
1261
1493
  */
1262
1494
  interface NewThreadRequest {
1495
+ /**
1496
+ * The selected project id. Choosing "Don't work in a project" submits BB's
1497
+ * personal-project id (not `null`) together with a `personal` workspace
1498
+ * environment. Forward those fields unchanged to `threads.spawn`; if the
1499
+ * plugin needs project metadata, request it from the plugin backend with
1500
+ * `bb.sdk.projects.list({ includePersonal: true })`.
1501
+ */
1263
1502
  projectId: string;
1264
1503
  providerId: string;
1265
1504
  model: string;
@@ -1287,7 +1526,11 @@ interface NewThreadRequest {
1287
1526
  * exception to the no-host-components rule (§5.5), same additive versioning.
1288
1527
  */
1289
1528
  interface NewThreadComposerProps {
1290
- /** Seeds the project picker. The user can change it. */
1529
+ /**
1530
+ * Seeds the project picker. The user can change it, including choosing
1531
+ * "Don't work in a project"; see {@link NewThreadRequest.projectId} for the
1532
+ * submitted projectless shape.
1533
+ */
1291
1534
  defaultProjectId?: string;
1292
1535
  /**
1293
1536
  * Seeds the provider picker. Like every `default*` prop this is a SEED, not
@@ -1421,11 +1664,7 @@ interface BbNavigate {
1421
1664
  * thread surface. Returns false when the surface has no thread side panel or
1422
1665
  * the action is unavailable.
1423
1666
  */
1424
- openThreadPanel(options: {
1425
- actionId: string;
1426
- title?: string;
1427
- params?: JsonValue;
1428
- }): boolean;
1667
+ openThreadPanel(options: PluginTargetedPanelActionOpenOptions): boolean;
1429
1668
  }
1430
1669
  /**
1431
1670
  * Everything `@get-bb/plugin-sdk/app` resolves to at runtime. The BB app builds
@@ -1451,6 +1690,13 @@ interface PluginSdkApp {
1451
1690
  * The sidebar's live thread view (see {@link PluginSidebarThreadsState}).
1452
1691
  * Reads the host's own cache and realtime subscriptions, so it costs no
1453
1692
  * extra request and updates exactly when the built-in sidebar does.
1693
+ *
1694
+ * `threads` is one array of every visible thread and is not capped. Thread
1695
+ * objects keep their identity across updates while the underlying entry is
1696
+ * unchanged, so a memoized row re-renders only when its own thread changed;
1697
+ * the array itself is new on every update. Window your rows (render only
1698
+ * what is on screen) as the built-in sidebar does — a list that mounts one
1699
+ * row per thread is slow on phones with many threads.
1454
1700
  * Experimental: see docs/api_to_audit.md.
1455
1701
  */
1456
1702
  experimental_useSidebarThreads(): PluginSidebarThreadsState;
@@ -1495,6 +1741,21 @@ interface PluginSdkApp {
1495
1741
  * docs/api_to_audit.md for what to audit before the prefix drops.
1496
1742
  */
1497
1743
  experimental_NewThreadComposer: ComponentType<NewThreadComposerProps>;
1744
+ /**
1745
+ * The host-owned source viewer (see {@link SourceCodeProps}). Renders
1746
+ * supplied source text with BB's syntax highlighting, gutters, and live code
1747
+ * theme, and honours an active `experimental_sourceCodeRenderer`
1748
+ * replacement. Experimental: see docs/api_to_audit.md.
1749
+ */
1750
+ experimental_SourceCode: ComponentType<SourceCodeProps>;
1751
+ /**
1752
+ * The host-owned diff viewer (see {@link DiffProps}). Renders supplied patch
1753
+ * content with BB's normalization, syntax highlighting, unified/split
1754
+ * presentation, and live code theme, and honours an active
1755
+ * `experimental_diffRenderer` replacement. Experimental: see
1756
+ * docs/api_to_audit.md.
1757
+ */
1758
+ experimental_Diff: ComponentType<DiffProps>;
1498
1759
  useComposerView(): ComposerView;
1499
1760
  }
1500
1761
 
@@ -1502,6 +1763,8 @@ declare const definePluginApp: (setup: PluginAppSetup) => PluginAppDefinition;
1502
1763
  declare const ThreadChat: react.ComponentType<ThreadChatProps>;
1503
1764
  declare const Markdown: react.ComponentType<MarkdownProps>;
1504
1765
  declare const experimental_NewThreadComposer: react.ComponentType<NewThreadComposerProps>;
1766
+ declare const experimental_SourceCode: react.ComponentType<SourceCodeProps>;
1767
+ declare const experimental_Diff: react.ComponentType<DiffProps>;
1505
1768
  declare const useRpc: <Contract extends PluginRpcContract = Readonly<Record<string, PluginRpcMethodContract<StandardSchemaV1<unknown, unknown>, StandardSchemaV1<unknown, unknown>>>>>() => PluginRpcClient<Contract>;
1506
1769
  declare const useRealtime: (channel: string, handler: (payload: unknown) => void) => void;
1507
1770
  declare const useRealtimeConnectionState: () => PluginRealtimeConnectionState;
@@ -1515,5 +1778,5 @@ declare const experimental_useSidebarThreadActions: () => PluginSidebarThreadAct
1515
1778
  declare const experimental_useSidebarThreadPullRequest: (threadId: string) => PluginSidebarThreadPullRequestState;
1516
1779
  declare const experimental_useSidebarThreadSplit: (threadId: string) => PluginSidebarThreadSplit;
1517
1780
 
1518
- export { Markdown, ThreadChat, definePluginApp, experimental_NewThreadComposer, experimental_useSidebarThreadActions, experimental_useSidebarThreadPullRequest, experimental_useSidebarThreadSplit, experimental_useSidebarThreads, useBbContext, useBbNavigate, useComposer, useComposerView, useRealtime, useRealtimeConnectionState, useRpc, useSettings };
1519
- export type { BbContext, BbNavigate, ComposerCustomization, ComposerPlusMenuItem, ComposerRichTextSpec, ComposerStructuredDraft, ComposerView, JsonValue, MarkdownProps, NewThreadComposerProps, NewThreadRequest, PluginAppBuilder, PluginAppComposer, PluginAppContentScripts, PluginAppDefinition, PluginAppSetup, PluginAppSlots, PluginComposerApi, PluginComposerMention, PluginComposerScope, PluginComposerTextEffect, PluginComposerThreadRowStatus, PluginContentScriptContext, PluginContentScriptDisposer, PluginContentScriptRegistration, PluginFileOpenerProps, PluginFileOpenerRegistration, PluginFileOpenerSource, PluginHomepageSectionProps, PluginHomepageSectionRegistration, PluginMessageActionContext, PluginMessageActionRegistration, PluginMessageActionThreadPanelOptions, PluginMessageDirectiveMessage, PluginMessageDirectiveOpenWorkspaceFile, PluginMessageDirectiveProps, PluginMessageDirectiveRegistration, PluginNavPanelProps, PluginNavPanelRegistration, PluginNewThreadPanelActionContext, PluginNewThreadPanelActionRegistration, PluginNewThreadPanelProps, PluginPendingInteractionProps, PluginPendingInteractionRegistration, PluginPendingInteractionView, 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, PluginSidebarWorkspaceKind, PluginThreadHeaderActionProps, PluginThreadHeaderActionRegistration, PluginThreadListProps, PluginThreadListRegistration, PluginThreadPanelActionContext, PluginThreadPanelActionRegistration, PluginThreadPanelProps, StandardSchemaV1, StandardSchemaV1InferInput, StandardSchemaV1InferOutput, StandardSchemaV1Issue, StandardSchemaV1Result, ThreadChatMessageAction, ThreadChatMessageReference, ThreadChatProps };
1781
+ export { Markdown, ThreadChat, definePluginApp, experimental_Diff, experimental_NewThreadComposer, experimental_SourceCode, experimental_useSidebarThreadActions, experimental_useSidebarThreadPullRequest, experimental_useSidebarThreadSplit, experimental_useSidebarThreads, useBbContext, useBbNavigate, useComposer, useComposerView, useRealtime, useRealtimeConnectionState, useRpc, useSettings };
1782
+ export type { BbContext, BbNavigate, CodeOverflowMode, ComposerCustomization, ComposerPlusMenuItem, ComposerRichTextSpec, ComposerStructuredDraft, ComposerView, DiffProps, DiffViewMode, JsonValue, MarkdownProps, NewThreadComposerProps, NewThreadRequest, PluginAppBuilder, PluginAppComposer, PluginAppContentScripts, PluginAppDefinition, PluginAppSetup, PluginAppSlots, PluginComposerApi, PluginComposerMention, PluginComposerScope, PluginComposerTextEffect, PluginComposerThreadRowStatus, PluginContentScriptContext, PluginContentScriptDisposer, PluginContentScriptRegistration, PluginDiffRendererProps, PluginDiffRendererRegistration, PluginFileOpenerProps, PluginFileOpenerRegistration, PluginFileOpenerSource, PluginHomepageSectionProps, PluginHomepageSectionRegistration, PluginMessageActionContext, PluginMessageActionRegistration, PluginMessageDirectiveMessage, PluginMessageDirectiveOpenWorkspaceFile, PluginMessageDirectiveProps, PluginMessageDirectiveRegistration, PluginNavPanelProps, PluginNavPanelRegistration, PluginNewThreadPanelActionContext, PluginNewThreadPanelActionRegistration, PluginNewThreadPanelProps, PluginPanelActionOpenOptions, PluginPendingInteractionProps, PluginPendingInteractionRegistration, PluginPendingInteractionView, PluginProviderIconRegistration, 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, PluginSidebarWorkspaceKind, PluginSourceCodeRendererProps, PluginSourceCodeRendererRegistration, PluginTargetedPanelActionOpenOptions, PluginThreadHeaderActionProps, PluginThreadHeaderActionRegistration, PluginThreadListProps, PluginThreadListRegistration, PluginThreadPanelActionContext, PluginThreadPanelActionRegistration, PluginThreadPanelProps, SourceCodeLineRange, SourceCodeProps, StandardSchemaV1, StandardSchemaV1InferInput, StandardSchemaV1InferOutput, StandardSchemaV1Issue, StandardSchemaV1Result, ThreadChatMessageAction, ThreadChatMessageReference, ThreadChatProps };