@blade-hq/agent-kit 0.4.4 → 0.4.6

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 (51) hide show
  1. package/README.md +8 -1
  2. package/dist/chunk-2UP7MG3J.js +66 -0
  3. package/dist/chunk-2UP7MG3J.js.map +1 -0
  4. package/dist/chunk-4VWLTG5L.js +2984 -0
  5. package/dist/chunk-4VWLTG5L.js.map +1 -0
  6. package/dist/chunk-7LEKQI47.js +32 -0
  7. package/dist/chunk-7LEKQI47.js.map +1 -0
  8. package/dist/chunk-DQCXSPHP.js +33 -0
  9. package/dist/chunk-DQCXSPHP.js.map +1 -0
  10. package/dist/chunk-I3FFV63W.js +30 -0
  11. package/dist/chunk-I3FFV63W.js.map +1 -0
  12. package/dist/chunk-J3XVFPOV.js +58 -0
  13. package/dist/chunk-J3XVFPOV.js.map +1 -0
  14. package/dist/chunk-JCJFFJ42.js +39 -0
  15. package/dist/chunk-JCJFFJ42.js.map +1 -0
  16. package/dist/chunk-LIL4FIZP.js +7992 -0
  17. package/dist/chunk-LIL4FIZP.js.map +1 -0
  18. package/dist/chunk-OKQWPNE3.js +1077 -0
  19. package/dist/chunk-OKQWPNE3.js.map +1 -0
  20. package/dist/chunk-PZ5AY32C.js +10 -0
  21. package/dist/chunk-PZ5AY32C.js.map +1 -0
  22. package/dist/chunk-TC5BBLWO.js +29 -0
  23. package/dist/chunk-TC5BBLWO.js.map +1 -0
  24. package/dist/chunk-VD4CKRMT.js +127 -0
  25. package/dist/chunk-VD4CKRMT.js.map +1 -0
  26. package/dist/chunk-X6MEYCU7.js +1401 -0
  27. package/dist/chunk-X6MEYCU7.js.map +1 -0
  28. package/dist/client/index.d.ts +529 -40
  29. package/dist/client/index.js +24 -1033
  30. package/dist/client/index.js.map +1 -1
  31. package/dist/react/api/licenses.js +11 -1470
  32. package/dist/react/api/licenses.js.map +1 -1
  33. package/dist/react/api/vibe-coding.js +25 -1481
  34. package/dist/react/api/vibe-coding.js.map +1 -1
  35. package/dist/react/cards/register.js +45 -138
  36. package/dist/react/cards/register.js.map +1 -1
  37. package/dist/react/components/chat/index.js +28 -11366
  38. package/dist/react/components/chat/index.js.map +1 -1
  39. package/dist/react/components/plan/index.js +135 -3054
  40. package/dist/react/components/plan/index.js.map +1 -1
  41. package/dist/react/components/session/index.js +21 -1499
  42. package/dist/react/components/session/index.js.map +1 -1
  43. package/dist/react/components/workspace/index.js +116 -1715
  44. package/dist/react/components/workspace/index.js.map +1 -1
  45. package/dist/react/devtools/bridge-devtools/index.js +8 -51
  46. package/dist/react/devtools/bridge-devtools/index.js.map +1 -1
  47. package/dist/react/index.d.ts +74 -2
  48. package/dist/react/index.js +656 -13958
  49. package/dist/react/index.js.map +1 -1
  50. package/dist/style.css +2 -0
  51. package/package.json +5 -2
@@ -1,3 +1,11 @@
1
+ import {
2
+ flushPendingBridgeEvents,
3
+ flushPendingIframeRegistrations,
4
+ registerBridgeIframe,
5
+ tapBridgeEvent
6
+ } from "../../../chunk-J3XVFPOV.js";
7
+ import "../../../chunk-PZ5AY32C.js";
8
+
1
9
  // src/react/devtools/bridge-devtools/mount.tsx
2
10
  import { StrictMode } from "react";
3
11
  import { createRoot } from "react-dom/client";
@@ -43,57 +51,6 @@ var useBridgeDevtoolsStore = create()((set) => ({
43
51
  }
44
52
  }));
45
53
 
46
- // src/react/devtools/bridge-devtools/tap.ts
47
- function isDev() {
48
- return import.meta.env?.DEV === true;
49
- }
50
- var PENDING_EVENT_LIMIT = 500;
51
- var pendingEvents = [];
52
- function tapBridgeEvent(event) {
53
- if (!isDev()) return;
54
- const hook = globalThis.__bladeBridgeDevtools;
55
- if (hook) {
56
- hook.record(event);
57
- return;
58
- }
59
- if (pendingEvents.length >= PENDING_EVENT_LIMIT) {
60
- pendingEvents.shift();
61
- }
62
- pendingEvents.push(event);
63
- }
64
- function flushPendingBridgeEvents() {
65
- const hook = globalThis.__bladeBridgeDevtools;
66
- if (!hook) return;
67
- for (const event of pendingEvents) {
68
- hook.record(event);
69
- }
70
- pendingEvents.length = 0;
71
- }
72
- var pendingRegistrations = [];
73
- function registerBridgeIframe(entry) {
74
- if (!isDev()) return () => {
75
- };
76
- const hook = globalThis.__bladeBridgeDevtools;
77
- if (hook) {
78
- return hook.registerIframe(entry);
79
- }
80
- const pending = { entry, unregister: null };
81
- pendingRegistrations.push(pending);
82
- return () => {
83
- const idx = pendingRegistrations.indexOf(pending);
84
- if (idx >= 0) pendingRegistrations.splice(idx, 1);
85
- pending.unregister?.();
86
- };
87
- }
88
- function flushPendingIframeRegistrations() {
89
- const hook = globalThis.__bladeBridgeDevtools;
90
- if (!hook) return;
91
- for (const pending of pendingRegistrations) {
92
- pending.unregister = hook.registerIframe(pending.entry);
93
- }
94
- pendingRegistrations.length = 0;
95
- }
96
-
97
54
  // src/react/devtools/bridge-devtools/BridgeDevtoolsFab.tsx
