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