@blade-hq/agent-react 2612.0.0-beta.75 → 2612.0.0-beta.77

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 (42) hide show
  1. package/README.md +4 -0
  2. package/dist/chat/TurnNavRail.d.ts +1 -4
  3. package/dist/chat/index.d.ts +2 -1
  4. package/dist/chat/turn-locate-channel.d.ts +53 -0
  5. package/dist/{chunk-HCW7SI5Q.js → chunk-26NE55SJ.js} +4 -4
  6. package/dist/{chunk-WRIMPZPN.js → chunk-EQOKPZI2.js} +35 -21
  7. package/dist/chunk-EQOKPZI2.js.map +1 -0
  8. package/dist/{chunk-2DPLLZOU.js → chunk-F2IJZX2Z.js} +3 -3
  9. package/dist/{chunk-XP6T6SHZ.js → chunk-IVGTMWRV.js} +908 -755
  10. package/dist/chunk-IVGTMWRV.js.map +1 -0
  11. package/dist/{chunk-XJ6ZA6LN.js → chunk-VBHHFIII.js} +3 -3
  12. package/dist/{chunk-J72ZLILV.js → chunk-WO2VCQ5N.js} +5 -2
  13. package/dist/chunk-WO2VCQ5N.js.map +1 -0
  14. package/dist/{chunk-QIR73CES.js → chunk-XBEN2ASY.js} +7776 -7140
  15. package/dist/chunk-XBEN2ASY.js.map +1 -0
  16. package/dist/{chunk-7MCGQH34.js → chunk-ZIECHNZA.js} +14 -7
  17. package/dist/chunk-ZIECHNZA.js.map +1 -0
  18. package/dist/components/AccountConnectorRules.d.ts +7 -0
  19. package/dist/components/ConnectorRulesPanel.d.ts +9 -0
  20. package/dist/connectors.d.ts +1 -0
  21. package/dist/connectors.js +5 -2
  22. package/dist/hooks/use-turn-navigation.d.ts +19 -0
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +10 -7
  25. package/dist/internal.d.ts +1 -1
  26. package/dist/internal.js +10 -8
  27. package/dist/internal.js.map +1 -1
  28. package/dist/questions.js +3 -3
  29. package/dist/rich-input.js +21 -5
  30. package/dist/rich-input.js.map +1 -1
  31. package/dist/style.full.css +1 -1
  32. package/dist/tool-details.js +4 -4
  33. package/package.json +2 -2
  34. package/public-api.md +7 -1
  35. package/dist/chunk-7MCGQH34.js.map +0 -1
  36. package/dist/chunk-J72ZLILV.js.map +0 -1
  37. package/dist/chunk-QIR73CES.js.map +0 -1
  38. package/dist/chunk-WRIMPZPN.js.map +0 -1
  39. package/dist/chunk-XP6T6SHZ.js.map +0 -1
  40. /package/dist/{chunk-HCW7SI5Q.js.map → chunk-26NE55SJ.js.map} +0 -0
  41. /package/dist/{chunk-2DPLLZOU.js.map → chunk-F2IJZX2Z.js.map} +0 -0
  42. /package/dist/{chunk-XJ6ZA6LN.js.map → chunk-VBHHFIII.js.map} +0 -0
@@ -5,13 +5,14 @@ import {
5
5
  catalogToConnectorItems,
6
6
  filterConnectorItems,
7
7
  useSessionPluginActivation
8
- } from "./chunk-2DPLLZOU.js";
8
+ } from "./chunk-F2IJZX2Z.js";
9
9
  import {
10
10
  ConnectorConnection
11
- } from "./chunk-J72ZLILV.js";
11
+ } from "./chunk-WO2VCQ5N.js";
12
12
  import {
13
+ AccountConnectorRules,
13
14
  BrowserConnectionDialog
14
- } from "./chunk-WRIMPZPN.js";
15
+ } from "./chunk-EQOKPZI2.js";
15
16
  import {
16
17
  Check,
17
18
  LoaderCircle,
@@ -21,7 +22,7 @@ import {
21
22
  Search,
22
23
  Trash2,
23
24
  Unplug
24
- } from "./chunk-QIR73CES.js";
25
+ } from "./chunk-XBEN2ASY.js";
25
26
 
26
27
  // src/components/connector-panel-types.ts
27
28
  function selectionFromItem(item) {
@@ -62,6 +63,7 @@ async function failureMessage(error) {
62
63
  return "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5";
63
64
  }
64
65
  function DeviceDialog({ client, connector, onChanged, onClose }) {
66
+ const [rulesRefresh, setRulesRefresh] = useState(0);
65
67
  const dialog = useRef(null);
66
68
  useEffect(() => {
67
69
  const element = dialog.current;
@@ -72,7 +74,11 @@ function DeviceDialog({ client, connector, onChanged, onClose }) {
72
74
  event.preventDefault();
73
75
  onClose();
74
76
  }, 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) }),
77
+ /* @__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: async () => {
78
+ await onChanged();
79
+ setRulesRefresh((value) => value + 1);
80
+ }, onDisable: () => client.connectors.disconnect(connector.name) }),
81
+ /* @__PURE__ */ jsx(AccountConnectorRules, { client, name: connector.name, refresh: rulesRefresh }),
76
82
  /* @__PURE__ */ jsx("button", { type: "button", className: actionClass, onClick: onClose, children: "\u8FD4\u56DE\u8FDE\u63A5\u5668" })
77
83
  ] });
78
84
  }
@@ -159,6 +165,7 @@ function ConnectionDialog({ client, connector, onConnected, onClose }) {
159
165
  }
160
166
  }
161
167
  ) : null,
168
+ /* @__PURE__ */ jsx(AccountConnectorRules, { client, name: connector.name }),
162
169
  connected ? /* @__PURE__ */ jsx("output", { className: "block text-sm", children: failure || "\u8D26\u53F7\u5DF2\u8FDE\u63A5\u3002" }) : null,
163
170
  !view || connected ? /* @__PURE__ */ jsx("button", { type: "button", className: `${actionClass} mt-3`, onClick: onClose, children: "\u5173\u95ED" }) : null
164
171
  ] })