98
55
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
99
56
  var FAB_HEIGHT = 44;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/react/devtools/bridge-devtools/mount.tsx","../../../../src/react/devtools/bridge-devtools/BridgeDevtoolsFab.tsx","../../../../src/react/devtools/bridge-devtools/store.ts","../../../../src/react/devtools/bridge-devtools/tap.ts"],"sourcesContent":["import { StrictMode } from \"react\"\nimport { createRoot } from \"react-dom/client\"\nimport { BridgeDevtoolsFab } from \"./BridgeDevtoolsFab\"\nimport { useBridgeDevtoolsStore } from \"./store\"\nimport { flushPendingBridgeEvents, flushPendingIframeRegistrations } from \"./tap\"\nimport type { BridgeDevtoolsHook } from \"./types\"\n\nlet mounted = false\n\nexport function mountBridgeDevtools() {\n if (mounted || typeof document === \"undefined\") return\n mounted = true\n\n const hook: BridgeDevtoolsHook = {\n record: (event) => useBridgeDevtoolsStore.getState().record(event),\n registerIframe: (entry) => useBridgeDevtoolsStore.getState().registerIframe(entry),\n }\n globalThis.__bladeBridgeDevtools = hook\n flushPendingBridgeEvents()\n flushPendingIframeRegistrations()\n\n const container = document.createElement(\"div\")\n container.id = \"blade-bridge-devtools-root\"\n document.body.appendChild(container)\n createRoot(container).render(\n <StrictMode>\n <BridgeDevtoolsFab />\n </StrictMode>,\n )\n}\n","import { animate, motion, type PanInfo, useMotionValue } from \"motion/react\"\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { useShallow } from \"zustand/react/shallow\"\nimport { useBridgeDevtoolsStore } from \"./store\"\nimport { tapBridgeEvent } from \"./tap\"\nimport type {\n BridgeEventDirection,\n BridgeEventRecord,\n BridgeEventSide,\n} from \"./types\"\n\nconst FAB_HEIGHT = 44\nconst FAB_PEEK = 18\nconst FAB_POS_STORAGE = \"blade.bridge-devtools-fab.pos\"\nconst FAB_SPRING = { type: \"spring\" as const, stiffness: 380, damping: 32 }\n\ninterface FabSavedPos {\n x: number\n y: number\n}\n\nfunction clamp(v: number, min: number, max: number) {\n return Math.min(Math.max(v, min), max)\n}\n\nfunction loadFabPos(): FabSavedPos | null {\n if (typeof window === \"undefined\") return null\n try {\n const raw = window.localStorage.getItem(FAB_POS_STORAGE)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n if (typeof parsed?.x === \"number\" && typeof parsed?.y === \"number\") {\n return { x: parsed.x, y: parsed.y }\n }\n } catch {\n /* ignore */\n }\n return null\n}\n\nfunction saveFabPos(pos: FabSavedPos) {\n if (typeof window === \"undefined\") return\n try {\n window.localStorage.setItem(FAB_POS_STORAGE, JSON.stringify(pos))\n } catch {\n /* ignore */\n }\n}\n\nfunction snapXToEdge(currentX: number, btnW: number) {\n const maxX = Math.max(0, window.innerWidth - btnW)\n const center = currentX + btnW / 2\n return center < window.innerWidth / 2 ? 0 : maxX\n}\n\nfunction hiddenXFor(snappedX: number, btnW: number) {\n const maxX = Math.max(0, window.innerWidth - btnW)\n const offset = Math.max(0, btnW - FAB_PEEK)\n return snappedX <= maxX / 2 ? snappedX - offset : snappedX + offset\n}\n\nfunction defaultFabPos(): FabSavedPos {\n if (typeof window === \"undefined\") return { x: 0, y: 0 }\n return {\n x: window.innerWidth,\n y: window.innerHeight - FAB_HEIGHT - 80,\n }\n}\n\ntype SideTab = \"agent\" | \"host\" | string\n\nconst DIRECTION_LABEL: Record<BridgeEventDirection, string> = {\n \"host-to-agent\": \"host → agent\",\n \"agent-to-host\": \"agent → host\",\n \"host-to-iframe\": \"host → iframe\",\n \"iframe-to-host\": \"iframe → host\",\n}\n\nconst ALL_DIRECTIONS: BridgeEventDirection[] = [\n \"host-to-agent\",\n \"agent-to-host\",\n \"host-to-iframe\",\n \"iframe-to-host\",\n]\n\nfunction safeStringify(value: unknown, indent?: number) {\n // 通过 postMessage 结构化克隆进来的 payload 可能带 BigInt、cyclic、\n // 或其它 JSON.stringify 处理不了的值,必须包一层 fallback,否则\n // 任何搜索/展开/导出都会把 devtools 自己炸掉。\n const seen = new WeakSet<object>()\n try {\n return JSON.stringify(\n value,\n (_k, v) => {\n if (typeof v === \"bigint\") return `${v.toString()}n`\n if (typeof v === \"object\" && v !== null) {\n if (seen.has(v)) return \"[Circular]\"\n seen.add(v)\n }\n return v\n },\n indent,\n ) ?? String(value)\n } catch (err) {\n return `[unserializable: ${(err as Error).message}]`\n }\n}\n\nfunction formatTime(ts: number) {\n const d = new Date(ts)\n const pad = (n: number) => n.toString().padStart(2, \"0\")\n const ms = d.getMilliseconds().toString().padStart(3, \"0\")\n return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}.${ms}`\n}\n\nfunction filterEvents(\n events: BridgeEventRecord[],\n tab: SideTab,\n search: string,\n enabledDirections: Set<BridgeEventDirection>,\n) {\n const needle = search.trim().toLowerCase()\n return events.filter((e) => {\n if (tab === \"agent\" && e.side !== \"agent\") return false\n if (tab !== \"agent\" && tab !== \"host\" && e.iframeKey !== tab) return false\n if (tab === \"host\" && e.side !== \"host\") return false\n if (!enabledDirections.has(e.direction)) return false\n if (needle) {\n const hay = `${e.action} ${safeStringify(e.payload ?? \"\")} ${e.note ?? \"\"}`.toLowerCase()\n if (!hay.includes(needle)) return false\n }\n return true\n })\n}\n\nfunction downloadJson(filename: string, data: unknown) {\n const blob = new Blob([safeStringify(data, 2)], { type: \"application/json\" })\n const url = URL.createObjectURL(blob)\n const a = document.createElement(\"a\")\n a.href = url\n a.download = filename\n a.click()\n setTimeout(() => URL.revokeObjectURL(url), 1000)\n}\n\nexport function BridgeDevtoolsFab() {\n const [open, setOpen] = useState(false)\n const [tab, setTab] = useState<SideTab>(\"agent\")\n const [search, setSearch] = useState(\"\")\n const [enabled, setEnabled] = useState<Set<BridgeEventDirection>>(\n () => new Set(ALL_DIRECTIONS),\n )\n const [expandedId, setExpandedId] = useState<string | null>(null)\n\n const events = useBridgeDevtoolsStore((s) => s.events)\n const iframes = useBridgeDevtoolsStore(useShallow((s) => Object.values(s.iframes)))\n const clear = useBridgeDevtoolsStore((s) => s.clear)\n\n const filtered = useMemo(\n () => filterEvents(events, tab, search, enabled),\n [events, tab, search, enabled],\n )\n\n const counts = useMemo(() => {\n const c = { agent: 0, host: 0 as number }\n const perIframe: Record<string, number> = {}\n for (const e of events) {\n if (e.side === \"agent\") c.agent++\n else c.host++\n if (e.iframeKey) perIframe[e.iframeKey] = (perIframe[e.iframeKey] ?? 0) + 1\n }\n return { ...c, perIframe }\n }, [events])\n\n const rejectedCount = events.filter((e) => e.rejected).length\n\n const initialPos = useMemo(() => {\n const saved = loadFabPos() ?? defaultFabPos()\n if (typeof window === \"undefined\") return saved\n return {\n x: saved.x,\n y: clamp(saved.y, 0, Math.max(0, window.innerHeight - FAB_HEIGHT)),\n }\n }, [])\n const [snapped, setSnapped] = useState<FabSavedPos>(initialPos)\n const [btnW, setBtnW] = useState(FAB_HEIGHT)\n const [hover, setHover] = useState(false)\n const [dragging, setDragging] = useState(false)\n const x = useMotionValue(initialPos.x)\n const y = useMotionValue(initialPos.y)\n const btnRef = useRef<HTMLButtonElement | null>(null)\n\n // Measure rendered button width — needed for edge snapping math.\n useEffect(() => {\n const el = btnRef.current\n if (!el) return\n const update = () => setBtnW(el.offsetWidth || FAB_HEIGHT)\n update()\n const ro = new ResizeObserver(update)\n ro.observe(el)\n return () => ro.disconnect()\n }, [])\n\n // Drive the visible/hidden animation imperatively against the motion value.\n // Recompute edgeX each tick so width measurement / viewport resize stay correct.\n const visible = open || hover || dragging\n useEffect(() => {\n if (dragging) return\n const edgeX = snapXToEdge(snapped.x, btnW)\n const targetX = visible ? edgeX : hiddenXFor(edgeX, btnW)\n const ctrl = animate(x, targetX, FAB_SPRING)\n return () => ctrl.stop()\n }, [visible, snapped.x, btnW, dragging, x])\n\n // Re-snap to nearest edge on viewport resize.\n useEffect(() => {\n const onResize = () => {\n const newX = snapXToEdge(snapped.x, btnW)\n const newY = clamp(snapped.y, 0, window.innerHeight - FAB_HEIGHT)\n if (newX !== snapped.x || newY !== snapped.y) {\n setSnapped({ x: newX, y: newY })\n saveFabPos({ x: newX, y: newY })\n y.set(newY)\n }\n }\n window.addEventListener(\"resize\", onResize)\n return () => window.removeEventListener(\"resize\", onResize)\n }, [snapped.x, snapped.y, btnW, y])\n\n const handleDragEnd = (_: PointerEvent | MouseEvent | TouchEvent, _info: PanInfo) => {\n const newX = snapXToEdge(x.get(), btnW)\n const newY = clamp(y.get(), 0, window.innerHeight - FAB_HEIGHT)\n setSnapped({ x: newX, y: newY })\n saveFabPos({ x: newX, y: newY })\n setDragging(false)\n animate(x, newX, FAB_SPRING)\n animate(y, newY, FAB_SPRING)\n }\n\n return (\n <>\n <motion.div\n style={{\n x,\n y,\n position: \"fixed\",\n top: 0,\n left: 0,\n zIndex: 9998,\n touchAction: \"none\",\n }}\n drag\n dragMomentum={false}\n dragElastic={0.05}\n onDragStart={() => setDragging(true)}\n onDragEnd={handleDragEnd}\n onPointerEnter={() => setHover(true)}\n onPointerLeave={() => setHover(false)}\n >\n <button\n ref={btnRef}\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"inline-flex h-11 min-w-[44px] cursor-grab items-center justify-center gap-1 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--background))]/95 px-3 text-sm font-medium text-[hsl(var(--foreground))] shadow-xl backdrop-blur hover:bg-[hsl(var(--accent))] active:cursor-grabbing\"\n title=\"Bridge 事件调试(可拖动到任意边缘)\"\n >\n <span className=\"text-base\">🌉</span>\n <span className=\"tabular-nums\">{events.length}</span>\n {rejectedCount > 0 ? (\n <span className=\"rounded bg-red-500/15 px-1 text-xs text-red-500 tabular-nums\">\n {rejectedCount}\n </span>\n ) : null}\n </button>\n </motion.div>\n {open && typeof document !== \"undefined\"\n ? createPortal(\n <BridgeDevtoolsPanel\n onClose={() => setOpen(false)}\n tab={tab}\n setTab={setTab}\n search={search}\n setSearch={setSearch}\n enabled={enabled}\n setEnabled={setEnabled}\n events={filtered}\n totalEvents={events}\n expandedId={expandedId}\n setExpandedId={setExpandedId}\n counts={counts}\n iframes={iframes}\n onClear={clear}\n />,\n document.body,\n )\n : null}\n </>\n )\n}\n\ninterface PanelProps {\n onClose: () => void\n tab: SideTab\n setTab: (t: SideTab) => void\n search: string\n setSearch: (s: string) => void\n enabled: Set<BridgeEventDirection>\n setEnabled: (s: Set<BridgeEventDirection>) => void\n events: BridgeEventRecord[]\n totalEvents: BridgeEventRecord[]\n expandedId: string | null\n setExpandedId: (id: string | null) => void\n counts: { agent: number; host: number; perIframe: Record<string, number> }\n iframes: Array<{ key: string; label: string; getContentWindow: () => Window | null }>\n onClear: () => void\n}\n\nfunction BridgeDevtoolsPanel(props: PanelProps) {\n const {\n onClose,\n tab,\n setTab,\n search,\n setSearch,\n enabled,\n setEnabled,\n events,\n totalEvents,\n expandedId,\n setExpandedId,\n counts,\n iframes,\n onClear,\n } = props\n\n const toggleDirection = (d: BridgeEventDirection) => {\n const next = new Set(enabled)\n if (next.has(d)) next.delete(d)\n else next.add(d)\n setEnabled(next)\n }\n\n return (\n <div className=\"fixed inset-0 z-[9999] flex items-end justify-end\">\n <button\n type=\"button\"\n aria-label=\"关闭调试面板\"\n className=\"absolute inset-0 bg-black/20\"\n onClick={onClose}\n />\n <div\n className=\"relative flex h-[85vh] w-full max-w-[720px] flex-col overflow-hidden rounded-t-xl border border-[hsl(var(--border))] bg-[hsl(var(--background))] shadow-2xl\"\n >\n <header className=\"flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-2\">\n <div className=\"flex items-center gap-2 text-sm font-semibold\">\n <span>🌉 Bridge 事件调试</span>\n <span className=\"text-xs text-[hsl(var(--muted-foreground))]\">\n {totalEvents.length} / 500\n </span>\n </div>\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n className=\"rounded px-2 py-1 text-xs hover:bg-[hsl(var(--accent))]\"\n onClick={() =>\n downloadJson(`bridge-events-${Date.now()}.json`, totalEvents)\n }\n >\n 导出 JSON\n </button>\n <button\n type=\"button\"\n className=\"rounded px-2 py-1 text-xs hover:bg-[hsl(var(--accent))]\"\n onClick={onClear}\n >\n 清空\n </button>\n <button\n type=\"button\"\n className=\"rounded px-2 py-1 text-xs hover:bg-[hsl(var(--accent))]\"\n onClick={onClose}\n >\n ✕\n </button>\n </div>\n </header>\n\n <nav className=\"flex items-center gap-1 overflow-x-auto border-b border-[hsl(var(--border))] px-3 py-2 text-xs\">\n <TabButton active={tab === \"agent\"} onClick={() => setTab(\"agent\")}>\n Agent 侧 ({counts.agent})\n </TabButton>\n <TabButton active={tab === \"host\"} onClick={() => setTab(\"host\")}>\n Host 全部 ({counts.host})\n </TabButton>\n {iframes.map((f) => (\n <TabButton\n key={f.key}\n active={tab === f.key}\n onClick={() => setTab(f.key)}\n title={f.label}\n >\n 📄 {f.label.length > 16 ? `${f.label.slice(0, 16)}…` : f.label} (\n {counts.perIframe[f.key] ?? 0})\n </TabButton>\n ))}\n </nav>\n\n <div className=\"flex flex-wrap items-center gap-2 border-b border-[hsl(var(--border))] px-3 py-2 text-xs\">\n <input\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"搜索 action / payload / note…\"\n className=\"min-w-[160px] flex-1 rounded border border-[hsl(var(--border))] bg-transparent px-2 py-1\"\n />\n {ALL_DIRECTIONS.map((d) => (\n <label key={d} className=\"flex items-center gap-1\">\n <input\n type=\"checkbox\"\n checked={enabled.has(d)}\n onChange={() => toggleDirection(d)}\n />\n <span>{DIRECTION_LABEL[d]}</span>\n </label>\n ))}\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n {events.length === 0 ? (\n <div className=\"p-6 text-center text-sm text-[hsl(var(--muted-foreground))]\">\n 无匹配事件\n </div>\n ) : (\n <ul className=\"divide-y divide-[hsl(var(--border))]\">\n {events.map((e) => (\n <EventRow\n key={e.id}\n event={e}\n expanded={expandedId === e.id}\n onToggle={() => setExpandedId(expandedId === e.id ? null : e.id)}\n />\n ))}\n </ul>\n )}\n </div>\n\n <ManualSendBar tab={tab} iframes={iframes} />\n </div>\n </div>\n )\n}\n\nfunction TabButton(props: {\n active: boolean\n onClick: () => void\n title?: string\n children: React.ReactNode\n}) {\n return (\n <button\n type=\"button\"\n onClick={props.onClick}\n title={props.title}\n className={`whitespace-nowrap rounded px-2 py-1 ${\n props.active\n ? \"bg-[hsl(var(--accent))] font-semibold\"\n : \"hover:bg-[hsl(var(--accent))]/50\"\n }`}\n >\n {props.children}\n </button>\n )\n}\n\nfunction EventRow({\n event,\n expanded,\n onToggle,\n}: {\n event: BridgeEventRecord\n expanded: boolean\n onToggle: () => void\n}) {\n return (\n <li\n className={`px-3 py-1.5 text-xs ${event.rejected ? \"bg-red-500/5\" : \"\"}`}\n >\n <button\n type=\"button\"\n onClick={onToggle}\n className=\"flex w-full items-center gap-2 text-left\"\n >\n <span className=\"w-[90px] font-mono tabular-nums text-[hsl(var(--muted-foreground))]\">\n {formatTime(event.ts)}\n </span>\n <span\n className={`w-[120px] font-mono ${\n event.side === \"agent\" ? \"text-blue-500\" : \"text-purple-500\"\n }`}\n >\n {DIRECTION_LABEL[event.direction]}\n </span>\n <span className=\"flex-1 truncate font-semibold\">{event.action}</span>\n {event.rejected ? (\n <span className=\"rounded bg-red-500/20 px-1.5 text-[10px] text-red-500\">\n rejected\n </span>\n ) : null}\n <span className=\"text-[hsl(var(--muted-foreground))]\">{expanded ? \"▼\" : \"▶\"}</span>\n </button>\n {expanded ? (\n <div className=\"mt-2 space-y-1 pl-[90px] font-mono\">\n {event.note ? (\n <div className=\"text-red-500\">note: {event.note}</div>\n ) : null}\n {event.iframeLabel ? (\n <div className=\"text-[hsl(var(--muted-foreground))]\">\n iframe: {event.iframeLabel}\n </div>\n ) : null}\n {event.meta ? (\n <pre className=\"whitespace-pre-wrap break-words text-[hsl(var(--muted-foreground))]\">\n meta: {safeStringify(event.meta, 2)}\n </pre>\n ) : null}\n <pre className=\"whitespace-pre-wrap break-words\">\n payload: {safeStringify(event.payload, 2)}\n </pre>\n </div>\n ) : null}\n </li>\n )\n}\n\nfunction ManualSendBar({\n tab,\n iframes,\n}: {\n tab: SideTab\n iframes: Array<{ key: string; label: string; getContentWindow: () => Window | null }>\n}) {\n const [action, setAction] = useState(\"\")\n const [payloadText, setPayloadText] = useState(\"{}\")\n const [error, setError] = useState<string | null>(null)\n const [targetKey, setTargetKey] = useState<string>(\"\")\n\n const effectiveSide: BridgeEventSide = tab === \"agent\" ? \"agent\" : \"host\"\n\n const send = () => {\n setError(null)\n let payload: unknown\n try {\n payload = payloadText.trim() ? JSON.parse(payloadText) : undefined\n } catch (err) {\n setError(`payload JSON 解析失败: ${(err as Error).message}`)\n return\n }\n if (!action.trim()) {\n setError(\"action 不能为空\")\n return\n }\n\n if (effectiveSide === \"agent\") {\n // 模拟 host → agent:直接 dispatch 到 window,parent-bridge 监听器会收到\n window.postMessage(\n {\n __bladeBridge: true,\n direction: \"host-to-agent\",\n action,\n payload,\n meta: { timestamp: Date.now(), injectedBy: \"devtools\" },\n },\n \"*\",\n )\n return\n }\n\n // host 侧:发送给某个 iframe\n const target = tab !== \"host\" && tab !== \"agent\" ? tab : targetKey\n const entry = iframes.find((f) => f.key === target)\n if (!entry) {\n setError(\"请选择目标 iframe\")\n return\n }\n const win = entry.getContentWindow()\n if (!win) {\n setError(\"目标 iframe contentWindow 为空(可能未加载)\")\n return\n }\n win.postMessage(\n {\n __resourceBridge: true,\n direction: \"host-to-iframe\",\n event: action,\n action,\n payload,\n },\n \"*\",\n )\n tapBridgeEvent({\n side: \"host\",\n direction: \"host-to-iframe\",\n action,\n payload,\n iframeKey: entry.key,\n iframeLabel: entry.label,\n note: \"injected by devtools\",\n })\n }\n\n return (\n <div className=\"border-t border-[hsl(var(--border))] bg-[hsl(var(--muted))]/30 px-3 py-2\">\n <div className=\"mb-1 text-xs font-semibold text-[hsl(var(--muted-foreground))]\">\n 手动发送 envelope({effectiveSide === \"agent\" ? \"模拟 host → agent\" : \"host → iframe\"})\n </div>\n <div className=\"flex flex-wrap items-start gap-2 text-xs\">\n {effectiveSide === \"host\" && tab === \"host\" ? (\n <select\n value={targetKey}\n onChange={(e) => setTargetKey(e.target.value)}\n className=\"rounded border border-[hsl(var(--border))] bg-transparent px-2 py-1\"\n >\n <option value=\"\">选择 iframe…</option>\n {iframes.map((f) => (\n <option key={f.key} value={f.key}>\n {f.label}\n </option>\n ))}\n </select>\n ) : null}\n <input\n value={action}\n onChange={(e) => setAction(e.target.value)}\n placeholder=\"action(如 addContext / theme)\"\n className=\"min-w-[140px] flex-1 rounded border border-[hsl(var(--border))] bg-transparent px-2 py-1\"\n />\n <input\n value={payloadText}\n onChange={(e) => setPayloadText(e.target.value)}\n placeholder='payload JSON(如 {\"foo\":1})'\n className=\"min-w-[180px] flex-[2] rounded border border-[hsl(var(--border))] bg-transparent px-2 py-1 font-mono\"\n />\n <button\n type=\"button\"\n onClick={send}\n className=\"rounded bg-[hsl(var(--primary))] px-3 py-1 text-[hsl(var(--primary-foreground))] hover:opacity-90\"\n >\n 发送\n </button>\n </div>\n {error ? <div className=\"mt-1 text-xs text-red-500\">{error}</div> : null}\n </div>\n )\n}\n","import { create } from \"zustand\"\nimport type { BridgeEventInput, BridgeEventRecord } from \"./types\"\n\nconst MAX_EVENTS = 500\n\nfunction buildId() {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID()\n }\n return `bev-${Date.now()}-${Math.random().toString(36).slice(2)}`\n}\n\nexport interface RegisteredIframe {\n key: string\n label: string\n getContentWindow: () => Window | null\n}\n\ninterface BridgeDevtoolsState {\n events: BridgeEventRecord[]\n iframes: Record<string, RegisteredIframe>\n record: (event: BridgeEventInput) => void\n clear: () => void\n registerIframe: (entry: RegisteredIframe) => () => void\n}\n\nexport const useBridgeDevtoolsStore = create<BridgeDevtoolsState>()((set) => ({\n events: [],\n iframes: {},\n record: (input) =>\n set((state) => {\n const record: BridgeEventRecord = {\n id: buildId(),\n ts: Date.now(),\n ...input,\n }\n const events =\n state.events.length >= MAX_EVENTS\n ? [...state.events.slice(state.events.length - MAX_EVENTS + 1), record]\n : [...state.events, record]\n return { events }\n }),\n clear: () => set({ events: [] }),\n registerIframe: (entry) => {\n set((state) => ({ iframes: { ...state.iframes, [entry.key]: entry } }))\n return () => {\n set((state) => {\n if (!(entry.key in state.iframes)) return state\n const next = { ...state.iframes }\n delete next[entry.key]\n return { iframes: next }\n })\n }\n },\n}))\n","import type { BridgeEventInput, RegisteredIframeEntry } from \"./types\"\n\nfunction isDev() {\n return (import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV === true\n}\n\nconst PENDING_EVENT_LIMIT = 500\nconst pendingEvents: BridgeEventInput[] = []\n\nexport function tapBridgeEvent(event: BridgeEventInput) {\n if (!isDev()) return\n const hook = globalThis.__bladeBridgeDevtools\n if (hook) {\n hook.record(event)\n return\n }\n // hook 异步安装,启动阶段事件(如首个 postTheme、早期 host 消息)\n // 在 mount 前触达,直接丢弃会让 debugger 错过初始化链,故先入队。\n if (pendingEvents.length >= PENDING_EVENT_LIMIT) {\n pendingEvents.shift()\n }\n pendingEvents.push(event)\n}\n\nexport function flushPendingBridgeEvents() {\n const hook = globalThis.__bladeBridgeDevtools\n if (!hook) return\n for (const event of pendingEvents) {\n hook.record(event)\n }\n pendingEvents.length = 0\n}\n\ninterface PendingRegistration {\n entry: RegisteredIframeEntry\n unregister: (() => void) | null\n}\n\nconst pendingRegistrations: PendingRegistration[] = []\n\nexport function registerBridgeIframe(entry: RegisteredIframeEntry) {\n if (!isDev()) return () => {}\n const hook = globalThis.__bladeBridgeDevtools\n if (hook) {\n return hook.registerIframe(entry)\n }\n // devtools hook 在 main.tsx 里通过动态 import 异步安装,ResourceIframe\n // 可能先于 hook mount。先把 entry 排进队列,mount 时 flush 掉。\n const pending: PendingRegistration = { entry, unregister: null }\n pendingRegistrations.push(pending)\n return () => {\n const idx = pendingRegistrations.indexOf(pending)\n if (idx >= 0) pendingRegistrations.splice(idx, 1)\n pending.unregister?.()\n }\n}\n\nexport function flushPendingIframeRegistrations() {\n const hook = globalThis.__bladeBridgeDevtools\n if (!hook) return\n for (const pending of pendingRegistrations) {\n pending.unregister = hook.registerIframe(pending.entry)\n }\n pendingRegistrations.length = 0\n}\n"],"mappings":"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","names":["jsx"]}
