@blade-hq/agent-react 2612.0.0-beta.8 → 2612.0.0-beta.80

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.
Files changed (177) hide show
  1. package/README.md +47 -0
  2. package/dist/SessionPluginConfigForm-7LJ5SUNY.js +9 -0
  3. package/dist/SessionPluginConfigForm-7LJ5SUNY.js.map +1 -0
  4. package/dist/chat/AgentLoopBlock.d.ts +0 -2
  5. package/dist/chat/AskUserQuestionBlock.d.ts +3 -20
  6. package/dist/chat/AssistantTurnBlock.d.ts +1 -9
  7. package/dist/chat/AttachmentPreviewDialog.d.ts +0 -1
  8. package/dist/chat/ChatLoadingIndicator.d.ts +7 -0
  9. package/dist/chat/ContextAttachmentPills.d.ts +4 -0
  10. package/dist/chat/CurrentPlanPanel.d.ts +0 -3
  11. package/dist/chat/FileDeliveryCards.d.ts +0 -4
  12. package/dist/chat/FinalArtifactCards.d.ts +0 -1
  13. package/dist/chat/ImageLightbox.d.ts +1 -1
  14. package/dist/chat/LiteMessageList.d.ts +5 -3
  15. package/dist/chat/MessageFileAttachmentList.d.ts +0 -5
  16. package/dist/chat/QuestionnaireQuestionBlock.d.ts +11 -0
  17. package/dist/chat/SessionReplayBar.d.ts +0 -1
  18. package/dist/chat/TextAttachmentPills.d.ts +0 -3
  19. package/dist/chat/TurnNavRail.d.ts +1 -7
  20. package/dist/chat/WorkflowRunBlock.d.ts +21 -4
  21. package/dist/chat/ai-elements/shimmer.d.ts +0 -4
  22. package/dist/chat/customization.d.ts +1 -1
  23. package/dist/chat/index.d.ts +3 -2
  24. package/dist/chat/markdown/ExternalAnchor.d.ts +2 -2
  25. package/dist/chat/markdown/MarkdownContent.d.ts +3 -0
  26. package/dist/chat/message-list-blocks.d.ts +0 -1
  27. package/dist/chat/runtime/actions.d.ts +2 -2
  28. package/dist/chat/runtime/background-task-dismissals.d.ts +0 -1
  29. package/dist/chat/runtime/composer-channels.d.ts +0 -3
  30. package/dist/chat/runtime/input-cache-reset.d.ts +0 -5
  31. package/dist/chat/runtime/input-services.d.ts +10 -0
  32. package/dist/chat/runtime/session-source.d.ts +0 -5
  33. package/dist/chat/runtime/use-chat-actions.d.ts +0 -4
  34. package/dist/chat/turn-locate-channel.d.ts +53 -0
  35. package/dist/{chat-OCLOVB3H.css → chat-IHPRU35X.css} +5 -18
  36. package/dist/chat.css +5 -18
  37. package/dist/chunk-66JXSDLB.js +13770 -0
  38. package/dist/chunk-66JXSDLB.js.map +1 -0
  39. package/dist/chunk-C3LBNHVM.js +9482 -0
  40. package/dist/chunk-C3LBNHVM.js.map +1 -0
  41. package/dist/chunk-F4MWGSKX.js +1308 -0
  42. package/dist/chunk-F4MWGSKX.js.map +1 -0
  43. package/dist/chunk-FBGCDXRK.js +607 -0
  44. package/dist/chunk-FBGCDXRK.js.map +1 -0
  45. package/dist/{chunk-67GHJQK5.js → chunk-FDB3J5QF.js} +3889 -26106
  46. package/dist/chunk-FDB3J5QF.js.map +1 -0
  47. package/dist/chunk-FH5HA3GW.js +2416 -0
  48. package/dist/chunk-FH5HA3GW.js.map +1 -0
  49. package/dist/chunk-KHJEIHMJ.js +973 -0
  50. package/dist/chunk-KHJEIHMJ.js.map +1 -0
  51. package/dist/chunk-MWILWSPG.js +9629 -0
  52. package/dist/chunk-MWILWSPG.js.map +1 -0
  53. package/dist/chunk-NRYLAO3X.js +3978 -0
  54. package/dist/chunk-NRYLAO3X.js.map +1 -0
  55. package/dist/{chunk-MERN5XEM.js → chunk-SK43YNRX.js} +4181 -16594
  56. package/dist/chunk-SK43YNRX.js.map +1 -0
  57. package/dist/components/AccountConnectorRules.d.ts +7 -0
  58. package/dist/components/AccountConnectors.d.ts +13 -0
  59. package/dist/components/BrowserConnectionDialog.d.ts +8 -0
  60. package/dist/components/ChatInput.d.ts +1 -15
  61. package/dist/components/ConfigConnection.d.ts +16 -0
  62. package/dist/components/ConnectorAuthorizationProgress.d.ts +6 -0
  63. package/dist/components/ConnectorConnection.d.ts +4 -0
  64. package/dist/components/ConnectorDetail.d.ts +46 -0
  65. package/dist/components/ConnectorPanel.d.ts +3 -1
  66. package/dist/components/ConnectorRulesPanel.d.ts +10 -0
  67. package/dist/components/ConnectorRuntimeDiagnostics.d.ts +5 -0
  68. package/dist/components/DeviceConnection.d.ts +17 -0
  69. package/dist/components/FeishuCapabilitySelection.d.ts +14 -0
  70. package/dist/components/FeishuPermissionStatus.d.ts +7 -0
  71. package/dist/components/LlmAdvancedSettings.d.ts +0 -1
  72. package/dist/components/ManagedConnection.d.ts +12 -0
  73. package/dist/components/McpAppFrame.d.ts +17 -0
  74. package/dist/components/PackEventNotice.d.ts +3 -0
  75. package/dist/components/PlanUpdateBlock.d.ts +0 -1
  76. package/dist/components/SessionPluginConfigForm.d.ts +4 -1
  77. package/dist/components/SessionPluginIcon.d.ts +1 -0
  78. package/dist/components/plugin-connector.d.ts +1 -0
  79. package/dist/connectors.d.ts +6 -0
  80. package/dist/connectors.js +19 -0
  81. package/dist/connectors.js.map +1 -0
  82. package/dist/embed/blade-chat-element.d.ts +0 -8
  83. package/dist/embed/entry.d.ts +13 -19
  84. package/dist/hooks/use-message-pin.d.ts +1 -1
  85. package/dist/hooks/use-turn-navigation.d.ts +19 -0
  86. package/dist/index.d.ts +6 -0
  87. package/dist/index.js +23 -3
  88. package/dist/internal.d.ts +7 -3
  89. package/dist/internal.js +59 -71
  90. package/dist/internal.js.map +1 -1
  91. package/dist/lib/message-shortcuts.d.ts +5 -0
  92. package/dist/questions.d.ts +7 -0
  93. package/dist/questions.js +910 -0
  94. package/dist/questions.js.map +1 -0
  95. package/dist/rich-input/ConnectButton.d.ts +7 -5
  96. package/dist/rich-input/FileCompletionMenu.d.ts +1 -2
  97. package/dist/rich-input/InputActionSubmenu.d.ts +10 -0
  98. package/dist/rich-input/SkillActionMenu.d.ts +10 -0
  99. package/dist/rich-input/SkillStatusBar.d.ts +0 -6
  100. package/dist/rich-input/extensions/skill-mention.d.ts +3 -20
  101. package/dist/rich-input/index.d.ts +3 -2
  102. package/dist/rich-input/lib/composer-content.d.ts +5 -1
  103. package/dist/rich-input/lib/plugin-suggestions.d.ts +5 -5
  104. package/dist/rich-input/lib/reference-candidates.d.ts +0 -1
  105. package/dist/rich-input/lib/skill-suggestions.d.ts +1 -1
  106. package/dist/rich-input/lib/user-home.d.ts +0 -17
  107. package/dist/rich-input/services.d.ts +1 -1
  108. package/dist/rich-input/voice/VoiceWaveform.d.ts +0 -3
  109. package/dist/rich-input.js +793 -1068
  110. package/dist/rich-input.js.map +1 -1
  111. package/dist/style.css +16 -55
  112. package/dist/style.full.css +23 -77
  113. package/dist/tool-details.d.ts +8 -0
  114. package/dist/tool-details.js +25 -0
  115. package/dist/tool-details.js.map +1 -0
  116. package/node_modules/@modelcontextprotocol/ext-apps/LICENSE +216 -0
  117. package/node_modules/@modelcontextprotocol/ext-apps/README.md +284 -0
  118. package/node_modules/@modelcontextprotocol/ext-apps/dist/docs/patterns.d.ts +9 -0
  119. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.d.ts +1348 -0
  120. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.examples.d.ts +9 -0
  121. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.js +39 -0
  122. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.test.d.ts +1 -0
  123. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-with-deps.js +82 -0
  124. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app.d.ts +1214 -0
  125. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app.examples.d.ts +9 -0
  126. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app.js +39 -0
  127. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app.test.d.ts +1 -0
  128. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/constants.d.ts +65 -0
  129. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/events.d.ts +47 -0
  130. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/events.test.d.ts +1 -0
  131. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/generated/schema.d.ts +1047 -0
  132. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/generated/schema.json +6170 -0
  133. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/generated/schema.test.d.ts +41 -0
  134. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/interop-v1.test.d.ts +1 -0
  135. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/legacy-handlers.d.ts +66 -0
  136. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/legacy-handlers.test.d.ts +1 -0
  137. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/message-transport.d.ts +126 -0
  138. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/message-transport.examples.d.ts +9 -0
  139. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/message-transport.test.d.ts +1 -0
  140. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/index.d.ts +37 -0
  141. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/index.examples.d.ts +6 -0
  142. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/index.js +39 -0
  143. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/react-with-deps.js +82 -0
  144. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useApp.d.ts +115 -0
  145. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useApp.examples.d.ts +6 -0
  146. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useAutoResize.d.ts +54 -0
  147. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useAutoResize.examples.d.ts +6 -0
  148. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useDocumentTheme.d.ts +44 -0
  149. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useDocumentTheme.examples.d.ts +6 -0
  150. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useHostStyles.d.ts +113 -0
  151. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useHostStyles.examples.d.ts +6 -0
  152. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/server/index.d.ts +381 -0
  153. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/server/index.examples.d.ts +9 -0
  154. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/server/index.js +1 -0
  155. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/server/index.test.d.ts +1 -0
  156. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/spec.types.d.ts +698 -0
  157. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/standard-schema.d.ts +23 -0
  158. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/styles.d.ts +184 -0
  159. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/styles.examples.d.ts +9 -0
  160. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/types.d.ts +33 -0
  161. package/node_modules/@modelcontextprotocol/ext-apps/dist/src/wire-compat.test.d.ts +1 -0
  162. package/node_modules/@modelcontextprotocol/ext-apps/package.json +144 -0
  163. package/node_modules/@standard-schema/spec/LICENSE +21 -0
  164. package/node_modules/@standard-schema/spec/README.md +198 -0
  165. package/node_modules/@standard-schema/spec/dist/index.cjs +18 -0
  166. package/node_modules/@standard-schema/spec/dist/index.d.cts +119 -0
  167. package/node_modules/@standard-schema/spec/dist/index.d.ts +119 -0
  168. package/node_modules/@standard-schema/spec/dist/index.js +0 -0
  169. package/node_modules/@standard-schema/spec/package.json +52 -0
  170. package/package.json +19 -3
  171. package/public-api.md +60 -4
  172. package/dist/chunk-67GHJQK5.js.map +0 -1
  173. package/dist/chunk-DPDXGYGM.js +0 -258
  174. package/dist/chunk-DPDXGYGM.js.map +0 -1
  175. package/dist/chunk-MERN5XEM.js.map +0 -1
  176. package/dist/lib/agent-computer-command.d.ts +0 -32
  177. package/dist/rich-input/extensions/workflow-mention.d.ts +0 -10