@@ -233,7 +240,7 @@ function AccountConnectors({ client, query = "", sessionId = null, pending, onUs
233
240
  setEditing(item);
234
241
  }, children: [
235
242
  /* @__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"
243
+ ["device", "managed"].includes(item.authorization?.type ?? "") ? "\u7BA1\u7406\u6388\u6743" : connected ? "\u7BA1\u7406\u8FDE\u63A5" : "\u8FDE\u63A5"
237
244
  ] });
238
245
  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
246
  const scope = lifetime.current;
@@ -602,4 +609,4 @@ export {
602
609
  ConnectorPanel,
603
610
  PluginTriggerStack
604
611
  };
605
- //# sourceMappingURL=chunk-7MCGQH34.js.map
612
+ //# sourceMappingURL=chunk-ZIECHNZA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/connector-panel-types.ts","../src/components/AccountConnectors.tsx","../src/components/ConnectorPanel.tsx","../src/components/PluginTriggerStack.tsx"],"sourcesContent":["import type { PluginConnectorItem } from \"./plugin-connector\"\n\n/**\n * 首页选中的一个待选插件。\n *\n * 带上展示名和图标是为了两件事:后续的配置弹窗与失败提示能一直用业务名(只传技术\n * ID 的话,用户在面板里看到「示例登录」、在弹窗标题里看到 `demo-login`,等于要他认\n * 两遍),以及不用打开面板就能在触发器上看到自己选了什么。\n *\n * 技术 ID 仍是路径、授权、缓存与调用的权威。\n */\nexport interface PluginConnectorSelection {\n name: string\n displayName: string | null\n icon: string | null\n iconSource: PluginConnectorItem[\"iconSource\"]\n}\n\n/** 面板一行 → 待选条目。 */\nexport function selectionFromItem(item: PluginConnectorItem): PluginConnectorSelection {\n return {\n name: item.name,\n displayName: item.display_name ?? null,\n icon: item.icon,\n iconSource: item.iconSource,\n }\n}\n\n/** 触发器上最多直接显示几个插件头像,其余折成数量。 */\nexport const TRIGGER_ICON_LIMIT = 3\n\n/** 触发器上的头像堆叠内容:前三个 + 折起来的数量。 */\nexport interface TriggerSummary {\n /** 前 TRIGGER_ICON_LIMIT 个选中项,**不管有没有图标 token**。 */\n visible: Array<Pick<PluginConnectorSelection, \"name\" | \"displayName\" | \"icon\" | \"iconSource\">>\n /** 超出 TRIGGER_ICON_LIMIT 的数量;0 表示不显示 `+N`。 */\n overflow: number\n /** 已选/已启用的总数,用于无障碍标签与提示。 */\n total: number\n}\n\n/**\n * 把一份插件列表折成触发器上的头像堆叠。\n *\n * 前三项都占位,**不管有没有图标 token**:没有图标的用显示名首字起头的圆形占位,\n * 「选了哪个」照样看得见。早先的实现把无图标的项从图标位里剔掉、还把它们算进\n * `overflow`,于是选中一个没有图标的插件时触发器毫无变化——选择在入口上不可见。\n */\nexport function triggerSummary(\n items: Array<Pick<PluginConnectorSelection, \"name\" | \"displayName\" | \"icon\" | \"iconSource\">>,\n): TriggerSummary {\n const visible = items.slice(0, TRIGGER_ICON_LIMIT)\n return {\n visible,\n overflow: items.length - visible.length,\n total: items.length,\n }\n}\n","import { isLocalConnectorName } from \"@blade-hq/agent-client/internal\"\nimport type { AccountConnector, BladeClient, ConnectorConnectionView } from \"@blade-hq/agent-client/internal\"\nimport { Check, Pencil, Plug, RefreshCw, Trash2, Unplug } from \"lucide-react\"\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { SessionPluginIcon } from \"./SessionPluginIcon\"\nimport { AccountConnectorRules } from \"./AccountConnectorRules\"\nimport { ConnectorConnection } from \"./ConnectorConnection\"\nimport { BrowserConnectionDialog } from \"./BrowserConnectionDialog\"\nimport { SessionPluginConfigForm } from \"./SessionPluginConfigForm\"\n\nconst 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\"\nconst actionClass = `${actionBaseClass} px-3`\nconst iconActionClass = `${actionBaseClass} w-8 p-0`\n\nasync function failureMessage(error: unknown): Promise<string> {\n const response = (error as { response?: Response })?.response\n if (response) {\n try {\n const body = await response.json()\n if (typeof body.detail === \"string\") return body.detail\n if (typeof body.detail?.message === \"string\") return body.detail.message\n } catch { /* Use a stable message without response contents. */ }\n }\n return \"操作未完成,请重试\"\n}\n\nfunction DeviceDialog({ client, connector, onChanged, onClose }: {\n client: BladeClient; connector: AccountConnector; onChanged: () => Promise<unknown>; onClose: () => void\n}) {\n const [rulesRefresh,setRulesRefresh]=useState(0)\n const dialog = useRef<HTMLDialogElement>(null)\n useEffect(() => { const element = dialog.current; element?.showModal(); return () => element?.close() }, [])\n return <dialog ref={dialog} aria-label={`连接 ${connector.display_name || connector.name}`} onCancel={(event) => { event.preventDefault(); onClose() }} 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\">\n <ConnectorConnection type={connector.authorization?.type === \"managed\" ? \"managed\" : \"device\"} read={() => client.connectors.authorization(connector.name)} act={(action, options) => client.connectors.authorize(connector.name, action, undefined, options)} plan={capabilities => client.connectors.authorizationPlan(connector.name, capabilities)} diagnostics={() => client.connectors.diagnostics(connector.name)} onChanged={async () => {await onChanged();setRulesRefresh(value => value+1)}} onDisable={() => client.connectors.disconnect(connector.name)} />\n <AccountConnectorRules client={client} name={connector.name} refresh={rulesRefresh} />\n <button type=\"button\" className={actionClass} onClick={onClose}>返回连接器</button>\n </dialog>\n}\n\nfunction ConnectionDialog({ client, connector, onConnected, onClose }: {\n client: BladeClient\n connector: AccountConnector\n onConnected: () => Promise<void>\n onClose: () => void\n}) {\n const [view, setView] = useState<ConnectorConnectionView | null>(null)\n const [failure, setFailure] = useState<string | null>(null)\n const [submitting, setSubmitting] = useState(false)\n const [connected, setConnected] = useState(false)\n const dialog = useRef<HTMLDialogElement | null>(null)\n const connectionRequest = useRef<AbortController | null>(null)\n useEffect(() => () => connectionRequest.current?.abort(), [])\n useEffect(() => {\n const element = dialog.current\n element?.showModal()\n return () => element?.close()\n }, [])\n useEffect(() => {\n const abort = new AbortController()\n client.connectors.read(connector.name, { signal: abort.signal }).then((value) => {\n if (!abort.signal.aborted) setView(value)\n }).catch(async (error) => {\n const message = await failureMessage(error)\n if (!abort.signal.aborted) setFailure(message)\n })\n return () => abort.abort()\n }, [client, connector.name])\n\n return (\n <dialog\n ref={dialog} aria-label={`连接 ${connector.display_name || connector.name}`}\n 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\"\n onCancel={(event) => { event.preventDefault(); if (!submitting) onClose() }}\n >\n <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\">\n <div className=\"mb-3 text-sm font-medium\">连接 {connector.display_name || connector.name}</div>\n <p className=\"mb-3 text-xs text-[hsl(var(--muted-foreground))]\">{view?.config.state === \"not_required\" ? \"无需填写账号,验证连接后即可使用。\" : \"填写你的账号信息,验证通过后可在对话中使用。\"}</p>\n {!view ? <div className=\"text-xs\">{failure || \"正在获取认证表单…\"}</div> : !connected ? (\n <SessionPluginConfigForm\n config={view.config} submitting={submitting} errors={[]} failure={failure}\n submitLabel=\"连接并验证\" submittingLabel=\"正在连接…\" onCancel={onClose}\n onSubmit={async (draft) => {\n setSubmitting(true)\n setFailure(null)\n const request = new AbortController()\n connectionRequest.current = request\n try {\n const connected = await client.connectors.connect(connector.name, {\n expected_revision: view.config.revision, set: draft.set, remove: draft.remove,\n }, { signal: request.signal })\n if (request.signal.aborted) return\n setView(connected)\n setConnected(true)\n try { await onConnected() }\n catch { if(!request.signal.aborted)setFailure(\"已连接,但列表或对话状态未能刷新。请返回后重试刷新或启用。\"); return }\n if (!request.signal.aborted) onClose()\n } catch (error) {\n if (request.signal.aborted) return\n setFailure(await failureMessage(error))\n // A failed login may still have saved the configuration. Reload\n // its revision so retry doesn't submit a stale version.\n try { setView(await client.connectors.read(connector.name)) } catch { /* Keep the form. */ }\n } finally { if (!request.signal.aborted) setSubmitting(false) }\n }}\n />\n ) : null}\n <AccountConnectorRules client={client} name={connector.name} />\n {connected ? <output className=\"block text-sm\">{failure || \"账号已连接。\"}</output> : null}\n {!view || connected ? <button type=\"button\" className={`${actionClass} mt-3`} onClick={onClose}>关闭</button> : null}\n </div>\n </dialog>\n )\n}\n\nexport function AccountConnectors({ client, query = \"\", sessionId = null, pending, onUse, onSelectedChange, disabledReason, catalog = false, manage = false, onEdit }: {\n client: BladeClient\n query?: string\n sessionId?: string | null\n pending?: Set<string>\n onUse?: (name: string, label: string, enabled: boolean, icon?: string | null) => Promise<void>\n onSelectedChange?: (items: AccountConnector[]) => void\n disabledReason?: string | null\n manage?: boolean\n onEdit?: (item: AccountConnector) => void\n catalog?: boolean\n}) {\n const [items, setItems] = useState<AccountConnector[]>([])\n const [editing, setEditing] = useState<AccountConnector | null>(null)\n const [failure, setFailure] = useState<string | null>(null)\n const [loading, setLoading] = useState(true)\n const deleteDialog = useRef<HTMLDialogElement>(null)\n const [deleting, setDeleting] = useState<AccountConnector | null>(null)\n const [busy, setBusy] = useState(false)\n useEffect(() => {\n if (!deleting) return\n const element = deleteDialog.current\n element?.showModal()\n return () => element?.close()\n }, [deleting])\n const lifetime = useRef<AbortController | null>(null)\n const load = useCallback((signal?: AbortSignal) => sessionId\n ? client.connectors.listForSession(sessionId, { signal })\n : client.connectors.list({ signal }), [client, sessionId])\n const reload = useCallback(async () => {\n const scope = lifetime.current\n const result = await load(scope?.signal)\n if (scope === lifetime.current && !scope?.signal.aborted) { setItems(result.connectors); setFailure(null) }\n }, [load])\n useEffect(() => {\n const abort = new AbortController()\n lifetime.current = abort\n setItems([])\n setEditing(null)\n setLoading(true)\n setFailure(null)\n load(abort.signal).then((value) => {\n if (!abort.signal.aborted) setItems(value.connectors)\n }).catch(async (error) => {\n const message = await failureMessage(error)\n if (!abort.signal.aborted) setFailure(message)\n }).finally(() => { if (!abort.signal.aborted) setLoading(false) })\n return () => abort.abort()\n }, [load])\n const visible = useMemo(() => {\n const result=items.map((item)=>({...item,active:sessionId?item.active:Boolean(pending?.has(item.name))}))\n if(!sessionId)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:\"连接器已移除或暂不可用,可取消选择后继续。\",source:name.startsWith(\"connector.builtin.\")?\"builtin\":\"personal\",operations:0,available:false,active:true,connection:{status:\"disconnected\",revision:0,account_label:\"\",verified_at:\"\"}})\n return result\n },[items,pending,sessionId])\n const selected = useRef(onSelectedChange)\n selected.current = onSelectedChange\n useEffect(() => { selected.current?.(visible.filter((item) => item.active)) }, [visible])\n const matching = visible.filter((item) => `${item.display_name} ${item.description}`.toLowerCase().includes(query.trim().toLowerCase()))\n\n return (\n <div className={catalog ? \"grid gap-4 sm:grid-cols-2 xl:grid-cols-3\" : undefined}>\n {!catalog ? <div className=\"px-3 pt-1 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]\">连接器</div> : null}\n {loading ? <p className=\"px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]\">正在读取连接器…</p> : null}\n {!loading && !failure && matching.length === 0 ? <p className=\"px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]\">{query.trim() ? \"没有匹配的连接器\" : \"暂无连接器\"}</p> : null}\n {matching.map((item) => {\n const connected = item.connection.status === \"connected\"\n const label = item.display_name || item.name\n const ConnectIcon = connected ? RefreshCw : Plug\n const connectionClass = `${actionClass} ${!connected ? \"border-transparent bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] hover:bg-[hsl(var(--primary)/0.9)]\" : \"\"}`\n const connectAction = (\n <button type=\"button\" disabled={busy || item.available === false} className={connectionClass} onClick={() => { setFailure(null); setEditing(item) }}><ConnectIcon size={14} aria-hidden=\"true\" />{[\"device\", \"managed\"].includes(item.authorization?.type ?? \"\") ? \"管理授权\" : connected ? \"管理连接\" : \"连接\"}</button>\n )\n const useAction = onUse && (item.active || connected && item.operations > 0) ? (\n <button type=\"button\" disabled={busy || Boolean(disabledReason)} title={disabledReason ?? undefined} className={actionClass} onClick={async () => {\n const scope = lifetime.current\n setBusy(true)\n setFailure(null)\n try {\n await onUse(item.name, label, !item.active, item.icon ?? null)\n if (sessionId) await reload()\n } catch (error) {\n const message = await failureMessage(error)\n if (scope === lifetime.current && !scope?.signal.aborted) setFailure(message)\n }\n finally { if (scope === lifetime.current && !scope?.signal.aborted) setBusy(false) }\n }}>{item.active ? <Check size={14} aria-hidden=\"true\" /> : null}{item.active ? \"已启用\" : \"使用\"}</button>\n ) : null\n return (\n <div key={item.name} className={catalog ? \"flex flex-col rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-5\" : \"px-3 py-1.5\"}>\n <div className={`flex items-center gap-2 ${catalog ? \"text-sm\" : \"text-[11px]\"}`}>\n <SessionPluginIcon client={client} sessionId={null} plugin={{ name: item.name, icon: item.icon ?? null }} size={catalog ? 32 : 20} />\n <span className=\"min-w-0 flex-1 truncate font-medium\" title={label}>{label}</span>\n <span className=\"shrink-0 rounded-md bg-[hsl(var(--muted))] px-1.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]\">{item.source === \"builtin\" ? \"内置\" : \"我创建的\"}</span>\n {!catalog ? <>{connectAction}{useAction}</> : null}\n </div>\n {catalog ? <p className=\"mt-2 flex-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]\">{item.description}</p> : null}\n <div className=\"mt-3 flex items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]\">\n <span aria-hidden=\"true\" className={`size-1.5 shrink-0 rounded-full ${connected ? \"bg-emerald-500\" : \"bg-[hsl(var(--muted-foreground)/0.4)]\"}`} />\n {connected ? `已连接${item.connection.account_label ? ` · ${item.connection.account_label}` : \"\"}${item.name === \"connector.builtin.feishu\" ? \",按已开通能力提供操作\" : item.operations === 0 ? \",尚未配置业务操作\" : \"\"}` : item.connection.status === \"auth_required\" ? \"需要重新认证\" : \"未连接\"}\n </div>\n {catalog ? <div className=\"mt-4 flex items-center gap-2 border-t border-[hsl(var(--border))] pt-4\">\n {connectAction}{useAction}\n {manage ? <div className=\"ml-auto flex items-center gap-1.5\">\n {<button type=\"button\" disabled={busy} aria-label={[\"device\", \"managed\"].includes(item.authorization?.type ?? \"\") ? \"停用 BA 连接\" : \"断开\"} title={[\"device\", \"managed\"].includes(item.authorization?.type ?? \"\") ? \"仅停用 BA,SuperWork 账号和消息订阅保留\" : \"断开连接\"} className={iconActionClass} onClick={async () => {\n setBusy(true)\n try { await client.connectors.disconnect(item.name); await reload() }\n catch (error) { setFailure(await failureMessage(error)) }\n finally { setBusy(false) }\n }}><Unplug size={15} aria-hidden=\"true\" /></button>}\n {item.source === \"personal\" ? <>\n <button type=\"button\" disabled={busy} aria-label=\"编辑\" title=\"编辑连接器\" className={iconActionClass} onClick={() => onEdit?.(item)}><Pencil size={15} aria-hidden=\"true\" /></button>\n <button type=\"button\" disabled={busy} aria-label=\"删除\" title=\"删除连接器\" className={`${iconActionClass} text-[hsl(var(--destructive))] hover:border-[hsl(var(--destructive)/0.3)] hover:bg-[hsl(var(--destructive)/0.08)]`} onClick={() => setDeleting(item)}><Trash2 size={15} aria-hidden=\"true\" /></button>\n </> : null}\n </div> : null}\n </div> : null}\n </div>\n )\n })}\n {deleting ? <dialog ref={deleteDialog} onCancel={(event) => { event.preventDefault(); if (!busy) setDeleting(null) }} aria-label=\"删除连接器\" 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\">\n <p className=\"text-sm\">删除「{deleting.display_name || deleting.name}」及其连接信息?需要使用时可以重新创建。</p>\n <div className=\"mt-4 flex justify-end gap-3\">\n <button type=\"button\" disabled={busy} className={actionClass} onClick={() => setDeleting(null)}>取消</button>\n <button type=\"button\" disabled={busy} className={`${actionClass} border-transparent bg-[hsl(var(--destructive))] text-white hover:bg-[hsl(var(--destructive)/0.9)]`} onClick={async () => {\n setBusy(true)\n try { await client.connectors.delete(deleting.name); setDeleting(null); await reload() }\n catch (error) { setFailure(await failureMessage(error)); setDeleting(null) }\n finally { setBusy(false) }\n }}>{busy ? \"正在删除…\" : \"确认删除\"}</button>\n </div>\n </dialog> : null}\n {failure ? <div role=\"alert\" className=\"px-3 py-1 text-xs text-[hsl(var(--destructive))]\">{failure}<button type=\"button\" className={`${actionClass} ml-2`} onClick={() => { void reload().catch(() => setFailure(\"读取失败,请重试\")) }}>重试</button></div> : null}\n {editing && [\"device\", \"managed\"].includes(editing.authorization?.type ?? \"\") ? <DeviceDialog key={editing.name} client={client} connector={editing} onChanged={reload} onClose={() => { setEditing(null); void reload() }} /> : editing?.authorization?.type === \"browser\" ? <BrowserConnectionDialog key={editing.name} client={client} name={editing.name} label={editing.display_name || editing.name} onClose={() => {\n setEditing(null)\n void reload().catch(() => setFailure(\"读取失败,请重试\"))\n }} /> : editing ? <ConnectionDialog key={editing.name} client={client} connector={editing} onClose={() => setEditing(null)} onConnected={async () => {\n const scope = lifetime.current\n await reload()\n if (scope !== lifetime.current || scope?.signal.aborted) return\n if (onUse && editing.operations > 0 && !disabledReason) {\n await onUse(editing.name, editing.display_name || editing.name, true)\n if (sessionId) await reload()\n }\n }} /> : null}\n </div>\n )\n}\n","import { isLocalConnectorName } from \"@blade-hq/agent-client/internal\"\nimport type { AccountConnector, BladeClient, PluginCatalogEntry, SessionPluginActivation } from \"@blade-hq/agent-client/internal\"\nimport { Loader2, Search } from \"lucide-react\"\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from \"react\"\nimport { PluginConnectorList } from \"./PluginConnectorList\"\nimport { useSessionPluginActivation } from \"./use-session-plugin-activation\"\nimport { catalogToConnectorItems, filterConnectorItems, type PluginConnectorItem } from \"./plugin-connector\"\nimport { selectionFromItem, type PluginConnectorSelection } from \"./connector-panel-types\"\nimport { AccountConnectors } from \"./AccountConnectors\"\n\nexport interface ConnectorPanelProps {\n client: BladeClient\n /**\n * `null` 表示首页:插件开关只记下本次输入的待选,不激活任何东西、不建会话、\n * 不启动沙盒或 MCP。待选项随首条消息一起交给宿主处理。\n */\n sessionId: string | null\n /** 首页待选插件;`sessionId` 为 null 时使用。 */\n pendingPlugins?: PluginConnectorSelection[]\n onPendingPluginsChange?: (next: PluginConnectorSelection[]) => void\n /** 首页候选开关不可用时的说明(例如软件工厂模式会先建项目再启动)。 */\n pendingDisabledReason?: string | null\n /** 会话内插件启用/停用结果;宿主据此刷新技能统计。 */\n onPluginsChanged?: (plugin: SessionPluginActivation) => void\n /**\n * 当前已选(首页待选 / 会话内已启用)的插件,按行原样报给宿主。\n *\n * 触发器要在不打开面板时就能显示「选了哪几个、几个」,它自己拿不到这份状态,\n * 所以由面板单向汇报;面板未挂载时宿主保留上一次的结果。\n */\n onSelectedChange?: (items: PluginConnectorItem[]) => void\n /** 宿主注入:电脑分区。参数是搜索词,宿主自己决定怎么过滤。 */\n renderComputerSection?: (query: string) => ReactNode\n /** 宿主注入:手机分区,渲染在电脑下面。参数是搜索词。 */\n renderPhoneSection?: (query: string) => ReactNode\n /** 宿主注入:外部账号分区(飞书 / GitHub 等固定连接入口)。 */\n renderExternalAccounts?: (query: string) => ReactNode\n /** 宿主注入:底部操作区;不注入就不渲染这一块。 */\n renderFooterActions?: () => ReactNode\n className?: string\n}\n\nfunction PanelDivider() {\n return <div className=\"my-1 border-[hsl(var(--border))] border-t\" />\n}\n\nfunction PanelTitle({ children }: { children: ReactNode }) {\n return (\n <div className=\"px-3 pt-1 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]\">\n {children}\n </div>\n )\n}\n\n/**\n * 统一连接器面板:顶部搜索、按「电脑 / 插件 / 外部账号」分区、底部添加与管理。\n *\n * 插件分区是这一层唯一的共享实现:首页和会话用同一个列表、同一套启用判定,\n * 判定不各写一份。电脑与外部账号由宿主注入——那些入口需要宿主的路由与 CLI\n * 引导,SDK 不硬编码内部路径,也不替第三方决定跳到哪里。\n */\nexport function ConnectorPanel({\n client,\n sessionId,\n pendingPlugins,\n onPendingPluginsChange,\n pendingDisabledReason,\n onPluginsChanged,\n onSelectedChange,\n renderComputerSection,\n renderPhoneSection,\n renderExternalAccounts,\n renderFooterActions,\n className,\n}: ConnectorPanelProps) {\n const [query, setQuery] = useState(\"\")\n const [selectedConnectors, setSelectedConnectors] = useState<AccountConnector[]>([])\n const [pendingCatalog, setPendingCatalog] = useState<PluginCatalogEntry[] | null>(null)\n const [pendingLoading, setPendingLoading] = useState(false)\n const [pendingError, setPendingError] = useState(false)\n\n const activation = useSessionPluginActivation({\n client,\n sessionId: sessionId ?? \"\",\n onChange: onPluginsChanged,\n })\n const { reload, items: sessionItems } = activation\n\n useEffect(() => {\n if (sessionId) reload()\n }, [reload, sessionId])\n\n const loadPendingCatalog = useCallback(async () => {\n setPendingLoading(true)\n setPendingError(false)\n try {\n const { plugins } = await client.plugins.catalog()\n setPendingCatalog(plugins)\n } catch {\n setPendingError(true)\n } finally {\n setPendingLoading(false)\n }\n }, [client])\n\n useEffect(() => {\n if (sessionId) return\n void loadPendingCatalog()\n }, [loadPendingCatalog, sessionId])\n\n const selected = useMemo(\n () => new Set((pendingPlugins ?? []).map((item) => item.name)),\n [pendingPlugins],\n )\n const items = useMemo(() => {\n if (sessionId) return sessionItems\n return catalogToConnectorItems(pendingCatalog ?? []).map((item) => ({\n ...item,\n active: selected.has(item.name),\n }))\n }, [pendingCatalog, selected, sessionId, sessionItems])\n const visibleItems = useMemo(\n () => (sessionId\n ? filterConnectorItems(items, query)\n : filterConnectorItems(items, query).map((item) => ({ ...item, config: undefined }))),\n [items, query, sessionId],\n )\n\n const togglePending = useCallback((item: PluginConnectorItem, next: boolean) => {\n const kept = (pendingPlugins ?? []).filter((entry) => entry.name !== item.name)\n onPendingPluginsChange?.(next ? [...kept, selectionFromItem(item)] : kept)\n }, [onPendingPluginsChange, pendingPlugins])\n\n const toggle = useCallback((item: PluginConnectorItem, next: boolean) => {\n if (sessionId) activation.toggle(item, next)\n else togglePending(item, next)\n }, [activation, sessionId, togglePending])\n\n const selectedItems = useMemo(\n () => [\n ...items.filter((item) => item.active && !isLocalConnectorName(item.name)),\n ...selectedConnectors.map((item) => ({\n name: item.name, display_name: item.display_name, icon: item.icon ?? null,\n iconSource: \"account\" as const, installed: true, active: true,\n status: \"valid\", projected: false, connector: true,\n })),\n ],\n [items, selectedConnectors],\n )\n const onSelectedChangeRef = useRef(onSelectedChange)\n onSelectedChangeRef.current = onSelectedChange\n const latestSelected = useRef(selectedItems)\n latestSelected.current = selectedItems\n const reportSelected = useCallback(() => {\n onSelectedChangeRef.current?.(latestSelected.current)\n }, [])\n const selectedNames = selectedItems.map((item) => item.name).join(\"\\u0000\")\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: selectedNames 是选中集合的稳定指纹\n useEffect(reportSelected, [reportSelected, selectedNames])\n\n const failed = sessionId ? activation.listError : pendingError\n\n return (\n <div className={className}>\n <div className=\"flex items-center gap-2 border-[hsl(var(--border))] border-b px-3 py-2\">\n <Search size={12} className=\"shrink-0 text-[hsl(var(--muted-foreground))]\" aria-hidden=\"true\" />\n <input\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n placeholder=\"搜索连接器\"\n aria-label=\"搜索连接器\"\n className=\"min-w-0 flex-1 bg-transparent text-[11px] outline-none placeholder:text-[hsl(var(--muted-foreground))]\"\n />\n </div>\n\n {renderComputerSection ? (\n <>\n <PanelTitle>电脑</PanelTitle>\n {renderComputerSection(query)}\n </>\n ) : null}\n\n {renderPhoneSection ? renderPhoneSection(query) : null}\n\n <PanelDivider />\n <AccountConnectors\n client={client} query={query} sessionId={sessionId} pending={selected}\n onSelectedChange={setSelectedConnectors} disabledReason={pendingDisabledReason}\n onUse={async (name, label, enabled, icon) => {\n if (sessionId) {\n const result = await client.sessions.setSessionPluginActivation(sessionId, name, enabled)\n onPluginsChanged?.(result.plugin)\n } else {\n const kept = (pendingPlugins ?? []).filter((item) => item.name !== name)\n onPendingPluginsChange?.(enabled ? [...kept, { name, displayName: label, icon: icon ?? null, iconSource: \"account\" }] : kept)\n }\n }}\n />\n <PanelDivider />\n <PanelTitle>插件</PanelTitle>\n {!sessionId ? (\n <div className=\"px-3 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]\">\n 先选中,发送这条消息时会一并启用\n </div>\n ) : null}\n {(sessionId ? activation.loading : pendingLoading) && visibleItems.length === 0 ? (\n <div className=\"px-3 py-1.5 text-[11px] text-[hsl(var(--muted-foreground))]\">\n <Loader2 size={12} className=\"mr-1 inline animate-spin\" />\n 正在获取插件…\n </div>\n ) : null}\n {failed ? (\n <button\n type=\"button\"\n onClick={() => (sessionId ? reload() : void loadPendingCatalog())}\n className=\"px-3 py-1.5 text-left text-[11px] text-[hsl(var(--muted-foreground))] underline\"\n >\n 插件列表暂不可用,点击重试\n </button>\n ) : null}\n <PluginConnectorList\n client={client}\n sessionId={sessionId}\n items={visibleItems.filter((item) => !isLocalConnectorName(item.name))}\n inFlight={activation.inFlight}\n busy={sessionId ? activation.busy : pendingLoading}\n mutationError={sessionId ? activation.mutationError : false}\n onToggle={toggle}\n onRetry={activation.retry}\n onEditConfig={activation.editConfig}\n configuring={sessionId ? activation.configuring : null}\n onConfigSaved={activation.onConfigSaved}\n onConfigClose={activation.onConfigClose}\n disabledReason={sessionId ? null : pendingDisabledReason}\n unavailableText={\n failed\n ? null\n : query.trim()\n ? \"没有匹配的插件\"\n : null\n }\n emptyText={sessionId ? \"尚未安装插件\" : \"尚未安装插件,去应用市场添加一个\"}\n draft={!sessionId}\n />\n\n {renderExternalAccounts ? (\n <>\n <PanelDivider />\n <PanelTitle>外部账号</PanelTitle>\n {renderExternalAccounts(query)}\n </>\n ) : null}\n\n {renderFooterActions ? (\n <>\n <PanelDivider />\n {renderFooterActions()}\n </>\n ) : null}\n </div>\n )\n}\n","import type { BladeClient } from \"@blade-hq/agent-client\"\nimport { SessionPluginIcon } from \"./SessionPluginIcon\"\nimport type { TriggerSummary } from \"./connector-panel-types\"\n\nexport interface PluginTriggerStackProps {\n client: BladeClient\n /** 会话内图标走会话接口;首页待选传 `null`(走账号级目录图标)。 */\n sessionId: string | null\n /** 折叠结果,来自 `triggerSummary`——折叠规则只有那一处。 */\n summary: TriggerSummary\n className?: string\n}\n\nconst AVATAR_SIZE = 20\n\nfunction hueOf(name: string): number {\n let hash = 0\n for (const char of name) hash = (hash * 31 + char.codePointAt(0)!) % 1000003\n return hash % 360\n}\n\n/**\n * 首字占位的身份色板。\n *\n * 不是自己调的色:直接取 Tailwind 默认调色板里相隔开的 8 个色相(Slack 那类头像\n * 色板也是这个量级、这个思路),深浅主题各一套。用 Tailwind 默认色而不是新造\n * token,是因为仓库里本来就在用(status、图表那批 bg-red-500 / text-sky-400)。\n *\n * 字色取 800 档而不是 700:100 底 + 700 字在浅色下只有 4.5–5.2:1,而这个字只有\n * 11px,够不上「小字看不清」这条线;100 + 800 各色相都在 6.4:1 以上。\n */\nconst AVATAR_PALETTE = [\n \"bg-violet-100 text-violet-800 dark:bg-violet-500/25 dark:text-violet-200\",\n \"bg-sky-100 text-sky-800 dark:bg-sky-500/25 dark:text-sky-200\",\n \"bg-emerald-100 text-emerald-800 dark:bg-emerald-500/25 dark:text-emerald-200\",\n \"bg-amber-100 text-amber-800 dark:bg-amber-500/25 dark:text-amber-200\",\n \"bg-rose-100 text-rose-800 dark:bg-rose-500/25 dark:text-rose-200\",\n \"bg-indigo-100 text-indigo-800 dark:bg-indigo-500/25 dark:text-indigo-200\",\n \"bg-teal-100 text-teal-800 dark:bg-teal-500/25 dark:text-teal-200\",\n \"bg-fuchsia-100 text-fuchsia-800 dark:bg-fuchsia-500/25 dark:text-fuchsia-200\",\n]\n\n/**\n * 触发器上的插件头像堆叠:前三枚圆形头像 + 其余折成 `+N`。\n *\n * 没有图标 token 的插件也用显示名首字占一枚圆——它和别的插件长得不一样,\n * 「我选过它」就看得见;早先把这类项直接剔掉,选中后入口毫无变化。\n *\n * 圆环色取 `--background`(盖住被压住的那枚),与整站头像堆叠同一约定,见\n * `apps/web/src/components/agent-board/ProjectMembers.tsx`:容器没有自己的底色时,\n * 环就等于容器露出来的那层底。图标裁成圆形:插件 logo 多是方的,套在圆按钮里\n * 「方套圆」才是那个视觉冲突的来源。\n */\nexport function PluginTriggerStack({ client, sessionId, summary, className }: PluginTriggerStackProps) {\n if (summary.total === 0) return null\n const ring = \"ring-2 ring-[hsl(var(--background))]\"\n return (\n <span className={`flex items-center -space-x-1 ${className ?? \"\"}`}>\n {summary.visible.map((item) => {\n const label = item.displayName?.trim() || item.name\n const tone = AVATAR_PALETTE[hueOf(item.name) % AVATAR_PALETTE.length]\n return item.icon ? (\n <SessionPluginIcon\n key={item.name}\n client={client}\n sessionId={item.iconSource === \"account\" ? null : sessionId}\n plugin={item}\n size={AVATAR_SIZE}\n shape=\"circle\"\n className={ring}\n />\n ) : (\n <span\n key={item.name}\n title={label}\n className={`flex shrink-0 items-center justify-center rounded-full font-semibold text-[11px] ${tone} ${ring}`}\n style={{ width: AVATAR_SIZE, height: AVATAR_SIZE }}\n >\n {Array.from(label.trim())[0]?.toUpperCase() ?? \"?\"}\n </span>\n )\n })}\n {summary.overflow > 0 ? (\n <span\n className={`flex shrink-0 items-center justify-center rounded-full bg-[hsl(var(--muted))] font-medium text-[hsl(var(--muted-foreground))] text-[10px] ${ring}`}\n style={{ width: AVATAR_SIZE, height: AVATAR_SIZE }}\n >\n +{summary.overflow}\n </span>\n ) : null}\n </span>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBO,SAAS,kBAAkB,MAAqD;AACrF,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,aAAa,KAAK,gBAAgB;AAAA,IAClC,MAAM,KAAK;AAAA,IACX,YAAY,KAAK;AAAA,EACnB;AACF;AAGO,IAAM,qBAAqB;AAmB3B,SAAS,eACd,OACgB;AAChB,QAAM,UAAU,MAAM,MAAM,GAAG,kBAAkB;AACjD,SAAO;AAAA,IACL;AAAA,IACA,UAAU,MAAM,SAAS,QAAQ;AAAA,IACjC,OAAO,MAAM;AAAA,EACf;AACF;;;ACzDA,SAAS,4BAA4B;AAGrC,SAAS,aAAa,WAAW,SAAS,QAAQ,gBAAgB;AA6BzD,SA+KiB,UA9KtB,KADK;AAtBT,IAAM,kBAAkB;AACxB,IAAM,cAAc,GAAG,eAAe;AACtC,IAAM,kBAAkB,GAAG,eAAe;AAE1C,eAAe,eAAe,OAAiC;AAC7D,QAAM,WAAY,OAAmC;AACrD,MAAI,UAAU;AACZ,QAAI;AACF,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAI,OAAO,KAAK,WAAW,SAAU,QAAO,KAAK;AACjD,UAAI,OAAO,KAAK,QAAQ,YAAY,SAAU,QAAO,KAAK,OAAO;AAAA,IACnE,QAAQ;AAAA,IAAwD;AAAA,EAClE;AACA,SAAO;AACT;AAEA,SAAS,aAAa,EAAE,QAAQ,WAAW,WAAW,QAAQ,GAE3D;AACD,QAAM,CAAC,cAAa,eAAe,IAAE,SAAS,CAAC;AAC/C,QAAM,SAAS,OAA0B,IAAI;AAC7C,YAAU,MAAM;AAAE,UAAM,UAAU,OAAO;AAAS,aAAS,UAAU;AAAG,WAAO,MAAM,SAAS,MAAM;AAAA,EAAE,GAAG,CAAC,CAAC;AAC3G,SAAO,qBAAC,YAAO,KAAK,QAAQ,cAAY,gBAAM,UAAU,gBAAgB,UAAU,IAAI,IAAI,UAAU,CAAC,UAAU;AAAE,UAAM,eAAe;AAAG,YAAQ;AAAA,EAAE,GAAG,WAAU,0MAC9J;AAAA,wBAAC,uBAAoB,MAAM,UAAU,eAAe,SAAS,YAAY,YAAY,UAAU,MAAM,MAAM,OAAO,WAAW,cAAc,UAAU,IAAI,GAAG,KAAK,CAAC,QAAQ,YAAY,OAAO,WAAW,UAAU,UAAU,MAAM,QAAQ,QAAW,OAAO,GAAG,MAAM,kBAAgB,OAAO,WAAW,kBAAkB,UAAU,MAAM,YAAY,GAAG,aAAa,MAAM,OAAO,WAAW,YAAY,UAAU,IAAI,GAAG,WAAW,YAAY;AAAC,YAAM,UAAU;AAAE,sBAAgB,WAAS,QAAM,CAAC;AAAA,IAAC,GAAG,WAAW,MAAM,OAAO,WAAW,WAAW,UAAU,IAAI,GAAG;AAAA,IACviB,oBAAC,yBAAsB,QAAgB,MAAM,UAAU,MAAM,SAAS,cAAc;AAAA,IACpF,oBAAC,YAAO,MAAK,UAAS,WAAW,aAAa,SAAS,SAAS,4CAAK;AAAA,KACvE;AACF;AAEA,SAAS,iBAAiB,EAAE,QAAQ,WAAW,aAAa,QAAQ,GAKjE;AACD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAyC,IAAI;AACrE,QAAM,CAAC,SAAS,UAAU,IAAI,SAAwB,IAAI;AAC1D,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,SAAS,OAAiC,IAAI;AACpD,QAAM,oBAAoB,OAA+B,IAAI;AAC7D,YAAU,MAAM,MAAM,kBAAkB,SAAS,MAAM,GAAG,CAAC,CAAC;AAC5D,YAAU,MAAM;AACd,UAAM,UAAU,OAAO;AACvB,aAAS,UAAU;AACnB,WAAO,MAAM,SAAS,MAAM;AAAA,EAC9B,GAAG,CAAC,CAAC;AACL,YAAU,MAAM;AACd,UAAM,QAAQ,IAAI,gBAAgB;AAClC,WAAO,WAAW,KAAK,UAAU,MAAM,EAAE,QAAQ,MAAM,OAAO,CAAC,EAAE,KAAK,CAAC,UAAU;AAC/E,UAAI,CAAC,MAAM,OAAO,QAAS,SAAQ,KAAK;AAAA,IAC1C,CAAC,EAAE,MAAM,OAAO,UAAU;AACxB,YAAM,UAAU,MAAM,eAAe,KAAK;AAC1C,UAAI,CAAC,MAAM,OAAO,QAAS,YAAW,OAAO;AAAA,IAC/C,CAAC;AACD,WAAO,MAAM,MAAM,MAAM;AAAA,EAC3B,GAAG,CAAC,QAAQ,UAAU,IAAI,CAAC;AAE3B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MAAQ,cAAY,gBAAM,UAAU,gBAAgB,UAAU,IAAI;AAAA,MACvE,WAAU;AAAA,MACV,UAAU,CAAC,UAAU;AAAE,cAAM,eAAe;AAAG,YAAI,CAAC,WAAY,SAAQ;AAAA,MAAE;AAAA,MAE1E,+BAAC,SAAI,WAAU,4LACb;AAAA,6BAAC,SAAI,WAAU,4BAA2B;AAAA;AAAA,UAAI,UAAU,gBAAgB,UAAU;AAAA,WAAK;AAAA,QACvF,oBAAC,OAAE,WAAU,oDAAoD,gBAAM,OAAO,UAAU,iBAAiB,2GAAsB,wIAAyB;AAAA,QACvJ,CAAC,OAAO,oBAAC,SAAI,WAAU,WAAW,qBAAW,0DAAY,IAAS,CAAC,YAClE;AAAA,UAAC;AAAA;AAAA,YACC,QAAQ,KAAK;AAAA,YAAQ;AAAA,YAAwB,QAAQ,CAAC;AAAA,YAAG;AAAA,YACzD,aAAY;AAAA,YAAQ,iBAAgB;AAAA,YAAQ,UAAU;AAAA,YACtD,UAAU,OAAO,UAAU;AACzB,4BAAc,IAAI;AAClB,yBAAW,IAAI;AACf,oBAAM,UAAU,IAAI,gBAAgB;AACpC,gCAAkB,UAAU;AAC5B,kBAAI;AACF,sBAAMA,aAAY,MAAM,OAAO,WAAW,QAAQ,UAAU,MAAM;AAAA,kBAChE,mBAAmB,KAAK,OAAO;AAAA,kBAAU,KAAK,MAAM;AAAA,kBAAK,QAAQ,MAAM;AAAA,gBACzE,GAAG,EAAE,QAAQ,QAAQ,OAAO,CAAC;AAC7B,oBAAI,QAAQ,OAAO,QAAS;AAC5B,wBAAQA,UAAS;AACjB,6BAAa,IAAI;AACjB,oBAAI;AAAE,wBAAM,YAAY;AAAA,gBAAE,QACpB;AAAE,sBAAG,CAAC,QAAQ,OAAO,QAAQ,YAAW,gLAA+B;AAAG;AAAA,gBAAO;AACvF,oBAAI,CAAC,QAAQ,OAAO,QAAS,SAAQ;AAAA,cACvC,SAAS,OAAO;AACd,oBAAI,QAAQ,OAAO,QAAS;AAC5B,2BAAW,MAAM,eAAe,KAAK,CAAC;AAGtC,oBAAI;AAAE,0BAAQ,MAAM,OAAO,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,gBAAE,QAAQ;AAAA,gBAAuB;AAAA,cAC7F,UAAE;AAAU,oBAAI,CAAC,QAAQ,OAAO,QAAS,eAAc,KAAK;AAAA,cAAE;AAAA,YAChE;AAAA;AAAA,QACF,IACE;AAAA,QACJ,oBAAC,yBAAsB,QAAgB,MAAM,UAAU,MAAM;AAAA,QAC5D,YAAY,oBAAC,YAAO,WAAU,iBAAiB,qBAAW,wCAAS,IAAY;AAAA,QAC/E,CAAC,QAAQ,YAAY,oBAAC,YAAO,MAAK,UAAS,WAAW,GAAG,WAAW,SAAS,SAAS,SAAS,0BAAE,IAAY;AAAA,SAChH;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,kBAAkB,EAAE,QAAQ,QAAQ,IAAI,YAAY,MAAM,SAAS,OAAO,kBAAkB,gBAAgB,UAAU,OAAO,SAAS,OAAO,OAAO,GAWjK;AACD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA6B,CAAC,CAAC;AACzD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAkC,IAAI;AACpE,QAAM,CAAC,SAAS,UAAU,IAAI,SAAwB,IAAI;AAC1D,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,eAAe,OAA0B,IAAI;AACnD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAkC,IAAI;AACtE,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,YAAU,MAAM;AACd,QAAI,CAAC,SAAU;AACf,UAAM,UAAU,aAAa;AAC7B,aAAS,UAAU;AACnB,WAAO,MAAM,SAAS,MAAM;AAAA,EAC9B,GAAG,CAAC,QAAQ,CAAC;AACb,QAAM,WAAW,OAA+B,IAAI;AACpD,QAAM,OAAO,YAAY,CAAC,WAAyB,YAC/C,OAAO,WAAW,eAAe,WAAW,EAAE,OAAO,CAAC,IACtD,OAAO,WAAW,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,SAAS,CAAC;AAC3D,QAAM,SAAS,YAAY,YAAY;AACrC,UAAM,QAAQ,SAAS;AACvB,UAAM,SAAS,MAAM,KAAK,OAAO,MAAM;AACvC,QAAI,UAAU,SAAS,WAAW,CAAC,OAAO,OAAO,SAAS;AAAE,eAAS,OAAO,UAAU;AAAG,iBAAW,IAAI;AAAA,IAAE;AAAA,EAC5G,GAAG,CAAC,IAAI,CAAC;AACT,YAAU,MAAM;AACd,UAAM,QAAQ,IAAI,gBAAgB;AAClC,aAAS,UAAU;AACnB,aAAS,CAAC,CAAC;AACX,eAAW,IAAI;AACf,eAAW,IAAI;AACf,eAAW,IAAI;AACf,SAAK,MAAM,MAAM,EAAE,KAAK,CAAC,UAAU;AACjC,UAAI,CAAC,MAAM,OAAO,QAAS,UAAS,MAAM,UAAU;AAAA,IACtD,CAAC,EAAE,MAAM,OAAO,UAAU;AACxB,YAAM,UAAU,MAAM,eAAe,KAAK;AAC1C,UAAI,CAAC,MAAM,OAAO,QAAS,YAAW,OAAO;AAAA,IAC/C,CAAC,EAAE,QAAQ,MAAM;AAAE,UAAI,CAAC,MAAM,OAAO,QAAS,YAAW,KAAK;AAAA,IAAE,CAAC;AACjE,WAAO,MAAM,MAAM,MAAM;AAAA,EAC3B,GAAG,CAAC,IAAI,CAAC;AACT,QAAM,UAAU,QAAQ,MAAM;AAC5B,UAAM,SAAO,MAAM,IAAI,CAAC,UAAQ,EAAC,GAAG,MAAK,QAAO,YAAU,KAAK,SAAO,QAAQ,SAAS,IAAI,KAAK,IAAI,CAAC,EAAC,EAAE;AACxG,QAAG,CAAC;AAAU,iBAAU,QAAQ,WAAS,CAAC,EAAE,KAAG,qBAAqB,IAAI,KAAG,CAAC,OAAO,KAAK,CAAC,SAAO,KAAK,SAAO,IAAI,EAAE,QAAO,KAAK,EAAC,MAAK,cAAa,KAAK,MAAM,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,GAAE,aAAY,kIAAwB,QAAO,KAAK,WAAW,oBAAoB,IAAE,YAAU,YAAW,YAAW,GAAE,WAAU,OAAM,QAAO,MAAK,YAAW,EAAC,QAAO,gBAAe,UAAS,GAAE,eAAc,IAAG,aAAY,GAAE,EAAC,CAAC;AAAA;AACjZ,WAAO;AAAA,EACT,GAAE,CAAC,OAAM,SAAQ,SAAS,CAAC;AAC3B,QAAM,WAAW,OAAO,gBAAgB;AACxC,WAAS,UAAU;AACnB,YAAU,MAAM;AAAE,aAAS,UAAU,QAAQ,OAAO,CAAC,SAAS,KAAK,MAAM,CAAC;AAAA,EAAE,GAAG,CAAC,OAAO,CAAC;AACxF,QAAM,WAAW,QAAQ,OAAO,CAAC,SAAS,GAAG,KAAK,YAAY,IAAI,KAAK,WAAW,GAAG,YAAY,EAAE,SAAS,MAAM,KAAK,EAAE,YAAY,CAAC,CAAC;AAEvI,SACE,qBAAC,SAAI,WAAW,UAAU,6CAA6C,QACpE;AAAA,KAAC,UAAU,oBAAC,SAAI,WAAU,oEAAmE,gCAAG,IAAS;AAAA,IACzG,UAAU,oBAAC,OAAE,WAAU,yDAAwD,8DAAQ,IAAO;AAAA,IAC9F,CAAC,WAAW,CAAC,WAAW,SAAS,WAAW,IAAI,oBAAC,OAAE,WAAU,yDAAyD,gBAAM,KAAK,IAAI,qDAAa,kCAAQ,IAAO;AAAA,IACjK,SAAS,IAAI,CAAC,SAAS;AACtB,YAAM,YAAY,KAAK,WAAW,WAAW;AAC7C,YAAM,QAAQ,KAAK,gBAAgB,KAAK;AACxC,YAAM,cAAc,YAAY,YAAY;AAC5C,YAAM,kBAAkB,GAAG,WAAW,IAAI,CAAC,YAAY,yHAAyH,EAAE;AAClL,YAAM,gBACJ,qBAAC,YAAO,MAAK,UAAS,UAAU,QAAQ,KAAK,cAAc,OAAO,WAAW,iBAAiB,SAAS,MAAM;AAAE,mBAAW,IAAI;AAAG,mBAAW,IAAI;AAAA,MAAE,GAAG;AAAA,4BAAC,eAAY,MAAM,IAAI,eAAY,QAAO;AAAA,QAAG,CAAC,UAAU,SAAS,EAAE,SAAS,KAAK,eAAe,QAAQ,EAAE,IAAI,6BAAS,YAAY,6BAAS;AAAA,SAAK;AAExS,YAAM,YAAY,UAAU,KAAK,UAAU,aAAa,KAAK,aAAa,KACxE,qBAAC,YAAO,MAAK,UAAS,UAAU,QAAQ,QAAQ,cAAc,GAAG,OAAO,kBAAkB,QAAW,WAAW,aAAa,SAAS,YAAY;AAChJ,cAAM,QAAQ,SAAS;AACvB,gBAAQ,IAAI;AACZ,mBAAW,IAAI;AACf,YAAI;AACF,gBAAM,MAAM,KAAK,MAAM,OAAO,CAAC,KAAK,QAAQ,KAAK,QAAQ,IAAI;AAC7D,cAAI,UAAW,OAAM,OAAO;AAAA,QAC9B,SAAS,OAAO;AACd,gBAAM,UAAU,MAAM,eAAe,KAAK;AAC1C,cAAI,UAAU,SAAS,WAAW,CAAC,OAAO,OAAO,QAAS,YAAW,OAAO;AAAA,QAC9E,UACA;AAAU,cAAI,UAAU,SAAS,WAAW,CAAC,OAAO,OAAO,QAAS,SAAQ,KAAK;AAAA,QAAE;AAAA,MACrF,GAAI;AAAA,aAAK,SAAS,oBAAC,SAAM,MAAM,IAAI,eAAY,QAAO,IAAK;AAAA,QAAM,KAAK,SAAS,uBAAQ;AAAA,SAAK,IAC1F;AACJ,aACE,qBAAC,SAAoB,WAAW,UAAU,0FAA0F,eAClI;AAAA,6BAAC,SAAI,WAAW,2BAA2B,UAAU,YAAY,aAAa,IAC5E;AAAA,8BAAC,qBAAkB,QAAgB,WAAW,MAAM,QAAQ,EAAE,MAAM,KAAK,MAAM,MAAM,KAAK,QAAQ,KAAK,GAAG,MAAM,UAAU,KAAK,IAAI;AAAA,UACnI,oBAAC,UAAK,WAAU,uCAAsC,OAAO,OAAQ,iBAAM;AAAA,UAC3E,oBAAC,UAAK,WAAU,4GAA4G,eAAK,WAAW,YAAY,iBAAO,4BAAO;AAAA,UACrK,CAAC,UAAU,iCAAG;AAAA;AAAA,YAAe;AAAA,aAAU,IAAM;AAAA,WAChD;AAAA,QACC,UAAU,oBAAC,OAAE,WAAU,qEAAqE,eAAK,aAAY,IAAO;AAAA,QACrH,qBAAC,SAAI,WAAU,kFACb;AAAA,8BAAC,UAAK,eAAY,QAAO,WAAW,kCAAkC,YAAY,mBAAmB,uCAAuC,IAAI;AAAA,UAC/I,YAAY,qBAAM,KAAK,WAAW,gBAAgB,SAAM,KAAK,WAAW,aAAa,KAAK,EAAE,GAAG,KAAK,SAAS,6BAA6B,uEAAgB,KAAK,eAAe,IAAI,2DAAc,EAAE,KAAK,KAAK,WAAW,WAAW,kBAAkB,yCAAW;AAAA,WAClQ;AAAA,QACC,UAAU,qBAAC,SAAI,WAAU,0EACvB;AAAA;AAAA,UAAe;AAAA,UACf,SAAS,qBAAC,SAAI,WAAU,qCACtB;AAAA,gCAAC,YAAO,MAAK,UAAS,UAAU,MAAM,cAAY,CAAC,UAAU,SAAS,EAAE,SAAS,KAAK,eAAe,QAAQ,EAAE,IAAI,iCAAa,gBAAM,OAAO,CAAC,UAAU,SAAS,EAAE,SAAS,KAAK,eAAe,QAAQ,EAAE,IAAI,gGAA+B,4BAAQ,WAAW,iBAAiB,SAAS,YAAY;AACrS,sBAAQ,IAAI;AACZ,kBAAI;AAAE,sBAAM,OAAO,WAAW,WAAW,KAAK,IAAI;AAAG,sBAAM,OAAO;AAAA,cAAE,SAC7D,OAAO;AAAE,2BAAW,MAAM,eAAe,KAAK,CAAC;AAAA,cAAE,UACxD;AAAU,wBAAQ,KAAK;AAAA,cAAE;AAAA,YAC3B,GAAG,8BAAC,UAAO,MAAM,IAAI,eAAY,QAAO,GAAE;AAAA,YACzC,KAAK,WAAW,aAAa,iCAC5B;AAAA,kCAAC,YAAO,MAAK,UAAS,UAAU,MAAM,cAAW,gBAAK,OAAM,kCAAQ,WAAW,iBAAiB,SAAS,MAAM,SAAS,IAAI,GAAG,8BAAC,UAAO,MAAM,IAAI,eAAY,QAAO,GAAE;AAAA,cACtK,oBAAC,YAAO,MAAK,UAAS,UAAU,MAAM,cAAW,gBAAK,OAAM,kCAAQ,WAAW,GAAG,eAAe,sHAAsH,SAAS,MAAM,YAAY,IAAI,GAAG,8BAAC,UAAO,MAAM,IAAI,eAAY,QAAO,GAAE;AAAA,eAClS,IAAM;AAAA,aACR,IAAS;AAAA,WACX,IAAS;AAAA,WA1BD,KAAK,IA2Bf;AAAA,IAEJ,CAAC;AAAA,IACA,WAAW,qBAAC,YAAO,KAAK,cAAc,UAAU,CAAC,UAAU;AAAE,YAAM,eAAe;AAAG,UAAI,CAAC,KAAM,aAAY,IAAI;AAAA,IAAE,GAAG,cAAW,kCAAQ,WAAU,yLACjJ;AAAA,2BAAC,OAAE,WAAU,WAAU;AAAA;AAAA,QAAI,SAAS,gBAAgB,SAAS;AAAA,QAAK;AAAA,SAAoB;AAAA,MACtF,qBAAC,SAAI,WAAU,+BACb;AAAA,4BAAC,YAAO,MAAK,UAAS,UAAU,MAAM,WAAW,aAAa,SAAS,MAAM,YAAY,IAAI,GAAG,0BAAE;AAAA,QAClG,oBAAC,YAAO,MAAK,UAAS,UAAU,MAAM,WAAW,GAAG,WAAW,sGAAsG,SAAS,YAAY;AACxL,kBAAQ,IAAI;AACZ,cAAI;AAAE,kBAAM,OAAO,WAAW,OAAO,SAAS,IAAI;AAAG,wBAAY,IAAI;AAAG,kBAAM,OAAO;AAAA,UAAE,SAChF,OAAO;AAAE,uBAAW,MAAM,eAAe,KAAK,CAAC;AAAG,wBAAY,IAAI;AAAA,UAAE,UAC3E;AAAU,oBAAQ,KAAK;AAAA,UAAE;AAAA,QAC3B,GAAI,iBAAO,mCAAU,4BAAO;AAAA,SAC9B;AAAA,OACF,IAAY;AAAA,IACX,UAAU,qBAAC,SAAI,MAAK,SAAQ,WAAU,oDAAoD;AAAA;AAAA,MAAQ,oBAAC,YAAO,MAAK,UAAS,WAAW,GAAG,WAAW,SAAS,SAAS,MAAM;AAAE,aAAK,OAAO,EAAE,MAAM,MAAM,WAAW,kDAAU,CAAC;AAAA,MAAE,GAAG,0BAAE;AAAA,OAAS,IAAS;AAAA,IACpP,WAAW,CAAC,UAAU,SAAS,EAAE,SAAS,QAAQ,eAAe,QAAQ,EAAE,IAAI,oBAAC,gBAAgC,QAAgB,WAAW,SAAS,WAAW,QAAQ,SAAS,MAAM;AAAE,iBAAW,IAAI;AAAG,WAAK,OAAO;AAAA,IAAE,KAAtH,QAAQ,IAAiH,IAAK,SAAS,eAAe,SAAS,YAAY,oBAAC,2BAA2C,QAAgB,MAAM,QAAQ,MAAM,OAAO,QAAQ,gBAAgB,QAAQ,MAAM,SAAS,MAAM;AACxZ,iBAAW,IAAI;AACf,WAAK,OAAO,EAAE,MAAM,MAAM,WAAW,kDAAU,CAAC;AAAA,IAClD,KAH4S,QAAQ,IAGjT,IAAK,UAAU,oBAAC,oBAAoC,QAAgB,WAAW,SAAS,SAAS,MAAM,WAAW,IAAI,GAAG,aAAa,YAAY;AACnJ,YAAM,QAAQ,SAAS;AACvB,YAAM,OAAO;AACb,UAAI,UAAU,SAAS,WAAW,OAAO,OAAO,QAAS;AACzD,UAAI,SAAS,QAAQ,aAAa,KAAK,CAAC,gBAAgB;AACtD,cAAM,MAAM,QAAQ,MAAM,QAAQ,gBAAgB,QAAQ,MAAM,IAAI;AACpE,YAAI,UAAW,OAAM,OAAO;AAAA,MAC9B;AAAA,IACF,KARyC,QAAQ,IAQ9C,IAAK;AAAA,KACV;AAEJ;;;ACnQA,SAAS,wBAAAC,6BAA4B;AAGrC,SAAS,eAAAC,cAAa,aAAAC,YAAW,WAAAC,UAAS,UAAAC,SAAQ,YAAAC,iBAAgC;AAwCzE,SAsID,YAAAC,WAtIC,OAAAC,MA0HH,QAAAC,aA1HG;AADT,SAAS,eAAe;AACtB,SAAO,gBAAAD,KAAC,SAAI,WAAU,6CAA4C;AACpE;AAEA,SAAS,WAAW,EAAE,SAAS,GAA4B;AACzD,SACE,gBAAAA,KAAC,SAAI,WAAU,oEACZ,UACH;AAEJ;AASO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,QAAM,CAAC,OAAO,QAAQ,IAAIE,UAAS,EAAE;AACrC,QAAM,CAAC,oBAAoB,qBAAqB,IAAIA,UAA6B,CAAC,CAAC;AACnF,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAsC,IAAI;AACtF,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,KAAK;AAC1D,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAS,KAAK;AAEtD,QAAM,aAAa,2BAA2B;AAAA,IAC5C;AAAA,IACA,WAAW,aAAa;AAAA,IACxB,UAAU;AAAA,EACZ,CAAC;AACD,QAAM,EAAE,QAAQ,OAAO,aAAa,IAAI;AAExC,EAAAC,WAAU,MAAM;AACd,QAAI,UAAW,QAAO;AAAA,EACxB,GAAG,CAAC,QAAQ,SAAS,CAAC;AAEtB,QAAM,qBAAqBC,aAAY,YAAY;AACjD,sBAAkB,IAAI;AACtB,oBAAgB,KAAK;AACrB,QAAI;AACF,YAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,QAAQ,QAAQ;AACjD,wBAAkB,OAAO;AAAA,IAC3B,QAAQ;AACN,sBAAgB,IAAI;AAAA,IACtB,UAAE;AACA,wBAAkB,KAAK;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAD,WAAU,MAAM;AACd,QAAI,UAAW;AACf,SAAK,mBAAmB;AAAA,EAC1B,GAAG,CAAC,oBAAoB,SAAS,CAAC;AAElC,QAAM,WAAWE;AAAA,IACf,MAAM,IAAI,KAAK,kBAAkB,CAAC,GAAG,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC;AAAA,IAC7D,CAAC,cAAc;AAAA,EACjB;AACA,QAAM,QAAQA,SAAQ,MAAM;AAC1B,QAAI,UAAW,QAAO;AACtB,WAAO,wBAAwB,kBAAkB,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU;AAAA,MAClE,GAAG;AAAA,MACH,QAAQ,SAAS,IAAI,KAAK,IAAI;AAAA,IAChC,EAAE;AAAA,EACJ,GAAG,CAAC,gBAAgB,UAAU,WAAW,YAAY,CAAC;AACtD,QAAM,eAAeA;AAAA,IACnB,MAAO,YACH,qBAAqB,OAAO,KAAK,IACjC,qBAAqB,OAAO,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,QAAQ,OAAU,EAAE;AAAA,IACrF,CAAC,OAAO,OAAO,SAAS;AAAA,EAC1B;AAEA,QAAM,gBAAgBD,aAAY,CAAC,MAA2B,SAAkB;AAC9E,UAAM,QAAQ,kBAAkB,CAAC,GAAG,OAAO,CAAC,UAAU,MAAM,SAAS,KAAK,IAAI;AAC9E,6BAAyB,OAAO,CAAC,GAAG,MAAM,kBAAkB,IAAI,CAAC,IAAI,IAAI;AAAA,EAC3E,GAAG,CAAC,wBAAwB,cAAc,CAAC;AAE3C,QAAM,SAASA,aAAY,CAAC,MAA2B,SAAkB;AACvE,QAAI,UAAW,YAAW,OAAO,MAAM,IAAI;AAAA,QACtC,eAAc,MAAM,IAAI;AAAA,EAC/B,GAAG,CAAC,YAAY,WAAW,aAAa,CAAC;AAEzC,QAAM,gBAAgBC;AAAA,IACpB,MAAM;AAAA,MACJ,GAAG,MAAM,OAAO,CAAC,SAAS,KAAK,UAAU,CAACC,sBAAqB,KAAK,IAAI,CAAC;AAAA,MACzE,GAAG,mBAAmB,IAAI,CAAC,UAAU;AAAA,QACnC,MAAM,KAAK;AAAA,QAAM,cAAc,KAAK;AAAA,QAAc,MAAM,KAAK,QAAQ;AAAA,QACrE,YAAY;AAAA,QAAoB,WAAW;AAAA,QAAM,QAAQ;AAAA,QACzD,QAAQ;AAAA,QAAS,WAAW;AAAA,QAAO,WAAW;AAAA,MAChD,EAAE;AAAA,IACJ;AAAA,IACA,CAAC,OAAO,kBAAkB;AAAA,EAC5B;AACA,QAAM,sBAAsBC,QAAO,gBAAgB;AACnD,sBAAoB,UAAU;AAC9B,QAAM,iBAAiBA,QAAO,aAAa;AAC3C,iBAAe,UAAU;AACzB,QAAM,iBAAiBH,aAAY,MAAM;AACvC,wBAAoB,UAAU,eAAe,OAAO;AAAA,EACtD,GAAG,CAAC,CAAC;AACL,QAAM,gBAAgB,cAAc,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,KAAK,IAAQ;AAG1E,EAAAD,WAAU,gBAAgB,CAAC,gBAAgB,aAAa,CAAC;AAEzD,QAAM,SAAS,YAAY,WAAW,YAAY;AAElD,SACE,gBAAAF,MAAC,SAAI,WACH;AAAA,oBAAAA,MAAC,SAAI,WAAU,0EACb;AAAA,sBAAAD,KAAC,UAAO,MAAM,IAAI,WAAU,gDAA+C,eAAY,QAAO;AAAA,MAC9F,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,KAAK;AAAA,UAChD,aAAY;AAAA,UACZ,cAAW;AAAA,UACX,WAAU;AAAA;AAAA,MACZ;AAAA,OACF;AAAA,IAEC,wBACC,gBAAAC,MAAAF,WAAA,EACE;AAAA,sBAAAC,KAAC,cAAW,0BAAE;AAAA,MACb,sBAAsB,KAAK;AAAA,OAC9B,IACE;AAAA,IAEH,qBAAqB,mBAAmB,KAAK,IAAI;AAAA,IAElD,gBAAAA,KAAC,gBAAa;AAAA,IACd,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QAAgB;AAAA,QAAc;AAAA,QAAsB,SAAS;AAAA,QAC7D,kBAAkB;AAAA,QAAuB,gBAAgB;AAAA,QACzD,OAAO,OAAO,MAAM,OAAO,SAAS,SAAS;AAC3C,cAAI,WAAW;AACb,kBAAM,SAAS,MAAM,OAAO,SAAS,2BAA2B,WAAW,MAAM,OAAO;AACxF,+BAAmB,OAAO,MAAM;AAAA,UAClC,OAAO;AACL,kBAAM,QAAQ,kBAAkB,CAAC,GAAG,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI;AACvE,qCAAyB,UAAU,CAAC,GAAG,MAAM,EAAE,MAAM,aAAa,OAAO,MAAM,QAAQ,MAAM,YAAY,UAAU,CAAC,IAAI,IAAI;AAAA,UAC9H;AAAA,QACF;AAAA;AAAA,IACF;AAAA,IACA,gBAAAA,KAAC,gBAAa;AAAA,IACd,gBAAAA,KAAC,cAAW,0BAAE;AAAA,IACb,CAAC,YACA,gBAAAA,KAAC,SAAI,WAAU,+DAA8D,8GAE7E,IACE;AAAA,KACF,YAAY,WAAW,UAAU,mBAAmB,aAAa,WAAW,IAC5E,gBAAAC,MAAC,SAAI,WAAU,+DACb;AAAA,sBAAAD,KAAC,gBAAQ,MAAM,IAAI,WAAU,4BAA2B;AAAA,MAAE;AAAA,OAE5D,IACE;AAAA,IACH,SACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,MAAO,YAAY,OAAO,IAAI,KAAK,mBAAmB;AAAA,QAC/D,WAAU;AAAA,QACX;AAAA;AAAA,IAED,IACE;AAAA,IACJ,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,OAAO,aAAa,OAAO,CAAC,SAAS,CAACM,sBAAqB,KAAK,IAAI,CAAC;AAAA,QACrE,UAAU,WAAW;AAAA,QACrB,MAAM,YAAY,WAAW,OAAO;AAAA,QACpC,eAAe,YAAY,WAAW,gBAAgB;AAAA,QACtD,UAAU;AAAA,QACV,SAAS,WAAW;AAAA,QACpB,cAAc,WAAW;AAAA,QACzB,aAAa,YAAY,WAAW,cAAc;AAAA,QAClD,eAAe,WAAW;AAAA,QAC1B,eAAe,WAAW;AAAA,QAC1B,gBAAgB,YAAY,OAAO;AAAA,QACnC,iBACE,SACI,OACA,MAAM,KAAK,IACT,+CACA;AAAA,QAER,WAAW,YAAY,yCAAW;AAAA,QAClC,OAAO,CAAC;AAAA;AAAA,IACV;AAAA,IAEC,yBACC,gBAAAL,MAAAF,WAAA,EACE;AAAA,sBAAAC,KAAC,gBAAa;AAAA,MACd,gBAAAA,KAAC,cAAW,sCAAI;AAAA,MACf,uBAAuB,KAAK;AAAA,OAC/B,IACE;AAAA,IAEH,sBACC,gBAAAC,MAAAF,WAAA,EACE;AAAA,sBAAAC,KAAC,gBAAa;AAAA,MACb,oBAAoB;AAAA,OACvB,IACE;AAAA,KACN;AAEJ;;;ACxMU,gBAAAQ,MAqBF,QAAAC,aArBE;AAjDV,IAAM,cAAc;AAEpB,SAAS,MAAM,MAAsB;AACnC,MAAI,OAAO;AACX,aAAW,QAAQ,KAAM,SAAQ,OAAO,KAAK,KAAK,YAAY,CAAC,KAAM;AACrE,SAAO,OAAO;AAChB;AAYA,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAaO,SAAS,mBAAmB,EAAE,QAAQ,WAAW,SAAS,UAAU,GAA4B;AACrG,MAAI,QAAQ,UAAU,EAAG,QAAO;AAChC,QAAM,OAAO;AACb,SACE,gBAAAA,MAAC,UAAK,WAAW,gCAAgC,aAAa,EAAE,IAC7D;AAAA,YAAQ,QAAQ,IAAI,CAAC,SAAS;AAC7B,YAAM,QAAQ,KAAK,aAAa,KAAK,KAAK,KAAK;AAC/C,YAAM,OAAO,eAAe,MAAM,KAAK,IAAI,IAAI,eAAe,MAAM;AACpE,aAAO,KAAK,OACV,gBAAAD;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA,WAAW,KAAK,eAAe,YAAY,OAAO;AAAA,UAClD,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,OAAM;AAAA,UACN,WAAW;AAAA;AAAA,QANN,KAAK;AAAA,MAOZ,IAEA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO;AAAA,UACP,WAAW,oFAAoF,IAAI,IAAI,IAAI;AAAA,UAC3G,OAAO,EAAE,OAAO,aAAa,QAAQ,YAAY;AAAA,UAEhD,gBAAM,KAAK,MAAM,KAAK,CAAC,EAAE,CAAC,GAAG,YAAY,KAAK;AAAA;AAAA,QAL1C,KAAK;AAAA,MAMZ;AAAA,IAEJ,CAAC;AAAA,IACA,QAAQ,WAAW,IAClB,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,6IAA6I,IAAI;AAAA,QAC5J,OAAO,EAAE,OAAO,aAAa,QAAQ,YAAY;AAAA,QAClD;AAAA;AAAA,UACG,QAAQ;AAAA;AAAA;AAAA,IACZ,IACE;AAAA,KACN;AAEJ;","names":["connected","isLocalConnectorName","useCallback","useEffect","useMemo","useRef","useState","Fragment","jsx","jsxs","useState","useEffect","useCallback","useMemo","isLocalConnectorName","useRef","jsx","jsxs"]}
@@ -0,0 +1,7 @@
1
+ import type { BladeClient } from "@blade-hq/agent-client";
2
+ /** One authenticated rules binding for every account authorization type. */
3
+ export declare function AccountConnectorRules({ client, name, refresh }: {
4
+ client: BladeClient;
5
+ name: string;
6
+ refresh?: number;
7
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import type { ConnectorRules, ConnectorRuleValue } from "@blade-hq/agent-client";
2
+ /** Hosts supply authenticated SDK reads/writes and their existing theme. */
3
+ export declare function ConnectorRulesPanel({ read, update, onCountChange, refresh, className }: {
4
+ read: () => Promise<ConnectorRules>;
5
+ update: (set: Record<string, ConnectorRuleValue>) => Promise<ConnectorRules>;
6
+ onCountChange?: (count: number, operations?: number) => void;
7
+ refresh?: number;
8
+ className?: string;
9
+ }): import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,3 @@
1
1
  export { DeviceConnection } from "./components/DeviceConnection";
2
2
  export { ConnectorConnection } from "./components/ConnectorConnection";
3
+ export { ConnectorRulesPanel } from "./components/ConnectorRulesPanel";
@@ -1,11 +1,14 @@
1
1
  import {
2
2
  ConnectorConnection,
3
3
  DeviceConnection
4
- } from "./chunk-J72ZLILV.js";
5
- import "./chunk-QIR73CES.js";
4
+ } from "./chunk-WO2VCQ5N.js";
5
+ import {
6
+ ConnectorRulesPanel
7
+ } from "./chunk-XBEN2ASY.js";
6
8
  import "./chunk-PR4QN5HX.js";
7
9
  export {
8
10
  ConnectorConnection,
11
+ ConnectorRulesPanel,
9
12
  DeviceConnection
10
13
  };
11
14
  //# sourceMappingURL=connectors.js.map
@@ -11,6 +11,25 @@ export declare const TURN_NAV_HIGHLIGHT_CLASS = "blade-turn-nav-flash";
11
11
  export interface TurnNavItem {
12
12
  id: string;
13
13
  title: string;
14
+ /** 这一段的小结(post_chat_followup.recaption);空时表示这一段没有小结。 */
15
+ recaption?: string;
16
+ /** 这一段交付的产物(final_artifacts),脉络卡片上直接列出来。 */
17
+ artifacts?: TurnNavArtifact[];
18
+ /** 这一段里的每一次用户发言(脉络展开后逐条列出)。 */
19
+ entries?: TurnNavEntry[];
20
+ }
21
+ /** 分段里的一次用户发言。 */
22
+ export interface TurnNavEntry {
23
+ id: string;
24
+ title: string;
25
+ /** AskUserQuestion 的应答:消息列表里没有独立行,点它定位不到。 */
26
+ answer?: boolean;
27
+ }
28
+ /** 这一段交付的产物(文件 / 链接)。 */
29
+ export interface TurnNavArtifact {
30
+ kind: "file" | "link";
31
+ target: string;
32
+ label: string;
14
33
  }
15
34
  export interface TurnNavigationSource {
16
35
  /** 目录来源;不传就不请求目录,导航条目只由 `fallbackItems` 兜底。 */
package/dist/index.d.ts CHANGED
@@ -23,3 +23,4 @@ export { TopicAssetSubmitDialog, useTopicAssetSubmissionAccess } from "./compone
23
23
  export type { TopicAssetSubmitDialogProps } from "./components/TopicAssetSubmitDialog";
24
24
  export { DeviceConnection } from "./components/DeviceConnection";
25
25
  export { ConnectorConnection } from "./components/ConnectorConnection";
26
+ export { ConnectorRulesPanel } from "./components/ConnectorRulesPanel";
package/dist/index.js CHANGED
@@ -6,26 +6,29 @@ import {
6
6
  useAgentSession,
7
7
  useReplay,
8
8
  useTopicAssetSubmissionAccess
9
- } from "./chunk-XP6T6SHZ.js";
10
- import "./chunk-2DPLLZOU.js";
9
+ } from "./chunk-IVGTMWRV.js";
10
+ import "./chunk-F2IJZX2Z.js";
11
11
  import {
12
12
  ConnectorConnection,
13
13
  DeviceConnection
14
- } from "./chunk-J72ZLILV.js";
15
- import "./chunk-HCW7SI5Q.js";
14
+ } from "./chunk-WO2VCQ5N.js";
15
+ import "./chunk-26NE55SJ.js";
16
16
  import {
17
17
  MarkdownContent
18
- } from "./chunk-XJ6ZA6LN.js";
18
+ } from "./chunk-VBHHFIII.js";
19
19
  import {
20
20
  BladeProvider,
21
21
  useBladeClient
22
- } from "./chunk-WRIMPZPN.js";
23
- import "./chunk-QIR73CES.js";
22
+ } from "./chunk-EQOKPZI2.js";
23
+ import {
24
+ ConnectorRulesPanel
25
+ } from "./chunk-XBEN2ASY.js";
24
26
  import "./chunk-PR4QN5HX.js";
25
27
  export {
26
28
  BladeProvider,
27
29
  ChatView,
28
30
  ConnectorConnection,
31
+ ConnectorRulesPanel,
29
32
  DeviceConnection,
30
33
  MarkdownContent,
31
34
  ReplayBar,
@@ -8,7 +8,7 @@ export type { UseMessagePinOptions } from "./hooks/use-message-pin";
8
8
  export { useTypewriterReveal } from "./hooks/use-typewriter-reveal";
9
9
  export type { UseTypewriterRevealResult } from "./hooks/use-typewriter-reveal";
10
10
  export { latestUserSpeechEntryId, TURN_NAV_HIGHLIGHT_CLASS, turnNavItemsFromMessages, useTurnNavigation, } from "./hooks/use-turn-navigation";
11
- export type { TurnNavigationOptions, TurnNavigationResult, TurnNavigationSource, } from "./hooks/use-turn-navigation";
11
+ export type { TurnNavigationOptions, TurnNavigationResult, TurnNavigationSource, TurnNavArtifact, TurnNavEntry, TurnNavItem, } from "./hooks/use-turn-navigation";
12
12
  export type { UseLlmChatResult } from "./hooks/use-llm-chat";
13
13
  export { ConnectorPanel } from "./components/ConnectorPanel";
14
14
  export type { ConnectorPanelProps } from "./components/ConnectorPanel";
package/dist/internal.js CHANGED
@@ -25,7 +25,7 @@ import {
25
25
  useTopicAssetSubmissionAccess,
26
26
  useTurnNavigation,
27
27
  useTypewriterReveal
28
- } from "./chunk-XP6T6SHZ.js";
28
+ } from "./chunk-IVGTMWRV.js";
29
29
  import {
30
30
  AccountConnectors,
31
31
  ConnectorPanel,
@@ -33,7 +33,7 @@ import {
33
33
  TRIGGER_ICON_LIMIT,
34
34
  selectionFromItem,
35
35
  triggerSummary
36
- } from "./chunk-7MCGQH34.js";
36
+ } from "./chunk-ZIECHNZA.js";
37
37
  import {
38
38
  PluginConnectorList,
39
39
  SessionPluginConfigDialog,
@@ -44,23 +44,23 @@ import {
44
44
  mergeConnectorItems,
45
45
  sessionPluginLabel,
46
46
  useSessionPluginActivation
47
- } from "./chunk-2DPLLZOU.js";
47
+ } from "./chunk-F2IJZX2Z.js";
48
48
  import {
49
49
  ConnectorConnection,
50
50
  DeviceConnection
51
- } from "./chunk-J72ZLILV.js";
51
+ } from "./chunk-WO2VCQ5N.js";
52
52
  import {
53
53
  McpAppCard,
54
54
  McpAppFrame,
55
55
  MessageImage,
56
56
  ToolUiCardView
57
- } from "./chunk-HCW7SI5Q.js";
57
+ } from "./chunk-26NE55SJ.js";
58
58
  import {
59
59
  CodeBlockPre,
60
60
  DEFAULT_ALLOWED_TAGS,
61
61
  MarkdownContent,
62
62
  MarkdownRenderer
63
- } from "./chunk-XJ6ZA6LN.js";
63
+ } from "./chunk-VBHHFIII.js";
64
64
  import {
65
65
  BladeProvider,
66
66
  BrowserConnectionDialog,
@@ -74,14 +74,15 @@ import {
74
74
  useBladeClient,
75
75
  useBladeHost,
76
76
  useOptionalBladeClient
77
- } from "./chunk-WRIMPZPN.js";
77
+ } from "./chunk-EQOKPZI2.js";
78
78
  import {
79
+ ConnectorRulesPanel,
79
80
  Content2,
80
81
  Portal,
81
82
  Provider,
82
83
  Root3,
83
84
  Trigger
84
- } from "./chunk-QIR73CES.js";
85
+ } from "./chunk-XBEN2ASY.js";
85
86
  import "./chunk-PR4QN5HX.js";