1
+ {"version":3,"sources":["../../../../src/react/devtools/bridge-devtools/mount.tsx","../../../../src/react/devtools/bridge-devtools/BridgeDevtoolsFab.tsx","../../../../src/react/devtools/bridge-devtools/store.ts"],"sourcesContent":["import { StrictMode } from \"react\"\nimport { createRoot } from \"react-dom/client\"\nimport { BridgeDevtoolsFab } from \"./BridgeDevtoolsFab\"\nimport { useBridgeDevtoolsStore } from \"./store\"\nimport { flushPendingBridgeEvents, flushPendingIframeRegistrations } from \"./tap\"\nimport type { BridgeDevtoolsHook } from \"./types\"\n\nlet mounted = false\n\nexport function mountBridgeDevtools() {\n if (mounted || typeof document === \"undefined\") return\n mounted = true\n\n const hook: BridgeDevtoolsHook = {\n record: (event) => useBridgeDevtoolsStore.getState().record(event),\n registerIframe: (entry) => useBridgeDevtoolsStore.getState().registerIframe(entry),\n }\n globalThis.__bladeBridgeDevtools = hook\n flushPendingBridgeEvents()\n flushPendingIframeRegistrations()\n\n const container = document.createElement(\"div\")\n container.id = \"blade-bridge-devtools-root\"\n document.body.appendChild(container)\n createRoot(container).render(\n <StrictMode>\n <BridgeDevtoolsFab />\n </StrictMode>,\n )\n}\n","import { animate, motion, type PanInfo, useMotionValue } from \"motion/react\"\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { useShallow } from \"zustand/react/shallow\"\nimport { useBridgeDevtoolsStore } from \"./store\"\nimport { tapBridgeEvent } from \"./tap\"\nimport type {\n BridgeEventDirection,\n BridgeEventRecord,\n BridgeEventSide,\n} from \"./types\"\n\nconst FAB_HEIGHT = 44\nconst FAB_PEEK = 18\nconst FAB_POS_STORAGE = \"blade.bridge-devtools-fab.pos\"\nconst FAB_SPRING = { type: \"spring\" as const, stiffness: 380, damping: 32 }\n\ninterface FabSavedPos {\n x: number\n y: number\n}\n\nfunction clamp(v: number, min: number, max: number) {\n return Math.min(Math.max(v, min), max)\n}\n\nfunction loadFabPos(): FabSavedPos | null {\n if (typeof window === \"undefined\") return null\n try {\n const raw = window.localStorage.getItem(FAB_POS_STORAGE)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n if (typeof parsed?.x === \"number\" && typeof parsed?.y === \"number\") {\n return { x: parsed.x, y: parsed.y }\n }\n } catch {\n /* ignore */\n }\n return null\n}\n\nfunction saveFabPos(pos: FabSavedPos) {\n if (typeof window === \"undefined\") return\n try {\n window.localStorage.setItem(FAB_POS_STORAGE, JSON.stringify(pos))\n } catch {\n /* ignore */\n }\n}\n\nfunction snapXToEdge(currentX: number, btnW: number) {\n const maxX = Math.max(0, window.innerWidth - btnW)\n const center = currentX + btnW / 2\n return center < window.innerWidth / 2 ? 0 : maxX\n}\n\nfunction hiddenXFor(snappedX: number, btnW: number) {\n const maxX = Math.max(0, window.innerWidth - btnW)\n const offset = Math.max(0, btnW - FAB_PEEK)\n return snappedX <= maxX / 2 ? snappedX - offset : snappedX + offset\n}\n\nfunction defaultFabPos(): FabSavedPos {\n if (typeof window === \"undefined\") return { x: 0, y: 0 }\n return {\n x: window.innerWidth,\n y: window.innerHeight - FAB_HEIGHT - 80,\n }\n}\n\ntype SideTab = \"agent\" | \"host\" | string\n\nconst DIRECTION_LABEL: Record<BridgeEventDirection, string> = {\n \"host-to-agent\": \"host → agent\",\n \"agent-to-host\": \"agent → host\",\n \"host-to-iframe\": \"host → iframe\",\n \"iframe-to-host\": \"iframe → host\",\n}\n\nconst ALL_DIRECTIONS: BridgeEventDirection[] = [\n \"host-to-agent\",\n \"agent-to-host\",\n \"host-to-iframe\",\n \"iframe-to-host\",\n]\n\nfunction safeStringify(value: unknown, indent?: number) {\n // 通过 postMessage 结构化克隆进来的 payload 可能带 BigInt、cyclic、\n // 或其它 JSON.stringify 处理不了的值,必须包一层 fallback,否则\n // 任何搜索/展开/导出都会把 devtools 自己炸掉。\n const seen = new WeakSet<object>()\n try {\n return JSON.stringify(\n value,\n (_k, v) => {\n if (typeof v === \"bigint\") return `${v.toString()}n`\n if (typeof v === \"object\" && v !== null) {\n if (seen.has(v)) return \"[Circular]\"\n seen.add(v)\n }\n return v\n },\n indent,\n ) ?? String(value)\n } catch (err) {\n return `[unserializable: ${(err as Error).message}]`\n }\n}\n\nfunction formatTime(ts: number) {\n const d = new Date(ts)\n const pad = (n: number) => n.toString().padStart(2, \"0\")\n const ms = d.getMilliseconds().toString().padStart(3, \"0\")\n return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}.${ms}`\n}\n\nfunction filterEvents(\n events: BridgeEventRecord[],\n tab: SideTab,\n search: string,\n enabledDirections: Set<BridgeEventDirection>,\n) {\n const needle = search.trim().toLowerCase()\n return events.filter((e) => {\n if (tab === \"agent\" && e.side !== \"agent\") return false\n if (tab !== \"agent\" && tab !== \"host\" && e.iframeKey !== tab) return false\n if (tab === \"host\" && e.side !== \"host\") return false\n if (!enabledDirections.has(e.direction)) return false\n if (needle) {\n const hay = `${e.action} ${safeStringify(e.payload ?? \"\")} ${e.note ?? \"\"}`.toLowerCase()\n if (!hay.includes(needle)) return false\n }\n return true\n })\n}\n\nfunction downloadJson(filename: string, data: unknown) {\n const blob = new Blob([safeStringify(data, 2)], { type: \"application/json\" })\n const url = URL.createObjectURL(blob)\n const a = document.createElement(\"a\")\n a.href = url\n a.download = filename\n a.click()\n setTimeout(() => URL.revokeObjectURL(url), 1000)\n}\n\nexport function BridgeDevtoolsFab() {\n const [open, setOpen] = useState(false)\n const [tab, setTab] = useState<SideTab>(\"agent\")\n const [search, setSearch] = useState(\"\")\n const [enabled, setEnabled] = useState<Set<BridgeEventDirection>>(\n () => new Set(ALL_DIRECTIONS),\n )\n const [expandedId, setExpandedId] = useState<string | null>(null)\n\n const events = useBridgeDevtoolsStore((s) => s.events)\n const iframes = useBridgeDevtoolsStore(useShallow((s) => Object.values(s.iframes)))\n const clear = useBridgeDevtoolsStore((s) => s.clear)\n\n const filtered = useMemo(\n () => filterEvents(events, tab, search, enabled),\n [events, tab, search, enabled],\n )\n\n const counts = useMemo(() => {\n const c = { agent: 0, host: 0 as number }\n const perIframe: Record<string, number> = {}\n for (const e of events) {\n if (e.side === \"agent\") c.agent++\n else c.host++\n if (e.iframeKey) perIframe[e.iframeKey] = (perIframe[e.iframeKey] ?? 0) + 1\n }\n return { ...c, perIframe }\n }, [events])\n\n const rejectedCount = events.filter((e) => e.rejected).length\n\n const initialPos = useMemo(() => {\n const saved = loadFabPos() ?? defaultFabPos()\n if (typeof window === \"undefined\") return saved\n return {\n x: saved.x,\n y: clamp(saved.y, 0, Math.max(0, window.innerHeight - FAB_HEIGHT)),\n }\n }, [])\n const [snapped, setSnapped] = useState<FabSavedPos>(initialPos)\n const [btnW, setBtnW] = useState(FAB_HEIGHT)\n const [hover, setHover] = useState(false)\n const [dragging, setDragging] = useState(false)\n const x = useMotionValue(initialPos.x)\n const y = useMotionValue(initialPos.y)\n const btnRef = useRef<HTMLButtonElement | null>(null)\n\n // Measure rendered button width — needed for edge snapping math.\n useEffect(() => {\n const el = btnRef.current\n if (!el) return\n const update = () => setBtnW(el.offsetWidth || FAB_HEIGHT)\n update()\n const ro = new ResizeObserver(update)\n ro.observe(el)\n return () => ro.disconnect()\n }, [])\n\n // Drive the visible/hidden animation imperatively against the motion value.\n // Recompute edgeX each tick so width measurement / viewport resize stay correct.\n const visible = open || hover || dragging\n useEffect(() => {\n if (dragging) return\n const edgeX = snapXToEdge(snapped.x, btnW)\n const targetX = visible ? edgeX : hiddenXFor(edgeX, btnW)\n const ctrl = animate(x, targetX, FAB_SPRING)\n return () => ctrl.stop()\n }, [visible, snapped.x, btnW, dragging, x])\n\n // Re-snap to nearest edge on viewport resize.\n useEffect(() => {\n const onResize = () => {\n const newX = snapXToEdge(snapped.x, btnW)\n const newY = clamp(snapped.y, 0, window.innerHeight - FAB_HEIGHT)\n if (newX !== snapped.x || newY !== snapped.y) {\n setSnapped({ x: newX, y: newY })\n saveFabPos({ x: newX, y: newY })\n y.set(newY)\n }\n }\n window.addEventListener(\"resize\", onResize)\n return () => window.removeEventListener(\"resize\", onResize)\n }, [snapped.x, snapped.y, btnW, y])\n\n const handleDragEnd = (_: PointerEvent | MouseEvent | TouchEvent, _info: PanInfo) => {\n const newX = snapXToEdge(x.get(), btnW)\n const newY = clamp(y.get(), 0, window.innerHeight - FAB_HEIGHT)\n setSnapped({ x: newX, y: newY })\n saveFabPos({ x: newX, y: newY })\n setDragging(false)\n animate(x, newX, FAB_SPRING)\n animate(y, newY, FAB_SPRING)\n }\n\n return (\n <>\n <motion.div\n style={{\n x,\n y,\n position: \"fixed\",\n top: 0,\n left: 0,\n zIndex: 9998,\n touchAction: \"none\",\n }}\n drag\n dragMomentum={false}\n dragElastic={0.05}\n onDragStart={() => setDragging(true)}\n onDragEnd={handleDragEnd}\n onPointerEnter={() => setHover(true)}\n onPointerLeave={() => setHover(false)}\n >\n <button\n ref={btnRef}\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"inline-flex h-11 min-w-[44px] cursor-grab items-center justify-center gap-1 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--background))]/95 px-3 text-sm font-medium text-[hsl(var(--foreground))] shadow-xl backdrop-blur hover:bg-[hsl(var(--accent))] active:cursor-grabbing\"\n title=\"Bridge 事件调试(可拖动到任意边缘)\"\n >\n <span className=\"text-base\">🌉</span>\n <span className=\"tabular-nums\">{events.length}</span>\n {rejectedCount > 0 ? (\n <span className=\"rounded bg-red-500/15 px-1 text-xs text-red-500 tabular-nums\">\n {rejectedCount}\n </span>\n ) : null}\n </button>\n </motion.div>\n {open && typeof document !== \"undefined\"\n ? createPortal(\n <BridgeDevtoolsPanel\n onClose={() => setOpen(false)}\n tab={tab}\n setTab={setTab}\n search={search}\n setSearch={setSearch}\n enabled={enabled}\n setEnabled={setEnabled}\n events={filtered}\n totalEvents={events}\n expandedId={expandedId}\n setExpandedId={setExpandedId}\n counts={counts}\n iframes={iframes}\n onClear={clear}\n />,\n document.body,\n )\n : null}\n </>\n )\n}\n\ninterface PanelProps {\n onClose: () => void\n tab: SideTab\n setTab: (t: SideTab) => void\n search: string\n setSearch: (s: string) => void\n enabled: Set<BridgeEventDirection>\n setEnabled: (s: Set<BridgeEventDirection>) => void\n events: BridgeEventRecord[]\n totalEvents: BridgeEventRecord[]\n expandedId: string | null\n setExpandedId: (id: string | null) => void\n counts: { agent: number; host: number; perIframe: Record<string, number> }\n iframes: Array<{ key: string; label: string; getContentWindow: () => Window | null }>\n onClear: () => void\n}\n\nfunction BridgeDevtoolsPanel(props: PanelProps) {\n const {\n onClose,\n tab,\n setTab,\n search,\n setSearch,\n enabled,\n setEnabled,\n events,\n totalEvents,\n expandedId,\n setExpandedId,\n counts,\n iframes,\n onClear,\n } = props\n\n const toggleDirection = (d: BridgeEventDirection) => {\n const next = new Set(enabled)\n if (next.has(d)) next.delete(d)\n else next.add(d)\n setEnabled(next)\n }\n\n return (\n <div className=\"fixed inset-0 z-[9999] flex items-end justify-end\">\n <button\n type=\"button\"\n aria-label=\"关闭调试面板\"\n className=\"absolute inset-0 bg-black/20\"\n onClick={onClose}\n />\n <div\n className=\"relative flex h-[85vh] w-full max-w-[720px] flex-col overflow-hidden rounded-t-xl border border-[hsl(var(--border))] bg-[hsl(var(--background))] shadow-2xl\"\n >\n <header className=\"flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-2\">\n <div className=\"flex items-center gap-2 text-sm font-semibold\">\n <span>🌉 Bridge 事件调试</span>\n <span className=\"text-xs text-[hsl(var(--muted-foreground))]\">\n {totalEvents.length} / 500\n </span>\n </div>\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n className=\"rounded px-2 py-1 text-xs hover:bg-[hsl(var(--accent))]\"\n onClick={() =>\n downloadJson(`bridge-events-${Date.now()}.json`, totalEvents)\n }\n >\n 导出 JSON\n </button>\n <button\n type=\"button\"\n className=\"rounded px-2 py-1 text-xs hover:bg-[hsl(var(--accent))]\"\n onClick={onClear}\n >\n 清空\n </button>\n <button\n type=\"button\"\n className=\"rounded px-2 py-1 text-xs hover:bg-[hsl(var(--accent))]\"\n onClick={onClose}\n >\n ✕\n </button>\n </div>\n </header>\n\n <nav className=\"flex items-center gap-1 overflow-x-auto border-b border-[hsl(var(--border))] px-3 py-2 text-xs\">\n <TabButton active={tab === \"agent\"} onClick={() => setTab(\"agent\")}>\n Agent 侧 ({counts.agent})\n </TabButton>\n <TabButton active={tab === \"host\"} onClick={() => setTab(\"host\")}>\n Host 全部 ({counts.host})\n </TabButton>\n {iframes.map((f) => (\n <TabButton\n key={f.key}\n active={tab === f.key}\n onClick={() => setTab(f.key)}\n title={f.label}\n >\n 📄 {f.label.length > 16 ? `${f.label.slice(0, 16)}…` : f.label} (\n {counts.perIframe[f.key] ?? 0})\n </TabButton>\n ))}\n </nav>\n\n <div className=\"flex flex-wrap items-center gap-2 border-b border-[hsl(var(--border))] px-3 py-2 text-xs\">\n <input\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"搜索 action / payload / note…\"\n className=\"min-w-[160px] flex-1 rounded border border-[hsl(var(--border))] bg-transparent px-2 py-1\"\n />\n {ALL_DIRECTIONS.map((d) => (\n <label key={d} className=\"flex items-center gap-1\">\n <input\n type=\"checkbox\"\n checked={enabled.has(d)}\n onChange={() => toggleDirection(d)}\n />\n <span>{DIRECTION_LABEL[d]}</span>\n </label>\n ))}\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto\">\n {events.length === 0 ? (\n <div className=\"p-6 text-center text-sm text-[hsl(var(--muted-foreground))]\">\n 无匹配事件\n </div>\n ) : (\n <ul className=\"divide-y divide-[hsl(var(--border))]\">\n {events.map((e) => (\n <EventRow\n key={e.id}\n event={e}\n expanded={expandedId === e.id}\n onToggle={() => setExpandedId(expandedId === e.id ? null : e.id)}\n />\n ))}\n </ul>\n )}\n </div>\n\n <ManualSendBar tab={tab} iframes={iframes} />\n </div>\n </div>\n )\n}\n\nfunction TabButton(props: {\n active: boolean\n onClick: () => void\n title?: string\n children: React.ReactNode\n}) {\n return (\n <button\n type=\"button\"\n onClick={props.onClick}\n title={props.title}\n className={`whitespace-nowrap rounded px-2 py-1 ${\n props.active\n ? \"bg-[hsl(var(--accent))] font-semibold\"\n : \"hover:bg-[hsl(var(--accent))]/50\"\n }`}\n >\n {props.children}\n </button>\n )\n}\n\nfunction EventRow({\n event,\n expanded,\n onToggle,\n}: {\n event: BridgeEventRecord\n expanded: boolean\n onToggle: () => void\n}) {\n return (\n <li\n className={`px-3 py-1.5 text-xs ${event.rejected ? \"bg-red-500/5\" : \"\"}`}\n >\n <button\n type=\"button\"\n onClick={onToggle}\n className=\"flex w-full items-center gap-2 text-left\"\n >\n <span className=\"w-[90px] font-mono tabular-nums text-[hsl(var(--muted-foreground))]\">\n {formatTime(event.ts)}\n </span>\n <span\n className={`w-[120px] font-mono ${\n event.side === \"agent\" ? \"text-blue-500\" : \"text-purple-500\"\n }`}\n >\n {DIRECTION_LABEL[event.direction]}\n </span>\n <span className=\"flex-1 truncate font-semibold\">{event.action}</span>\n {event.rejected ? (\n <span className=\"rounded bg-red-500/20 px-1.5 text-[10px] text-red-500\">\n rejected\n </span>\n ) : null}\n <span className=\"text-[hsl(var(--muted-foreground))]\">{expanded ? \"▼\" : \"▶\"}</span>\n </button>\n {expanded ? (\n <div className=\"mt-2 space-y-1 pl-[90px] font-mono\">\n {event.note ? (\n <div className=\"text-red-500\">note: {event.note}</div>\n ) : null}\n {event.iframeLabel ? (\n <div className=\"text-[hsl(var(--muted-foreground))]\">\n iframe: {event.iframeLabel}\n </div>\n ) : null}\n {event.meta ? (\n <pre className=\"whitespace-pre-wrap break-words text-[hsl(var(--muted-foreground))]\">\n meta: {safeStringify(event.meta, 2)}\n </pre>\n ) : null}\n <pre className=\"whitespace-pre-wrap break-words\">\n payload: {safeStringify(event.payload, 2)}\n </pre>\n </div>\n ) : null}\n </li>\n )\n}\n\nfunction ManualSendBar({\n tab,\n iframes,\n}: {\n tab: SideTab\n iframes: Array<{ key: string; label: string; getContentWindow: () => Window | null }>\n}) {\n const [action, setAction] = useState(\"\")\n const [payloadText, setPayloadText] = useState(\"{}\")\n const [error, setError] = useState<string | null>(null)\n const [targetKey, setTargetKey] = useState<string>(\"\")\n\n const effectiveSide: BridgeEventSide = tab === \"agent\" ? \"agent\" : \"host\"\n\n const send = () => {\n setError(null)\n let payload: unknown\n try {\n payload = payloadText.trim() ? JSON.parse(payloadText) : undefined\n } catch (err) {\n setError(`payload JSON 解析失败: ${(err as Error).message}`)\n return\n }\n if (!action.trim()) {\n setError(\"action 不能为空\")\n return\n }\n\n if (effectiveSide === \"agent\") {\n // 模拟 host → agent:直接 dispatch 到 window,parent-bridge 监听器会收到\n window.postMessage(\n {\n __bladeBridge: true,\n direction: \"host-to-agent\",\n action,\n payload,\n meta: { timestamp: Date.now(), injectedBy: \"devtools\" },\n },\n \"*\",\n )\n return\n }\n\n // host 侧:发送给某个 iframe\n const target = tab !== \"host\" && tab !== \"agent\" ? tab : targetKey\n const entry = iframes.find((f) => f.key === target)\n if (!entry) {\n setError(\"请选择目标 iframe\")\n return\n }\n const win = entry.getContentWindow()\n if (!win) {\n setError(\"目标 iframe contentWindow 为空(可能未加载)\")\n return\n }\n win.postMessage(\n {\n __resourceBridge: true,\n direction: \"host-to-iframe\",\n event: action,\n action,\n payload,\n },\n \"*\",\n )\n tapBridgeEvent({\n side: \"host\",\n direction: \"host-to-iframe\",\n action,\n payload,\n iframeKey: entry.key,\n iframeLabel: entry.label,\n note: \"injected by devtools\",\n })\n }\n\n return (\n <div className=\"border-t border-[hsl(var(--border))] bg-[hsl(var(--muted))]/30 px-3 py-2\">\n <div className=\"mb-1 text-xs font-semibold text-[hsl(var(--muted-foreground))]\">\n 手动发送 envelope({effectiveSide === \"agent\" ? \"模拟 host → agent\" : \"host → iframe\"})\n </div>\n <div className=\"flex flex-wrap items-start gap-2 text-xs\">\n {effectiveSide === \"host\" && tab === \"host\" ? (\n <select\n value={targetKey}\n onChange={(e) => setTargetKey(e.target.value)}\n className=\"rounded border border-[hsl(var(--border))] bg-transparent px-2 py-1\"\n >\n <option value=\"\">选择 iframe…</option>\n {iframes.map((f) => (\n <option key={f.key} value={f.key}>\n {f.label}\n </option>\n ))}\n </select>\n ) : null}\n <input\n value={action}\n onChange={(e) => setAction(e.target.value)}\n placeholder=\"action(如 addContext / theme)\"\n className=\"min-w-[140px] flex-1 rounded border border-[hsl(var(--border))] bg-transparent px-2 py-1\"\n />\n <input\n value={payloadText}\n onChange={(e) => setPayloadText(e.target.value)}\n placeholder='payload JSON(如 {\"foo\":1})'\n className=\"min-w-[180px] flex-[2] rounded border border-[hsl(var(--border))] bg-transparent px-2 py-1 font-mono\"\n />\n <button\n type=\"button\"\n onClick={send}\n className=\"rounded bg-[hsl(var(--primary))] px-3 py-1 text-[hsl(var(--primary-foreground))] hover:opacity-90\"\n >\n 发送\n </button>\n </div>\n {error ? <div className=\"mt-1 text-xs text-red-500\">{error}</div> : null}\n </div>\n )\n}\n","import { create } from \"zustand\"\nimport type { BridgeEventInput, BridgeEventRecord } from \"./types\"\n\nconst MAX_EVENTS = 500\n\nfunction buildId() {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID()\n }\n return `bev-${Date.now()}-${Math.random().toString(36).slice(2)}`\n}\n\nexport interface RegisteredIframe {\n key: string\n label: string\n getContentWindow: () => Window | null\n}\n\ninterface BridgeDevtoolsState {\n events: BridgeEventRecord[]\n iframes: Record<string, RegisteredIframe>\n record: (event: BridgeEventInput) => void\n clear: () => void\n registerIframe: (entry: RegisteredIframe) => () => void\n}\n\nexport const useBridgeDevtoolsStore = create<BridgeDevtoolsState>()((set) => ({\n events: [],\n iframes: {},\n record: (input) =>\n set((state) => {\n const record: BridgeEventRecord = {\n id: buildId(),\n ts: Date.now(),\n ...input,\n }\n const events =\n state.events.length >= MAX_EVENTS\n ? [...state.events.slice(state.events.length - MAX_EVENTS + 1), record]\n : [...state.events, record]\n return { events }\n }),\n clear: () => set({ events: [] }),\n registerIframe: (entry) => {\n set((state) => ({ iframes: { ...state.iframes, [entry.key]: entry } }))\n return () => {\n set((state) => {\n if (!(entry.key in state.iframes)) return state\n const next = { ...state.iframes }\n delete next[entry.key]\n return { iframes: next }\n })\n }\n },\n}))\n"],"mappings":"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","names":["jsx"]}
@@ -8,6 +8,7 @@ import { T as TurnProjection, a as PatchEnvelope } from '../projection-DIfyh6RK.
8
8
  export { C as ContentBlock, b as ToolCallProjection } from '../projection-DIfyh6RK.js';