@@ -0,0 +1,607 @@
1
+ import {
2
+ PluginConnectorList,
3
+ SessionPluginIcon,
4
+ catalogToConnectorItems,
5
+ filterConnectorItems,
6
+ useSessionPluginActivation
7
+ } from "./chunk-F4MWGSKX.js";
8
+ import {
9
+ ConnectorConnection
10
+ } from "./chunk-FH5HA3GW.js";
11
+ import {
12
+ AccountConnectorRules,
13
+ BrowserConnectionDialog
14
+ } from "./chunk-NRYLAO3X.js";
15
+ import {
16
+ ConfigConnection,
17
+ Dialog,
18
+ DialogContent,
19
+ DialogTitle
20
+ } from "./chunk-MWILWSPG.js";
21
+ import {
22
+ Check,
23
+ LoaderCircle,
24
+ Pencil,
25
+ Plug,
26
+ RefreshCw,
27
+ Search,
28
+ Trash2
29
+ } from "./chunk-KHJEIHMJ.js";
30
+
31
+ // src/components/connector-panel-types.ts
32
+ function selectionFromItem(item) {
33
+ return {
34
+ name: item.name,
35
+ displayName: item.display_name ?? null,
36
+ icon: item.icon,
37
+ iconSource: item.iconSource
38
+ };
39
+ }
40
+ var TRIGGER_ICON_LIMIT = 3;
41
+ function triggerSummary(items) {
42
+ const visible = items.slice(0, TRIGGER_ICON_LIMIT);
43
+ return {
44
+ visible,
45
+ overflow: items.length - visible.length,
46
+ total: items.length
47
+ };
48
+ }
49
+
50
+ // src/components/AccountConnectors.tsx
51
+ import { isLocalConnectorName } from "@blade-hq/agent-client/internal";
52
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
53
+ import { Suspense, lazy } from "react";
54
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
55
+ var SessionPluginConfigForm = lazy(() => import("./SessionPluginConfigForm-7LJ5SUNY.js").then((module) => ({ default: module.SessionPluginConfigForm })));
56
+ var actionBaseClass = "inline-flex h-8 shrink-0 items-center justify-center gap-1.5 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--background))] text-xs font-medium text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))] focus-visible:outline-2 focus-visible:outline-offset-2 disabled:pointer-events-none disabled:opacity-50";
57
+ var actionClass = `${actionBaseClass} px-3`;
58
+ var iconActionClass = `${actionBaseClass} w-8 p-0`;
59
+ async function failureMessage(error) {
60
+ const response = error?.response;
61
+ if (response) {
62
+ try {
63
+ const body = await response.json();
64
+ if (typeof body.detail === "string") return body.detail;
65
+ if (typeof body.detail?.message === "string") return body.detail.message;
66
+ } catch {
67
+ }
68
+ }
69
+ return "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5";
70
+ }
71
+ function DeviceDialog({ client, connector, onChanged, onClose }) {
72
+ const [rulesRefresh, setRulesRefresh] = useState(0);
73
+ return /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange: (open) => {
74
+ if (!open) onClose();
75
+ }, children: /* @__PURE__ */ jsxs(DialogContent, { "aria-describedby": void 0, className: "max-h-[85dvh] overflow-y-auto sm:max-w-[640px]", children: [
76
+ /* @__PURE__ */ jsxs(DialogTitle, { className: "sr-only", children: [
77
+ "\u8FDE\u63A5 ",
78
+ connector.display_name || connector.name
79
+ ] }),
80
+ /* @__PURE__ */ jsx(ConnectorConnection, { detail: { name: connector.name, title: connector.display_name || connector.name, icon: /* @__PURE__ */ jsx(SessionPluginIcon, { client, sessionId: null, plugin: connector, size: 44 }), rules: /* @__PURE__ */ jsx(AccountConnectorRules, { client, name: connector.name, refresh: rulesRefresh }) }, type: connector.authorization?.type === "managed" ? "managed" : "device", read: () => client.connectors.authorization(connector.name), act: (action, options) => client.connectors.authorize(connector.name, action, void 0, options), plan: (capabilities) => client.connectors.authorizationPlan(connector.name, capabilities), diagnostics: () => client.connectors.diagnostics(connector.name), onChanged: async () => {
81
+ await onChanged();
82
+ setRulesRefresh((value) => value + 1);
83
+ }, onDisable: () => client.connectors.disconnect(connector.name) }),
84
+ /* @__PURE__ */ jsx("button", { type: "button", className: actionClass, onClick: onClose, children: "\u8FD4\u56DE\u8FDE\u63A5\u5668" })
85
+ ] }) });
86
+ }
87
+ function ConnectionDialog({ client, connector, onConnected, onChanged, onClose }) {
88
+ const [view, setView] = useState(null);
89
+ const [failure, setFailure] = useState(null);
90
+ const [submitting, setSubmitting] = useState(false);
91
+ const [editing, setEditing] = useState(false);
92
+ const [rulesRefresh, setRulesRefresh] = useState(0);
93
+ const connectionRequest = useRef(null);
94
+ const alive = useRef(false);
95
+ useEffect(() => {
96
+ alive.current = true;
97
+ const abort = new AbortController();
98
+ client.connectors.read(connector.name, { signal: abort.signal }).then((value) => {
99
+ if (!abort.signal.aborted) setView(value);
100
+ }).catch(async (error) => {
101
+ const message = await failureMessage(error);
102
+ if (!abort.signal.aborted) setFailure(message);
103
+ });
104
+ return () => {
105
+ alive.current = false;
106
+ abort.abort();
107
+ connectionRequest.current?.abort();
108
+ };
109
+ }, [client, connector.name]);
110
+ async function submit(draft) {
111
+ if (!view || submitting) return;
112
+ setSubmitting(true);
113
+ setFailure(null);
114
+ const request = new AbortController();
115
+ connectionRequest.current = request;
116
+ try {
117
+ const next = await client.connectors.connect(connector.name, { expected_revision: view.config.revision, ...draft }, { signal: request.signal });
118
+ if (request.signal.aborted) return;
119
+ setView(next);
120
+ setEditing(false);
121
+ setRulesRefresh((value) => value + 1);
122
+ try {
123
+ await onConnected();
124
+ } catch {
125
+ if (!request.signal.aborted) setFailure("\u5DF2\u8FDE\u63A5\uFF0C\u4F46\u5217\u8868\u6216\u5BF9\u8BDD\u72B6\u6001\u672A\u80FD\u5237\u65B0\u3002\u8BF7\u8FD4\u56DE\u540E\u91CD\u8BD5\u5237\u65B0\u6216\u542F\u7528\u3002");
126
+ }
127
+ } catch (error) {
128
+ if (request.signal.aborted) return;
129
+ setFailure(await failureMessage(error));
130
+ try {
131
+ const next = await client.connectors.read(connector.name);
132
+ if (!request.signal.aborted) setView(next);
133
+ } catch {
134
+ }
135
+ } finally {
136
+ if (!request.signal.aborted) setSubmitting(false);
137
+ }
138
+ }
139
+ const form = view && /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("output", { children: "\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u8868\u5355\u2026" }), children: /* @__PURE__ */ jsx(SessionPluginConfigForm, { collapseHelp: true, config: view.config, submitting, errors: [], failure, submitLabel: editing ? "\u4FDD\u5B58\u5E76\u8FDE\u63A5" : "\u8FDE\u63A5\u5E76\u9A8C\u8BC1", submittingLabel: "\u6B63\u5728\u8FDE\u63A5\u2026", onCancel: () => editing ? setEditing(false) : onClose(), onSubmit: (draft) => void submit(draft) }) });
140
+ const current = view?.connection ?? connector.connection;
141
+ return /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange: (open) => {
142
+ if (!open && !submitting) onClose();
143
+ }, children: /* @__PURE__ */ jsxs(DialogContent, { "aria-describedby": void 0, className: "max-h-[85dvh] overflow-y-auto sm:max-w-[640px]", onEscapeKeyDown: (event) => {
144
+ if (submitting) event.preventDefault();
145
+ }, onInteractOutside: (event) => {
146
+ if (submitting) event.preventDefault();
147
+ }, children: [
148
+ /* @__PURE__ */ jsxs(DialogTitle, { className: "sr-only", children: [
149
+ "\u8FDE\u63A5 ",
150
+ connector.display_name || connector.name
151
+ ] }),
152
+ /* @__PURE__ */ jsx(ConfigConnection, { detail: { title: connector.display_name || connector.name, icon: /* @__PURE__ */ jsx(SessionPluginIcon, { client, sessionId: null, plugin: connector, size: 44 }), rules: /* @__PURE__ */ jsx(AccountConnectorRules, { client, name: connector.name, refresh: rulesRefresh }) }, status: current.status, account: current.account_label, verifiedAt: current.verified_at, busy: submitting, connection: view ? form : /* @__PURE__ */ jsx("output", { children: failure || "\u6B63\u5728\u83B7\u53D6\u8BA4\u8BC1\u8868\u5355\u2026" }), onEdit: () => setEditing(true), onDisconnect: async () => {
153
+ setSubmitting(true);
154
+ try {
155
+ const next = await client.connectors.disconnect(connector.name);
156
+ if (alive.current) {
157
+ setView(next);
158
+ setRulesRefresh((value) => value + 1);
159
+ }
160
+ await onChanged();
161
+ } finally {
162
+ if (alive.current) setSubmitting(false);
163
+ }
164
+ }, onVerify: async () => {
165
+ const next = await client.connectors.verify(connector.name);
166
+ if (alive.current) setView(next);
167
+ } }),
168
+ failure && current.status === "connected" && /* @__PURE__ */ jsx("p", { role: "alert", children: failure }),
169
+ editing && /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange: (open) => {
170
+ if (!open && !submitting) setEditing(false);
171
+ }, children: /* @__PURE__ */ jsxs(DialogContent, { "aria-describedby": void 0, className: "max-h-[85dvh] overflow-y-auto", onEscapeKeyDown: (event) => {
172
+ if (submitting) event.preventDefault();
173
+ }, onInteractOutside: (event) => {
174
+ if (submitting) event.preventDefault();
175
+ }, children: [
176
+ /* @__PURE__ */ jsx(DialogTitle, { children: "\u66F4\u6362\u8D26\u53F7" }),
177
+ /* @__PURE__ */ jsx("p", { children: "\u4FDD\u5B58\u540E\u65E7\u8D26\u53F7\u8FDE\u63A5\u4F1A\u88AB\u66FF\u6362\uFF0C\u4F7F\u7528\u89C4\u5219\u4FDD\u7559\u3002" }),
178
+ form
179
+ ] }) }),
180
+ /* @__PURE__ */ jsx("button", { type: "button", disabled: submitting, className: actionClass, onClick: onClose, children: "\u8FD4\u56DE\u8FDE\u63A5\u5668" })
181
+ ] }) });
182
+ }
183
+ function AccountConnectors({ client, query = "", sessionId = null, pending, onUse, onSelectedChange, disabledReason, catalog = false, manage = false, onEdit }) {
184
+ const [items, setItems] = useState([]);
185
+ const [editing, setEditing] = useState(null);
186
+ const [failure, setFailure] = useState(null);
187
+ const [loading, setLoading] = useState(true);
188
+ const deleteDialog = useRef(null);
189
+ const [deleting, setDeleting] = useState(null);
190
+ const [busy, setBusy] = useState(false);
191
+ useEffect(() => {
192
+ if (!deleting) return;
193
+ const element = deleteDialog.current;
194
+ element?.showModal();
195
+ return () => element?.close();
196
+ }, [deleting]);
197
+ const lifetime = useRef(null);
198
+ const load = useCallback((signal) => sessionId ? client.connectors.listForSession(sessionId, { signal }) : client.connectors.list({ signal }), [client, sessionId]);
199
+ const reload = useCallback(async () => {
200
+ const scope = lifetime.current;
201
+ const result = await load(scope?.signal);
202
+ if (scope === lifetime.current && !scope?.signal.aborted) {
203
+ setItems(result.connectors);
204
+ setFailure(null);
205
+ }
206
+ }, [load]);
207
+ useEffect(() => {
208
+ const abort = new AbortController();
209
+ lifetime.current = abort;
210
+ setItems([]);
211
+ setEditing(null);
212
+ setLoading(true);
213
+ setFailure(null);
214
+ load(abort.signal).then((value) => {
215
+ if (!abort.signal.aborted) setItems(value.connectors);
216
+ }).catch(async (error) => {
217
+ const message = await failureMessage(error);
218
+ if (!abort.signal.aborted) setFailure(message);
219
+ }).finally(() => {
220
+ if (!abort.signal.aborted) setLoading(false);
221
+ });
222
+ return () => abort.abort();
223
+ }, [load]);
224
+ const visible = useMemo(() => {
225
+ const result = items.map((item) => ({ ...item, active: sessionId ? item.active : Boolean(pending?.has(item.name)) }));
226
+ if (!sessionId) {
227
+ for (const name of pending ?? []) if (isLocalConnectorName(name) && !result.some((item) => item.name === name)) result.push({ name, display_name: name.split(".").slice(2).join("."), description: "\u8FDE\u63A5\u5668\u5DF2\u79FB\u9664\u6216\u6682\u4E0D\u53EF\u7528\uFF0C\u53EF\u53D6\u6D88\u9009\u62E9\u540E\u7EE7\u7EED\u3002", source: name.startsWith("connector.builtin.") ? "builtin" : "personal", operations: 0, available: false, active: true, connection: { status: "disconnected", revision: 0, account_label: "", verified_at: "" } });
228
+ }
229
+ return result;
230
+ }, [items, pending, sessionId]);
231
+ const selected = useRef(onSelectedChange);
232
+ selected.current = onSelectedChange;
233
+ useEffect(() => {
234
+ selected.current?.(visible.filter((item) => item.active));
235
+ }, [visible]);
236
+ const matching = visible.filter((item) => `${item.display_name} ${item.description}`.toLowerCase().includes(query.trim().toLowerCase()));
237
+ return /* @__PURE__ */ jsxs("div", { className: catalog ? "grid gap-4 sm:grid-cols-2 xl:grid-cols-3" : void 0, children: [
238
+ !catalog ? /* @__PURE__ */ jsx("div", { className: "px-3 pt-1 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: "\u8FDE\u63A5\u5668" }) : null,
239
+ loading ? /* @__PURE__ */ jsx("p", { className: "px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u5668\u2026" }) : null,
240
+ !loading && !failure && matching.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: query.trim() ? "\u6CA1\u6709\u5339\u914D\u7684\u8FDE\u63A5\u5668" : "\u6682\u65E0\u8FDE\u63A5\u5668" }) : null,
241
+ matching.map((item) => {
242
+ const connected = item.connection.status === "connected";
243
+ const label = item.display_name || item.name;
244
+ const ConnectIcon = connected ? RefreshCw : Plug;
245
+ const connectionClass = `${actionClass} ${!connected ? "border-transparent bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] hover:bg-[hsl(var(--primary)/0.9)]" : ""}`;
246
+ const connectAction = /* @__PURE__ */ jsxs("button", { type: "button", disabled: busy || item.available === false, className: connectionClass, onClick: () => {
247
+ setFailure(null);
248
+ setEditing(item);
249
+ }, children: [
250
+ /* @__PURE__ */ jsx(ConnectIcon, { size: 14, "aria-hidden": "true" }),
251
+ ["device", "managed"].includes(item.authorization?.type ?? "") ? "\u7BA1\u7406\u6388\u6743" : connected ? "\u7BA1\u7406\u8FDE\u63A5" : "\u8FDE\u63A5"
252
+ ] });
253
+ const useAction = onUse && (item.active || connected && item.operations > 0) ? /* @__PURE__ */ jsxs("button", { type: "button", disabled: busy || Boolean(disabledReason), title: disabledReason ?? void 0, className: actionClass, onClick: async () => {
254
+ const scope = lifetime.current;
255
+ setBusy(true);
256
+ setFailure(null);
257
+ try {
258
+ await onUse(item.name, label, !item.active, item.icon ?? null);
259
+ if (sessionId) await reload();
260
+ } catch (error) {
261
+ const message = await failureMessage(error);
262
+ if (scope === lifetime.current && !scope?.signal.aborted) setFailure(message);
263
+ } finally {
264
+ if (scope === lifetime.current && !scope?.signal.aborted) setBusy(false);
265
+ }
266
+ }, children: [
267
+ item.active ? /* @__PURE__ */ jsx(Check, { size: 14, "aria-hidden": "true" }) : null,
268
+ item.active ? "\u5DF2\u542F\u7528" : "\u4F7F\u7528"
269
+ ] }) : null;
270
+ return /* @__PURE__ */ jsxs("div", { className: catalog ? "flex flex-col rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-5" : "px-3 py-1.5", children: [
271
+ /* @__PURE__ */ jsxs("div", { className: `flex items-center gap-2 ${catalog ? "text-sm" : "text-[11px]"}`, children: [
272
+ /* @__PURE__ */ jsx(SessionPluginIcon, { client, sessionId: null, plugin: { name: item.name, icon: item.icon ?? null }, size: catalog ? 32 : 20 }),
273
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-medium", title: label, children: label }),
274
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded-md bg-[hsl(var(--muted))] px-1.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: item.source === "builtin" ? "\u5185\u7F6E" : "\u6211\u521B\u5EFA\u7684" }),
275
+ !catalog ? /* @__PURE__ */ jsxs(Fragment, { children: [
276
+ connectAction,
277
+ useAction
278
+ ] }) : null
279
+ ] }),
280
+ catalog ? /* @__PURE__ */ jsx("p", { className: "mt-2 flex-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: item.description }) : null,
281
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
282
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: `size-1.5 shrink-0 rounded-full ${connected ? "bg-emerald-500" : "bg-[hsl(var(--muted-foreground)/0.4)]"}` }),
283
+ connected ? `\u5DF2\u8FDE\u63A5${item.connection.account_label ? ` \xB7 ${item.connection.account_label}` : ""}${item.name === "connector.builtin.feishu" ? "\uFF0C\u6309\u5DF2\u5F00\u901A\u80FD\u529B\u63D0\u4F9B\u64CD\u4F5C" : item.operations === 0 ? "\uFF0C\u5C1A\u672A\u914D\u7F6E\u4E1A\u52A1\u64CD\u4F5C" : ""}` : item.connection.status === "auth_required" ? "\u9700\u8981\u91CD\u65B0\u8BA4\u8BC1" : "\u672A\u8FDE\u63A5"
284
+ ] }),
285
+ catalog ? /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-center gap-2 border-t border-[hsl(var(--border))] pt-4", children: [
286
+ connectAction,
287
+ useAction,
288
+ manage ? /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-1.5", children: item.source === "personal" ? /* @__PURE__ */ jsxs(Fragment, { children: [
289
+ /* @__PURE__ */ jsx("button", { type: "button", disabled: busy, "aria-label": "\u7F16\u8F91", title: "\u7F16\u8F91\u8FDE\u63A5\u5668", className: iconActionClass, onClick: () => onEdit?.(item), children: /* @__PURE__ */ jsx(Pencil, { size: 15, "aria-hidden": "true" }) }),
290
+ /* @__PURE__ */ jsx("button", { type: "button", disabled: busy, "aria-label": "\u5220\u9664", title: "\u5220\u9664\u8FDE\u63A5\u5668", className: `${iconActionClass} text-[hsl(var(--destructive))] hover:border-[hsl(var(--destructive)/0.3)] hover:bg-[hsl(var(--destructive)/0.08)]`, onClick: () => setDeleting(item), children: /* @__PURE__ */ jsx(Trash2, { size: 15, "aria-hidden": "true" }) })
291
+ ] }) : null }) : null
292
+ ] }) : null
293
+ ] }, item.name);
294
+ }),
295
+ deleting ? /* @__PURE__ */ jsxs("dialog", { ref: deleteDialog, onCancel: (event) => {
296
+ event.preventDefault();
297
+ if (!busy) setDeleting(null);
298
+ }, "aria-label": "\u5220\u9664\u8FDE\u63A5\u5668", className: "fixed inset-0 z-50 m-auto w-[min(420px,calc(100%_-_32px))] rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-5 text-[hsl(var(--popover-foreground))] shadow-xl", children: [
299
+ /* @__PURE__ */ jsxs("p", { className: "text-sm", children: [
300
+ "\u5220\u9664\u300C",
301
+ deleting.display_name || deleting.name,
302
+ "\u300D\u53CA\u5176\u8FDE\u63A5\u4FE1\u606F\uFF1F\u9700\u8981\u4F7F\u7528\u65F6\u53EF\u4EE5\u91CD\u65B0\u521B\u5EFA\u3002"
303
+ ] }),
304
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 flex justify-end gap-3", children: [
305
+ /* @__PURE__ */ jsx("button", { type: "button", disabled: busy, className: actionClass, onClick: () => setDeleting(null), children: "\u53D6\u6D88" }),
306
+ /* @__PURE__ */ jsx("button", { type: "button", disabled: busy, className: `${actionClass} border-transparent bg-[hsl(var(--destructive))] text-white hover:bg-[hsl(var(--destructive)/0.9)]`, onClick: async () => {
307
+ setBusy(true);
308
+ try {
309
+ await client.connectors.delete(deleting.name);
310
+ setDeleting(null);
311
+ await reload();
312
+ } catch (error) {
313
+ setFailure(await failureMessage(error));
314
+ setDeleting(null);
315
+ } finally {
316
+ setBusy(false);
317
+ }
318
+ }, children: busy ? "\u6B63\u5728\u5220\u9664\u2026" : "\u786E\u8BA4\u5220\u9664" })
319
+ ] })
320
+ ] }) : null,
321
+ failure ? /* @__PURE__ */ jsxs("div", { role: "alert", className: "px-3 py-1 text-xs text-[hsl(var(--destructive))]", children: [
322
+ failure,
323
+ /* @__PURE__ */ jsx("button", { type: "button", className: `${actionClass} ml-2`, onClick: () => {
324
+ void reload().catch(() => setFailure("\u8BFB\u53D6\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5"));
325
+ }, children: "\u91CD\u8BD5" })
326
+ ] }) : null,
327
+ editing && ["device", "managed"].includes(editing.authorization?.type ?? "") ? /* @__PURE__ */ jsx(DeviceDialog, { client, connector: editing, onChanged: reload, onClose: () => {
328
+ setEditing(null);
329
+ void reload();
330
+ } }, editing.name) : editing?.authorization?.type === "browser" ? /* @__PURE__ */ jsx(BrowserConnectionDialog, { connector: editing, client, name: editing.name, label: editing.display_name || editing.name, onClose: () => {
331
+ setEditing(null);
332
+ void reload().catch(() => setFailure("\u8BFB\u53D6\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5"));
333
+ } }, editing.name) : editing ? /* @__PURE__ */ jsx(ConnectionDialog, { client, onChanged: reload, connector: editing, onClose: () => setEditing(null), onConnected: async () => {
334
+ const scope = lifetime.current;
335
+ await reload();
336
+ if (scope !== lifetime.current || scope?.signal.aborted) return;
337
+ if (onUse && editing.operations > 0 && !disabledReason) {
338
+ await onUse(editing.name, editing.display_name || editing.name, true);
339
+ if (sessionId) await reload();
340
+ }
341
+ } }, editing.name) : null
342
+ ] });
343
+ }
344
+
345
+ // src/components/ConnectorPanel.tsx
346
+ import { isLocalConnectorName as isLocalConnectorName2 } from "@blade-hq/agent-client/internal";
347
+ import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
348
+ import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
349
+ function PanelDivider() {
350
+ return /* @__PURE__ */ jsx2("div", { className: "my-1 border-[hsl(var(--border))] border-t" });
351
+ }
352
+ function PanelTitle({ children }) {
353
+ return /* @__PURE__ */ jsx2("div", { className: "px-3 pt-1 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children });
354
+ }
355
+ function ConnectorPanel({
356
+ client,
357
+ sessionId,
358
+ pendingPlugins,
359
+ onPendingPluginsChange,
360
+ pendingDisabledReason,
361
+ onPluginsChanged,
362
+ onSelectedChange,
363
+ renderComputerSection,
364
+ renderPhoneSection,
365
+ renderExternalAccounts,
366
+ renderFooterActions,
367
+ className
368
+ }) {
369
+ const [query, setQuery] = useState2("");
370
+ const [selectedConnectors, setSelectedConnectors] = useState2([]);
371
+ const [pendingCatalog, setPendingCatalog] = useState2(null);
372
+ const [pendingLoading, setPendingLoading] = useState2(false);
373
+ const [pendingError, setPendingError] = useState2(false);
374
+ const activation = useSessionPluginActivation({
375
+ client,
376
+ sessionId: sessionId ?? "",
377
+ onChange: onPluginsChanged
378
+ });
379
+ const { reload, items: sessionItems } = activation;
380
+ useEffect2(() => {
381
+ if (sessionId) reload();
382
+ }, [reload, sessionId]);
383
+ const loadPendingCatalog = useCallback2(async () => {
384
+ setPendingLoading(true);
385
+ setPendingError(false);
386
+ try {
387
+ const { plugins } = await client.plugins.catalog();
388
+ setPendingCatalog(plugins);
389
+ } catch {
390
+ setPendingError(true);
391
+ } finally {
392
+ setPendingLoading(false);
393
+ }
394
+ }, [client]);
395
+ useEffect2(() => {
396
+ if (sessionId) return;
397
+ void loadPendingCatalog();
398
+ }, [loadPendingCatalog, sessionId]);
399
+ const selected = useMemo2(
400
+ () => new Set((pendingPlugins ?? []).map((item) => item.name)),
401
+ [pendingPlugins]
402
+ );
403
+ const items = useMemo2(() => {
404
+ if (sessionId) return sessionItems;
405
+ return catalogToConnectorItems(pendingCatalog ?? []).map((item) => ({
406
+ ...item,
407
+ active: selected.has(item.name)
408
+ }));
409
+ }, [pendingCatalog, selected, sessionId, sessionItems]);
410
+ const visibleItems = useMemo2(
411
+ () => sessionId ? filterConnectorItems(items, query) : filterConnectorItems(items, query).map((item) => ({ ...item, config: void 0 })),
412
+ [items, query, sessionId]
413
+ );
414
+ const togglePending = useCallback2((item, next) => {
415
+ const kept = (pendingPlugins ?? []).filter((entry) => entry.name !== item.name);
416
+ onPendingPluginsChange?.(next ? [...kept, selectionFromItem(item)] : kept);
417
+ }, [onPendingPluginsChange, pendingPlugins]);
418
+ const toggle = useCallback2((item, next) => {
419
+ if (sessionId) activation.toggle(item, next);
420
+ else togglePending(item, next);
421
+ }, [activation, sessionId, togglePending]);
422
+ const selectedItems = useMemo2(
423
+ () => [
424
+ ...items.filter((item) => item.active && !isLocalConnectorName2(item.name)),
425
+ ...selectedConnectors.map((item) => ({
426
+ name: item.name,
427
+ display_name: item.display_name,
428
+ icon: item.icon ?? null,
429
+ iconSource: "account",
430
+ installed: true,
431
+ active: true,
432
+ status: "valid",
433
+ projected: false,
434
+ connector: true
435
+ }))
436
+ ],
437
+ [items, selectedConnectors]
438
+ );
439
+ const onSelectedChangeRef = useRef2(onSelectedChange);
440
+ onSelectedChangeRef.current = onSelectedChange;
441
+ const latestSelected = useRef2(selectedItems);
442
+ latestSelected.current = selectedItems;
443
+ const reportSelected = useCallback2(() => {
444
+ onSelectedChangeRef.current?.(latestSelected.current);
445
+ }, []);
446
+ const selectedNames = selectedItems.map((item) => item.name).join("\0");
447
+ useEffect2(reportSelected, [reportSelected, selectedNames]);
448
+ const failed = sessionId ? activation.listError : pendingError;
449
+ return /* @__PURE__ */ jsxs2("div", { className, children: [
450
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 border-[hsl(var(--border))] border-b px-3 py-2", children: [
451
+ /* @__PURE__ */ jsx2(Search, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]", "aria-hidden": "true" }),
452
+ /* @__PURE__ */ jsx2(
453
+ "input",
454
+ {
455
+ value: query,
456
+ onChange: (event) => setQuery(event.target.value),
457
+ placeholder: "\u641C\u7D22\u8FDE\u63A5\u5668",
458
+ "aria-label": "\u641C\u7D22\u8FDE\u63A5\u5668",
459
+ className: "min-w-0 flex-1 bg-transparent text-[11px] outline-none placeholder:text-[hsl(var(--muted-foreground))]"
460
+ }
461
+ )
462
+ ] }),
463
+ renderComputerSection ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
464
+ /* @__PURE__ */ jsx2(PanelTitle, { children: "\u7535\u8111" }),
465
+ renderComputerSection(query)
466
+ ] }) : null,
467
+ renderPhoneSection ? renderPhoneSection(query) : null,
468
+ /* @__PURE__ */ jsx2(PanelDivider, {}),
469
+ /* @__PURE__ */ jsx2(
470
+ AccountConnectors,
471
+ {
472
+ client,
473
+ query,
474
+ sessionId,
475
+ pending: selected,
476
+ onSelectedChange: setSelectedConnectors,
477
+ disabledReason: pendingDisabledReason,
478
+ onUse: async (name, label, enabled, icon) => {
479
+ if (sessionId) {
480
+ const result = await client.sessions.setSessionPluginActivation(sessionId, name, enabled);
481
+ onPluginsChanged?.(result.plugin);
482
+ } else {
483
+ const kept = (pendingPlugins ?? []).filter((item) => item.name !== name);
484
+ onPendingPluginsChange?.(enabled ? [...kept, { name, displayName: label, icon: icon ?? null, iconSource: "account" }] : kept);
485
+ }
486
+ }
487
+ }
488
+ ),
489
+ /* @__PURE__ */ jsx2(PanelDivider, {}),
490
+ /* @__PURE__ */ jsx2(PanelTitle, { children: "\u63D2\u4EF6" }),
491
+ !sessionId ? /* @__PURE__ */ jsx2("div", { className: "px-3 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: "\u5148\u9009\u4E2D\uFF0C\u53D1\u9001\u8FD9\u6761\u6D88\u606F\u65F6\u4F1A\u4E00\u5E76\u542F\u7528" }) : null,
492
+ (sessionId ? activation.loading : pendingLoading) && visibleItems.length === 0 ? /* @__PURE__ */ jsxs2("div", { className: "px-3 py-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
493
+ /* @__PURE__ */ jsx2(LoaderCircle, { size: 12, className: "mr-1 inline animate-spin" }),
494
+ "\u6B63\u5728\u83B7\u53D6\u63D2\u4EF6\u2026"
495
+ ] }) : null,
496
+ failed ? /* @__PURE__ */ jsx2(
497
+ "button",
498
+ {
499
+ type: "button",
500
+ onClick: () => sessionId ? reload() : void loadPendingCatalog(),
501
+ className: "px-3 py-1.5 text-left text-[11px] text-[hsl(var(--muted-foreground))] underline",
502
+ children: "\u63D2\u4EF6\u5217\u8868\u6682\u4E0D\u53EF\u7528\uFF0C\u70B9\u51FB\u91CD\u8BD5"
503
+ }
504
+ ) : null,
505
+ /* @__PURE__ */ jsx2(
506
+ PluginConnectorList,
507
+ {
508
+ client,
509
+ sessionId,
510
+ items: visibleItems.filter((item) => !isLocalConnectorName2(item.name)),
511
+ inFlight: activation.inFlight,
512
+ busy: sessionId ? activation.busy : pendingLoading,
513
+ mutationError: sessionId ? activation.mutationError : false,
514
+ onToggle: toggle,
515
+ onRetry: activation.retry,
516
+ onEditConfig: activation.editConfig,
517
+ configuring: sessionId ? activation.configuring : null,
518
+ onConfigSaved: activation.onConfigSaved,
519
+ onConfigClose: activation.onConfigClose,
520
+ disabledReason: sessionId ? null : pendingDisabledReason,
521
+ unavailableText: failed ? null : query.trim() ? "\u6CA1\u6709\u5339\u914D\u7684\u63D2\u4EF6" : null,
522
+ emptyText: sessionId ? "\u5C1A\u672A\u5B89\u88C5\u63D2\u4EF6" : "\u5C1A\u672A\u5B89\u88C5\u63D2\u4EF6\uFF0C\u53BB\u5E94\u7528\u5E02\u573A\u6DFB\u52A0\u4E00\u4E2A",
523
+ draft: !sessionId
524
+ }
525
+ ),
526
+ renderExternalAccounts ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
527
+ /* @__PURE__ */ jsx2(PanelDivider, {}),
528
+ /* @__PURE__ */ jsx2(PanelTitle, { children: "\u5916\u90E8\u8D26\u53F7" }),
529
+ renderExternalAccounts(query)
530
+ ] }) : null,
531
+ renderFooterActions ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
532
+ /* @__PURE__ */ jsx2(PanelDivider, {}),
533
+ renderFooterActions()
534
+ ] }) : null
535
+ ] });
536
+ }
537
+
538
+ // src/components/PluginTriggerStack.tsx
539
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
540
+ var AVATAR_SIZE = 20;
541
+ function hueOf(name) {
542
+ let hash = 0;
543
+ for (const char of name) hash = (hash * 31 + char.codePointAt(0)) % 1000003;
544
+ return hash % 360;
545
+ }
546
+ var AVATAR_PALETTE = [
547
+ "bg-violet-100 text-violet-800 dark:bg-violet-500/25 dark:text-violet-200",
548
+ "bg-sky-100 text-sky-800 dark:bg-sky-500/25 dark:text-sky-200",
549
+ "bg-emerald-100 text-emerald-800 dark:bg-emerald-500/25 dark:text-emerald-200",
550
+ "bg-amber-100 text-amber-800 dark:bg-amber-500/25 dark:text-amber-200",
551
+ "bg-rose-100 text-rose-800 dark:bg-rose-500/25 dark:text-rose-200",
552
+ "bg-indigo-100 text-indigo-800 dark:bg-indigo-500/25 dark:text-indigo-200",
553
+ "bg-teal-100 text-teal-800 dark:bg-teal-500/25 dark:text-teal-200",
554
+ "bg-fuchsia-100 text-fuchsia-800 dark:bg-fuchsia-500/25 dark:text-fuchsia-200"
555
+ ];
556
+ function PluginTriggerStack({ client, sessionId, summary, className }) {
557
+ if (summary.total === 0) return null;
558
+ const ring = "ring-2 ring-[hsl(var(--background))]";
559
+ return /* @__PURE__ */ jsxs3("span", { className: `flex items-center -space-x-1 ${className ?? ""}`, children: [
560
+ summary.visible.map((item) => {
561
+ const label = item.displayName?.trim() || item.name;
562
+ const tone = AVATAR_PALETTE[hueOf(item.name) % AVATAR_PALETTE.length];
563
+ return item.icon ? /* @__PURE__ */ jsx3(
564
+ SessionPluginIcon,
565
+ {
566
+ client,
567
+ sessionId: item.iconSource === "account" ? null : sessionId,
568
+ plugin: item,
569
+ size: AVATAR_SIZE,
570
+ shape: "circle",
571
+ className: ring
572
+ },
573
+ item.name
574
+ ) : /* @__PURE__ */ jsx3(
575
+ "span",
576
+ {
577
+ title: label,
578
+ className: `flex shrink-0 items-center justify-center rounded-full font-semibold text-[11px] ${tone} ${ring}`,
579
+ style: { width: AVATAR_SIZE, height: AVATAR_SIZE },
580
+ children: Array.from(label.trim())[0]?.toUpperCase() ?? "?"
581
+ },
582
+ item.name
583
+ );
584
+ }),
585
+ summary.overflow > 0 ? /* @__PURE__ */ jsxs3(
586
+ "span",
587
+ {
588
+ className: `flex shrink-0 items-center justify-center rounded-full bg-[hsl(var(--muted))] font-medium text-[hsl(var(--muted-foreground))] text-[10px] ${ring}`,
589
+ style: { width: AVATAR_SIZE, height: AVATAR_SIZE },
590
+ children: [
591
+ "+",
592
+ summary.overflow
593
+ ]
594
+ }
595
+ ) : null
596
+ ] });
597
+ }
598
+
599
+ export {
600
+ selectionFromItem,
601
+ TRIGGER_ICON_LIMIT,
602
+ triggerSummary,
603
+ AccountConnectors,
604
+ ConnectorPanel,
605
+ PluginTriggerStack
606
+ };
607
+ //# sourceMappingURL=chunk-FBGCDXRK.js.map