86
87
 
87
88
  // src/internal.ts
@@ -578,6 +579,7 @@ export {
578
579
  CodeBlockPre,
579
580
  ConnectorConnection,
580
581
  ConnectorPanel,
582
+ ConnectorRulesPanel,
581
583
  ContextCard,
582
584
  ContextGroupCard,
583
585
  DEFAULT_ALLOWED_TAGS,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal.ts","../src/lib/mount-renderers.tsx","../src/components/SessionMemoryToggle.tsx","../src/components/SessionBranchPicker.tsx"],"sourcesContent":["export * from \"./index\"\nexport * from \"./chat\"\nexport { useBladeHost, useOptionalBladeClient } from \"./context\"\nexport { MountHostContext, MountSlot, mountRenderersToReact } from \"./lib/mount-renderers\"\n\nexport { useLlmChat } from \"./hooks/use-llm-chat\"\nexport { useMessagePin } from \"./hooks/use-message-pin\"\nexport type { UseMessagePinOptions } from \"./hooks/use-message-pin\"\nexport { useTypewriterReveal } from \"./hooks/use-typewriter-reveal\"\nexport type { UseTypewriterRevealResult } from \"./hooks/use-typewriter-reveal\"\nexport {\n latestUserSpeechEntryId,\n TURN_NAV_HIGHLIGHT_CLASS,\n turnNavItemsFromMessages,\n useTurnNavigation,\n} from \"./hooks/use-turn-navigation\"\nexport type {\n TurnNavigationOptions,\n TurnNavigationResult,\n TurnNavigationSource,\n} from \"./hooks/use-turn-navigation\"\nexport type { UseLlmChatResult } from \"./hooks/use-llm-chat\"\n\nexport { ConnectorPanel } from \"./components/ConnectorPanel\"\nexport type { ConnectorPanelProps } from \"./components/ConnectorPanel\"\nexport { PluginConnectorList } from \"./components/PluginConnectorList\"\nexport type { ConfiguringPlugin, PluginConnectorListProps } from \"./components/PluginConnectorList\"\nexport { useSessionPluginActivation } from \"./components/use-session-plugin-activation\"\nexport type { UseSessionPluginActivationResult } from \"./components/use-session-plugin-activation\"\nexport {\n catalogToConnectorItems,\n filterConnectorItems,\n mergeConnectorItems,\n} from \"./components/plugin-connector\"\nexport type { PluginConnectorItem } from \"./components/plugin-connector\"\nexport { selectionFromItem, triggerSummary, TRIGGER_ICON_LIMIT } from \"./components/connector-panel-types\"\nexport type {\n PluginConnectorSelection,\n TriggerSummary,\n} from \"./components/connector-panel-types\"\nexport { SessionPluginSelector } from \"./components/SessionPluginSelector\"\nexport type { SessionPluginSelectorProps } from \"./components/SessionPluginSelector\"\nexport { SessionPluginIcon, sessionPluginLabel } from \"./components/SessionPluginIcon\"\nexport type { SessionPluginIconProps, SessionPluginLabelProps } from \"./components/SessionPluginIcon\"\nexport { PluginTriggerStack } from \"./components/PluginTriggerStack\"\nexport type { PluginTriggerStackProps } from \"./components/PluginTriggerStack\"\nexport { SessionPluginConfigDialog } from \"./components/SessionPluginConfigDialog\"\nexport type { SessionPluginConfigDialogProps } from \"./components/SessionPluginConfigDialog\"\nexport { SessionPluginConfigForm } from \"./components/SessionPluginConfigForm\"\nexport type {\n SessionPluginConfigDraft,\n SessionPluginConfigFormProps,\n} from \"./components/SessionPluginConfigForm\"\nexport { AgentChat } from \"./components/AgentChat\"\nexport type { AgentChatProps } from \"./components/AgentChat\"\nexport { LlmChat } from \"./components/LlmChat\"\nexport type { LlmChatProps } from \"./components/LlmChat\"\nexport type { LlmAdvancedSettings, LlmOverride } from \"./components/LlmAdvancedSettings\"\nexport { DEFAULT_ALLOWED_TAGS, MarkdownRenderer } from \"./components/markdown\"\nexport type {\n AllowedTags,\n CodeBlockOverrides,\n LinkSafetyConfig,\n MarkdownComponents,\n MarkdownRendererProps,\n RawHtmlPlugin,\n} from \"./components/markdown\"\nexport { WhatIfUserBubble } from \"./components/WhatIfUserBubble\"\nexport type { WhatIfUserBubbleProps } from \"./components/WhatIfUserBubble\"\nexport { parseWhatIfPrompt } from \"./lib/whatif-prompt\"\nexport type { ParsedWhatIfPrompt, WhatIfQuote } from \"./lib/whatif-prompt\"\nexport {\n getPlanUpdateDisplayState,\n isPlanUpdateTool,\n PLAN_AUTO_COLLAPSE_MS,\n parsePlanUpdate,\n pickCurrentPlanStep,\n PlanUpdateBlock,\n} from \"./components/PlanUpdateBlock\"\nexport type { PlanUpdateDisplayState } from \"./components/PlanUpdateBlock\"\nexport { ContextCard, ContextGroupCard } from \"./components/ContextCard\"\nexport type { ContextCardProps, ContextGroupCardProps } from \"./components/ContextCard\"\nexport { ToolUiCardView } from \"./components/ToolUiCardView\"\nexport { McpAppCard } from \"./components/McpAppCard\"\nexport type { McpAppMessage } from \"./components/McpAppCard\"\nexport { SessionMemoryToggle } from \"./components/SessionMemoryToggle\"\nexport type { SessionMemoryToggleProps } from \"./components/SessionMemoryToggle\"\nexport { SessionQueuePanel, isQueuePanelVisible } from \"./components/SessionQueuePanel\"\nexport type { SessionQueuePanelProps } from \"./components/SessionQueuePanel\"\n\nexport { SessionBranchPicker } from \"./components/SessionBranchPicker\"\nexport type { SessionBranchPickerProps } from \"./components/SessionBranchPicker\"\n\nexport { MessageImage, type MessageImageProps } from \"./components/MessageImage\"\n\nexport { BackgroundWakeNotice } from \"./components/BackgroundWakeNotice\"\n\nexport { TopicAssetSubmitDialog, useTopicAssetSubmissionAccess } from \"./components/TopicAssetSubmitDialog\"\nexport type { TopicAssetSubmitDialogProps } from \"./components/TopicAssetSubmitDialog\"\n\nexport { CodeBlockPre } from \"./chat/markdown/MarkdownContent\"\n\nexport { ChatLoadingIndicator, isPreparingReply } from \"./chat/ChatLoadingIndicator\"\n\nexport { BrowserConnectionDialog } from \"./components/BrowserConnectionDialog\"\n\nexport { AccountConnectors } from \"./components/AccountConnectors\"\n\nexport { McpAppFrame } from \"./components/McpAppFrame\"\nexport type { McpAppFrameProps } from \"./components/McpAppFrame\"\n","import type {\n BladeChatMountRenderers,\n MountHandle,\n MountRenderer,\n MountRendererObject,\n MountResult,\n} from \"@blade-hq/agent-client\"\nimport { createContext, useContext, useId, useLayoutEffect, useRef, type ReactNode } from \"react\"\nimport type { ChatViewRenderers } from \"../chat/customization\"\n\n/**\n * 挂载节点放在哪里。\n *\n * `<blade-chat>` 把它设成元素本身:挂载节点作为元素的 light DOM 子节点,经 Shadow DOM\n * 里的 `<slot>` 显示在区块位置,宿主页面的样式(包括 Vue 的 scoped 样式)直接生效。\n * 没有设置时(npm 包里),挂载节点就是组件内的一个 div。\n */\nexport const MountHostContext = createContext<HTMLElement | null>(null)\n\nfunction normalizeResult<T>(result: MountResult<T>): MountHandle<T> {\n if (typeof result === \"function\") return { destroy: result }\n if (result && typeof result === \"object\") return result\n return { destroy: () => {} }\n}\n\nfunction toObject<T>(renderer: MountRenderer<T>): MountRendererObject<T> {\n return typeof renderer === \"function\" ? { mount: renderer } : renderer\n}\n\nfunction sameData(a: object, b: object): boolean {\n const aKeys = Object.keys(a)\n if (aKeys.length !== Object.keys(b).length) return false\n return aKeys.every((key) => Object.is((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]))\n}\n\ninterface MountSlotProps<T extends object> {\n renderer: MountRendererObject<T>\n data: T\n}\n\n/** 给宿主一个 DOM 节点挂自己的内容;数据变化时原地更新或清理后重挂,卸载时清理。 */\nexport function MountSlot<T extends object>({ renderer, data }: MountSlotProps<T>) {\n const host = useContext(MountHostContext)\n const slotName = `blade-mount-${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`\n const localRef = useRef<HTMLDivElement>(null)\n const dataRef = useRef(data)\n const mountedRef = useRef<{ target: HTMLElement; handle: MountHandle<T>; data: T } | null>(null)\n\n useLayoutEffect(() => {\n dataRef.current = data\n })\n\n useLayoutEffect(() => {\n let target: HTMLElement\n if (host) {\n target = document.createElement(\"div\")\n target.slot = slotName\n host.appendChild(target)\n } else {\n if (!localRef.current) return\n target = localRef.current\n }\n const initial = dataRef.current\n mountedRef.current = { target, handle: normalizeResult(renderer.mount(target, initial)), data: initial }\n return () => {\n const mounted = mountedRef.current\n mountedRef.current = null\n mounted?.handle.destroy()\n if (host) target.remove()\n else target.replaceChildren()\n }\n }, [host, renderer, slotName])\n\n useLayoutEffect(() => {\n const mounted = mountedRef.current\n if (!mounted || sameData(mounted.data, data)) return\n mounted.data = data\n if (mounted.handle.update) {\n mounted.handle.update(data)\n return\n }\n mounted.handle.destroy()\n mounted.target.replaceChildren()\n mounted.handle = normalizeResult(renderer.mount(mounted.target, data))\n }, [data, renderer])\n\n return host ? <slot name={slotName} /> : <div ref={localRef} data-blade-mount=\"\" />\n}\n\nfunction slotFor<T extends object>(renderer: MountRendererObject<T>, data: T): ReactNode | null {\n if (renderer.match && !renderer.match(data)) return null\n return <MountSlot renderer={renderer} data={data} />\n}\n\n/**\n * 把挂载式渲染器转成普通 React 渲染器:两种写法走同一条渲染路径,`match` 返回\n * false 等于 React 渲染器返回 null(走默认渲染)。调用方要按 `renderers` 对象缓存结果,\n * 否则每次渲染都会得到新的渲染器、挂载内容被反复重建。\n */\nexport function mountRenderersToReact(\n renderers: BladeChatMountRenderers | null | undefined,\n context: { sessionId?: string } = {},\n): ChatViewRenderers | undefined {\n if (!renderers) return undefined\n const result: ChatViewRenderers = {}\n if (renderers.toolCall) {\n const renderer = toObject(renderers.toolCall)\n result.toolCall = (toolCall) => slotFor(renderer, { toolCall, sessionId: context.sessionId })\n }\n if (renderers.userMessage) {\n const renderer = toObject(renderers.userMessage)\n result.userMessage = ({ message }) => slotFor(renderer, { message })\n }\n if (renderers.assistantText) {\n const renderer = toObject(renderers.assistantText)\n result.assistantText = ({ message, streaming, compact, sessionId }) =>\n slotFor(renderer, { message, streaming, compact, sessionId })\n }\n return result\n}\n","import type { BladeClient } from \"@blade-hq/agent-client\"\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from \"react\"\nimport { useOptionalBladeClient } from \"../context\"\nimport { cn } from \"../lib/utils\"\n\ninterface SaveState {\n saving: boolean\n listeners: Set<() => void>\n}\n\nconst saveStates = new WeakMap<BladeClient, Map<string, SaveState>>()\n\nfunction getSaveState(client: BladeClient, sessionId: string): SaveState {\n let clientStates = saveStates.get(client)\n if (!clientStates) {\n clientStates = new Map()\n saveStates.set(client, clientStates)\n }\n let state = clientStates.get(sessionId)\n if (!state) {\n state = { saving: false, listeners: new Set() }\n clientStates.set(sessionId, state)\n }\n return state\n}\n\nfunction notify(state: SaveState) {\n for (const listener of state.listeners) listener()\n}\n\nfunction cleanupSaveState(client: BladeClient, sessionId: string, state: SaveState) {\n if (state.saving || state.listeners.size > 0) return\n const clientStates = saveStates.get(client)\n if (clientStates?.get(sessionId) === state) clientStates.delete(sessionId)\n}\n\nexport interface SessionMemoryToggleProps {\n sessionId: string\n enabled: boolean\n /** 不在 BladeProvider 内使用时显式传入,与宿主现有 BladeClient 复用连接和鉴权。 */\n client?: BladeClient\n disabled?: boolean\n label?: string\n className?: string\n labelClassName?: string\n inputClassName?: string\n onSaved?: (sessionId: string, enabled: boolean) => void\n onError?: (error: unknown) => void\n}\n\n/**\n * 当前会话记忆开关。同一 client + sessionId 的所有实例共享保存锁,避免多个聊天入口\n * 或会话切换时发出乱序更新;服务端成功后才通过 onSaved 交还权威值。\n */\nexport function SessionMemoryToggle({\n sessionId,\n enabled,\n client: clientProp,\n disabled = false,\n label = \"当前会话使用记忆\",\n className,\n labelClassName,\n inputClassName,\n onSaved,\n onError,\n}: SessionMemoryToggleProps) {\n const contextClient = useOptionalBladeClient()\n const client = clientProp ?? contextClient\n if (!client) {\n throw new Error(\"SessionMemoryToggle 必须在 <BladeProvider> 内使用或显式传入 client\")\n }\n\n const saveState = getSaveState(client, sessionId)\n const subscribe = useCallback(\n (listener: () => void) => {\n saveState.listeners.add(listener)\n return () => {\n saveState.listeners.delete(listener)\n cleanupSaveState(client, sessionId, saveState)\n }\n },\n [client, saveState, sessionId],\n )\n const getSaving = useCallback(() => saveState.saving, [saveState])\n const saving = useSyncExternalStore(\n subscribe,\n getSaving,\n getSaving,\n )\n const [draftEnabled, setDraftEnabled] = useState(enabled)\n const activeSessionIdRef = useRef(sessionId)\n activeSessionIdRef.current = sessionId\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new session must discard this component instance's optimistic value even when both sessions share the same enabled prop\n useEffect(() => {\n setDraftEnabled(enabled)\n }, [enabled, sessionId])\n\n const update = useCallback(\n (nextEnabled: boolean) => {\n const currentSaveState = getSaveState(client, sessionId)\n if (currentSaveState.saving) return\n currentSaveState.saving = true\n notify(currentSaveState)\n setDraftEnabled(nextEnabled)\n\n void client.sessions.updateSessionMemory(sessionId, nextEnabled).then(\n (updated) => {\n if (activeSessionIdRef.current === sessionId) {\n setDraftEnabled(updated.memory_enabled)\n }\n onSaved?.(sessionId, updated.memory_enabled)\n },\n (error) => {\n if (activeSessionIdRef.current === sessionId) setDraftEnabled(enabled)\n onError?.(error)\n },\n ).finally(() => {\n currentSaveState.saving = false\n notify(currentSaveState)\n cleanupSaveState(client, sessionId, currentSaveState)\n })\n },\n [client, enabled, onError, onSaved, sessionId],\n )\n\n return (\n <label className={cn(\"flex items-center justify-between\", className)}>\n <span className={labelClassName}>{label}</span>\n <input\n type=\"checkbox\"\n checked={draftEnabled}\n onChange={(event) => update(event.target.checked)}\n disabled={disabled || saving}\n className={inputClassName}\n />\n </label>\n )\n}\n","import type { BladeClient } from \"@blade-hq/agent-client\"\nimport * as Tooltip from \"@radix-ui/react-tooltip\"\nimport { useMemo, useState } from \"react\"\nimport { cn } from \"../lib/utils\"\n\ntype CheckpointTree = Awaited<ReturnType<BladeClient[\"sessions\"][\"getSessionCheckpoints\"]>>\ntype CheckpointNode = CheckpointTree[\"nodes\"][number]\n\nexport interface SessionBranchPickerProps {\n tree: CheckpointTree\n /** Disable changes while this session is running or read-only. */\n disabled?: boolean\n /** Restore only the conversation; the host owns history refresh and composer drafts. */\n onCheckout: (checkpointId: string, position: \"before\" | \"turn_end\") => Promise<void>\n}\n\nconst ROW_HEIGHT = 32\nconst SVG_WIDTH = 44\n\ninterface LayoutNode {\n id: string\n column: number\n row: number\n parentRow: number | null\n parentColumn: number | null\n isActive: boolean\n isCurrent: boolean\n isVirtual: boolean\n preview: string\n content: string\n}\n\ninterface LayoutGraph {\n nodes: LayoutNode[]\n hasCycle: boolean\n maxColumn: number\n maxRow: number\n}\n\nexport function SessionBranchPicker({\n tree,\n disabled = false,\n onCheckout,\n}: SessionBranchPickerProps) {\n const [checkoutError, setCheckoutError] = useState<string | null>(null)\n const [pendingNodeId, setPendingNodeId] = useState<string | null>(null)\n const hasHistory = tree.nodes.length > 0\n const layout = useMemo(() => buildLayoutNodes(tree), [tree])\n const nodeMap = useMemo(() => new Map(tree.nodes.map((node) => [node.id, node])), [tree])\n const isBusy = disabled || pendingNodeId !== null\n const graphHeight = Math.max((layout.maxRow + 1) * ROW_HEIGHT, ROW_HEIGHT)\n const graphWidth = Math.max(SVG_WIDTH, getColumnX(layout.maxColumn) + 12)\n\n async function checkoutNode(node: CheckpointNode, position: \"before\" | \"turn_end\") {\n if (isBusy) return\n setCheckoutError(null)\n setPendingNodeId(node.id)\n try {\n await onCheckout(node.id, position)\n } catch (error) {\n setCheckoutError(error instanceof Error ? error.message : \"切换失败,请稍后重试\")\n } finally {\n setPendingNodeId(null)\n }\n }\n\n async function handleVirtualClick(node: LayoutNode) {\n if (isBusy || !node.isVirtual || node.isActive) return\n const sourceNode = nodeMap.get(node.content)\n if (sourceNode) await checkoutNode(sourceNode, \"turn_end\")\n }\n\n async function handleNodeSelect(node: LayoutNode) {\n if (isBusy) return\n const sourceNode = nodeMap.get(node.id)\n if (sourceNode) await checkoutNode(sourceNode, \"before\")\n }\n\n if (!hasHistory) return null\n\n return (\n <Tooltip.Provider delayDuration={200}>\n {checkoutError ? (\n <p role=\"alert\" className=\"mb-2 text-xs text-destructive\">\n {checkoutError}\n </p>\n ) : null}\n <div className=\"flex max-h-52 justify-center overflow-x-auto overflow-y-auto\">\n <div className=\"relative\" style={{ height: graphHeight, width: graphWidth }}>\n <svg\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-0 top-0 z-10 overflow-visible\"\n width={graphWidth}\n height={graphHeight}\n viewBox={`0 0 ${graphWidth} ${graphHeight}`}\n fill=\"none\"\n >\n {layout.nodes.map((node) => {\n if (node.parentRow == null || node.parentColumn == null) {\n return null\n }\n\n const childStroke = node.isActive\n ? \"hsl(var(--primary))\"\n : \"hsl(var(--muted-foreground))\"\n\n return (\n <path\n key={`path-${node.id}`}\n d={buildEdgePath(\n getColumnX(node.parentColumn),\n getRowY(node.parentRow),\n getColumnX(node.column),\n getRowY(node.row),\n )}\n stroke={childStroke}\n strokeOpacity={node.isActive ? 0.95 : 0.45}\n strokeWidth={node.isActive ? 1.8 : 1.4}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeDasharray={node.isVirtual ? \"3 3\" : undefined}\n />\n )\n })}\n </svg>\n\n <div className=\"relative z-0 h-full\">\n {layout.nodes.map((node) => {\n const isPendingNode = pendingNodeId === node.id\n const color = node.isActive ? \"hsl(var(--primary))\" : \"hsl(var(--muted-foreground))\"\n const previewText = node.isVirtual\n ? isPendingNode\n ? \"切换中...\"\n : \"\"\n : isPendingNode\n ? \"切换中...\"\n : node.preview\n const shouldShowTooltip = !node.isVirtual || Boolean(previewText)\n const button = (\n <button\n type=\"button\"\n onClick={() =>\n void (node.isVirtual ? handleVirtualClick(node) : handleNodeSelect(node))\n }\n disabled={isBusy}\n aria-current={!node.isVirtual && node.isCurrent ? \"step\" : undefined}\n aria-label={node.isVirtual ? \"切换到该分支\" : node.preview}\n className={cn(\n \"absolute z-20 m-0 h-8 w-6 overflow-visible border-0 bg-transparent p-0\",\n isBusy ? \"cursor-not-allowed opacity-60\" : \"cursor-pointer\",\n )}\n style={{\n top: node.row * ROW_HEIGHT,\n left: getColumnX(node.column) - 12,\n }}\n >\n <span aria-hidden=\"true\" className=\"absolute left-0 top-0 h-8 w-6\">\n <svg\n aria-hidden=\"true\"\n role=\"img\"\n className=\"pointer-events-none absolute left-0 top-0 h-full w-full overflow-visible\"\n width={24}\n height={ROW_HEIGHT}\n viewBox={`0 0 24 ${ROW_HEIGHT}`}\n fill=\"none\"\n >\n {node.isVirtual ? (\n <circle\n cx={12}\n cy={ROW_HEIGHT / 2}\n r={3.5}\n fill=\"none\"\n stroke={color}\n strokeWidth={1.2}\n strokeDasharray=\"2 2\"\n opacity={0.7}\n />\n ) : (\n <g>\n {node.isCurrent ? (\n <circle cx={12} cy={ROW_HEIGHT / 2} r={9} fill={color} opacity={0.18} />\n ) : null}\n <circle\n cx={12}\n cy={ROW_HEIGHT / 2}\n r={node.isCurrent ? 5.5 : 4}\n fill={color}\n />\n </g>\n )}\n </svg>\n </span>\n </button>\n )\n\n if (!shouldShowTooltip) {\n return <div key={node.id}>{button}</div>\n }\n\n return (\n <Tooltip.Root key={node.id}>\n <Tooltip.Trigger asChild>{button}</Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content\n side=\"right\"\n sideOffset={8}\n className={cn(\n \"z-[60] rounded-md border border-border bg-popover px-2 py-1 text-xs text-foreground shadow-md\",\n !node.isVirtual && node.isCurrent && \"font-semibold\",\n )}\n >\n {previewText}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n )\n })}\n </div>\n </div>\n </div>\n </Tooltip.Provider>\n )\n}\nfunction buildLayoutNodes(tree: CheckpointTree | undefined): LayoutGraph {\n if (!tree || tree.nodes.length === 0) {\n return { nodes: [], hasCycle: false, maxColumn: 0, maxRow: 0 }\n }\n\n const nodeMap = new Map(tree.nodes.map((node) => [node.id, node]))\n const order = new Map(tree.nodes.map((node, index) => [node.id, index]))\n const childrenMap = new Map<string | null, CheckpointNode[]>()\n\n for (const node of tree.nodes) {\n const parentId = node.parent_id && nodeMap.has(node.parent_id) ? node.parent_id : null\n const siblings = childrenMap.get(parentId) ?? []\n siblings.push(node)\n childrenMap.set(parentId, siblings)\n }\n\n const activeIds = new Set<string>()\n const activeVisited = new Set<string>()\n const leafId = tree.leaf_id\n let current = tree.leaf_id\n\n while (current && nodeMap.has(current) && !activeVisited.has(current)) {\n activeIds.add(current)\n activeVisited.add(current)\n current = nodeMap.get(current)?.parent_id ?? null\n }\n\n const layoutNodes: LayoutNode[] = []\n const placed = new Set<string>()\n const visiting = new Set<string>()\n let nextColumn = 1\n let maxColumn = 0\n let maxRow = 0\n let hasCycle = false\n\n const rootSort = (a: CheckpointNode, b: CheckpointNode) =>\n (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0)\n\n const childSort = (a: CheckpointNode, b: CheckpointNode) =>\n (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0)\n\n const allocateColumn = () => {\n const fresh = nextColumn\n nextColumn += 1\n return fresh\n }\n\n function walk(node: CheckpointNode, parent: LayoutNode | null, column: number, row: number) {\n if (visiting.has(node.id)) {\n hasCycle = true\n return\n }\n\n if (placed.has(node.id)) {\n return\n }\n\n visiting.add(node.id)\n maxColumn = Math.max(maxColumn, column)\n maxRow = Math.max(maxRow, row)\n\n const layoutNode: LayoutNode = {\n id: node.id,\n column,\n row,\n parentRow: parent?.row ?? null,\n parentColumn: parent?.column ?? null,\n isActive: activeIds.has(node.id),\n isCurrent: node.id === leafId,\n isVirtual: false,\n preview: formatPreview(node.content_preview),\n content: node.content,\n }\n\n layoutNodes.push(layoutNode)\n placed.add(node.id)\n\n const children = [...(childrenMap.get(node.id) ?? [])].sort(childSort)\n\n if (children.length === 0) {\n const virtualRow = row + 1\n maxRow = Math.max(maxRow, virtualRow)\n layoutNodes.push({\n id: `__virtual__${node.id}`,\n column,\n row: virtualRow,\n parentRow: layoutNode.row,\n parentColumn: layoutNode.column,\n isActive: activeIds.has(node.id),\n isCurrent: false,\n isVirtual: true,\n preview: \"\",\n content: node.id,\n })\n } else {\n for (const [index, child] of children.entries()) {\n if (visiting.has(child.id)) {\n hasCycle = true\n continue\n }\n\n const childColumn = index === 0 ? column : allocateColumn()\n walk(child, layoutNode, childColumn, row + 1)\n }\n }\n\n visiting.delete(node.id)\n }\n\n const roots = [...(childrenMap.get(null) ?? [])].sort(rootSort)\n for (const [index, root] of roots.entries()) {\n const rootColumn = index === 0 ? 0 : allocateColumn()\n walk(root, null, rootColumn, 0)\n }\n\n for (const node of [...tree.nodes].sort(rootSort)) {\n if (!placed.has(node.id)) {\n hasCycle = true\n const rootColumn = layoutNodes.length === 0 ? 0 : allocateColumn()\n walk(node, null, rootColumn, 0)\n }\n }\n\n return {\n nodes: layoutNodes,\n hasCycle,\n maxColumn,\n maxRow,\n }\n}\n\nfunction formatPreview(preview: string): string {\n const normalized = preview.replace(/\\s+/g, \" \").trim()\n return normalized.length > 0 ? normalized : \"(空消息)\"\n}\n\nfunction getColumnX(column: number): number {\n return 12 + column * 24\n}\n\nfunction getRowY(row: number): number {\n return row * ROW_HEIGHT + ROW_HEIGHT / 2\n}\n\nfunction buildEdgePath(fromX: number, fromY: number, toX: number, toY: number): string {\n if (fromX === toX || fromY === toY) {\n return `M ${fromX} ${fromY} L ${toX} ${toY}`\n }\n\n const r = Math.min(5, Math.abs(toX - fromX), Math.abs(toY - fromY))\n const dx = toX > fromX ? 1 : -1\n\n return [\n `M ${fromX} ${fromY}`,\n `H ${toX - dx * r}`,\n `A ${r} ${r} 0 0 ${dx > 0 ? 1 : 0} ${toX} ${fromY + r}`,\n `V ${toY}`,\n ].join(\" \")\n}\n"],"mappings":"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","names":["useRef","jsx","useRef","useState","jsx","jsxs","useState"]}