9
9
  import { b as SessionDetail, S as SessionInfo, B as BizRole, c as Solution } from '../session-CDeiO81j.js';
10
10
  export { L as LayoutType, M as ModeId, P as PrimarySkillParallelMode, d as PrimarySkillSnapshot, e as PrimarySkillStageSpec, f as PrimarySkillStepSpec, a as SessionStatus, g as SkillEditorTemplateId, T as TemplateId } from '../session-CDeiO81j.js';
11
+ import * as arktype_internal_variants_object_ts from 'arktype/internal/variants/object.ts';
11
12
  import { M as MessageContent, C as ChatMessage, A as AskUserAnswerData, a as CompactionInfo } from '../AskUserQuestionBlock-CjvG_pUY.js';
12
13
  export { F as FileContentPart, I as ImageUrlContentPart, c as MessageContentPart, d as TextContentPart, T as ToolCallInfo } from '../AskUserQuestionBlock-CjvG_pUY.js';
13
14
  import * as _tanstack_react_query from '@tanstack/react-query';
@@ -20,7 +21,6 @@ import { Streamdown, ExtraProps } from 'streamdown';
20
21
  import * as _tiptap_core from '@tiptap/core';
21
22
  import * as _tiptap_extension_mention from '@tiptap/extension-mention';
