@get-bb/plugin-sdk 0.4.45 → 0.4.47
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.
- package/bundled-types/bb-plugin-sdk-app.d.ts +48 -1
- package/bundled-types/bb-plugin-sdk-internal-plugin-app-collector.d.ts +34 -3
- package/bundled-types/bb-plugin-sdk-testing-app.d.ts +18 -1
- package/bundled-types/bb-plugin-sdk-testing.d.ts +20 -1
- package/bundled-types/bb-plugin-sdk.d.ts +80 -1
- package/dist/internal/plugin-app-collector.js +142 -5
- package/dist/provider-bridge-acp.js +10 -8
- package/dist/provider-bridge-testing.js +2 -11
- package/dist/provider-bridge.js +10 -8
- package/dist/testing/app.js +136 -4
- package/dist/testing/index.js +150 -0
- package/package.json +1 -1
|
@@ -406,6 +406,11 @@ interface PluginPendingInteractionProps {
|
|
|
406
406
|
*/
|
|
407
407
|
interface PluginSidebarFooterActionProps {
|
|
408
408
|
}
|
|
409
|
+
/** Props passed to an experimental sidebar-footer disclosure component. */
|
|
410
|
+
interface ExperimentalSidebarFooterDisclosureProps {
|
|
411
|
+
/** Hide this disclosure without affecting another plugin's open disclosure. */
|
|
412
|
+
dismiss(): void;
|
|
413
|
+
}
|
|
409
414
|
/** Display and accessibility metadata for a host-owned sidebar shortcut. */
|
|
410
415
|
interface ExperimentalSidebarNavigationShortcut {
|
|
411
416
|
label: string;
|
|
@@ -942,6 +947,46 @@ interface PluginSidebarFooterActionRegistration {
|
|
|
942
947
|
*/
|
|
943
948
|
run(context: PluginSidebarFooterActionContext): void | Promise<void>;
|
|
944
949
|
}
|
|
950
|
+
/** Context handed to an experimental sidebar-footer action. */
|
|
951
|
+
interface ExperimentalSidebarFooterActionContext {
|
|
952
|
+
/** Navigate to this plugin's detail page in Tools. */
|
|
953
|
+
openPluginDetails(): void;
|
|
954
|
+
}
|
|
955
|
+
/** Fields shared by both experimental sidebar-footer item behaviors. */
|
|
956
|
+
interface ExperimentalSidebarFooterItemBase {
|
|
957
|
+
/** Unique within the plugin's unified sidebar footer; letters, digits, `-`, `_`. */
|
|
958
|
+
id: string;
|
|
959
|
+
/** Tooltip and accessible label for the host-rendered icon button. */
|
|
960
|
+
label: string;
|
|
961
|
+
/** BB icon-name hint; unknown names fall back to a generic icon. */
|
|
962
|
+
icon: string;
|
|
963
|
+
}
|
|
964
|
+
/** A sidebar-footer item that runs a callback when activated. */
|
|
965
|
+
interface ExperimentalSidebarFooterActionRegistration extends ExperimentalSidebarFooterItemBase {
|
|
966
|
+
kind: "action";
|
|
967
|
+
onActivate(context: ExperimentalSidebarFooterActionContext): void | Promise<void>;
|
|
968
|
+
}
|
|
969
|
+
/** A sidebar-footer item that reveals plugin-rendered content above the row. */
|
|
970
|
+
interface ExperimentalSidebarFooterDisclosureRegistration extends ExperimentalSidebarFooterItemBase {
|
|
971
|
+
kind: "disclosure";
|
|
972
|
+
component: ComponentType<ExperimentalSidebarFooterDisclosureProps>;
|
|
973
|
+
}
|
|
974
|
+
/** One host-rendered item in the app sidebar footer. */
|
|
975
|
+
type ExperimentalSidebarFooterItemRegistration = ExperimentalSidebarFooterActionRegistration | ExperimentalSidebarFooterDisclosureRegistration;
|
|
976
|
+
/** Live controls for an experimental sidebar-footer disclosure. */
|
|
977
|
+
interface ExperimentalSidebarFooterDisclosureController {
|
|
978
|
+
/** Request that the host open this disclosure, replacing any open sibling. */
|
|
979
|
+
open(): void;
|
|
980
|
+
/** Close this disclosure if it is currently open. */
|
|
981
|
+
close(): void;
|
|
982
|
+
/** Open this disclosure, or close it when it is currently open. */
|
|
983
|
+
toggle(): void;
|
|
984
|
+
}
|
|
985
|
+
/** Managed registration surface for items in the app sidebar footer. */
|
|
986
|
+
interface ExperimentalSidebarFooter {
|
|
987
|
+
register(registration: ExperimentalSidebarFooterActionRegistration): void;
|
|
988
|
+
register(registration: ExperimentalSidebarFooterDisclosureRegistration): ExperimentalSidebarFooterDisclosureController;
|
|
989
|
+
}
|
|
945
990
|
/**
|
|
946
991
|
* The one status bb would paint for a thread, already resolved through the
|
|
947
992
|
* host's precedence (attention before work; plan and goal before the generic
|
|
@@ -1664,6 +1709,8 @@ interface PluginAppBuilder {
|
|
|
1664
1709
|
slots: PluginAppSlots;
|
|
1665
1710
|
composer: PluginAppComposer;
|
|
1666
1711
|
contentScripts: PluginAppContentScripts;
|
|
1712
|
+
/** Experimental managed region for actions and disclosures in the sidebar footer. */
|
|
1713
|
+
experimental_sidebarFooter: ExperimentalSidebarFooter;
|
|
1667
1714
|
}
|
|
1668
1715
|
type PluginAppSetup = (app: PluginAppBuilder) => void;
|
|
1669
1716
|
/**
|
|
@@ -2470,4 +2517,4 @@ declare const experimental_useProviders: () => PluginProvidersState;
|
|
|
2470
2517
|
declare const experimental_useCodeTheme: () => PluginCodeThemeState;
|
|
2471
2518
|
|
|
2472
2519
|
export { Markdown, ThreadChat, UrlLink, definePluginApp, experimental_Diff, experimental_FileLink, experimental_NewThreadComposer, experimental_PermissionModePicker, experimental_ProviderModelPicker, experimental_SourceCode, experimental_useAppPanel, experimental_useCodeTheme, experimental_useFixedTabTarget, experimental_useProviders, experimental_useSidebarThreadActions, experimental_useSidebarThreadPullRequest, experimental_useSidebarThreadSplit, experimental_useSidebarThreads, useBbContext, useBbNavigate, useComposer, useComposerView, useRealtime, useRealtimeConnectionState, useRpc, useSettings };
|
|
2473
|
-
export type { BbContext, BbNavigate, CodeOverflowMode, ComposerCustomization, ComposerPlusMenuItem, ComposerRichTextSpec, ComposerStructuredDraft, ComposerView, DiffProps, DiffViewMode, ExperimentalAppOverlayProps, ExperimentalAppOverlayRegistration, ExperimentalAppPanel, ExperimentalAppPanelSurface, ExperimentalComposerSubmitOptions, ExperimentalDiffFileContent, ExperimentalDiffFullFileContents, ExperimentalFileLinkProps, ExperimentalFileLocation, ExperimentalFileOpenOptions, ExperimentalFixedTabTargetContract, ExperimentalFixedTabTargetState, ExperimentalLiveFileTarget, ExperimentalOpenFixedTabOptions, ExperimentalPermissionModePickerProps, ExperimentalPluginFixedTabReference, ExperimentalProviderModelPickerProps, ExperimentalProviderModelPickerRouting, ExperimentalProviderModelPickerValue, ExperimentalSidebarNavigationAction, ExperimentalSidebarNavigationActivationOptions, ExperimentalSidebarNavigationIcon, ExperimentalSidebarNavigationItem, ExperimentalSidebarNavigationProps, ExperimentalSidebarNavigationRegistration, ExperimentalSidebarNavigationShortcut, JsonValue, MarkdownProps, NewThreadComposerProps, NewThreadRequest, PluginAppBuilder, PluginAppComposer, PluginAppContentScripts, PluginAppDefinition, PluginAppSetup, PluginAppSlots, PluginCodeThemeData, PluginCodeThemeState, PluginCodeThemeTokenRule, PluginCommandPaletteActionContext, PluginCommandPaletteActionRegistration, PluginComposerApi, PluginComposerMention, PluginComposerScope, PluginComposerTextEffect, PluginComposerThreadRowStatus, PluginContentScriptContext, PluginContentScriptDisposer, PluginContentScriptRegistration, PluginDiffRendererProps, PluginDiffRendererRegistration, PluginFileOpenerProps, PluginFileOpenerRegistration, PluginFileOpenerSource, PluginFixedTabDeclaration, PluginFixedTabRegistration, PluginHomepageSectionProps, PluginHomepageSectionRegistration, 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, PluginSidebarWorkspaceKind, PluginSourceCodeRendererProps, PluginSourceCodeRendererRegistration, PluginTargetedPanelActionOpenOptions, PluginThreadHeaderActionProps, PluginThreadHeaderActionRegistration, PluginThreadListProps, PluginThreadListRegistration, PluginThreadPanelActionContext, PluginThreadPanelActionRegistration, PluginThreadPanelProps, PluginTimelineRendererProps, PluginTimelineRendererRegistration, PluginTimelineRendererRow, PluginTimelineRowPresentation, PluginTimelineRowStatus, SourceCodeLineRange, SourceCodeProps, StandardSchemaV1, StandardSchemaV1InferInput, StandardSchemaV1InferOutput, StandardSchemaV1Issue, StandardSchemaV1Result, ThreadChatMessageAction, ThreadChatMessageReference, ThreadChatProps, UrlLinkProps };
|
|
2520
|
+
export type { BbContext, BbNavigate, CodeOverflowMode, ComposerCustomization, ComposerPlusMenuItem, ComposerRichTextSpec, ComposerStructuredDraft, ComposerView, DiffProps, DiffViewMode, ExperimentalAppOverlayProps, ExperimentalAppOverlayRegistration, ExperimentalAppPanel, ExperimentalAppPanelSurface, ExperimentalComposerSubmitOptions, ExperimentalDiffFileContent, ExperimentalDiffFullFileContents, ExperimentalFileLinkProps, ExperimentalFileLocation, ExperimentalFileOpenOptions, ExperimentalFixedTabTargetContract, ExperimentalFixedTabTargetState, ExperimentalLiveFileTarget, ExperimentalOpenFixedTabOptions, ExperimentalPermissionModePickerProps, ExperimentalPluginFixedTabReference, ExperimentalProviderModelPickerProps, ExperimentalProviderModelPickerRouting, ExperimentalProviderModelPickerValue, ExperimentalSidebarFooter, ExperimentalSidebarFooterActionContext, ExperimentalSidebarFooterActionRegistration, ExperimentalSidebarFooterDisclosureController, ExperimentalSidebarFooterDisclosureProps, ExperimentalSidebarFooterDisclosureRegistration, ExperimentalSidebarFooterItemBase, ExperimentalSidebarFooterItemRegistration, ExperimentalSidebarNavigationAction, ExperimentalSidebarNavigationActivationOptions, ExperimentalSidebarNavigationIcon, ExperimentalSidebarNavigationItem, ExperimentalSidebarNavigationProps, ExperimentalSidebarNavigationRegistration, ExperimentalSidebarNavigationShortcut, JsonValue, MarkdownProps, NewThreadComposerProps, NewThreadRequest, PluginAppBuilder, PluginAppComposer, PluginAppContentScripts, PluginAppDefinition, PluginAppSetup, PluginAppSlots, PluginCodeThemeData, PluginCodeThemeState, PluginCodeThemeTokenRule, PluginCommandPaletteActionContext, PluginCommandPaletteActionRegistration, PluginComposerApi, PluginComposerMention, PluginComposerScope, PluginComposerTextEffect, PluginComposerThreadRowStatus, PluginContentScriptContext, PluginContentScriptDisposer, PluginContentScriptRegistration, PluginDiffRendererProps, PluginDiffRendererRegistration, PluginFileOpenerProps, PluginFileOpenerRegistration, PluginFileOpenerSource, PluginFixedTabDeclaration, PluginFixedTabRegistration, PluginHomepageSectionProps, PluginHomepageSectionRegistration, 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, PluginSidebarWorkspaceKind, PluginSourceCodeRendererProps, PluginSourceCodeRendererRegistration, PluginTargetedPanelActionOpenOptions, PluginThreadHeaderActionProps, PluginThreadHeaderActionRegistration, PluginThreadListProps, PluginThreadListRegistration, PluginThreadPanelActionContext, PluginThreadPanelActionRegistration, PluginThreadPanelProps, PluginTimelineRendererProps, PluginTimelineRendererRegistration, PluginTimelineRendererRow, PluginTimelineRowPresentation, PluginTimelineRowStatus, SourceCodeLineRange, SourceCodeProps, StandardSchemaV1, StandardSchemaV1InferInput, StandardSchemaV1InferOutput, StandardSchemaV1Issue, StandardSchemaV1Result, ThreadChatMessageAction, ThreadChatMessageReference, ThreadChatProps, UrlLinkProps };
|
|
@@ -5,8 +5,37 @@
|
|
|
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 { PluginHomepageSectionRegistration, PluginSettingsSectionRegistration, ExperimentalAppOverlayRegistration, PluginNavPanelRegistration, PluginThreadPanelActionRegistration, PluginNewThreadPanelActionRegistration, ComposerCustomization, PluginPendingInteractionRegistration, PluginSidebarFooterActionRegistration, ExperimentalSidebarNavigationRegistration, PluginThreadListRegistration, PluginThreadHeaderActionRegistration, PluginFileOpenerRegistration, PluginSourceCodeRendererRegistration, PluginDiffRendererRegistration, PluginMessageDirectiveRegistration, PluginMessageActionRegistration, PluginCommandPaletteActionRegistration, PluginProviderIconRegistration, PluginTimelineRendererRegistration, PluginContentScriptRegistration, PluginAppDefinition } from '@get-bb/plugin-sdk';
|
|
8
|
+
import { ExperimentalSidebarFooterActionContext, ExperimentalSidebarFooterItemRegistration, PluginHomepageSectionRegistration, PluginSettingsSectionRegistration, ExperimentalAppOverlayRegistration, PluginNavPanelRegistration, PluginThreadPanelActionRegistration, PluginNewThreadPanelActionRegistration, ComposerCustomization, PluginPendingInteractionRegistration, PluginSidebarFooterActionRegistration, ExperimentalSidebarNavigationRegistration, PluginThreadListRegistration, PluginThreadHeaderActionRegistration, PluginFileOpenerRegistration, PluginSourceCodeRendererRegistration, PluginDiffRendererRegistration, PluginMessageDirectiveRegistration, PluginMessageActionRegistration, PluginCommandPaletteActionRegistration, PluginProviderIconRegistration, PluginTimelineRendererRegistration, PluginContentScriptRegistration, PluginAppDefinition } from '@get-bb/plugin-sdk';
|
|
9
9
|
|
|
10
|
+
type ExperimentalSidebarFooterCommandKind = "close" | "open" | "toggle";
|
|
11
|
+
interface ExperimentalSidebarFooterRuntimeSnapshot {
|
|
12
|
+
command: {
|
|
13
|
+
sequence: number;
|
|
14
|
+
kind: ExperimentalSidebarFooterCommandKind;
|
|
15
|
+
} | null;
|
|
16
|
+
}
|
|
17
|
+
interface ExperimentalSidebarFooterItemRuntime {
|
|
18
|
+
subscribe(listener: () => void): () => void;
|
|
19
|
+
getSnapshot(): ExperimentalSidebarFooterRuntimeSnapshot;
|
|
20
|
+
acknowledgeCommand(sequence: number): void;
|
|
21
|
+
}
|
|
22
|
+
type CollectedExperimentalSidebarFooterItem = ExperimentalSidebarFooterItemRegistration & {
|
|
23
|
+
runtime: ExperimentalSidebarFooterItemRuntime;
|
|
24
|
+
};
|
|
25
|
+
type CollectedManagedSidebarFooterItem = CollectedExperimentalSidebarFooterItem & {
|
|
26
|
+
source: "experimental_sidebarFooter";
|
|
27
|
+
};
|
|
28
|
+
interface CollectedCompatibilitySidebarFooterItem {
|
|
29
|
+
source: "sidebarFooterAction";
|
|
30
|
+
id: string;
|
|
31
|
+
label: string;
|
|
32
|
+
icon: string;
|
|
33
|
+
kind: "action";
|
|
34
|
+
onActivate(context: ExperimentalSidebarFooterActionContext): void | Promise<void>;
|
|
35
|
+
runtime: ExperimentalSidebarFooterItemRuntime;
|
|
36
|
+
}
|
|
37
|
+
type CollectedSidebarFooterItem = CollectedCompatibilitySidebarFooterItem | CollectedManagedSidebarFooterItem;
|
|
38
|
+
declare function adaptSidebarFooterAction(registration: PluginSidebarFooterActionRegistration): CollectedCompatibilitySidebarFooterItem;
|
|
10
39
|
/** Validated registrations produced by one plugin app setup execution. */
|
|
11
40
|
interface CollectedPluginAppRegistrations {
|
|
12
41
|
homepageSections: PluginHomepageSectionRegistration[];
|
|
@@ -18,6 +47,7 @@ interface CollectedPluginAppRegistrations {
|
|
|
18
47
|
composerCustomizations: ComposerCustomization[];
|
|
19
48
|
pendingInteractions: PluginPendingInteractionRegistration[];
|
|
20
49
|
sidebarFooterActions: PluginSidebarFooterActionRegistration[];
|
|
50
|
+
experimentalSidebarFooterItems: CollectedExperimentalSidebarFooterItem[];
|
|
21
51
|
experimentalSidebarNavigations: ExperimentalSidebarNavigationRegistration[];
|
|
22
52
|
threadLists: PluginThreadListRegistration[];
|
|
23
53
|
threadHeaderActions: PluginThreadHeaderActionRegistration[];
|
|
@@ -31,6 +61,7 @@ interface CollectedPluginAppRegistrations {
|
|
|
31
61
|
timelineRenderers: PluginTimelineRendererRegistration[];
|
|
32
62
|
contentScripts: PluginContentScriptRegistration[];
|
|
33
63
|
}
|
|
64
|
+
declare function getCollectedSidebarFooterItems(registrations: object): readonly CollectedSidebarFooterItem[] | null;
|
|
34
65
|
/**
|
|
35
66
|
* Run a plugin app definition against the canonical validating collector.
|
|
36
67
|
* Both the BB app and the public test harness use this implementation so a
|
|
@@ -39,5 +70,5 @@ interface CollectedPluginAppRegistrations {
|
|
|
39
70
|
*/
|
|
40
71
|
declare function collectPluginAppRegistrations(definition: PluginAppDefinition, onComposerCustomizationRejected?: (reason: string) => void): CollectedPluginAppRegistrations;
|
|
41
72
|
|
|
42
|
-
export { collectPluginAppRegistrations };
|
|
43
|
-
export type { CollectedPluginAppRegistrations };
|
|
73
|
+
export { adaptSidebarFooterAction, collectPluginAppRegistrations, getCollectedSidebarFooterItems };
|
|
74
|
+
export type { CollectedCompatibilitySidebarFooterItem, CollectedExperimentalSidebarFooterItem, CollectedManagedSidebarFooterItem, CollectedPluginAppRegistrations, CollectedSidebarFooterItem, ExperimentalSidebarFooterCommandKind, ExperimentalSidebarFooterItemRuntime, ExperimentalSidebarFooterRuntimeSnapshot };
|
|
@@ -7,7 +7,23 @@
|
|
|
7
7
|
|
|
8
8
|
import { ReactNode, ComponentType } from 'react';
|
|
9
9
|
import { RenderResult } from '@testing-library/react';
|
|
10
|
-
import { PluginHomepageSectionRegistration, PluginSettingsSectionRegistration, ExperimentalAppOverlayRegistration, PluginNavPanelRegistration, PluginThreadPanelActionRegistration, PluginNewThreadPanelActionRegistration, ComposerCustomization, PluginPendingInteractionRegistration, PluginSidebarFooterActionRegistration, ExperimentalSidebarNavigationRegistration, PluginThreadListRegistration, PluginThreadHeaderActionRegistration, PluginFileOpenerRegistration, PluginSourceCodeRendererRegistration, PluginDiffRendererRegistration, PluginMessageDirectiveRegistration, PluginMessageActionRegistration, PluginProviderIconRegistration, PluginTimelineRendererRegistration, PluginContentScriptRegistration, PluginComposerScope, PluginComposerTextEffect, PluginComposerMention, PluginComposerThreadRowStatus, ExperimentalOpenFixedTabOptions, JsonValue, BbNavigate, ExperimentalFileOpenOptions, PluginAppDefinition, PluginRpcContract, StandardSchemaV1InferInput, PluginRpcResult, PluginRealtimeConnectionState, PluginSidebarThreadsState, PluginProvidersState, PluginCodeThemeState, PluginSidebarPullRequest, PluginSidebarThreadActions } from '@get-bb/plugin-sdk';
|
|
10
|
+
import { ExperimentalSidebarFooterItemRegistration, PluginHomepageSectionRegistration, PluginSettingsSectionRegistration, ExperimentalAppOverlayRegistration, PluginNavPanelRegistration, PluginThreadPanelActionRegistration, PluginNewThreadPanelActionRegistration, ComposerCustomization, PluginPendingInteractionRegistration, PluginSidebarFooterActionRegistration, ExperimentalSidebarNavigationRegistration, PluginThreadListRegistration, PluginThreadHeaderActionRegistration, PluginFileOpenerRegistration, PluginSourceCodeRendererRegistration, PluginDiffRendererRegistration, PluginMessageDirectiveRegistration, PluginMessageActionRegistration, PluginProviderIconRegistration, PluginTimelineRendererRegistration, PluginContentScriptRegistration, PluginComposerScope, PluginComposerTextEffect, PluginComposerMention, PluginComposerThreadRowStatus, ExperimentalOpenFixedTabOptions, JsonValue, BbNavigate, ExperimentalFileOpenOptions, PluginAppDefinition, PluginRpcContract, StandardSchemaV1InferInput, PluginRpcResult, PluginRealtimeConnectionState, PluginSidebarThreadsState, PluginProvidersState, PluginCodeThemeState, PluginSidebarPullRequest, PluginSidebarThreadActions } from '@get-bb/plugin-sdk';
|
|
11
|
+
|
|
12
|
+
type ExperimentalSidebarFooterCommandKind = "close" | "open" | "toggle";
|
|
13
|
+
interface ExperimentalSidebarFooterRuntimeSnapshot {
|
|
14
|
+
command: {
|
|
15
|
+
sequence: number;
|
|
16
|
+
kind: ExperimentalSidebarFooterCommandKind;
|
|
17
|
+
} | null;
|
|
18
|
+
}
|
|
19
|
+
interface ExperimentalSidebarFooterItemRuntime {
|
|
20
|
+
subscribe(listener: () => void): () => void;
|
|
21
|
+
getSnapshot(): ExperimentalSidebarFooterRuntimeSnapshot;
|
|
22
|
+
acknowledgeCommand(sequence: number): void;
|
|
23
|
+
}
|
|
24
|
+
type CollectedExperimentalSidebarFooterItem = ExperimentalSidebarFooterItemRegistration & {
|
|
25
|
+
runtime: ExperimentalSidebarFooterItemRuntime;
|
|
26
|
+
};
|
|
11
27
|
|
|
12
28
|
/**
|
|
13
29
|
* `@get-bb/plugin-sdk/testing/app` — the frontend plugin test harness. Tests a
|
|
@@ -125,6 +141,7 @@ interface CapturedPluginApp {
|
|
|
125
141
|
composerCustomizations: ComposerCustomization[];
|
|
126
142
|
pendingInteractions: PluginPendingInteractionRegistration[];
|
|
127
143
|
sidebarFooterActions: PluginSidebarFooterActionRegistration[];
|
|
144
|
+
experimentalSidebarFooterItems: CollectedExperimentalSidebarFooterItem[];
|
|
128
145
|
experimentalSidebarNavigations: ExperimentalSidebarNavigationRegistration[];
|
|
129
146
|
threadLists: PluginThreadListRegistration[];
|
|
130
147
|
threadHeaderActions: PluginThreadHeaderActionRegistration[];
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// and read the real source: https://github.com/get-bb/bb
|
|
7
7
|
|
|
8
8
|
import { z } from 'zod';
|
|
9
|
-
import { BbPluginApi, PluginSettingValue as PluginSettingValue$1, PluginSharedPortTunnelIdentity, PluginAgentToolPresentation, PluginAgentToolContext, PluginAgentToolResult, PluginCliCommandInfo, PluginCliContext, PluginCliResult, PluginHttpAuthMode, PluginHttpHandler, PluginMentionTrigger, PluginMentionSearchContext, PluginMentionItem, JsonValue as JsonValue$1, PluginCliExecutionResult, PluginThreadEventName, PluginThreadEventPayloads, PluginAgentConfigurationContext, ExperimentalPluginProviderEnvContext, ExperimentalPluginProviderEnvEntry, ExperimentalPluginProviderEnvHealthContext, ExperimentalPluginProviderEnvHealth, PluginSettingDescriptors, PluginAgentConfiguration, PluginHookName, PluginHookHandler, PluginAiServiceDeclaration, PluginInteractionRequest, MessageDispatchHookContext } from '@get-bb/plugin-sdk';
|
|
9
|
+
import { BbPluginApi, PluginSettingValue as PluginSettingValue$1, PluginSharedPortTunnelIdentity, PluginAgentToolPresentation, PluginAgentToolContext, PluginAgentToolResult, PluginCliCommandInfo, PluginCliContext, PluginCliResult, PluginHttpAuthMode, PluginHttpHandler, PluginMentionTrigger, PluginMentionSearchContext, PluginMentionItem, JsonValue as JsonValue$1, PluginCliExecutionResult, PluginThreadEventName, PluginThreadEventPayloads, PluginAgentConfigurationContext, ExperimentalPluginProviderEnvContext, ExperimentalPluginProviderEnvEntry, ExperimentalPluginProviderEnvHealthContext, ExperimentalPluginProviderEnvHealth, PluginSettingDescriptors, ExperimentalPluginWebSocketHandler, PluginAgentConfiguration, PluginHookName, PluginHookHandler, PluginAiServiceDeclaration, PluginInteractionRequest, MessageDispatchHookContext } from '@get-bb/plugin-sdk';
|
|
10
10
|
|
|
11
11
|
/** Input-form entry: a path, or a path with options. */
|
|
12
12
|
declare const providerNativeRootInputSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
@@ -555,6 +555,22 @@ interface FakeHttpRouteRecord {
|
|
|
555
555
|
auth: PluginHttpAuthMode;
|
|
556
556
|
handler: PluginHttpHandler;
|
|
557
557
|
}
|
|
558
|
+
interface ExperimentalFakeWebSocketRouteRecord {
|
|
559
|
+
path: string;
|
|
560
|
+
auth: PluginHttpAuthMode;
|
|
561
|
+
handler: ExperimentalPluginWebSocketHandler;
|
|
562
|
+
}
|
|
563
|
+
interface ExperimentalFakeWebSocketSession {
|
|
564
|
+
readonly sent: readonly (string | Uint8Array)[];
|
|
565
|
+
readonly closeCalls: readonly {
|
|
566
|
+
code: number | null;
|
|
567
|
+
reason: string | null;
|
|
568
|
+
}[];
|
|
569
|
+
readonly readyState: number;
|
|
570
|
+
receive(data: string | Uint8Array): Promise<void>;
|
|
571
|
+
close(code?: number, reason?: string): Promise<void>;
|
|
572
|
+
error(error: Error): Promise<void>;
|
|
573
|
+
}
|
|
558
574
|
interface FakeScheduleRecord {
|
|
559
575
|
name: string;
|
|
560
576
|
cron: string;
|
|
@@ -618,6 +634,7 @@ interface ExperimentalFakeHostRpcCall {
|
|
|
618
634
|
interface FakePluginRegistrations {
|
|
619
635
|
settingsDescriptors: PluginSettingDescriptors;
|
|
620
636
|
httpRoutes: FakeHttpRouteRecord[];
|
|
637
|
+
websocketRoutes: ExperimentalFakeWebSocketRouteRecord[];
|
|
621
638
|
rpcMethods: string[];
|
|
622
639
|
services: FakeServiceRecord[];
|
|
623
640
|
schedules: FakeScheduleRecord[];
|
|
@@ -707,6 +724,8 @@ interface FakePluginBehaviorDrivers {
|
|
|
707
724
|
* `{ ok: false, error: "plugin route failed: …" }` response.
|
|
708
725
|
*/
|
|
709
726
|
fetchHttp(method: string, path: string, init?: RequestInit): Promise<Response>;
|
|
727
|
+
/** Open and drive an exact-match `bb.http.experimental_websocket` route. */
|
|
728
|
+
experimental_openWebSocket(path: string, init?: RequestInit): Promise<ExperimentalFakeWebSocketSession>;
|
|
710
729
|
/**
|
|
711
730
|
* Start a registered background service once, deterministically. `done`
|
|
712
731
|
* settles when `start` returns; abort `controller` to signal shutdown.
|
|
@@ -312,6 +312,7 @@ declare const experimentsSchema: z$1.ZodRecord<z$1.ZodEnum<{
|
|
|
312
312
|
changelogPreview: "changelogPreview";
|
|
313
313
|
editMessages: "editMessages";
|
|
314
314
|
mobileApp: "mobileApp";
|
|
315
|
+
sidebarProgressiveDisclosure: "sidebarProgressiveDisclosure";
|
|
315
316
|
timelineWindowing: "timelineWindowing";
|
|
316
317
|
}>, z$1.ZodBoolean>;
|
|
317
318
|
type Experiments = z$1.infer<typeof experimentsSchema>;
|
|
@@ -8887,6 +8888,7 @@ declare const systemConfigResponseSchema: z$1.ZodObject<{
|
|
|
8887
8888
|
changelogPreview: "changelogPreview";
|
|
8888
8889
|
editMessages: "editMessages";
|
|
8889
8890
|
mobileApp: "mobileApp";
|
|
8891
|
+
sidebarProgressiveDisclosure: "sidebarProgressiveDisclosure";
|
|
8890
8892
|
timelineWindowing: "timelineWindowing";
|
|
8891
8893
|
}>, z$1.ZodBoolean>;
|
|
8892
8894
|
featureFlags: z$1.ZodObject<{
|
|
@@ -12767,6 +12769,7 @@ declare const threadTimelineResponseSchema: z$1.ZodObject<{
|
|
|
12767
12769
|
}, z$1.core.$strip>>;
|
|
12768
12770
|
workflowName: z$1.ZodNullable<z$1.ZodString>;
|
|
12769
12771
|
}, z$1.core.$strip>>;
|
|
12772
|
+
contextBoundarySeq: z$1.ZodNullable<z$1.ZodNumber>;
|
|
12770
12773
|
contextWindowUsage: z$1.ZodOptional<z$1.ZodObject<{
|
|
12771
12774
|
estimated: z$1.ZodBoolean;
|
|
12772
12775
|
modelContextWindow: z$1.ZodNumber;
|
|
@@ -13297,6 +13300,11 @@ interface PluginPendingInteractionProps {
|
|
|
13297
13300
|
*/
|
|
13298
13301
|
interface PluginSidebarFooterActionProps {
|
|
13299
13302
|
}
|
|
13303
|
+
/** Props passed to an experimental sidebar-footer disclosure component. */
|
|
13304
|
+
interface ExperimentalSidebarFooterDisclosureProps {
|
|
13305
|
+
/** Hide this disclosure without affecting another plugin's open disclosure. */
|
|
13306
|
+
dismiss(): void;
|
|
13307
|
+
}
|
|
13300
13308
|
/** Display and accessibility metadata for a host-owned sidebar shortcut. */
|
|
13301
13309
|
interface ExperimentalSidebarNavigationShortcut {
|
|
13302
13310
|
label: string;
|
|
@@ -13833,6 +13841,46 @@ interface PluginSidebarFooterActionRegistration {
|
|
|
13833
13841
|
*/
|
|
13834
13842
|
run(context: PluginSidebarFooterActionContext): void | Promise<void>;
|
|
13835
13843
|
}
|
|
13844
|
+
/** Context handed to an experimental sidebar-footer action. */
|
|
13845
|
+
interface ExperimentalSidebarFooterActionContext {
|
|
13846
|
+
/** Navigate to this plugin's detail page in Tools. */
|
|
13847
|
+
openPluginDetails(): void;
|
|
13848
|
+
}
|
|
13849
|
+
/** Fields shared by both experimental sidebar-footer item behaviors. */
|
|
13850
|
+
interface ExperimentalSidebarFooterItemBase {
|
|
13851
|
+
/** Unique within the plugin's unified sidebar footer; letters, digits, `-`, `_`. */
|
|
13852
|
+
id: string;
|
|
13853
|
+
/** Tooltip and accessible label for the host-rendered icon button. */
|
|
13854
|
+
label: string;
|
|
13855
|
+
/** BB icon-name hint; unknown names fall back to a generic icon. */
|
|
13856
|
+
icon: string;
|
|
13857
|
+
}
|
|
13858
|
+
/** A sidebar-footer item that runs a callback when activated. */
|
|
13859
|
+
interface ExperimentalSidebarFooterActionRegistration extends ExperimentalSidebarFooterItemBase {
|
|
13860
|
+
kind: "action";
|
|
13861
|
+
onActivate(context: ExperimentalSidebarFooterActionContext): void | Promise<void>;
|
|
13862
|
+
}
|
|
13863
|
+
/** A sidebar-footer item that reveals plugin-rendered content above the row. */
|
|
13864
|
+
interface ExperimentalSidebarFooterDisclosureRegistration extends ExperimentalSidebarFooterItemBase {
|
|
13865
|
+
kind: "disclosure";
|
|
13866
|
+
component: ComponentType<ExperimentalSidebarFooterDisclosureProps>;
|
|
13867
|
+
}
|
|
13868
|
+
/** One host-rendered item in the app sidebar footer. */
|
|
13869
|
+
type ExperimentalSidebarFooterItemRegistration = ExperimentalSidebarFooterActionRegistration | ExperimentalSidebarFooterDisclosureRegistration;
|
|
13870
|
+
/** Live controls for an experimental sidebar-footer disclosure. */
|
|
13871
|
+
interface ExperimentalSidebarFooterDisclosureController {
|
|
13872
|
+
/** Request that the host open this disclosure, replacing any open sibling. */
|
|
13873
|
+
open(): void;
|
|
13874
|
+
/** Close this disclosure if it is currently open. */
|
|
13875
|
+
close(): void;
|
|
13876
|
+
/** Open this disclosure, or close it when it is currently open. */
|
|
13877
|
+
toggle(): void;
|
|
13878
|
+
}
|
|
13879
|
+
/** Managed registration surface for items in the app sidebar footer. */
|
|
13880
|
+
interface ExperimentalSidebarFooter {
|
|
13881
|
+
register(registration: ExperimentalSidebarFooterActionRegistration): void;
|
|
13882
|
+
register(registration: ExperimentalSidebarFooterDisclosureRegistration): ExperimentalSidebarFooterDisclosureController;
|
|
13883
|
+
}
|
|
13836
13884
|
/**
|
|
13837
13885
|
* The one status bb would paint for a thread, already resolved through the
|
|
13838
13886
|
* host's precedence (attention before work; plan and goal before the generic
|
|
@@ -14555,6 +14603,8 @@ interface PluginAppBuilder {
|
|
|
14555
14603
|
slots: PluginAppSlots;
|
|
14556
14604
|
composer: PluginAppComposer;
|
|
14557
14605
|
contentScripts: PluginAppContentScripts;
|
|
14606
|
+
/** Experimental managed region for actions and disclosures in the sidebar footer. */
|
|
14607
|
+
experimental_sidebarFooter: ExperimentalSidebarFooter;
|
|
14558
14608
|
}
|
|
14559
14609
|
type PluginAppSetup = (app: PluginAppBuilder) => void;
|
|
14560
14610
|
/**
|
|
@@ -16550,6 +16600,7 @@ interface ThreadsArea {
|
|
|
16550
16600
|
childSummary(args: ThreadStatusArgs): Promise<ThreadChildSummaryResult>;
|
|
16551
16601
|
compact(args: ThreadActionArgs): Promise<ThreadCompactResult>;
|
|
16552
16602
|
cancelPlan(args: ThreadActionArgs): Promise<ThreadBannerActionResult>;
|
|
16603
|
+
clearContext(args: ThreadActionArgs): Promise<ThreadBannerActionResult>;
|
|
16553
16604
|
clearGoal(args: ThreadActionArgs): Promise<ThreadBannerActionResult>;
|
|
16554
16605
|
conversationOutline(args: ThreadStatusArgs): Promise<ThreadConversationOutlineResult>;
|
|
16555
16606
|
count(args?: ThreadCountArgs): Promise<ThreadCountResult>;
|
|
@@ -17189,6 +17240,26 @@ interface PluginHooks {
|
|
|
17189
17240
|
}
|
|
17190
17241
|
type PluginHttpAuthMode = "local" | "none" | "token";
|
|
17191
17242
|
type PluginHttpHandler = (context: Context) => Response | Promise<Response>;
|
|
17243
|
+
interface ExperimentalPluginWebSocket {
|
|
17244
|
+
send(data: string | Uint8Array): void;
|
|
17245
|
+
close(code?: number, reason?: string): void;
|
|
17246
|
+
readonly readyState: number;
|
|
17247
|
+
}
|
|
17248
|
+
interface ExperimentalPluginWebSocketContext {
|
|
17249
|
+
request: Request;
|
|
17250
|
+
url: URL;
|
|
17251
|
+
headers: Headers;
|
|
17252
|
+
}
|
|
17253
|
+
interface ExperimentalPluginWebSocketHandlers {
|
|
17254
|
+
onOpen?(socket: ExperimentalPluginWebSocket): void | Promise<void>;
|
|
17255
|
+
onMessage?(socket: ExperimentalPluginWebSocket, data: string | Uint8Array): void | Promise<void>;
|
|
17256
|
+
onClose?(socket: ExperimentalPluginWebSocket, event: {
|
|
17257
|
+
code: number;
|
|
17258
|
+
reason: string;
|
|
17259
|
+
}): void | Promise<void>;
|
|
17260
|
+
onError?(socket: ExperimentalPluginWebSocket, error: Error): void;
|
|
17261
|
+
}
|
|
17262
|
+
type ExperimentalPluginWebSocketHandler = (context: ExperimentalPluginWebSocketContext) => ExperimentalPluginWebSocketHandlers;
|
|
17192
17263
|
interface PluginHttp {
|
|
17193
17264
|
/**
|
|
17194
17265
|
* Register an HTTP route, mounted at
|
|
@@ -17202,6 +17273,14 @@ interface PluginHttp {
|
|
|
17202
17273
|
route(method: string, path: string, handler: PluginHttpHandler, opts?: {
|
|
17203
17274
|
auth?: PluginHttpAuthMode;
|
|
17204
17275
|
}): void;
|
|
17276
|
+
/**
|
|
17277
|
+
* Register a WebSocket route in the same `/http/` namespace as `route`.
|
|
17278
|
+
* A GET request upgrades only when it carries `Upgrade: websocket`.
|
|
17279
|
+
* Auth modes and exact-path matching are identical to HTTP routes.
|
|
17280
|
+
*/
|
|
17281
|
+
experimental_websocket(path: string, handler: ExperimentalPluginWebSocketHandler, opts?: {
|
|
17282
|
+
auth?: PluginHttpAuthMode;
|
|
17283
|
+
}): void;
|
|
17205
17284
|
}
|
|
17206
17285
|
interface PluginRpc {
|
|
17207
17286
|
/**
|
|
@@ -18158,4 +18237,4 @@ interface BbPluginApi {
|
|
|
18158
18237
|
}
|
|
18159
18238
|
|
|
18160
18239
|
export { PLUGIN_CLI_OUTPUT_MAX_BYTES, defineRpcContract, experimental_defineHostEntry };
|
|
18161
|
-
export type { BbContext, BbNavigate, BbPluginApi, CodeOverflowMode, ComposerCustomization, ComposerPlusMenuItem, ComposerRichTextSpec, ComposerStructuredDraft, ComposerView, DiffProps, DiffViewMode, ExperimentalAppOverlayProps, ExperimentalAppOverlayRegistration, ExperimentalAppPanel, ExperimentalAppPanelSurface, ExperimentalComposerSubmitOptions, ExperimentalDiffFileContent, ExperimentalDiffFullFileContents, ExperimentalFileLinkProps, ExperimentalFileLocation, ExperimentalFileOpenOptions, ExperimentalFixedTabTargetContract, ExperimentalFixedTabTargetState, ExperimentalHostCallOptions, ExperimentalHostClient, ExperimentalHostEntry, ExperimentalHostPaths, ExperimentalHostRpcContext, ExperimentalHostRpcHandlers, ExperimentalHostSignalContract, ExperimentalHostSignalEvent, ExperimentalHostSignals, ExperimentalHostWatchChange, ExperimentalHostWatchChangeType, ExperimentalHostWatchEvent, ExperimentalHostWatchListener, ExperimentalHostWatchOptions, ExperimentalHostWatchSubscription, ExperimentalHostWorkerLease, ExperimentalLiveFileTarget, ExperimentalOpenFixedTabOptions, ExperimentalPermissionModePickerProps, ExperimentalPluginFixedTabReference, ExperimentalPluginProviderEnvContext, ExperimentalPluginProviderEnvEntry, ExperimentalPluginProviderEnvHealth, ExperimentalPluginProviderEnvHealthContext, ExperimentalProviderModelPickerProps, ExperimentalProviderModelPickerRouting, ExperimentalProviderModelPickerValue, ExperimentalSidebarNavigationAction, ExperimentalSidebarNavigationActivationOptions, ExperimentalSidebarNavigationIcon, ExperimentalSidebarNavigationItem, ExperimentalSidebarNavigationProps, ExperimentalSidebarNavigationRegistration, ExperimentalSidebarNavigationShortcut, JsonValue, MarkdownProps, MessageDispatchHookContext, MessageDispatchHookDecision, NewThreadComposerProps, NewThreadRequest, PluginAgentConfiguration, PluginAgentConfigurationContext, PluginAgentToolContentPart, PluginAgentToolContext, PluginAgentToolLabels, PluginAgentToolPresentation, PluginAgentToolRegistrationBase, PluginAgentToolResult, PluginAgentToolSelection, PluginAgents, PluginAiServiceDeclaration, PluginAiServiceKind, PluginAiServices, PluginAppBuilder, PluginAppComposer, PluginAppContentScripts, PluginAppDefinition, PluginAppSetup, PluginAppSlots, PluginBackground, PluginCli, PluginCliCommandInfo, PluginCliContext, PluginCliExecutionResult, PluginCliOutputLimitError, PluginCliRegistration, PluginCliResult, PluginCodeThemeData, PluginCodeThemeState, PluginCodeThemeTokenRule, PluginCommandPaletteActionContext, PluginCommandPaletteActionRegistration, PluginComposerApi, PluginComposerMention, PluginComposerScope, PluginComposerTextEffect, PluginComposerThreadRowStatus, PluginContentScriptContext, PluginContentScriptDisposer, PluginContentScriptRegistration, PluginDiffRendererProps, PluginDiffRendererRegistration, PluginDispatchAttemptKind, PluginDispatchExecution, PluginDispatchExecutionSources, PluginDispatchInput, PluginEvents, PluginFileOpenerProps, PluginFileOpenerRegistration, PluginFileOpenerSource, PluginFixedTabDeclaration, PluginFixedTabRegistration, PluginHomepageSectionProps, PluginHomepageSectionRegistration, PluginHookHandler, PluginHookName, PluginHookSignatures, PluginHooks, PluginHosts, PluginHttp, PluginHttpAuthMode, PluginHttpHandler, PluginInteractionCancelReason, PluginInteractionRequest, PluginInteractionResult, PluginKvStorage, PluginLogger, PluginMentionItem, PluginMentionProviderRegistration, PluginMentionSearchContext, PluginMentionTrigger, PluginMessageActionContext, PluginMessageActionRegistration, PluginMessageDirectiveMessage, PluginMessageDirectiveOpenWorkspaceFile, PluginMessageDirectiveProps, PluginMessageDirectiveRegistration, PluginNavPanelProps, PluginNavPanelRegistration, PluginNewThreadPanelActionContext, PluginNewThreadPanelActionRegistration, PluginNewThreadPanelProps, PluginPanelActionOpenOptions, PluginPendingInteractionProps, PluginPendingInteractionRegistration, PluginPendingInteractionView, PluginProviderCapabilities, PluginProviderComposerAction, PluginProviderDeclaration, PluginProviderExtensionKindDeclaration, PluginProviderFallbackModel, PluginProviderIconRegistration, PluginProviderMaintenance, PluginProviderModelCatalogScope, PluginProviderNativeRootEntry, PluginProviderNativeRoots, PluginProviderOptionDescriptor, PluginProviderOptionsContext, PluginProviderPermissionMode, PluginProviderReasoningLevel, PluginProviderStrings, PluginProviders, PluginProvidersState, PluginRealtime, PluginRealtimeConnectionState, PluginRpc, PluginRpcCallArgs, PluginRpcClient, PluginRpcContract, PluginRpcError, PluginRpcErrorCode, PluginRpcHandlers, PluginRpcIssuePathSegment, PluginRpcMethodContract, PluginRpcResult, PluginRpcValidationIssue, PluginSdkApp, PluginServerApi, PluginSettingDescriptor, PluginSettingDescriptors, PluginSettingValue, PluginSettings, PluginSettingsHandle, PluginSettingsSectionProps, PluginSettingsSectionRegistration, PluginSettingsState, PluginSettingsValues, PluginSharedPortTunnelIdentity, PluginSidebarFooterActionContext, PluginSidebarFooterActionProps, PluginSidebarFooterActionRegistration, PluginSidebarProject, PluginSidebarPullRequest, PluginSidebarSplitPane, PluginSidebarThread, PluginSidebarThreadActions, PluginSidebarThreadActivity, PluginSidebarThreadIndicator, PluginSidebarThreadPullRequestState, PluginSidebarThreadSplit, PluginSidebarThreadsState, PluginSidebarWorkspaceKind, PluginSourceCodeRendererProps, PluginSourceCodeRendererRegistration, PluginStatusApi, PluginStorage, PluginTargetedPanelActionOpenOptions, PluginThreadEventHandler, PluginThreadEventName, PluginThreadEventPayloads, PluginThreadHeaderActionProps, PluginThreadHeaderActionRegistration, PluginThreadListProps, PluginThreadListRegistration, PluginThreadPanelActionContext, PluginThreadPanelActionRegistration, PluginThreadPanelProps, PluginTimelineRendererProps, PluginTimelineRendererRegistration, PluginTimelineRendererRow, PluginTimelineRowPresentation, PluginTimelineRowStatus, PluginTurnFailedEvent, PluginUi, SourceCodeLineRange, SourceCodeProps, StandardSchemaV1, StandardSchemaV1InferInput, StandardSchemaV1InferOutput, StandardSchemaV1Issue, StandardSchemaV1Result, ThreadChatMessageAction, ThreadChatMessageReference, ThreadChatProps, UrlLinkProps };
|
|
18240
|
+
export type { BbContext, BbNavigate, BbPluginApi, CodeOverflowMode, ComposerCustomization, ComposerPlusMenuItem, ComposerRichTextSpec, ComposerStructuredDraft, ComposerView, DiffProps, DiffViewMode, ExperimentalAppOverlayProps, ExperimentalAppOverlayRegistration, ExperimentalAppPanel, ExperimentalAppPanelSurface, ExperimentalComposerSubmitOptions, ExperimentalDiffFileContent, ExperimentalDiffFullFileContents, ExperimentalFileLinkProps, ExperimentalFileLocation, ExperimentalFileOpenOptions, ExperimentalFixedTabTargetContract, ExperimentalFixedTabTargetState, ExperimentalHostCallOptions, ExperimentalHostClient, ExperimentalHostEntry, ExperimentalHostPaths, ExperimentalHostRpcContext, ExperimentalHostRpcHandlers, ExperimentalHostSignalContract, ExperimentalHostSignalEvent, ExperimentalHostSignals, ExperimentalHostWatchChange, ExperimentalHostWatchChangeType, ExperimentalHostWatchEvent, ExperimentalHostWatchListener, ExperimentalHostWatchOptions, ExperimentalHostWatchSubscription, ExperimentalHostWorkerLease, ExperimentalLiveFileTarget, ExperimentalOpenFixedTabOptions, ExperimentalPermissionModePickerProps, ExperimentalPluginFixedTabReference, ExperimentalPluginProviderEnvContext, ExperimentalPluginProviderEnvEntry, ExperimentalPluginProviderEnvHealth, ExperimentalPluginProviderEnvHealthContext, ExperimentalPluginWebSocket, ExperimentalPluginWebSocketContext, ExperimentalPluginWebSocketHandler, ExperimentalPluginWebSocketHandlers, ExperimentalProviderModelPickerProps, ExperimentalProviderModelPickerRouting, ExperimentalProviderModelPickerValue, ExperimentalSidebarFooter, ExperimentalSidebarFooterActionContext, ExperimentalSidebarFooterActionRegistration, ExperimentalSidebarFooterDisclosureController, ExperimentalSidebarFooterDisclosureProps, ExperimentalSidebarFooterDisclosureRegistration, ExperimentalSidebarFooterItemBase, ExperimentalSidebarFooterItemRegistration, ExperimentalSidebarNavigationAction, ExperimentalSidebarNavigationActivationOptions, ExperimentalSidebarNavigationIcon, ExperimentalSidebarNavigationItem, ExperimentalSidebarNavigationProps, ExperimentalSidebarNavigationRegistration, ExperimentalSidebarNavigationShortcut, JsonValue, MarkdownProps, MessageDispatchHookContext, MessageDispatchHookDecision, NewThreadComposerProps, NewThreadRequest, PluginAgentConfiguration, PluginAgentConfigurationContext, PluginAgentToolContentPart, PluginAgentToolContext, PluginAgentToolLabels, PluginAgentToolPresentation, PluginAgentToolRegistrationBase, PluginAgentToolResult, PluginAgentToolSelection, PluginAgents, PluginAiServiceDeclaration, PluginAiServiceKind, PluginAiServices, PluginAppBuilder, PluginAppComposer, PluginAppContentScripts, PluginAppDefinition, PluginAppSetup, PluginAppSlots, PluginBackground, PluginCli, PluginCliCommandInfo, PluginCliContext, PluginCliExecutionResult, PluginCliOutputLimitError, PluginCliRegistration, PluginCliResult, PluginCodeThemeData, PluginCodeThemeState, PluginCodeThemeTokenRule, PluginCommandPaletteActionContext, PluginCommandPaletteActionRegistration, PluginComposerApi, PluginComposerMention, PluginComposerScope, PluginComposerTextEffect, PluginComposerThreadRowStatus, PluginContentScriptContext, PluginContentScriptDisposer, PluginContentScriptRegistration, PluginDiffRendererProps, PluginDiffRendererRegistration, PluginDispatchAttemptKind, PluginDispatchExecution, PluginDispatchExecutionSources, PluginDispatchInput, PluginEvents, PluginFileOpenerProps, PluginFileOpenerRegistration, PluginFileOpenerSource, PluginFixedTabDeclaration, PluginFixedTabRegistration, PluginHomepageSectionProps, PluginHomepageSectionRegistration, PluginHookHandler, PluginHookName, PluginHookSignatures, PluginHooks, PluginHosts, PluginHttp, PluginHttpAuthMode, PluginHttpHandler, PluginInteractionCancelReason, PluginInteractionRequest, PluginInteractionResult, PluginKvStorage, PluginLogger, PluginMentionItem, PluginMentionProviderRegistration, PluginMentionSearchContext, PluginMentionTrigger, PluginMessageActionContext, PluginMessageActionRegistration, PluginMessageDirectiveMessage, PluginMessageDirectiveOpenWorkspaceFile, PluginMessageDirectiveProps, PluginMessageDirectiveRegistration, PluginNavPanelProps, PluginNavPanelRegistration, PluginNewThreadPanelActionContext, PluginNewThreadPanelActionRegistration, PluginNewThreadPanelProps, PluginPanelActionOpenOptions, PluginPendingInteractionProps, PluginPendingInteractionRegistration, PluginPendingInteractionView, PluginProviderCapabilities, PluginProviderComposerAction, PluginProviderDeclaration, PluginProviderExtensionKindDeclaration, PluginProviderFallbackModel, PluginProviderIconRegistration, PluginProviderMaintenance, PluginProviderModelCatalogScope, PluginProviderNativeRootEntry, PluginProviderNativeRoots, PluginProviderOptionDescriptor, PluginProviderOptionsContext, PluginProviderPermissionMode, PluginProviderReasoningLevel, PluginProviderStrings, PluginProviders, PluginProvidersState, PluginRealtime, PluginRealtimeConnectionState, PluginRpc, PluginRpcCallArgs, PluginRpcClient, PluginRpcContract, PluginRpcError, PluginRpcErrorCode, PluginRpcHandlers, PluginRpcIssuePathSegment, PluginRpcMethodContract, PluginRpcResult, PluginRpcValidationIssue, PluginSdkApp, PluginServerApi, PluginSettingDescriptor, PluginSettingDescriptors, PluginSettingValue, PluginSettings, PluginSettingsHandle, PluginSettingsSectionProps, PluginSettingsSectionRegistration, PluginSettingsState, PluginSettingsValues, PluginSharedPortTunnelIdentity, PluginSidebarFooterActionContext, PluginSidebarFooterActionProps, PluginSidebarFooterActionRegistration, PluginSidebarProject, PluginSidebarPullRequest, PluginSidebarSplitPane, PluginSidebarThread, PluginSidebarThreadActions, PluginSidebarThreadActivity, PluginSidebarThreadIndicator, PluginSidebarThreadPullRequestState, PluginSidebarThreadSplit, PluginSidebarThreadsState, PluginSidebarWorkspaceKind, PluginSourceCodeRendererProps, PluginSourceCodeRendererRegistration, PluginStatusApi, PluginStorage, PluginTargetedPanelActionOpenOptions, PluginThreadEventHandler, PluginThreadEventName, PluginThreadEventPayloads, PluginThreadHeaderActionProps, PluginThreadHeaderActionRegistration, PluginThreadListProps, PluginThreadListRegistration, PluginThreadPanelActionContext, PluginThreadPanelActionRegistration, PluginThreadPanelProps, PluginTimelineRendererProps, PluginTimelineRendererRegistration, PluginTimelineRendererRow, PluginTimelineRowPresentation, PluginTimelineRowStatus, PluginTurnFailedEvent, PluginUi, SourceCodeLineRange, SourceCodeProps, StandardSchemaV1, StandardSchemaV1InferInput, StandardSchemaV1InferOutput, StandardSchemaV1Issue, StandardSchemaV1Result, ThreadChatMessageAction, ThreadChatMessageReference, ThreadChatProps, UrlLinkProps };
|
|
@@ -213,6 +213,127 @@ function collectComposerCustomization(registration, seenIds, onRejected) {
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
// src/internal/plugin-app-collector.ts
|
|
216
|
+
var sidebarFooterCommandSequence = 0;
|
|
217
|
+
var SIDEBAR_FOOTER_ACTION_KEYS = /* @__PURE__ */ new Set([
|
|
218
|
+
"id",
|
|
219
|
+
"label",
|
|
220
|
+
"icon",
|
|
221
|
+
"kind",
|
|
222
|
+
"onActivate"
|
|
223
|
+
]);
|
|
224
|
+
var SIDEBAR_FOOTER_DISCLOSURE_KEYS = /* @__PURE__ */ new Set([
|
|
225
|
+
"id",
|
|
226
|
+
"label",
|
|
227
|
+
"icon",
|
|
228
|
+
"kind",
|
|
229
|
+
"component"
|
|
230
|
+
]);
|
|
231
|
+
var SidebarFooterItemRuntime = class {
|
|
232
|
+
listeners = /* @__PURE__ */ new Set();
|
|
233
|
+
snapshot = {
|
|
234
|
+
command: null
|
|
235
|
+
};
|
|
236
|
+
subscribe = (listener) => {
|
|
237
|
+
this.listeners.add(listener);
|
|
238
|
+
return () => this.listeners.delete(listener);
|
|
239
|
+
};
|
|
240
|
+
getSnapshot = () => this.snapshot;
|
|
241
|
+
acknowledgeCommand = (sequence) => {
|
|
242
|
+
if (this.snapshot.command?.sequence !== sequence) return;
|
|
243
|
+
this.snapshot = { ...this.snapshot, command: null };
|
|
244
|
+
this.emit();
|
|
245
|
+
};
|
|
246
|
+
createDisclosureController() {
|
|
247
|
+
return Object.freeze({
|
|
248
|
+
open: () => this.request("open"),
|
|
249
|
+
close: () => this.request("close"),
|
|
250
|
+
toggle: () => this.request("toggle")
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
request(kind) {
|
|
254
|
+
sidebarFooterCommandSequence += 1;
|
|
255
|
+
this.snapshot = {
|
|
256
|
+
...this.snapshot,
|
|
257
|
+
command: { sequence: sidebarFooterCommandSequence, kind }
|
|
258
|
+
};
|
|
259
|
+
this.emit();
|
|
260
|
+
}
|
|
261
|
+
emit() {
|
|
262
|
+
for (const listener of this.listeners) listener();
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
function adaptSidebarFooterAction(registration) {
|
|
266
|
+
return {
|
|
267
|
+
source: "sidebarFooterAction",
|
|
268
|
+
id: registration.id,
|
|
269
|
+
label: registration.title,
|
|
270
|
+
icon: registration.icon,
|
|
271
|
+
kind: "action",
|
|
272
|
+
onActivate: ({ openPluginDetails }) => registration.run({ openSettings: openPluginDetails }),
|
|
273
|
+
runtime: new SidebarFooterItemRuntime()
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
var SidebarFooterCollector = class {
|
|
277
|
+
constructor(collected, allCollected, seenIds) {
|
|
278
|
+
this.collected = collected;
|
|
279
|
+
this.allCollected = allCollected;
|
|
280
|
+
this.seenIds = seenIds;
|
|
281
|
+
}
|
|
282
|
+
collected;
|
|
283
|
+
allCollected;
|
|
284
|
+
seenIds;
|
|
285
|
+
register(registration) {
|
|
286
|
+
const kind = "experimental_sidebarFooter.register";
|
|
287
|
+
const id = requireSlotId(kind, registration?.id);
|
|
288
|
+
requireUniqueId(kind, this.seenIds, id);
|
|
289
|
+
const label = requireNonEmptyString(kind, "label", registration.label);
|
|
290
|
+
const icon = requireNonEmptyString(kind, "icon", registration.icon);
|
|
291
|
+
const runtime = new SidebarFooterItemRuntime();
|
|
292
|
+
if (registration.kind === "action") {
|
|
293
|
+
this.rejectUnknownKeys(kind, registration, SIDEBAR_FOOTER_ACTION_KEYS);
|
|
294
|
+
if (typeof registration.onActivate !== "function") {
|
|
295
|
+
throw new Error(`${kind}: "onActivate" must be a function`);
|
|
296
|
+
}
|
|
297
|
+
const item = {
|
|
298
|
+
id,
|
|
299
|
+
label,
|
|
300
|
+
icon,
|
|
301
|
+
kind: "action",
|
|
302
|
+
onActivate: registration.onActivate,
|
|
303
|
+
source: "experimental_sidebarFooter",
|
|
304
|
+
runtime
|
|
305
|
+
};
|
|
306
|
+
this.collected.push(item);
|
|
307
|
+
this.allCollected.push(item);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (registration.kind === "disclosure") {
|
|
311
|
+
this.rejectUnknownKeys(
|
|
312
|
+
kind,
|
|
313
|
+
registration,
|
|
314
|
+
SIDEBAR_FOOTER_DISCLOSURE_KEYS
|
|
315
|
+
);
|
|
316
|
+
const item = {
|
|
317
|
+
id,
|
|
318
|
+
label,
|
|
319
|
+
icon,
|
|
320
|
+
kind: "disclosure",
|
|
321
|
+
component: requireComponent(kind, registration.component),
|
|
322
|
+
source: "experimental_sidebarFooter",
|
|
323
|
+
runtime
|
|
324
|
+
};
|
|
325
|
+
this.collected.push(item);
|
|
326
|
+
this.allCollected.push(item);
|
|
327
|
+
return runtime.createDisclosureController();
|
|
328
|
+
}
|
|
329
|
+
throw new Error(`${kind}: "kind" must be "action" or "disclosure"`);
|
|
330
|
+
}
|
|
331
|
+
rejectUnknownKeys(kind, registration, allowed) {
|
|
332
|
+
for (const key of Object.keys(registration)) {
|
|
333
|
+
if (!allowed.has(key)) throw new Error(`${kind}: unknown field "${key}"`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
};
|
|
216
337
|
var NAV_PANEL_REGISTRATION_KEYS = new Set(
|
|
217
338
|
Object.keys({
|
|
218
339
|
id: true,
|
|
@@ -242,7 +363,12 @@ function rejectStaleNavPanelKeys(kind, registration) {
|
|
|
242
363
|
}
|
|
243
364
|
}
|
|
244
365
|
}
|
|
366
|
+
var sidebarFooterItemsByRegistrationSet = /* @__PURE__ */ new WeakMap();
|
|
367
|
+
function getCollectedSidebarFooterItems(registrations) {
|
|
368
|
+
return sidebarFooterItemsByRegistrationSet.get(registrations) ?? null;
|
|
369
|
+
}
|
|
245
370
|
function collectPluginAppRegistrations(definition, onComposerCustomizationRejected = (reason) => console.warn(reason)) {
|
|
371
|
+
const sidebarFooterItems = [];
|
|
246
372
|
const collected = {
|
|
247
373
|
homepageSections: [],
|
|
248
374
|
settingsSections: [],
|
|
@@ -253,6 +379,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
253
379
|
composerCustomizations: [],
|
|
254
380
|
pendingInteractions: [],
|
|
255
381
|
sidebarFooterActions: [],
|
|
382
|
+
experimentalSidebarFooterItems: [],
|
|
256
383
|
experimentalSidebarNavigations: [],
|
|
257
384
|
threadLists: [],
|
|
258
385
|
threadHeaderActions: [],
|
|
@@ -266,6 +393,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
266
393
|
timelineRenderers: [],
|
|
267
394
|
contentScripts: []
|
|
268
395
|
};
|
|
396
|
+
sidebarFooterItemsByRegistrationSet.set(collected, sidebarFooterItems);
|
|
269
397
|
const seenIds = {
|
|
270
398
|
homepageSection: /* @__PURE__ */ new Set(),
|
|
271
399
|
settingsSection: /* @__PURE__ */ new Set(),
|
|
@@ -275,7 +403,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
275
403
|
newThreadPanelAction: /* @__PURE__ */ new Set(),
|
|
276
404
|
composerCustomization: /* @__PURE__ */ new Set(),
|
|
277
405
|
pendingInteraction: /* @__PURE__ */ new Set(),
|
|
278
|
-
|
|
406
|
+
sidebarFooterItem: /* @__PURE__ */ new Set(),
|
|
279
407
|
sidebarNavigation: /* @__PURE__ */ new Set(),
|
|
280
408
|
threadList: /* @__PURE__ */ new Set(),
|
|
281
409
|
threadHeaderAction: /* @__PURE__ */ new Set(),
|
|
@@ -466,16 +594,18 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
466
594
|
sidebarFooterAction(registration) {
|
|
467
595
|
const kind = "slots.sidebarFooterAction";
|
|
468
596
|
const id = requireSlotId(kind, registration?.id);
|
|
469
|
-
requireUniqueId(kind, seenIds.
|
|
597
|
+
requireUniqueId(kind, seenIds.sidebarFooterItem, id);
|
|
470
598
|
if (typeof registration.run !== "function") {
|
|
471
599
|
throw new Error(`${kind}: "run" must be a function`);
|
|
472
600
|
}
|
|
473
|
-
|
|
601
|
+
const legacyRegistration = {
|
|
474
602
|
id,
|
|
475
603
|
title: requireNonEmptyString(kind, "title", registration.title),
|
|
476
604
|
icon: requireNonEmptyString(kind, "icon", registration.icon),
|
|
477
605
|
run: registration.run
|
|
478
|
-
}
|
|
606
|
+
};
|
|
607
|
+
collected.sidebarFooterActions.push(legacyRegistration);
|
|
608
|
+
sidebarFooterItems.push(adaptSidebarFooterAction(legacyRegistration));
|
|
479
609
|
},
|
|
480
610
|
experimental_sidebarNavigation(registration) {
|
|
481
611
|
const kind = "slots.experimental_sidebarNavigation";
|
|
@@ -637,6 +767,11 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
637
767
|
});
|
|
638
768
|
}
|
|
639
769
|
},
|
|
770
|
+
experimental_sidebarFooter: new SidebarFooterCollector(
|
|
771
|
+
collected.experimentalSidebarFooterItems,
|
|
772
|
+
sidebarFooterItems,
|
|
773
|
+
seenIds.sidebarFooterItem
|
|
774
|
+
),
|
|
640
775
|
composer: {
|
|
641
776
|
customize(registration) {
|
|
642
777
|
const customization = collectComposerCustomization(
|
|
@@ -664,5 +799,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
664
799
|
return collected;
|
|
665
800
|
}
|
|
666
801
|
export {
|
|
667
|
-
|
|
802
|
+
adaptSidebarFooterAction,
|
|
803
|
+
collectPluginAppRegistrations,
|
|
804
|
+
getCollectedSidebarFooterItems
|
|
668
805
|
};
|
|
@@ -189,11 +189,11 @@ var promptInputSchema = z2.discriminatedUnion("type", [
|
|
|
189
189
|
function isSelectedPromptCommandMention(mention, selector) {
|
|
190
190
|
return mention.resource.kind === "command" && mention.resource.trigger === selector.trigger && mention.resource.name === selector.name;
|
|
191
191
|
}
|
|
192
|
-
|
|
193
|
-
|
|
192
|
+
function isStandaloneBuiltinCommand(input, name) {
|
|
193
|
+
const selector = { trigger: "/", name };
|
|
194
194
|
const selected = input.flatMap(
|
|
195
195
|
(item) => item.type === "text" ? item.mentions.filter(
|
|
196
|
-
(mention2) => isSelectedPromptCommandMention(mention2,
|
|
196
|
+
(mention2) => isSelectedPromptCommandMention(mention2, selector)
|
|
197
197
|
).map((mention2) => ({ mention: mention2, text: item.text })) : []
|
|
198
198
|
);
|
|
199
199
|
const standalone = selected[0];
|
|
@@ -201,13 +201,15 @@ function isStandaloneBuiltinCompactCommand(input) {
|
|
|
201
201
|
return false;
|
|
202
202
|
}
|
|
203
203
|
const { mention, text } = standalone;
|
|
204
|
-
if (mention.resource.kind !== "command" || mention.resource.source !== "command" || mention.resource.origin !== "builtin" || text.slice(mention.start, mention.end) !==
|
|
204
|
+
if (mention.resource.kind !== "command" || mention.resource.source !== "command" || mention.resource.origin !== "builtin" || text.slice(mention.start, mention.end) !== `/${name}`) {
|
|
205
205
|
return false;
|
|
206
206
|
}
|
|
207
|
-
return removeCommandMentionsFromPromptInput(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
return removeCommandMentionsFromPromptInput(input, selector).every(
|
|
208
|
+
(item) => item.type === "text" && item.text.trim() === ""
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
function isStandaloneBuiltinCompactCommand(input) {
|
|
212
|
+
return isStandaloneBuiltinCommand(input, "compact");
|
|
211
213
|
}
|
|
212
214
|
function commandRemovalRanges(input, selector) {
|
|
213
215
|
return input.mentions.filter((mention) => isSelectedPromptCommandMention(mention, selector)).map((mention) => ({
|
|
@@ -6404,15 +6404,6 @@ function isRequest(message) {
|
|
|
6404
6404
|
function isResponse(message) {
|
|
6405
6405
|
return message.id !== void 0 && message.method === void 0;
|
|
6406
6406
|
}
|
|
6407
|
-
function countTurnBoundaries(events) {
|
|
6408
|
-
let started = 0;
|
|
6409
|
-
let completed = 0;
|
|
6410
|
-
for (const event of events) {
|
|
6411
|
-
if (event.type === "turn/started") started += 1;
|
|
6412
|
-
if (event.type === "turn/completed") completed += 1;
|
|
6413
|
-
}
|
|
6414
|
-
return { started, completed };
|
|
6415
|
-
}
|
|
6416
6407
|
function planRuntimeSteps(recording, assembler) {
|
|
6417
6408
|
const steps = [];
|
|
6418
6409
|
const assembled = [];
|
|
@@ -6433,7 +6424,7 @@ function planRuntimeSteps(recording, assembler) {
|
|
|
6433
6424
|
steps.push({
|
|
6434
6425
|
entry,
|
|
6435
6426
|
message: parseWire(entry.line),
|
|
6436
|
-
gate:
|
|
6427
|
+
gate: countTurns(assembled),
|
|
6437
6428
|
eventsBefore: assembled.length
|
|
6438
6429
|
});
|
|
6439
6430
|
}
|
|
@@ -6682,7 +6673,7 @@ async function replayRecording(options) {
|
|
|
6682
6673
|
await waitFor(
|
|
6683
6674
|
`${step.gate.started} turn/started and ${step.gate.completed} turn/completed before ${method}`,
|
|
6684
6675
|
() => {
|
|
6685
|
-
const live =
|
|
6676
|
+
const live = countTurns(events);
|
|
6686
6677
|
return live.started >= step.gate.started && live.completed >= step.gate.completed;
|
|
6687
6678
|
}
|
|
6688
6679
|
);
|
package/dist/provider-bridge.js
CHANGED
|
@@ -1460,11 +1460,11 @@ var promptInputSchema = z6.discriminatedUnion("type", [
|
|
|
1460
1460
|
function isSelectedPromptCommandMention(mention, selector) {
|
|
1461
1461
|
return mention.resource.kind === "command" && mention.resource.trigger === selector.trigger && mention.resource.name === selector.name;
|
|
1462
1462
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1463
|
+
function isStandaloneBuiltinCommand(input, name) {
|
|
1464
|
+
const selector = { trigger: "/", name };
|
|
1465
1465
|
const selected = input.flatMap(
|
|
1466
1466
|
(item) => item.type === "text" ? item.mentions.filter(
|
|
1467
|
-
(mention2) => isSelectedPromptCommandMention(mention2,
|
|
1467
|
+
(mention2) => isSelectedPromptCommandMention(mention2, selector)
|
|
1468
1468
|
).map((mention2) => ({ mention: mention2, text: item.text })) : []
|
|
1469
1469
|
);
|
|
1470
1470
|
const standalone = selected[0];
|
|
@@ -1472,13 +1472,15 @@ function isStandaloneBuiltinCompactCommand(input) {
|
|
|
1472
1472
|
return false;
|
|
1473
1473
|
}
|
|
1474
1474
|
const { mention, text } = standalone;
|
|
1475
|
-
if (mention.resource.kind !== "command" || mention.resource.source !== "command" || mention.resource.origin !== "builtin" || text.slice(mention.start, mention.end) !==
|
|
1475
|
+
if (mention.resource.kind !== "command" || mention.resource.source !== "command" || mention.resource.origin !== "builtin" || text.slice(mention.start, mention.end) !== `/${name}`) {
|
|
1476
1476
|
return false;
|
|
1477
1477
|
}
|
|
1478
|
-
return removeCommandMentionsFromPromptInput(
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1478
|
+
return removeCommandMentionsFromPromptInput(input, selector).every(
|
|
1479
|
+
(item) => item.type === "text" && item.text.trim() === ""
|
|
1480
|
+
);
|
|
1481
|
+
}
|
|
1482
|
+
function isStandaloneBuiltinCompactCommand(input) {
|
|
1483
|
+
return isStandaloneBuiltinCommand(input, "compact");
|
|
1482
1484
|
}
|
|
1483
1485
|
function commandRemovalRanges(input, selector) {
|
|
1484
1486
|
return input.mentions.filter((mention) => isSelectedPromptCommandMention(mention, selector)).map((mention) => ({
|
package/dist/testing/app.js
CHANGED
|
@@ -392,6 +392,127 @@ function normalizeExperimentalFileOpenOptions(value) {
|
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
// src/internal/plugin-app-collector.ts
|
|
395
|
+
var sidebarFooterCommandSequence = 0;
|
|
396
|
+
var SIDEBAR_FOOTER_ACTION_KEYS = /* @__PURE__ */ new Set([
|
|
397
|
+
"id",
|
|
398
|
+
"label",
|
|
399
|
+
"icon",
|
|
400
|
+
"kind",
|
|
401
|
+
"onActivate"
|
|
402
|
+
]);
|
|
403
|
+
var SIDEBAR_FOOTER_DISCLOSURE_KEYS = /* @__PURE__ */ new Set([
|
|
404
|
+
"id",
|
|
405
|
+
"label",
|
|
406
|
+
"icon",
|
|
407
|
+
"kind",
|
|
408
|
+
"component"
|
|
409
|
+
]);
|
|
410
|
+
var SidebarFooterItemRuntime = class {
|
|
411
|
+
listeners = /* @__PURE__ */ new Set();
|
|
412
|
+
snapshot = {
|
|
413
|
+
command: null
|
|
414
|
+
};
|
|
415
|
+
subscribe = (listener) => {
|
|
416
|
+
this.listeners.add(listener);
|
|
417
|
+
return () => this.listeners.delete(listener);
|
|
418
|
+
};
|
|
419
|
+
getSnapshot = () => this.snapshot;
|
|
420
|
+
acknowledgeCommand = (sequence) => {
|
|
421
|
+
if (this.snapshot.command?.sequence !== sequence) return;
|
|
422
|
+
this.snapshot = { ...this.snapshot, command: null };
|
|
423
|
+
this.emit();
|
|
424
|
+
};
|
|
425
|
+
createDisclosureController() {
|
|
426
|
+
return Object.freeze({
|
|
427
|
+
open: () => this.request("open"),
|
|
428
|
+
close: () => this.request("close"),
|
|
429
|
+
toggle: () => this.request("toggle")
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
request(kind) {
|
|
433
|
+
sidebarFooterCommandSequence += 1;
|
|
434
|
+
this.snapshot = {
|
|
435
|
+
...this.snapshot,
|
|
436
|
+
command: { sequence: sidebarFooterCommandSequence, kind }
|
|
437
|
+
};
|
|
438
|
+
this.emit();
|
|
439
|
+
}
|
|
440
|
+
emit() {
|
|
441
|
+
for (const listener of this.listeners) listener();
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
function adaptSidebarFooterAction(registration) {
|
|
445
|
+
return {
|
|
446
|
+
source: "sidebarFooterAction",
|
|
447
|
+
id: registration.id,
|
|
448
|
+
label: registration.title,
|
|
449
|
+
icon: registration.icon,
|
|
450
|
+
kind: "action",
|
|
451
|
+
onActivate: ({ openPluginDetails }) => registration.run({ openSettings: openPluginDetails }),
|
|
452
|
+
runtime: new SidebarFooterItemRuntime()
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
var SidebarFooterCollector = class {
|
|
456
|
+
constructor(collected, allCollected, seenIds) {
|
|
457
|
+
this.collected = collected;
|
|
458
|
+
this.allCollected = allCollected;
|
|
459
|
+
this.seenIds = seenIds;
|
|
460
|
+
}
|
|
461
|
+
collected;
|
|
462
|
+
allCollected;
|
|
463
|
+
seenIds;
|
|
464
|
+
register(registration) {
|
|
465
|
+
const kind = "experimental_sidebarFooter.register";
|
|
466
|
+
const id = requireSlotId(kind, registration?.id);
|
|
467
|
+
requireUniqueId(kind, this.seenIds, id);
|
|
468
|
+
const label = requireNonEmptyString(kind, "label", registration.label);
|
|
469
|
+
const icon = requireNonEmptyString(kind, "icon", registration.icon);
|
|
470
|
+
const runtime = new SidebarFooterItemRuntime();
|
|
471
|
+
if (registration.kind === "action") {
|
|
472
|
+
this.rejectUnknownKeys(kind, registration, SIDEBAR_FOOTER_ACTION_KEYS);
|
|
473
|
+
if (typeof registration.onActivate !== "function") {
|
|
474
|
+
throw new Error(`${kind}: "onActivate" must be a function`);
|
|
475
|
+
}
|
|
476
|
+
const item = {
|
|
477
|
+
id,
|
|
478
|
+
label,
|
|
479
|
+
icon,
|
|
480
|
+
kind: "action",
|
|
481
|
+
onActivate: registration.onActivate,
|
|
482
|
+
source: "experimental_sidebarFooter",
|
|
483
|
+
runtime
|
|
484
|
+
};
|
|
485
|
+
this.collected.push(item);
|
|
486
|
+
this.allCollected.push(item);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
if (registration.kind === "disclosure") {
|
|
490
|
+
this.rejectUnknownKeys(
|
|
491
|
+
kind,
|
|
492
|
+
registration,
|
|
493
|
+
SIDEBAR_FOOTER_DISCLOSURE_KEYS
|
|
494
|
+
);
|
|
495
|
+
const item = {
|
|
496
|
+
id,
|
|
497
|
+
label,
|
|
498
|
+
icon,
|
|
499
|
+
kind: "disclosure",
|
|
500
|
+
component: requireComponent(kind, registration.component),
|
|
501
|
+
source: "experimental_sidebarFooter",
|
|
502
|
+
runtime
|
|
503
|
+
};
|
|
504
|
+
this.collected.push(item);
|
|
505
|
+
this.allCollected.push(item);
|
|
506
|
+
return runtime.createDisclosureController();
|
|
507
|
+
}
|
|
508
|
+
throw new Error(`${kind}: "kind" must be "action" or "disclosure"`);
|
|
509
|
+
}
|
|
510
|
+
rejectUnknownKeys(kind, registration, allowed) {
|
|
511
|
+
for (const key of Object.keys(registration)) {
|
|
512
|
+
if (!allowed.has(key)) throw new Error(`${kind}: unknown field "${key}"`);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
};
|
|
395
516
|
var NAV_PANEL_REGISTRATION_KEYS = new Set(
|
|
396
517
|
Object.keys({
|
|
397
518
|
id: true,
|
|
@@ -421,7 +542,9 @@ function rejectStaleNavPanelKeys(kind, registration) {
|
|
|
421
542
|
}
|
|
422
543
|
}
|
|
423
544
|
}
|
|
545
|
+
var sidebarFooterItemsByRegistrationSet = /* @__PURE__ */ new WeakMap();
|
|
424
546
|
function collectPluginAppRegistrations(definition, onComposerCustomizationRejected = (reason) => console.warn(reason)) {
|
|
547
|
+
const sidebarFooterItems = [];
|
|
425
548
|
const collected = {
|
|
426
549
|
homepageSections: [],
|
|
427
550
|
settingsSections: [],
|
|
@@ -432,6 +555,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
432
555
|
composerCustomizations: [],
|
|
433
556
|
pendingInteractions: [],
|
|
434
557
|
sidebarFooterActions: [],
|
|
558
|
+
experimentalSidebarFooterItems: [],
|
|
435
559
|
experimentalSidebarNavigations: [],
|
|
436
560
|
threadLists: [],
|
|
437
561
|
threadHeaderActions: [],
|
|
@@ -445,6 +569,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
445
569
|
timelineRenderers: [],
|
|
446
570
|
contentScripts: []
|
|
447
571
|
};
|
|
572
|
+
sidebarFooterItemsByRegistrationSet.set(collected, sidebarFooterItems);
|
|
448
573
|
const seenIds = {
|
|
449
574
|
homepageSection: /* @__PURE__ */ new Set(),
|
|
450
575
|
settingsSection: /* @__PURE__ */ new Set(),
|
|
@@ -454,7 +579,7 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
454
579
|
newThreadPanelAction: /* @__PURE__ */ new Set(),
|
|
455
580
|
composerCustomization: /* @__PURE__ */ new Set(),
|
|
456
581
|
pendingInteraction: /* @__PURE__ */ new Set(),
|
|
457
|
-
|
|
582
|
+
sidebarFooterItem: /* @__PURE__ */ new Set(),
|
|
458
583
|
sidebarNavigation: /* @__PURE__ */ new Set(),
|
|
459
584
|
threadList: /* @__PURE__ */ new Set(),
|
|
460
585
|
threadHeaderAction: /* @__PURE__ */ new Set(),
|
|
@@ -645,16 +770,18 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
645
770
|
sidebarFooterAction(registration) {
|
|
646
771
|
const kind = "slots.sidebarFooterAction";
|
|
647
772
|
const id = requireSlotId(kind, registration?.id);
|
|
648
|
-
requireUniqueId(kind, seenIds.
|
|
773
|
+
requireUniqueId(kind, seenIds.sidebarFooterItem, id);
|
|
649
774
|
if (typeof registration.run !== "function") {
|
|
650
775
|
throw new Error(`${kind}: "run" must be a function`);
|
|
651
776
|
}
|
|
652
|
-
|
|
777
|
+
const legacyRegistration = {
|
|
653
778
|
id,
|
|
654
779
|
title: requireNonEmptyString(kind, "title", registration.title),
|
|
655
780
|
icon: requireNonEmptyString(kind, "icon", registration.icon),
|
|
656
781
|
run: registration.run
|
|
657
|
-
}
|
|
782
|
+
};
|
|
783
|
+
collected.sidebarFooterActions.push(legacyRegistration);
|
|
784
|
+
sidebarFooterItems.push(adaptSidebarFooterAction(legacyRegistration));
|
|
658
785
|
},
|
|
659
786
|
experimental_sidebarNavigation(registration) {
|
|
660
787
|
const kind = "slots.experimental_sidebarNavigation";
|
|
@@ -816,6 +943,11 @@ function collectPluginAppRegistrations(definition, onComposerCustomizationReject
|
|
|
816
943
|
});
|
|
817
944
|
}
|
|
818
945
|
},
|
|
946
|
+
experimental_sidebarFooter: new SidebarFooterCollector(
|
|
947
|
+
collected.experimentalSidebarFooterItems,
|
|
948
|
+
sidebarFooterItems,
|
|
949
|
+
seenIds.sidebarFooterItem
|
|
950
|
+
),
|
|
819
951
|
composer: {
|
|
820
952
|
customize(registration) {
|
|
821
953
|
const customization = collectComposerCustomization(
|
package/dist/testing/index.js
CHANGED
|
@@ -2311,6 +2311,8 @@ function createFakePluginHostInternal(options, sharedState) {
|
|
|
2311
2311
|
}
|
|
2312
2312
|
};
|
|
2313
2313
|
const httpRoutes = [];
|
|
2314
|
+
const websocketRoutes = [];
|
|
2315
|
+
const websocketSessions = /* @__PURE__ */ new Set();
|
|
2314
2316
|
const http = {
|
|
2315
2317
|
route(method, path, handler, opts) {
|
|
2316
2318
|
assertLive();
|
|
@@ -2344,6 +2346,29 @@ function createFakePluginHostInternal(options, sharedState) {
|
|
|
2344
2346
|
);
|
|
2345
2347
|
}
|
|
2346
2348
|
httpRoutes.push({ method: normalizedMethod, path, auth, handler });
|
|
2349
|
+
},
|
|
2350
|
+
experimental_websocket(path, handler, opts) {
|
|
2351
|
+
assertLive();
|
|
2352
|
+
if (typeof path !== "string" || !path.startsWith("/")) {
|
|
2353
|
+
throw new Error(
|
|
2354
|
+
`websocket route path must be a string starting with "/", got ${JSON.stringify(path)}`
|
|
2355
|
+
);
|
|
2356
|
+
}
|
|
2357
|
+
if (typeof handler !== "function") {
|
|
2358
|
+
throw new Error(
|
|
2359
|
+
`websocket route handler for ${path} must be a function`
|
|
2360
|
+
);
|
|
2361
|
+
}
|
|
2362
|
+
const auth = opts?.auth ?? "local";
|
|
2363
|
+
if (auth !== "local" && auth !== "token" && auth !== "none") {
|
|
2364
|
+
throw new Error(
|
|
2365
|
+
`invalid auth mode "${String(auth)}" for websocket ${path} \u2014 use "local", "token", or "none"`
|
|
2366
|
+
);
|
|
2367
|
+
}
|
|
2368
|
+
if (websocketRoutes.some((route) => route.path === path)) {
|
|
2369
|
+
throw new Error(`websocket route ${path} is already registered`);
|
|
2370
|
+
}
|
|
2371
|
+
websocketRoutes.push({ path, auth, handler });
|
|
2347
2372
|
}
|
|
2348
2373
|
};
|
|
2349
2374
|
const rpcHandlers = /* @__PURE__ */ new Map();
|
|
@@ -3059,6 +3084,9 @@ function createFakePluginHostInternal(options, sharedState) {
|
|
|
3059
3084
|
pendingInteractions.delete(id);
|
|
3060
3085
|
pending.resolve({ outcome: "cancelled", reason: "plugin-disposed" });
|
|
3061
3086
|
}
|
|
3087
|
+
for (const session of [...websocketSessions]) {
|
|
3088
|
+
await session.closeForReload();
|
|
3089
|
+
}
|
|
3062
3090
|
for (const controller of serviceControllers) controller.abort();
|
|
3063
3091
|
for (const hook of [...disposeHooks].reverse()) {
|
|
3064
3092
|
try {
|
|
@@ -3104,6 +3132,7 @@ function createFakePluginHostInternal(options, sharedState) {
|
|
|
3104
3132
|
registrations: {
|
|
3105
3133
|
settingsDescriptors,
|
|
3106
3134
|
httpRoutes,
|
|
3135
|
+
websocketRoutes,
|
|
3107
3136
|
get rpcMethods() {
|
|
3108
3137
|
return [...rpcHandlers.keys()];
|
|
3109
3138
|
},
|
|
@@ -3321,6 +3350,127 @@ function createFakePluginHostInternal(options, sharedState) {
|
|
|
3321
3350
|
});
|
|
3322
3351
|
return app.request(path, { ...init, method: normalizedMethod });
|
|
3323
3352
|
},
|
|
3353
|
+
async experimental_openWebSocket(path, init) {
|
|
3354
|
+
assertLive();
|
|
3355
|
+
const url = new URL(path, "http://plugin.test");
|
|
3356
|
+
const route = websocketRoutes.find(
|
|
3357
|
+
(candidate) => candidate.path === url.pathname
|
|
3358
|
+
);
|
|
3359
|
+
if (!route) {
|
|
3360
|
+
throw new Error(
|
|
3361
|
+
`no websocket route ${url.pathname} is registered \u2014 registered: ${websocketRoutes.map((candidate) => candidate.path).join(", ") || "(none)"}`
|
|
3362
|
+
);
|
|
3363
|
+
}
|
|
3364
|
+
const request = new Request(url, { ...init, method: "GET" });
|
|
3365
|
+
let handlers;
|
|
3366
|
+
try {
|
|
3367
|
+
handlers = route.handler({
|
|
3368
|
+
request,
|
|
3369
|
+
url,
|
|
3370
|
+
headers: request.headers
|
|
3371
|
+
});
|
|
3372
|
+
if (typeof handlers !== "object" || handlers === null || Array.isArray(handlers)) {
|
|
3373
|
+
throw new Error("websocket route handler must return an object");
|
|
3374
|
+
}
|
|
3375
|
+
for (const name of [
|
|
3376
|
+
"onOpen",
|
|
3377
|
+
"onMessage",
|
|
3378
|
+
"onClose",
|
|
3379
|
+
"onError"
|
|
3380
|
+
]) {
|
|
3381
|
+
const callback = handlers[name];
|
|
3382
|
+
if (callback !== void 0 && typeof callback !== "function") {
|
|
3383
|
+
throw new Error(
|
|
3384
|
+
`websocket route handler ${name} must be a function`
|
|
3385
|
+
);
|
|
3386
|
+
}
|
|
3387
|
+
}
|
|
3388
|
+
} catch (error) {
|
|
3389
|
+
emitLog(
|
|
3390
|
+
"warn",
|
|
3391
|
+
`websocket ${route.path} connect failed: ${errorMessage(error)}`
|
|
3392
|
+
);
|
|
3393
|
+
throw error;
|
|
3394
|
+
}
|
|
3395
|
+
const sent = [];
|
|
3396
|
+
const closeCalls = [];
|
|
3397
|
+
let readyState = 0;
|
|
3398
|
+
let closeNotified = false;
|
|
3399
|
+
let eventQueue = Promise.resolve();
|
|
3400
|
+
const invoke = async (event, run) => {
|
|
3401
|
+
eventQueue = eventQueue.then(async () => {
|
|
3402
|
+
try {
|
|
3403
|
+
await run();
|
|
3404
|
+
} catch (error) {
|
|
3405
|
+
emitLog(
|
|
3406
|
+
"warn",
|
|
3407
|
+
`websocket ${route.path} ${event} failed: ${errorMessage(error)}`
|
|
3408
|
+
);
|
|
3409
|
+
}
|
|
3410
|
+
});
|
|
3411
|
+
await eventQueue;
|
|
3412
|
+
};
|
|
3413
|
+
const socket = {
|
|
3414
|
+
send(data) {
|
|
3415
|
+
sent.push(typeof data === "string" ? data : new Uint8Array(data));
|
|
3416
|
+
},
|
|
3417
|
+
close(code, reason) {
|
|
3418
|
+
closeCalls.push({ code: code ?? null, reason: reason ?? null });
|
|
3419
|
+
if (readyState < 2) readyState = 2;
|
|
3420
|
+
},
|
|
3421
|
+
get readyState() {
|
|
3422
|
+
return readyState;
|
|
3423
|
+
}
|
|
3424
|
+
};
|
|
3425
|
+
const notifyClose = async (code, reason) => {
|
|
3426
|
+
if (closeNotified) return;
|
|
3427
|
+
closeNotified = true;
|
|
3428
|
+
readyState = 3;
|
|
3429
|
+
websocketSessions.delete(session);
|
|
3430
|
+
if (handlers.onClose !== void 0) {
|
|
3431
|
+
await invoke(
|
|
3432
|
+
"close",
|
|
3433
|
+
() => handlers.onClose?.(socket, { code, reason })
|
|
3434
|
+
);
|
|
3435
|
+
}
|
|
3436
|
+
};
|
|
3437
|
+
const session = {
|
|
3438
|
+
sent,
|
|
3439
|
+
closeCalls,
|
|
3440
|
+
get readyState() {
|
|
3441
|
+
return readyState;
|
|
3442
|
+
},
|
|
3443
|
+
async receive(data) {
|
|
3444
|
+
if (readyState !== 1) {
|
|
3445
|
+
throw new Error(
|
|
3446
|
+
"cannot receive a websocket message while not open"
|
|
3447
|
+
);
|
|
3448
|
+
}
|
|
3449
|
+
if (handlers.onMessage !== void 0) {
|
|
3450
|
+
await invoke("message", () => handlers.onMessage?.(socket, data));
|
|
3451
|
+
}
|
|
3452
|
+
},
|
|
3453
|
+
async close(code = 1e3, reason = "") {
|
|
3454
|
+
if (readyState < 2) socket.close(code, reason);
|
|
3455
|
+
await notifyClose(code, reason);
|
|
3456
|
+
},
|
|
3457
|
+
async error(error) {
|
|
3458
|
+
if (handlers.onError !== void 0) {
|
|
3459
|
+
await invoke("error", () => handlers.onError?.(socket, error));
|
|
3460
|
+
}
|
|
3461
|
+
},
|
|
3462
|
+
async closeForReload() {
|
|
3463
|
+
socket.close(1012, "Plugin reloaded or disabled");
|
|
3464
|
+
await notifyClose(1012, "Plugin reloaded or disabled");
|
|
3465
|
+
}
|
|
3466
|
+
};
|
|
3467
|
+
websocketSessions.add(session);
|
|
3468
|
+
readyState = 1;
|
|
3469
|
+
if (handlers.onOpen !== void 0) {
|
|
3470
|
+
await invoke("open", () => handlers.onOpen?.(socket));
|
|
3471
|
+
}
|
|
3472
|
+
return session;
|
|
3473
|
+
},
|
|
3324
3474
|
runService(name) {
|
|
3325
3475
|
const service = services.find((record) => record.name === name);
|
|
3326
3476
|
if (!service) {
|