1
+ {"version":3,"sources":["../src/internal.ts","../src/lib/mount-renderers.tsx","../src/components/SessionMemoryToggle.tsx","../src/components/SessionBranchPicker.tsx"],"sourcesContent":["export * from \"./index\"\nexport * from \"./chat\"\nexport { useBladeHost, useOptionalBladeClient } from \"./context\"\nexport { MountHostContext, MountSlot, mountRenderersToReact } from \"./lib/mount-renderers\"\n\nexport { useLlmChat } from \"./hooks/use-llm-chat\"\nexport { useMessagePin } from \"./hooks/use-message-pin\"\nexport type { UseMessagePinOptions } from \"./hooks/use-message-pin\"\nexport { useTypewriterReveal } from \"./hooks/use-typewriter-reveal\"\nexport type { UseTypewriterRevealResult } from \"./hooks/use-typewriter-reveal\"\nexport {\n latestUserSpeechEntryId,\n TURN_NAV_HIGHLIGHT_CLASS,\n turnNavItemsFromMessages,\n useTurnNavigation,\n} from \"./hooks/use-turn-navigation\"\nexport type {\n TurnNavigationOptions,\n TurnNavigationResult,\n TurnNavigationSource,\n TurnNavArtifact,\n TurnNavEntry,\n TurnNavItem,\n} from \"./hooks/use-turn-navigation\"\nexport type { UseLlmChatResult } from \"./hooks/use-llm-chat\"\n\nexport { ConnectorPanel } from \"./components/ConnectorPanel\"\nexport type { ConnectorPanelProps } from \"./components/ConnectorPanel\"\nexport { PluginConnectorList } from \"./components/PluginConnectorList\"\nexport type { ConfiguringPlugin, PluginConnectorListProps } from \"./components/PluginConnectorList\"\nexport { useSessionPluginActivation } from \"./components/use-session-plugin-activation\"\nexport type { UseSessionPluginActivationResult } from \"./components/use-session-plugin-activation\"\nexport {\n catalogToConnectorItems,\n filterConnectorItems,\n mergeConnectorItems,\n} from \"./components/plugin-connector\"\nexport type { PluginConnectorItem } from \"./components/plugin-connector\"\nexport { selectionFromItem, triggerSummary, TRIGGER_ICON_LIMIT } from \"./components/connector-panel-types\"\nexport type {\n PluginConnectorSelection,\n TriggerSummary,\n} from \"./components/connector-panel-types\"\nexport { SessionPluginSelector } from \"./components/SessionPluginSelector\"\nexport type { SessionPluginSelectorProps } from \"./components/SessionPluginSelector\"\nexport { SessionPluginIcon, sessionPluginLabel } from \"./components/SessionPluginIcon\"\nexport type { SessionPluginIconProps, SessionPluginLabelProps } from \"./components/SessionPluginIcon\"\nexport { PluginTriggerStack } from \"./components/PluginTriggerStack\"\nexport type { PluginTriggerStackProps } from \"./components/PluginTriggerStack\"\nexport { SessionPluginConfigDialog } from \"./components/SessionPluginConfigDialog\"\nexport type { SessionPluginConfigDialogProps } from \"./components/SessionPluginConfigDialog\"\nexport { SessionPluginConfigForm } from \"./components/SessionPluginConfigForm\"\nexport type {\n SessionPluginConfigDraft,\n SessionPluginConfigFormProps,\n} from \"./components/SessionPluginConfigForm\"\nexport { AgentChat } from \"./components/AgentChat\"\nexport type { AgentChatProps } from \"./components/AgentChat\"\nexport { LlmChat } from \"./components/LlmChat\"\nexport type { LlmChatProps } from \"./components/LlmChat\"\nexport type { LlmAdvancedSettings, LlmOverride } from \"./components/LlmAdvancedSettings\"\nexport { DEFAULT_ALLOWED_TAGS, MarkdownRenderer } from \"./components/markdown\"\nexport type {\n AllowedTags,\n CodeBlockOverrides,\n LinkSafetyConfig,\n MarkdownComponents,\n MarkdownRendererProps,\n RawHtmlPlugin,\n} from \"./components/markdown\"\nexport { WhatIfUserBubble } from \"./components/WhatIfUserBubble\"\nexport type { WhatIfUserBubbleProps } from \"./components/WhatIfUserBubble\"\nexport { parseWhatIfPrompt } from \"./lib/whatif-prompt\"\nexport type { ParsedWhatIfPrompt, WhatIfQuote } from \"./lib/whatif-prompt\"\nexport {\n getPlanUpdateDisplayState,\n isPlanUpdateTool,\n PLAN_AUTO_COLLAPSE_MS,\n parsePlanUpdate,\n pickCurrentPlanStep,\n PlanUpdateBlock,\n} from \"./components/PlanUpdateBlock\"\nexport type { PlanUpdateDisplayState } from \"./components/PlanUpdateBlock\"\nexport { ContextCard, ContextGroupCard } from \"./components/ContextCard\"\nexport type { ContextCardProps, ContextGroupCardProps } from \"./components/ContextCard\"\nexport { ToolUiCardView } from \"./components/ToolUiCardView\"\nexport { McpAppCard } from \"./components/McpAppCard\"\nexport type { McpAppMessage } from \"./components/McpAppCard\"\nexport { SessionMemoryToggle } from \"./components/SessionMemoryToggle\"\nexport type { SessionMemoryToggleProps } from \"./components/SessionMemoryToggle\"\nexport { SessionQueuePanel, isQueuePanelVisible } from \"./components/SessionQueuePanel\"\nexport type { SessionQueuePanelProps } from \"./components/SessionQueuePanel\"\n\nexport { SessionBranchPicker } from \"./components/SessionBranchPicker\"\nexport type { SessionBranchPickerProps } from \"./components/SessionBranchPicker\"\n\nexport { MessageImage, type MessageImageProps } from \"./components/MessageImage\"\n\nexport { BackgroundWakeNotice } from \"./components/BackgroundWakeNotice\"\n\nexport { TopicAssetSubmitDialog, useTopicAssetSubmissionAccess } from \"./components/TopicAssetSubmitDialog\"\nexport type { TopicAssetSubmitDialogProps } from \"./components/TopicAssetSubmitDialog\"\n\nexport { CodeBlockPre } from \"./chat/markdown/MarkdownContent\"\n\nexport { ChatLoadingIndicator, isPreparingReply } from \"./chat/ChatLoadingIndicator\"\n\nexport { BrowserConnectionDialog } from \"./components/BrowserConnectionDialog\"\n\nexport { AccountConnectors } from \"./components/AccountConnectors\"\n\nexport { McpAppFrame } from \"./components/McpAppFrame\"\nexport type { McpAppFrameProps } from \"./components/McpAppFrame\"\n","import type {\n BladeChatMountRenderers,\n MountHandle,\n MountRenderer,\n MountRendererObject,\n MountResult,\n} from \"@blade-hq/agent-client\"\nimport { createContext, useContext, useId, useLayoutEffect, useRef, type ReactNode } from \"react\"\nimport type { ChatViewRenderers } from \"../chat/customization\"\n\n/**\n * 挂载节点放在哪里。\n *\n * `<blade-chat>` 把它设成元素本身:挂载节点作为元素的 light DOM 子节点,经 Shadow DOM\n * 里的 `<slot>` 显示在区块位置,宿主页面的样式(包括 Vue 的 scoped 样式)直接生效。\n * 没有设置时(npm 包里),挂载节点就是组件内的一个 div。\n */\nexport const MountHostContext = createContext<HTMLElement | null>(null)\n\nfunction normalizeResult<T>(result: MountResult<T>): MountHandle<T> {\n if (typeof result === \"function\") return { destroy: result }\n if (result && typeof result === \"object\") return result\n return { destroy: () => {} }\n}\n\nfunction toObject<T>(renderer: MountRenderer<T>): MountRendererObject<T> {\n return typeof renderer === \"function\" ? { mount: renderer } : renderer\n}\n\nfunction sameData(a: object, b: object): boolean {\n const aKeys = Object.keys(a)\n if (aKeys.length !== Object.keys(b).length) return false\n return aKeys.every((key) => Object.is((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]))\n}\n\ninterface MountSlotProps<T extends object> {\n renderer: MountRendererObject<T>\n data: T\n}\n\n/** 给宿主一个 DOM 节点挂自己的内容;数据变化时原地更新或清理后重挂,卸载时清理。 */\nexport function MountSlot<T extends object>({ renderer, data }: MountSlotProps<T>) {\n const host = useContext(MountHostContext)\n const slotName = `blade-mount-${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`\n const localRef = useRef<HTMLDivElement>(null)\n const dataRef = useRef(data)\n const mountedRef = useRef<{ target: HTMLElement; handle: MountHandle<T>; data: T } | null>(null)\n\n useLayoutEffect(() => {\n dataRef.current = data\n })\n\n useLayoutEffect(() => {\n let target: HTMLElement\n if (host) {\n target = document.createElement(\"div\")\n target.slot = slotName\n host.appendChild(target)\n } else {\n if (!localRef.current) return\n target = localRef.current\n }\n const initial = dataRef.current\n mountedRef.current = { target, handle: normalizeResult(renderer.mount(target, initial)), data: initial }\n return () => {\n const mounted = mountedRef.current\n mountedRef.current = null\n mounted?.handle.destroy()\n if (host) target.remove()\n else target.replaceChildren()\n }\n }, [host, renderer, slotName])\n\n useLayoutEffect(() => {\n const mounted = mountedRef.current\n if (!mounted || sameData(mounted.data, data)) return\n mounted.data = data\n if (mounted.handle.update) {\n mounted.handle.update(data)\n return\n }\n mounted.handle.destroy()\n mounted.target.replaceChildren()\n mounted.handle = normalizeResult(renderer.mount(mounted.target, data))\n }, [data, renderer])\n\n return host ? <slot name={slotName} /> : <div ref={localRef} data-blade-mount=\"\" />\n}\n\nfunction slotFor<T extends object>(renderer: MountRendererObject<T>, data: T): ReactNode | null {\n if (renderer.match && !renderer.match(data)) return null\n return <MountSlot renderer={renderer} data={data} />\n}\n\n/**\n * 把挂载式渲染器转成普通 React 渲染器:两种写法走同一条渲染路径,`match` 返回\n * false 等于 React 渲染器返回 null(走默认渲染)。调用方要按 `renderers` 对象缓存结果,\n * 否则每次渲染都会得到新的渲染器、挂载内容被反复重建。\n */\nexport function mountRenderersToReact(\n renderers: BladeChatMountRenderers | null | undefined,\n context: { sessionId?: string } = {},\n): ChatViewRenderers | undefined {\n if (!renderers) return undefined\n const result: ChatViewRenderers = {}\n if (renderers.toolCall) {\n const renderer = toObject(renderers.toolCall)\n result.toolCall = (toolCall) => slotFor(renderer, { toolCall, sessionId: context.sessionId })\n }\n if (renderers.userMessage) {\n const renderer = toObject(renderers.userMessage)\n result.userMessage = ({ message }) => slotFor(renderer, { message })\n }\n if (renderers.assistantText) {\n const renderer = toObject(renderers.assistantText)\n result.assistantText = ({ message, streaming, compact, sessionId }) =>\n slotFor(renderer, { message, streaming, compact, sessionId })\n }\n return result\n}\n","import type { BladeClient } from \"@blade-hq/agent-client\"\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from \"react\"\nimport { useOptionalBladeClient } from \"../context\"\nimport { cn } from \"../lib/utils\"\n\ninterface SaveState {\n saving: boolean\n listeners: Set<() => void>\n}\n\nconst saveStates = new WeakMap<BladeClient, Map<string, SaveState>>()\n\nfunction getSaveState(client: BladeClient, sessionId: string): SaveState {\n let clientStates = saveStates.get(client)\n if (!clientStates) {\n clientStates = new Map()\n saveStates.set(client, clientStates)\n }\n let state = clientStates.get(sessionId)\n if (!state) {\n state = { saving: false, listeners: new Set() }\n clientStates.set(sessionId, state)\n }\n return state\n}\n\nfunction notify(state: SaveState) {\n for (const listener of state.listeners) listener()\n}\n\nfunction cleanupSaveState(client: BladeClient, sessionId: string, state: SaveState) {\n if (state.saving || state.listeners.size > 0) return\n const clientStates = saveStates.get(client)\n if (clientStates?.get(sessionId) === state) clientStates.delete(sessionId)\n}\n\nexport interface SessionMemoryToggleProps {\n sessionId: string\n enabled: boolean\n /** 不在 BladeProvider 内使用时显式传入,与宿主现有 BladeClient 复用连接和鉴权。 */\n client?: BladeClient\n disabled?: boolean\n label?: string\n className?: string\n labelClassName?: string\n inputClassName?: string\n onSaved?: (sessionId: string, enabled: boolean) => void\n onError?: (error: unknown) => void\n}\n\n/**\n * 当前会话记忆开关。同一 client + sessionId 的所有实例共享保存锁,避免多个聊天入口\n * 或会话切换时发出乱序更新;服务端成功后才通过 onSaved 交还权威值。\n */\nexport function SessionMemoryToggle({\n sessionId,\n enabled,\n client: clientProp,\n disabled = false,\n label = \"当前会话使用记忆\",\n className,\n labelClassName,\n inputClassName,\n onSaved,\n onError,\n}: SessionMemoryToggleProps) {\n const contextClient = useOptionalBladeClient()\n const client = clientProp ?? contextClient\n if (!client) {\n throw new Error(\"SessionMemoryToggle 必须在 <BladeProvider> 内使用或显式传入 client\")\n }\n\n const saveState = getSaveState(client, sessionId)\n const subscribe = useCallback(\n (listener: () => void) => {\n saveState.listeners.add(listener)\n return () => {\n saveState.listeners.delete(listener)\n cleanupSaveState(client, sessionId, saveState)\n }\n },\n [client, saveState, sessionId],\n )\n const getSaving = useCallback(() => saveState.saving, [saveState])\n const saving = useSyncExternalStore(\n subscribe,\n getSaving,\n getSaving,\n )\n const [draftEnabled, setDraftEnabled] = useState(enabled)\n const activeSessionIdRef = useRef(sessionId)\n activeSessionIdRef.current = sessionId\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new session must discard this component instance's optimistic value even when both sessions share the same enabled prop\n useEffect(() => {\n setDraftEnabled(enabled)\n }, [enabled, sessionId])\n\n const update = useCallback(\n (nextEnabled: boolean) => {\n const currentSaveState = getSaveState(client, sessionId)\n if (currentSaveState.saving) return\n currentSaveState.saving = true\n notify(currentSaveState)\n setDraftEnabled(nextEnabled)\n\n void client.sessions.updateSessionMemory(sessionId, nextEnabled).then(\n (updated) => {\n if (activeSessionIdRef.current === sessionId) {\n setDraftEnabled(updated.memory_enabled)\n }\n onSaved?.(sessionId, updated.memory_enabled)\n },\n (error) => {\n if (activeSessionIdRef.current === sessionId) setDraftEnabled(enabled)\n onError?.(error)\n },\n ).finally(() => {\n currentSaveState.saving = false\n notify(currentSaveState)\n cleanupSaveState(client, sessionId, currentSaveState)\n })\n },\n [client, enabled, onError, onSaved, sessionId],\n )\n\n return (\n <label className={cn(\"flex items-center justify-between\", className)}>\n <span className={labelClassName}>{label}</span>\n <input\n type=\"checkbox\"\n checked={draftEnabled}\n onChange={(event) => update(event.target.checked)}\n disabled={disabled || saving}\n className={inputClassName}\n />\n </label>\n )\n}\n","import type { BladeClient } from \"@blade-hq/agent-client\"\nimport * as Tooltip from \"@radix-ui/react-tooltip\"\nimport { useMemo, useState } from \"react\"\nimport { cn } from \"../lib/utils\"\n\ntype CheckpointTree = Awaited<ReturnType<BladeClient[\"sessions\"][\"getSessionCheckpoints\"]>>\ntype CheckpointNode = CheckpointTree[\"nodes\"][number]\n\nexport interface SessionBranchPickerProps {\n tree: CheckpointTree\n /** Disable changes while this session is running or read-only. */\n disabled?: boolean\n /** Restore only the conversation; the host owns history refresh and composer drafts. */\n onCheckout: (checkpointId: string, position: \"before\" | \"turn_end\") => Promise<void>\n}\n\nconst ROW_HEIGHT = 32\nconst SVG_WIDTH = 44\n\ninterface LayoutNode {\n id: string\n column: number\n row: number\n parentRow: number | null\n parentColumn: number | null\n isActive: boolean\n isCurrent: boolean\n isVirtual: boolean\n preview: string\n content: string\n}\n\ninterface LayoutGraph {\n nodes: LayoutNode[]\n hasCycle: boolean\n maxColumn: number\n maxRow: number\n}\n\nexport function SessionBranchPicker({\n tree,\n disabled = false,\n onCheckout,\n}: SessionBranchPickerProps) {\n const [checkoutError, setCheckoutError] = useState<string | null>(null)\n const [pendingNodeId, setPendingNodeId] = useState<string | null>(null)\n const hasHistory = tree.nodes.length > 0\n const layout = useMemo(() => buildLayoutNodes(tree), [tree])\n const nodeMap = useMemo(() => new Map(tree.nodes.map((node) => [node.id, node])), [tree])\n const isBusy = disabled || pendingNodeId !== null\n const graphHeight = Math.max((layout.maxRow + 1) * ROW_HEIGHT, ROW_HEIGHT)\n const graphWidth = Math.max(SVG_WIDTH, getColumnX(layout.maxColumn) + 12)\n\n async function checkoutNode(node: CheckpointNode, position: \"before\" | \"turn_end\") {\n if (isBusy) return\n setCheckoutError(null)\n setPendingNodeId(node.id)\n try {\n await onCheckout(node.id, position)\n } catch (error) {\n setCheckoutError(error instanceof Error ? error.message : \"切换失败,请稍后重试\")\n } finally {\n setPendingNodeId(null)\n }\n }\n\n async function handleVirtualClick(node: LayoutNode) {\n if (isBusy || !node.isVirtual || node.isActive) return\n const sourceNode = nodeMap.get(node.content)\n if (sourceNode) await checkoutNode(sourceNode, \"turn_end\")\n }\n\n async function handleNodeSelect(node: LayoutNode) {\n if (isBusy) return\n const sourceNode = nodeMap.get(node.id)\n if (sourceNode) await checkoutNode(sourceNode, \"before\")\n }\n\n if (!hasHistory) return null\n\n return (\n <Tooltip.Provider delayDuration={200}>\n {checkoutError ? (\n <p role=\"alert\" className=\"mb-2 text-xs text-destructive\">\n {checkoutError}\n </p>\n ) : null}\n <div className=\"flex max-h-52 justify-center overflow-x-auto overflow-y-auto\">\n <div className=\"relative\" style={{ height: graphHeight, width: graphWidth }}>\n <svg\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-0 top-0 z-10 overflow-visible\"\n width={graphWidth}\n height={graphHeight}\n viewBox={`0 0 ${graphWidth} ${graphHeight}`}\n fill=\"none\"\n >\n {layout.nodes.map((node) => {\n if (node.parentRow == null || node.parentColumn == null) {\n return null\n }\n\n const childStroke = node.isActive\n ? \"hsl(var(--primary))\"\n : \"hsl(var(--muted-foreground))\"\n\n return (\n <path\n key={`path-${node.id}`}\n d={buildEdgePath(\n getColumnX(node.parentColumn),\n getRowY(node.parentRow),\n getColumnX(node.column),\n getRowY(node.row),\n )}\n stroke={childStroke}\n strokeOpacity={node.isActive ? 0.95 : 0.45}\n strokeWidth={node.isActive ? 1.8 : 1.4}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeDasharray={node.isVirtual ? \"3 3\" : undefined}\n />\n )\n })}\n </svg>\n\n <div className=\"relative z-0 h-full\">\n {layout.nodes.map((node) => {\n const isPendingNode = pendingNodeId === node.id\n const color = node.isActive ? \"hsl(var(--primary))\" : \"hsl(var(--muted-foreground))\"\n const previewText = node.isVirtual\n ? isPendingNode\n ? \"切换中...\"\n : \"\"\n : isPendingNode\n ? \"切换中...\"\n : node.preview\n const shouldShowTooltip = !node.isVirtual || Boolean(previewText)\n const button = (\n <button\n type=\"button\"\n onClick={() =>\n void (node.isVirtual ? handleVirtualClick(node) : handleNodeSelect(node))\n }\n disabled={isBusy}\n aria-current={!node.isVirtual && node.isCurrent ? \"step\" : undefined}\n aria-label={node.isVirtual ? \"切换到该分支\" : node.preview}\n className={cn(\n \"absolute z-20 m-0 h-8 w-6 overflow-visible border-0 bg-transparent p-0\",\n isBusy ? \"cursor-not-allowed opacity-60\" : \"cursor-pointer\",\n )}\n style={{\n top: node.row * ROW_HEIGHT,\n left: getColumnX(node.column) - 12,\n }}\n >\n <span aria-hidden=\"true\" className=\"absolute left-0 top-0 h-8 w-6\">\n <svg\n aria-hidden=\"true\"\n role=\"img\"\n className=\"pointer-events-none absolute left-0 top-0 h-full w-full overflow-visible\"\n width={24}\n height={ROW_HEIGHT}\n viewBox={`0 0 24 ${ROW_HEIGHT}`}\n fill=\"none\"\n >\n {node.isVirtual ? (\n <circle\n cx={12}\n cy={ROW_HEIGHT / 2}\n r={3.5}\n fill=\"none\"\n stroke={color}\n strokeWidth={1.2}\n strokeDasharray=\"2 2\"\n opacity={0.7}\n />\n ) : (\n <g>\n {node.isCurrent ? (\n <circle cx={12} cy={ROW_HEIGHT / 2} r={9} fill={color} opacity={0.18} />\n ) : null}\n <circle\n cx={12}\n cy={ROW_HEIGHT / 2}\n r={node.isCurrent ? 5.5 : 4}\n fill={color}\n />\n </g>\n )}\n </svg>\n </span>\n </button>\n )\n\n if (!shouldShowTooltip) {\n return <div key={node.id}>{button}</div>\n }\n\n return (\n <Tooltip.Root key={node.id}>\n <Tooltip.Trigger asChild>{button}</Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content\n side=\"right\"\n sideOffset={8}\n className={cn(\n \"z-[60] rounded-md border border-border bg-popover px-2 py-1 text-xs text-foreground shadow-md\",\n !node.isVirtual && node.isCurrent && \"font-semibold\",\n )}\n >\n {previewText}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n )\n })}\n </div>\n </div>\n </div>\n </Tooltip.Provider>\n )\n}\nfunction buildLayoutNodes(tree: CheckpointTree | undefined): LayoutGraph {\n if (!tree || tree.nodes.length === 0) {\n return { nodes: [], hasCycle: false, maxColumn: 0, maxRow: 0 }\n }\n\n const nodeMap = new Map(tree.nodes.map((node) => [node.id, node]))\n const order = new Map(tree.nodes.map((node, index) => [node.id, index]))\n const childrenMap = new Map<string | null, CheckpointNode[]>()\n\n for (const node of tree.nodes) {\n const parentId = node.parent_id && nodeMap.has(node.parent_id) ? node.parent_id : null\n const siblings = childrenMap.get(parentId) ?? []\n siblings.push(node)\n childrenMap.set(parentId, siblings)\n }\n\n const activeIds = new Set<string>()\n const activeVisited = new Set<string>()\n const leafId = tree.leaf_id\n let current = tree.leaf_id\n\n while (current && nodeMap.has(current) && !activeVisited.has(current)) {\n activeIds.add(current)\n activeVisited.add(current)\n current = nodeMap.get(current)?.parent_id ?? null\n }\n\n const layoutNodes: LayoutNode[] = []\n const placed = new Set<string>()\n const visiting = new Set<string>()\n let nextColumn = 1\n let maxColumn = 0\n let maxRow = 0\n let hasCycle = false\n\n const rootSort = (a: CheckpointNode, b: CheckpointNode) =>\n (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0)\n\n const childSort = (a: CheckpointNode, b: CheckpointNode) =>\n (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0)\n\n const allocateColumn = () => {\n const fresh = nextColumn\n nextColumn += 1\n return fresh\n }\n\n function walk(node: CheckpointNode, parent: LayoutNode | null, column: number, row: number) {\n if (visiting.has(node.id)) {\n hasCycle = true\n return\n }\n\n if (placed.has(node.id)) {\n return\n }\n\n visiting.add(node.id)\n maxColumn = Math.max(maxColumn, column)\n maxRow = Math.max(maxRow, row)\n\n const layoutNode: LayoutNode = {\n id: node.id,\n column,\n row,\n parentRow: parent?.row ?? null,\n parentColumn: parent?.column ?? null,\n isActive: activeIds.has(node.id),\n isCurrent: node.id === leafId,\n isVirtual: false,\n preview: formatPreview(node.content_preview),\n content: node.content,\n }\n\n layoutNodes.push(layoutNode)\n placed.add(node.id)\n\n const children = [...(childrenMap.get(node.id) ?? [])].sort(childSort)\n\n if (children.length === 0) {\n const virtualRow = row + 1\n maxRow = Math.max(maxRow, virtualRow)\n layoutNodes.push({\n id: `__virtual__${node.id}`,\n column,\n row: virtualRow,\n parentRow: layoutNode.row,\n parentColumn: layoutNode.column,\n isActive: activeIds.has(node.id),\n isCurrent: false,\n isVirtual: true,\n preview: \"\",\n content: node.id,\n })\n } else {\n for (const [index, child] of children.entries()) {\n if (visiting.has(child.id)) {\n hasCycle = true\n continue\n }\n\n const childColumn = index === 0 ? column : allocateColumn()\n walk(child, layoutNode, childColumn, row + 1)\n }\n }\n\n visiting.delete(node.id)\n }\n\n const roots = [...(childrenMap.get(null) ?? [])].sort(rootSort)\n for (const [index, root] of roots.entries()) {\n const rootColumn = index === 0 ? 0 : allocateColumn()\n walk(root, null, rootColumn, 0)\n }\n\n for (const node of [...tree.nodes].sort(rootSort)) {\n if (!placed.has(node.id)) {\n hasCycle = true\n const rootColumn = layoutNodes.length === 0 ? 0 : allocateColumn()\n walk(node, null, rootColumn, 0)\n }\n }\n\n return {\n nodes: layoutNodes,\n hasCycle,\n maxColumn,\n maxRow,\n }\n}\n\nfunction formatPreview(preview: string): string {\n const normalized = preview.replace(/\\s+/g, \" \").trim()\n return normalized.length > 0 ? normalized : \"(空消息)\"\n}\n\nfunction getColumnX(column: number): number {\n return 12 + column * 24\n}\n\nfunction getRowY(row: number): number {\n return row * ROW_HEIGHT + ROW_HEIGHT / 2\n}\n\nfunction buildEdgePath(fromX: number, fromY: number, toX: number, toY: number): string {\n if (fromX === toX || fromY === toY) {\n return `M ${fromX} ${fromY} L ${toX} ${toY}`\n }\n\n const r = Math.min(5, Math.abs(toX - fromX), Math.abs(toY - fromY))\n const dx = toX > fromX ? 1 : -1\n\n return [\n `M ${fromX} ${fromY}`,\n `H ${toX - dx * r}`,\n `A ${r} ${r} 0 0 ${dx > 0 ? 1 : 0} ${toX} ${fromY + r}`,\n `V ${toY}`,\n ].join(\" \")\n}\n"],"mappings":"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","names":["useRef","jsx","useRef","useState","jsx","jsxs","useState"]}
package/dist/questions.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  MarkdownContent
3
- } from "./chunk-XJ6ZA6LN.js";
4
- import "./chunk-WRIMPZPN.js";
3
+ } from "./chunk-VBHHFIII.js";
4
+ import "./chunk-EQOKPZI2.js";
5
5
  import {
6
6
  Check,
7
7
  LoaderCircle,
8
8
  MessageSquareMore,
9
9
  buttonVariants,
10
10
  cn
11
- } from "./chunk-QIR73CES.js";
11
+ } from "./chunk-XBEN2ASY.js";
12
12
  import "./chunk-PR4QN5HX.js";
13
13
 
14
14
  // src/chat/QuestionnaireQuestionBlock.tsx