22
23
  import { PluginKey } from '@tiptap/pm/state';
23
- import * as arktype_internal_variants_object_ts from 'arktype/internal/variants/object.ts';
24
24
  import * as arktype_internal_variants_string_ts from 'arktype/internal/variants/string.ts';
25
25
  import * as zustand_middleware from 'zustand/middleware';
26
26
  import 'socket.io-client';
@@ -371,6 +371,78 @@ declare namespace scenarios {
371
371
  export { scenarios_BladeHubScenarioResource as BladeHubScenarioResource, scenarios_CreateQuickScenarioPayload as CreateQuickScenarioPayload, scenarios_PreviewUrlItem as PreviewUrlItem, scenarios_QuickScenario as QuickScenario, scenarios_ScenariosResource as ScenariosResource, scenarios_UpdateQuickScenarioPayload as UpdateQuickScenarioPayload, scenarios_createQuickScenario as createQuickScenario, scenarios_deleteQuickScenario as deleteQuickScenario, scenarios_listBladeHubScenarioResources as listBladeHubScenarioResources, scenarios_listQuickScenarios as listQuickScenarios, scenarios_updateQuickScenario as updateQuickScenario };
372
372
  }
373
373
 
374
+ declare const ScheduledTask: arktype_internal_variants_object_ts.ObjectType<{
375
+ id: string;
376
+ title: string;
377
+ prompt: string;
378
+ cron: string;
379
+ timezone: string;
380
+ enabled: boolean;
381
+ expires_at: string | null;
382
+ skip_confirmations: boolean;
383
+ model: string | null;
384
+ next_run_at: string | null;
385
+ last_run_at: string | null;
386
+ created_at: string;
387
+ updated_at: string;
388
+ }, {}>;
389
+ type ScheduledTask = typeof ScheduledTask.infer;
390
+ declare const ScheduledTaskRun: arktype_internal_variants_object_ts.ObjectType<{
391
+ id: string;
392
+ task_id: string;
393
+ session_id: string | null;
394
+ status: string;
395
+ error: string | null;
396
+ triggered_at: string;
397
+ finished_at: string | null;
398
+ }, {}>;
399
+ type ScheduledTaskRun = typeof ScheduledTaskRun.infer;
400
+ declare const ScheduledTaskCalendarItem: arktype_internal_variants_object_ts.ObjectType<{
401
+ task_id: string;
402
+ title: string;
403
+ occurrences: string[];
404
+ }, {}>;
405
+ type ScheduledTaskCalendarItem = typeof ScheduledTaskCalendarItem.infer;
406
+
407
+ interface ScheduledTaskCreatePayload {
408
+ title: string;
409
+ prompt: string;
410
+ cron: string;
411
+ timezone?: string;
412
+ enabled?: boolean;
413
+ expires_at?: string | null;
414
+ skip_confirmations?: boolean;
415
+ model?: string | null;
416
+ }
417
+ type ScheduledTaskUpdatePayload = Partial<ScheduledTaskCreatePayload>;
418
+ declare function listScheduledTasks(): Promise<ScheduledTask[]>;
419
+ declare function createScheduledTask(payload: ScheduledTaskCreatePayload): Promise<ScheduledTask>;
420
+ declare function getScheduledTask(id: string): Promise<ScheduledTask>;
421
+ declare function updateScheduledTask(id: string, payload: ScheduledTaskUpdatePayload): Promise<ScheduledTask>;
422
+ declare function deleteScheduledTask(id: string): Promise<void>;
423
+ declare function startScheduledTask(id: string): Promise<ScheduledTask>;
424
+ declare function stopScheduledTask(id: string): Promise<ScheduledTask>;
425
+ declare function listScheduledTaskRuns(id: string): Promise<ScheduledTaskRun[]>;
426
+ declare function getScheduledTaskCalendar(params: {
427
+ from: string;
428
+ to: string;
429
+ }): Promise<ScheduledTaskCalendarItem[]>;
430
+
431
+ type scheduledTasks_ScheduledTaskCreatePayload = ScheduledTaskCreatePayload;
432
+ type scheduledTasks_ScheduledTaskUpdatePayload = ScheduledTaskUpdatePayload;
433
+ declare const scheduledTasks_createScheduledTask: typeof createScheduledTask;
434
+ declare const scheduledTasks_deleteScheduledTask: typeof deleteScheduledTask;
435
+ declare const scheduledTasks_getScheduledTask: typeof getScheduledTask;
436
+ declare const scheduledTasks_getScheduledTaskCalendar: typeof getScheduledTaskCalendar;
437
+ declare const scheduledTasks_listScheduledTaskRuns: typeof listScheduledTaskRuns;
438
+ declare const scheduledTasks_listScheduledTasks: typeof listScheduledTasks;
439
+ declare const scheduledTasks_startScheduledTask: typeof startScheduledTask;
440
+ declare const scheduledTasks_stopScheduledTask: typeof stopScheduledTask;
441
+ declare const scheduledTasks_updateScheduledTask: typeof updateScheduledTask;
442
+ declare namespace scheduledTasks {
443
+ export { type scheduledTasks_ScheduledTaskCreatePayload as ScheduledTaskCreatePayload, type scheduledTasks_ScheduledTaskUpdatePayload as ScheduledTaskUpdatePayload, scheduledTasks_createScheduledTask as createScheduledTask, scheduledTasks_deleteScheduledTask as deleteScheduledTask, scheduledTasks_getScheduledTask as getScheduledTask, scheduledTasks_getScheduledTaskCalendar as getScheduledTaskCalendar, scheduledTasks_listScheduledTaskRuns as listScheduledTaskRuns, scheduledTasks_listScheduledTasks as listScheduledTasks, scheduledTasks_startScheduledTask as startScheduledTask, scheduledTasks_stopScheduledTask as stopScheduledTask, scheduledTasks_updateScheduledTask as updateScheduledTask };
444
+ }
445
+
374
446
  declare const listSoftware: (...args: Parameters<SoftwareFactoryResource["listSoftware"]>) => Promise<SoftwareFactorySoftware[]>;
375
447
  declare const getSoftware: (...args: Parameters<SoftwareFactoryResource["getSoftware"]>) => Promise<SoftwareFactorySoftware>;
376
448
  declare const deleteSoftware: (...args: Parameters<SoftwareFactoryResource["deleteSoftware"]>) => Promise<{
@@ -1280,4 +1352,4 @@ interface UiBridgeState extends ClientAwareState {
1280
1352
  }
1281
1353
  declare const useUiBridgeStore: zustand.UseBoundStore<zustand.StoreApi<UiBridgeState>>;
1282
1354
 
1283
- export { type ActiveRightTab, type AnalyticsEventName, ApiKeyCreateResponse, ApiKeyPublic, BackgroundTask, BizRole, type BladeBridgeEnvelope, BladeClientOptions, BladeClientProvider, type BladeClientProviderProps, BladeContext, BladeHubScenarioResource, type Card, CardCodeBlock, type CardComponent, type CardComponentProps, CardContext, CardJSON, type ChatEnd, ChatMessage, type ConnectionStatus, type ContentDelta, CreateQuickScenarioPayload, CreateSoftwareFactorySharedFilePayload, CreateSoftwareFactorySoftwarePayload, EnvVariable, GisGoal, GisMapCommand, GisResource$1 as GisResource, GisState, GisTarget, type LlmResponseDone, MarkdownContent, Memory, MemoryCreateBody, MemoryListParams, MemoryListResponse, MessageContent, ModelSelector, PartnerSkillInstallPayload, PartnerSkillInstallPayload as PartnerSkillInstallPayloadData, PartnerSkillInstallResult, PartnerSkillInstallResult as PartnerSkillInstallResultData, PatchEnvelope, type PreviewTarget, PreviewUrlItem, QuickScenario, RegistryResource, ResourceApi, ResourceBase, ResourceIframe, RuntimeConfig, type RuntimeEvent, Scene, SceneStatus, SessionDetail, SessionInfo, type SessionStatusEvent, SkillCompletionMenu, type SkillCompletionMenuRef, SkillDetail, SkillMention, SkillOrgListResponse, SkillSearchResult, type SkillSuggestionItem, SkillSummary, SoftwareFactorySharedFile, SoftwareFactorySoftware, Solution, type StepMessageRange, type SystemError, Task, type ToolCallCreated, type ToolResultDone, TurnProjection, type UiMeta, UpdateQuickScenarioPayload, type UseTiptapVoiceInputOptions, type UseTiptapVoiceInputResult, type UseVoiceInputOptions, type UseVoiceInputResult, type VoiceInputError, type VoiceInputStatus, VoiceWaveform, agentApi, agentSocket, apiFetch, apiFetchResponse, apiFetchText, apiKeys as apiKeysApi, attachClientToStores, attachHostBridgeListener, auth as authApi, bootstrapBladeClient, buildMessageContent, buildSessionBinaryPreviewTarget, buildStepRanges, buildVoiceInputUnavailableError, cardRegistry, cn, copyToClipboard, createResourceApi, databaseApi, deriveDeprecateEntryIds, getAuthedUrl, getBaseUrl, getBootstrappedClient, getClient, getSocket, getTextContent, gisApi, groupMessagesByLoop, isInsideIframe, isUiMeta, knowledgeApi, listSkillOrgs, memories as memoriesApi, models as modelsApi, normalizeCodeLanguage, partnerSkill as partnerSkillApi, publishSkill, resolveEffectiveTheme, resolveSessionFilePreviewTarget, resourceBridgeDispatch, scenarios as scenariosApi, sessions as sessionsApi, setAnalyticsClient, setOnWorkspaceFilesChanged, skillMentionSuggestionKey, skills as skillsApi, softwareFactory as softwareFactoryApi, solutions as solutionsApi, toolApi, trackEvent, transformSlashCommand, uploadFiles, useAgents, useAuthStore, useBackgroundStore, useBackgroundTasks, useBladeClient, useCardContext, useCardState, useCardStateStore, useChat, useChatStore, useCheckSkillFile, useConnectionStore, useDataSources, useGisState, useGisStore, useGlobalSkillStats, useHighlightedCodeHtml, useInputHistory, useKnowledgeBases, useModelConfig, usePreferredModel, useRuntimeConfig, useRuntimeFeaturesStore, useRuntimeStore, useSession, useSkills, useTaskStore, useTiptapVoiceInput, useToolProviders, useUiBridgeStore, useUiStore, useVoiceInput, userPreferences as userPreferencesApi };
1355
+ export { type ActiveRightTab, type AnalyticsEventName, ApiKeyCreateResponse, ApiKeyPublic, BackgroundTask, BizRole, type BladeBridgeEnvelope, BladeClientOptions, BladeClientProvider, type BladeClientProviderProps, BladeContext, BladeHubScenarioResource, type Card, CardCodeBlock, type CardComponent, type CardComponentProps, CardContext, CardJSON, type ChatEnd, ChatMessage, type ConnectionStatus, type ContentDelta, CreateQuickScenarioPayload, CreateSoftwareFactorySharedFilePayload, CreateSoftwareFactorySoftwarePayload, EnvVariable, GisGoal, GisMapCommand, GisResource$1 as GisResource, GisState, GisTarget, type LlmResponseDone, MarkdownContent, Memory, MemoryCreateBody, MemoryListParams, MemoryListResponse, MessageContent, ModelSelector, PartnerSkillInstallPayload, PartnerSkillInstallPayload as PartnerSkillInstallPayloadData, PartnerSkillInstallResult, PartnerSkillInstallResult as PartnerSkillInstallResultData, PatchEnvelope, type PreviewTarget, PreviewUrlItem, QuickScenario, RegistryResource, ResourceApi, ResourceBase, ResourceIframe, RuntimeConfig, type RuntimeEvent, Scene, SceneStatus, ScheduledTask, ScheduledTaskCalendarItem, ScheduledTaskCalendarItem as ScheduledTaskCalendarItemData, type ScheduledTaskCreatePayload, ScheduledTask as ScheduledTaskData, ScheduledTaskRun, ScheduledTaskRun as ScheduledTaskRunData, type ScheduledTaskUpdatePayload, SessionDetail, SessionInfo, type SessionStatusEvent, SkillCompletionMenu, type SkillCompletionMenuRef, SkillDetail, SkillMention, SkillOrgListResponse, SkillSearchResult, type SkillSuggestionItem, SkillSummary, SoftwareFactorySharedFile, SoftwareFactorySoftware, Solution, type StepMessageRange, type SystemError, Task, type ToolCallCreated, type ToolResultDone, TurnProjection, type UiMeta, UpdateQuickScenarioPayload, type UseTiptapVoiceInputOptions, type UseTiptapVoiceInputResult, type UseVoiceInputOptions, type UseVoiceInputResult, type VoiceInputError, type VoiceInputStatus, VoiceWaveform, agentApi, agentSocket, apiFetch, apiFetchResponse, apiFetchText, apiKeys as apiKeysApi, attachClientToStores, attachHostBridgeListener, auth as authApi, bootstrapBladeClient, buildMessageContent, buildSessionBinaryPreviewTarget, buildStepRanges, buildVoiceInputUnavailableError, cardRegistry, cn, copyToClipboard, createResourceApi, databaseApi, deriveDeprecateEntryIds, getAuthedUrl, getBaseUrl, getBootstrappedClient, getClient, getSocket, getTextContent, gisApi, groupMessagesByLoop, isInsideIframe, isUiMeta, knowledgeApi, listSkillOrgs, memories as memoriesApi, models as modelsApi, normalizeCodeLanguage, partnerSkill as partnerSkillApi, publishSkill, resolveEffectiveTheme, resolveSessionFilePreviewTarget, resourceBridgeDispatch, scenarios as scenariosApi, scheduledTasks as scheduledTasksApi, sessions as sessionsApi, setAnalyticsClient, setOnWorkspaceFilesChanged, skillMentionSuggestionKey, skills as skillsApi, softwareFactory as softwareFactoryApi, solutions as solutionsApi, toolApi, trackEvent, transformSlashCommand, uploadFiles, useAgents, useAuthStore, useBackgroundStore, useBackgroundTasks, useBladeClient, useCardContext, useCardState, useCardStateStore, useChat, useChatStore, useCheckSkillFile, useConnectionStore, useDataSources, useGisState, useGisStore, useGlobalSkillStats, useHighlightedCodeHtml, useInputHistory, useKnowledgeBases, useModelConfig, usePreferredModel, useRuntimeConfig, useRuntimeFeaturesStore, useRuntimeStore, useSession, useSkills, useTaskStore, useTiptapVoiceInput, useToolProviders, useUiBridgeStore, useUiStore, useVoiceInput, userPreferences as userPreferencesApi };