@blade-hq/agent-react 2610.0.3 → 2610.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1659,6 +1659,43 @@ var require_react_is = __commonJS({
1659
1659
  }
1660
1660
  });
1661
1661
 
1662
+ // src/hooks/use-live-execution-duration.ts
1663
+ import { useEffect, useRef, useState } from "react";
1664
+ function useLiveExecutionDuration({
1665
+ turnKey,
1666
+ isStreaming,
1667
+ initialDurationMs,
1668
+ isInitialDurationReady
1669
+ }) {
1670
+ const initialDurationRef = useRef(initialDurationMs);
1671
+ initialDurationRef.current = initialDurationMs;
1672
+ const [durationMs, setDurationMs] = useState(initialDurationMs);
1673
+ useEffect(() => {
1674
+ if (!isStreaming || !isInitialDurationReady) return;
1675
+ const baseDurationMs = initialDurationRef.current;
1676
+ const startedAt = performance.now();
1677
+ setDurationMs(baseDurationMs);
1678
+ const timer = window.setInterval(() => {
1679
+ setDurationMs(baseDurationMs + Math.max(0, performance.now() - startedAt));
1680
+ }, 1e3);
1681
+ return () => window.clearInterval(timer);
1682
+ }, [isStreaming, turnKey, isInitialDurationReady]);
1683
+ return durationMs;
1684
+ }
1685
+ function getChatRun(messages) {
1686
+ const runs = messages.flatMap((message) => message.chat_run ? [message.chat_run] : []);
1687
+ const latestId = runs.at(-1)?.run_id;
1688
+ const settled = [...runs].reverse().find((run) => run.run_id === latestId && run.status !== "incomplete");
1689
+ return settled ?? runs.at(-1) ?? null;
1690
+ }
1691
+ function getChatRunDuration(messages, now) {
1692
+ const running = getChatRun(messages);
1693
+ if (!running) return null;
1694
+ if (running.status !== "incomplete") return running.duration_ms ?? 0;
1695
+ const start = running.started_at ? Date.parse(running.started_at) : Number.NaN;
1696
+ return now !== null && Number.isFinite(start) ? Math.max(0, now - start) : 0;
1697
+ }
1698
+
1662
1699
  // src/context.tsx
1663
1700
  import { createContext, useContext } from "react";
1664
1701
  import { jsx } from "react/jsx-runtime";
@@ -1678,28 +1715,28 @@ function useOptionalBladeClient() {
1678
1715
  }
1679
1716
 
1680
1717
  // src/hooks/use-agent-session.ts
1681
- import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
1718
+ import { useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2, useSyncExternalStore } from "react";
1682
1719
  var EMPTY_SUBSCRIBE = () => () => {
1683
1720
  };
1684
1721
  var DISPOSE_DELAY_MS = 1e3;
1685
1722
  function useAgentSession(sessionId, options = {}) {
1686
1723
  const client = useBladeClient();
1687
- const [session, setSession] = useState(null);
1688
- const [error61, setError] = useState(null);
1689
- const connRef = useRef({
1724
+ const [session, setSession] = useState2(null);
1725
+ const [error61, setError] = useState2(null);
1726
+ const connRef = useRef2({
1690
1727
  id: null,
1691
1728
  session: null,
1692
1729
  cleanup: null,
1693
1730
  gen: 0
1694
1731
  });
1695
- const createdIdPromiseRef = useRef(null);
1696
- const onCreatedRef = useRef(options.onSessionCreated);
1732
+ const createdIdPromiseRef = useRef2(null);
1733
+ const onCreatedRef = useRef2(options.onSessionCreated);
1697
1734
  onCreatedRef.current = options.onSessionCreated;
1698
- const onConnectedRef = useRef(options.onSessionConnected);
1735
+ const onConnectedRef = useRef2(options.onSessionConnected);
1699
1736
  onConnectedRef.current = options.onSessionConnected;
1700
- const createOptionsRef = useRef(options.createOptions);
1737
+ const createOptionsRef = useRef2(options.createOptions);
1701
1738
  createOptionsRef.current = options.createOptions;
1702
- const sessionIdRef = useRef(sessionId);
1739
+ const sessionIdRef = useRef2(sessionId);
1703
1740
  sessionIdRef.current = sessionId;
1704
1741
  const connect = useMemo(() => {
1705
1742
  return (targetId) => {
@@ -1739,7 +1776,7 @@ function useAgentSession(sessionId, options = {}) {
1739
1776
  });
1740
1777
  };
1741
1778
  }, [client]);
1742
- useEffect(() => {
1779
+ useEffect2(() => {
1743
1780
  connect(sessionIdRef.current);
1744
1781
  return () => {
1745
1782
  connRef.current.gen++;
@@ -1753,7 +1790,7 @@ function useAgentSession(sessionId, options = {}) {
1753
1790
  if (toRelease) setTimeout(() => toRelease.dispose(), DISPOSE_DELAY_MS);
1754
1791
  };
1755
1792
  }, [connect]);
1756
- useEffect(() => {
1793
+ useEffect2(() => {
1757
1794
  if (!sessionId) return;
1758
1795
  if (connRef.current.id === null) return;
1759
1796
  if (sessionId === connRef.current.id) return;
@@ -1779,20 +1816,20 @@ function useAgentSession(sessionId, options = {}) {
1779
1816
 
1780
1817
  // src/hooks/use-replay.ts
1781
1818
  import { DEFAULT_REPLAY_SPEED } from "@blade-hq/agent-client";
1782
- import { useCallback, useEffect as useEffect2, useState as useState2 } from "react";
1819
+ import { useCallback, useEffect as useEffect3, useState as useState3 } from "react";
1783
1820
  var replayCreating = /* @__PURE__ */ new Set();
1784
1821
  function useReplay(session) {
1785
1822
  const client = useBladeClient();
1786
1823
  const sessionId = session?.sessionId ?? null;
1787
- const [replay, setReplay] = useState2(null);
1788
- const [viewerRole, setViewerRole] = useState2(null);
1789
- const [sourceRunning, setSourceRunning] = useState2(false);
1790
- const [mismatch, setMismatch] = useState2(null);
1791
- const [preview, setPreview] = useState2({ status: "loading" });
1792
- const [isStarting, setIsStarting] = useState2(false);
1793
- const [error61, setError] = useState2(null);
1794
- const [draftSpeed, setDraftSpeed] = useState2(DEFAULT_REPLAY_SPEED);
1795
- useEffect2(() => {
1824
+ const [replay, setReplay] = useState3(null);
1825
+ const [viewerRole, setViewerRole] = useState3(null);
1826
+ const [sourceRunning, setSourceRunning] = useState3(false);
1827
+ const [mismatch, setMismatch] = useState3(null);
1828
+ const [preview, setPreview] = useState3({ status: "loading" });
1829
+ const [isStarting, setIsStarting] = useState3(false);
1830
+ const [error61, setError] = useState3(null);
1831
+ const [draftSpeed, setDraftSpeed] = useState3(DEFAULT_REPLAY_SPEED);
1832
+ useEffect3(() => {
1796
1833
  if (!session) {
1797
1834
  setReplay(null);
1798
1835
  setViewerRole(null);
@@ -1808,14 +1845,14 @@ function useReplay(session) {
1808
1845
  pull();
1809
1846
  return session.subscribe(pull);
1810
1847
  }, [session]);
1811
- const [lastSessionId, setLastSessionId] = useState2(sessionId);
1848
+ const [lastSessionId, setLastSessionId] = useState3(sessionId);
1812
1849
  if (sessionId !== lastSessionId) {
1813
1850
  setLastSessionId(sessionId);
1814
1851
  setMismatch(null);
1815
1852
  setError(null);
1816
1853
  setDraftSpeed(DEFAULT_REPLAY_SPEED);
1817
1854
  }
1818
- useEffect2(() => {
1855
+ useEffect3(() => {
1819
1856
  setPreview({ status: "loading" });
1820
1857
  if (!sessionId) return;
1821
1858
  let alive = true;
@@ -1833,7 +1870,7 @@ function useReplay(session) {
1833
1870
  alive = false;
1834
1871
  };
1835
1872
  }, [client, sessionId, sourceRunning]);
1836
- useEffect2(() => {
1873
+ useEffect3(() => {
1837
1874
  if (!session) return;
1838
1875
  return session.on("replayMismatch", ({ actualMessage, expectedMessage, respond }) => {
1839
1876
  setMismatch({
@@ -1911,23 +1948,23 @@ function useReplay(session) {
1911
1948
  }
1912
1949
 
1913
1950
  // src/hooks/use-llm-chat.ts
1914
- import { useCallback as useCallback2, useMemo as useMemo2, useRef as useRef2, useState as useState3 } from "react";
1951
+ import { useCallback as useCallback2, useMemo as useMemo2, useRef as useRef3, useState as useState4 } from "react";
1915
1952
  var DEFAULT_HISTORY_TURNS = 12;
1916
1953
  var DEFAULT_MAX_TOOL_ROUNDS = 4;
1917
1954
  var syntheticIdSeq = 0;
1918
1955
  function useLlmChat(options) {
1919
- const [history, setHistory] = useState3([]);
1920
- const [streamingText, setStreamingText] = useState3(null);
1921
- const [streamingCalls, setStreamingCalls] = useState3([]);
1922
- const [failedToolIds, setFailedToolIds] = useState3([]);
1923
- const [error61, setError] = useState3(null);
1924
- const [isStreaming, setIsStreaming] = useState3(false);
1925
- const abortRef = useRef2(null);
1926
- const activeStartedAtRef = useRef2(null);
1927
- const assistantTimingsRef = useRef2(/* @__PURE__ */ new WeakMap());
1928
- const generationRef = useRef2(0);
1929
- const historyRef = useRef2([]);
1930
- const optionsRef = useRef2(options);
1956
+ const [history, setHistory] = useState4([]);
1957
+ const [streamingText, setStreamingText] = useState4(null);
1958
+ const [streamingCalls, setStreamingCalls] = useState4([]);
1959
+ const [failedToolIds, setFailedToolIds] = useState4([]);
1960
+ const [error61, setError] = useState4(null);
1961
+ const [isStreaming, setIsStreaming] = useState4(false);
1962
+ const abortRef = useRef3(null);
1963
+ const activeStartedAtRef = useRef3(null);
1964
+ const assistantTimingsRef = useRef3(/* @__PURE__ */ new WeakMap());
1965
+ const generationRef = useRef3(0);
1966
+ const historyRef = useRef3([]);
1967
+ const optionsRef = useRef3(options);
1931
1968
  optionsRef.current = options;
1932
1969
  historyRef.current = history;
1933
1970
  const stop = useCallback2(() => {
@@ -2267,7 +2304,7 @@ function toToolCallInfo(call, results, failedToolIds) {
2267
2304
  }
2268
2305
 
2269
2306
  // src/hooks/use-message-pin.ts
2270
- import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef3 } from "react";
2307
+ import { useCallback as useCallback3, useEffect as useEffect4, useRef as useRef4 } from "react";
2271
2308
  var DEFAULT_MARGIN_PX = 24;
2272
2309
  var MANUAL_SCROLL_TOLERANCE_PX = 2;
2273
2310
  function useMessagePin({
@@ -2289,16 +2326,16 @@ function useMessagePin({
2289
2326
  scrollToBottom,
2290
2327
  margin = DEFAULT_MARGIN_PX
2291
2328
  }) {
2292
- const pinActiveRef = useRef3(false);
2293
- const frameRef = useRef3(null);
2294
- const retryTimeoutRef = useRef3(null);
2295
- const manualScrollCheckTimeoutRef = useRef3(null);
2296
- const repositionPendingRef = useRef3(false);
2297
- const pinnedTargetScrollTopRef = useRef3(null);
2298
- const appliedTargetKeyRef = useRef3(null);
2299
- const initialObservedTargetKeyRef = useRef3(pinTarget ? null : targetKey);
2300
- const observedTargetKeyRef = useRef3(initialObservedTargetKeyRef.current);
2301
- const setSpacerHeightRef = useRef3(setSpacerHeight);
2329
+ const pinActiveRef = useRef4(false);
2330
+ const frameRef = useRef4(null);
2331
+ const retryTimeoutRef = useRef4(null);
2332
+ const manualScrollCheckTimeoutRef = useRef4(null);
2333
+ const repositionPendingRef = useRef4(false);
2334
+ const pinnedTargetScrollTopRef = useRef4(null);
2335
+ const appliedTargetKeyRef = useRef4(null);
2336
+ const initialObservedTargetKeyRef = useRef4(pinTarget ? null : targetKey);
2337
+ const observedTargetKeyRef = useRef4(initialObservedTargetKeyRef.current);
2338
+ const setSpacerHeightRef = useRef4(setSpacerHeight);
2302
2339
  setSpacerHeightRef.current = setSpacerHeight;
2303
2340
  const release = useCallback3(() => {
2304
2341
  if (!pinActiveRef.current) return;
@@ -2360,7 +2397,7 @@ function useMessagePin({
2360
2397
  },
2361
2398
  [reposition]
2362
2399
  );
2363
- useEffect3(() => {
2400
+ useEffect4(() => {
2364
2401
  if (!targetKey) {
2365
2402
  release();
2366
2403
  appliedTargetKeyRef.current = null;
@@ -2390,10 +2427,10 @@ function useMessagePin({
2390
2427
  scheduleReposition();
2391
2428
  }, 80);
2392
2429
  }, [isStreaming, pinTarget, release, scheduleReposition, stopAutoScroll, targetKey]);
2393
- useEffect3(() => {
2430
+ useEffect4(() => {
2394
2431
  if (layoutKey !== void 0) scheduleReposition();
2395
2432
  }, [layoutKey, scheduleReposition]);
2396
- useEffect3(() => {
2433
+ useEffect4(() => {
2397
2434
  const scroll = getScrollElement();
2398
2435
  if (!scroll) return;
2399
2436
  const content3 = getContentElement?.();
@@ -2424,7 +2461,7 @@ function useMessagePin({
2424
2461
  scroll.removeEventListener("scroll", handleScroll);
2425
2462
  };
2426
2463
  }, [getContentElement, getScrollElement, release, scheduleReposition]);
2427
- useEffect3(
2464
+ useEffect4(
2428
2465
  () => () => {
2429
2466
  if (frameRef.current != null) cancelAnimationFrame(frameRef.current);
2430
2467
  frameRef.current = null;
@@ -2448,7 +2485,7 @@ function useMessagePin({
2448
2485
  }
2449
2486
 
2450
2487
  // src/hooks/use-typewriter-reveal.ts
2451
- import { useCallback as useCallback4, useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
2488
+ import { useCallback as useCallback4, useEffect as useEffect5, useRef as useRef5, useState as useState5 } from "react";
2452
2489
  var REVEAL_INITIAL_CPS = 18;
2453
2490
  var REVEAL_MIN_CPS = 6;
2454
2491
  var REVEAL_MAX_CPS = 240;
@@ -2484,15 +2521,15 @@ function initialRevealState(targetText, isLive, resetKey) {
2484
2521
  };
2485
2522
  }
2486
2523
  function useTypewriterReveal(targetText, isLive, resetKey) {
2487
- const [state, setState] = useState4(() => initialRevealState(targetText, isLive, resetKey));
2488
- const targetTextRef = useRef4(targetText);
2524
+ const [state, setState] = useState5(() => initialRevealState(targetText, isLive, resetKey));
2525
+ const targetTextRef = useRef5(targetText);
2489
2526
  targetTextRef.current = targetText;
2490
- const revealedLenRef = useRef4(state.revealedLen);
2491
- const priorTargetLenRef = useRef4(targetText.length);
2492
- const emaCpsRef = useRef4(REVEAL_INITIAL_CPS);
2493
- const lastTickTsRef = useRef4(null);
2494
- const lastArrivalTsRef = useRef4(null);
2495
- const cancelRef = useRef4(null);
2527
+ const revealedLenRef = useRef5(state.revealedLen);
2528
+ const priorTargetLenRef = useRef5(targetText.length);
2529
+ const emaCpsRef = useRef5(REVEAL_INITIAL_CPS);
2530
+ const lastTickTsRef = useRef5(null);
2531
+ const lastArrivalTsRef = useRef5(null);
2532
+ const cancelRef = useRef5(null);
2496
2533
  const stopTicking = useCallback4(() => {
2497
2534
  cancelRef.current?.();
2498
2535
  cancelRef.current = null;
@@ -2524,7 +2561,7 @@ function useTypewriterReveal(targetText, isLive, resetKey) {
2524
2561
  priorTargetLenRef.current = targetText.length;
2525
2562
  setState((s) => ({ ...s, displayedText: targetText, revealedLen: targetText.length, isRevealing: false }));
2526
2563
  }
2527
- const tickRef = useRef4(null);
2564
+ const tickRef = useRef5(null);
2528
2565
  tickRef.current = (ts) => {
2529
2566
  cancelRef.current = null;
2530
2567
  const currentTargetLen = targetTextRef.current.length;
@@ -2563,7 +2600,7 @@ function useTypewriterReveal(targetText, isLive, resetKey) {
2563
2600
  cancelRef.current = scheduleAnimationFrame((nextTs) => tickRef.current?.(nextTs));
2564
2601
  }
2565
2602
  };
2566
- useEffect4(() => {
2603
+ useEffect5(() => {
2567
2604
  if (!isLive) return;
2568
2605
  if (revealedLenRef.current === 0) return;
2569
2606
  if (revealedLenRef.current >= targetText.length) return;
@@ -2571,10 +2608,10 @@ function useTypewriterReveal(targetText, isLive, resetKey) {
2571
2608
  setState((s) => s.isRevealing ? s : { ...s, isRevealing: true });
2572
2609
  cancelRef.current = scheduleAnimationFrame((ts) => tickRef.current?.(ts));
2573
2610
  }, [targetText, isLive]);
2574
- useEffect4(() => {
2611
+ useEffect5(() => {
2575
2612
  if (!isLive) stopTicking();
2576
2613
  }, [isLive, stopTicking]);
2577
- useEffect4(() => {
2614
+ useEffect5(() => {
2578
2615
  if (typeof document === "undefined") return;
2579
2616
  const handleVisibilityChange = () => {
2580
2617
  if (document.visibilityState === "visible") flushNow();
@@ -2582,7 +2619,7 @@ function useTypewriterReveal(targetText, isLive, resetKey) {
2582
2619
  document.addEventListener("visibilitychange", handleVisibilityChange);
2583
2620
  return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
2584
2621
  }, [flushNow]);
2585
- useEffect4(() => stopTicking, [stopTicking]);
2622
+ useEffect5(() => stopTicking, [stopTicking]);
2586
2623
  return { displayedText: state.displayedText, isRevealing: state.isRevealing, flushNow };
2587
2624
  }
2588
2625
 
@@ -2592,7 +2629,7 @@ import {
2592
2629
  isHiddenInternalMessage,
2593
2630
  normalizeMessageContent
2594
2631
  } from "@blade-hq/agent-client";
2595
- import { useCallback as useCallback5, useEffect as useEffect5, useLayoutEffect, useRef as useRef5, useState as useState5 } from "react";
2632
+ import { useCallback as useCallback5, useEffect as useEffect6, useLayoutEffect, useRef as useRef6, useState as useState6 } from "react";
2596
2633
  var HIGHLIGHT_MS = 1600;
2597
2634
  var TURN_NAV_HIGHLIGHT_CLASS = "blade-turn-nav-flash";
2598
2635
  var MAX_FRAMES_AFTER_LOCATE = 20;
@@ -2647,7 +2684,7 @@ function useTurnNavigation({
2647
2684
  reloadKey,
2648
2685
  rewriteKey
2649
2686
  }) {
2650
- const callbacks = useRef5({
2687
+ const callbacks = useRef6({
2651
2688
  getLoadedEntryElement,
2652
2689
  isEntryLoaded,
2653
2690
  locateEntry,
@@ -2656,27 +2693,27 @@ function useTurnNavigation({
2656
2693
  revealEntry,
2657
2694
  beforeSeek
2658
2695
  });
2659
- const [index3, setIndex] = useState5({ sessionId: null, items: [] });
2660
- const [loadingEntryId, setLoadingEntryId] = useState5(null);
2661
- const [activeEntryId, setActiveEntryId] = useState5(null);
2662
- const [failedEntryId, setFailedEntryId] = useState5(null);
2663
- const [error61, setError] = useState5(null);
2664
- const [indexRefresh, setIndexRefresh] = useState5(0);
2665
- const seekSeq = useRef5(0);
2666
- const indexSeq = useRef5(0);
2667
- const indexRef = useRef5({
2696
+ const [index3, setIndex] = useState6({ sessionId: null, items: [] });
2697
+ const [loadingEntryId, setLoadingEntryId] = useState6(null);
2698
+ const [activeEntryId, setActiveEntryId] = useState6(null);
2699
+ const [failedEntryId, setFailedEntryId] = useState6(null);
2700
+ const [error61, setError] = useState6(null);
2701
+ const [indexRefresh, setIndexRefresh] = useState6(0);
2702
+ const seekSeq = useRef6(0);
2703
+ const indexSeq = useRef6(0);
2704
+ const indexRef = useRef6({
2668
2705
  sessionId: null,
2669
2706
  items: []
2670
2707
  });
2671
- const highlightTimer = useRef5(void 0);
2672
- const highlightedRef = useRef5(null);
2708
+ const highlightTimer = useRef6(void 0);
2709
+ const highlightedRef = useRef6(null);
2673
2710
  const clearHighlight = useCallback5(() => {
2674
2711
  clearTimeout(highlightTimer.current);
2675
2712
  highlightTimer.current = void 0;
2676
2713
  highlightedRef.current?.classList.remove(TURN_NAV_HIGHLIGHT_CLASS);
2677
2714
  highlightedRef.current = null;
2678
2715
  }, []);
2679
- useEffect5(
2716
+ useEffect6(
2680
2717
  () => () => {
2681
2718
  seekSeq.current += 1;
2682
2719
  indexSeq.current += 1;
@@ -2708,7 +2745,7 @@ function useTurnNavigation({
2708
2745
  beforeSeek
2709
2746
  };
2710
2747
  });
2711
- useEffect5(() => {
2748
+ useEffect6(() => {
2712
2749
  const load = callbacks.current.loadTurnIndex;
2713
2750
  indexSeq.current += 1;
2714
2751
  const seq = indexSeq.current;
@@ -2828,7 +2865,7 @@ function useTurnNavigation({
2828
2865
  }
2829
2866
 
2830
2867
  // src/components/TurnNavRail.tsx
2831
- import { useCallback as useCallback6, useEffect as useEffect6, useLayoutEffect as useLayoutEffect2, useRef as useRef6, useState as useState6 } from "react";
2868
+ import { useCallback as useCallback6, useEffect as useEffect7, useLayoutEffect as useLayoutEffect2, useRef as useRef7, useState as useState7 } from "react";
2832
2869
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
2833
2870
  var PANEL_MAX_HEIGHT = 448;
2834
2871
  var PANEL_MAX_WIDTH = 320;
@@ -2848,11 +2885,11 @@ function TurnNavRail({
2848
2885
  failedTurnId,
2849
2886
  onSelectTurn
2850
2887
  }) {
2851
- const [open2, setOpen] = useState6(false);
2852
- const [hoveredEntryId, setHoveredEntryId] = useState6(null);
2853
- const markersRef = useRef6(null);
2854
- const listRef = useRef6(null);
2855
- useEffect6(() => {
2888
+ const [open2, setOpen] = useState7(false);
2889
+ const [hoveredEntryId, setHoveredEntryId] = useState7(null);
2890
+ const markersRef = useRef7(null);
2891
+ const listRef = useRef7(null);
2892
+ useEffect7(() => {
2856
2893
  if (!activeTurnId) return;
2857
2894
  const marker = Array.from(
2858
2895
  markersRef.current?.querySelectorAll("[data-nav-entry-id]") ?? []
@@ -2878,7 +2915,7 @@ function TurnNavRail({
2878
2915
  if (!open2) return;
2879
2916
  clampPanel();
2880
2917
  }, [open2, items, clampPanel]);
2881
- useEffect6(() => {
2918
+ useEffect7(() => {
2882
2919
  if (!open2) return;
2883
2920
  const container = clippingAncestor(markersRef.current);
2884
2921
  if (!container || typeof ResizeObserver === "undefined") return;
@@ -3412,13 +3449,13 @@ var X = createLucideIcon("X", [
3412
3449
  ]);
3413
3450
 
3414
3451
  // src/components/AgentChat.tsx
3415
- import { useCallback as useCallback30, useEffect as useEffect26, useMemo as useMemo18, useRef as useRef28, useState as useState35 } from "react";
3452
+ import { useCallback as useCallback30, useEffect as useEffect28, useMemo as useMemo18, useRef as useRef30, useState as useState37 } from "react";
3416
3453
 
3417
3454
  // src/components/SessionPluginSelector.tsx
3418
- import { useEffect as useEffect14, useState as useState19 } from "react";
3455
+ import { useEffect as useEffect15, useState as useState20 } from "react";
3419
3456
 
3420
3457
  // src/components/SessionPluginConfigDialog.tsx
3421
- import { useEffect as useEffect12, useRef as useRef12, useState as useState17 } from "react";
3458
+ import { useEffect as useEffect13, useRef as useRef13, useState as useState18 } from "react";
3422
3459
 
3423
3460
  // ../../node_modules/.pnpm/@cfworker+json-schema@4.1.1/node_modules/@cfworker/json-schema/dist/esm/deep-compare-strict.js
3424
3461
  function deepCompareStrict(a, b2) {
@@ -9158,7 +9195,7 @@ function toFieldPathId(fieldPath, globalFormOptions, parentPath, isMultiValue) {
9158
9195
 
9159
9196
  // ../../node_modules/.pnpm/@rjsf+utils@6.10.0_react@19.2.4/node_modules/@rjsf/utils/lib/useAltDateWidgetProps.js
9160
9197
  import { jsx as _jsx3 } from "react/jsx-runtime";
9161
- import { useCallback as useCallback7, useEffect as useEffect7, useMemo as useMemo3, useState as useState7 } from "react";
9198
+ import { useCallback as useCallback7, useEffect as useEffect8, useMemo as useMemo3, useState as useState8 } from "react";
9162
9199
  function readyForChange(state) {
9163
9200
  return Object.values(state).every((value) => value !== -1);
9164
9201
  }
@@ -9171,8 +9208,8 @@ function DateElement(props) {
9171
9208
  }
9172
9209
  function useAltDateWidgetProps(props) {
9173
9210
  const { time: time5 = false, disabled = false, readonly: readonly2 = false, options, onChange, value } = props;
9174
- const [state, setState] = useState7(parseDateString(value, time5));
9175
- useEffect7(() => {
9211
+ const [state, setState] = useState8(parseDateString(value, time5));
9212
+ useEffect8(() => {
9176
9213
  setState(parseDateString(value, time5));
9177
9214
  }, [time5, value]);
9178
9215
  const handleChange = useCallback7((property, newValue) => {
@@ -9206,9 +9243,9 @@ function useAltDateWidgetProps(props) {
9206
9243
  }
9207
9244
 
9208
9245
  // ../../node_modules/.pnpm/@rjsf+utils@6.10.0_react@19.2.4/node_modules/@rjsf/utils/lib/useDeepCompareMemo.js
9209
- import { useRef as useRef7 } from "react";
9246
+ import { useRef as useRef8 } from "react";
9210
9247
  function useDeepCompareMemo(newValue) {
9211
- const valueRef = useRef7(newValue);
9248
+ const valueRef = useRef8(newValue);
9212
9249
  if (!deepEquals_default(newValue, valueRef.current)) {
9213
9250
  valueRef.current = newValue;
9214
9251
  }
@@ -9402,7 +9439,7 @@ var TranslatableString;
9402
9439
 
9403
9440
  // ../../node_modules/.pnpm/@rjsf+core@6.10.0_@rjsf+utils@6.10.0_react@19.2.4__react@19.2.4_vue@3.5.40_typescript@5.9.3_/node_modules/@rjsf/core/lib/components/fields/ArrayField.js
9404
9441
  import { jsx as _jsx4 } from "react/jsx-runtime";
9405
- import { memo, useCallback as useCallback9, useMemo as useMemo5, useRef as useRef8, useState as useState8 } from "react";
9442
+ import { memo, useCallback as useCallback9, useMemo as useMemo5, useRef as useRef9, useState as useState9 } from "react";
9406
9443
  var rowIdCounter = 0;
9407
9444
  function generateRowId() {
9408
9445
  rowIdCounter += 1;
@@ -9728,7 +9765,7 @@ function FixedArray(props) {
9728
9765
  }
9729
9766
  function useKeyedFormData(formData = []) {
9730
9767
  const newHash = useMemo5(() => hashObject(formData), [formData]);
9731
- const [state, setState] = useState8(() => ({
9768
+ const [state, setState] = useState9(() => ({
9732
9769
  formDataHash: newHash,
9733
9770
  keyedFormData: generateKeyedFormData(formData)
9734
9771
  }));
@@ -9755,9 +9792,9 @@ function ArrayField(props) {
9755
9792
  const { schema, uiSchema, errorSchema, fieldPathId, registry: registry2, formData, onChange } = props;
9756
9793
  const { globalFormOptions, schemaUtils, translateString } = registry2;
9757
9794
  const { keyedFormData, updateKeyedFormData } = useKeyedFormData(formData);
9758
- const keyedFormDataRef = useRef8(keyedFormData);
9795
+ const keyedFormDataRef = useRef9(keyedFormData);
9759
9796
  keyedFormDataRef.current = keyedFormData;
9760
- const errorSchemaRef = useRef8(errorSchema);
9797
+ const errorSchemaRef = useRef9(errorSchema);
9761
9798
  errorSchemaRef.current = errorSchema;
9762
9799
  const childFieldPathId = props.childFieldPathId ?? fieldPathId;
9763
9800
  const handleAddItem = useCallback9((event, index3) => {
@@ -9975,9 +10012,9 @@ var BooleanField_default = BooleanField;
9975
10012
 
9976
10013
  // ../../node_modules/.pnpm/@rjsf+core@6.10.0_@rjsf+utils@6.10.0_react@19.2.4__react@19.2.4_vue@3.5.40_typescript@5.9.3_/node_modules/@rjsf/core/lib/components/fields/CyclicSchemaField.js
9977
10014
  import { jsx as _jsx6 } from "react/jsx-runtime";
9978
- import { useState as useState9 } from "react";
10015
+ import { useState as useState10 } from "react";
9979
10016
  function CyclicSchemaField(props) {
9980
- const [expanded, setExpanded] = useState9(false);
10017
+ const [expanded, setExpanded] = useState10(false);
9981
10018
  const { name, registry: registry2, schema, uiSchema, fieldPathId } = props;
9982
10019
  const { globalUiOptions } = registry2;
9983
10020
  const uiOptions = getUiOptions(uiSchema, globalUiOptions);
@@ -9992,7 +10029,7 @@ function CyclicSchemaField(props) {
9992
10029
 
9993
10030
  // ../../node_modules/.pnpm/@rjsf+core@6.10.0_@rjsf+utils@6.10.0_react@19.2.4__react@19.2.4_vue@3.5.40_typescript@5.9.3_/node_modules/@rjsf/core/lib/components/fields/FallbackField.js
9994
10031
  import { jsx as _jsx7 } from "react/jsx-runtime";
9995
- import { useMemo as useMemo6, useState as useState10 } from "react";
10032
+ import { useMemo as useMemo6, useState as useState11 } from "react";
9996
10033
  function getFallbackTypeSelectionSchema(title) {
9997
10034
  return {
9998
10035
  type: "string",
@@ -10028,7 +10065,7 @@ function castToNewType(formData, newType) {
10028
10065
  function FallbackField(props) {
10029
10066
  const { id, formData, displayLabel = true, schema, name, uiSchema, required: required2, disabled = false, readonly: readonly2 = false, onBlur, onFocus, registry: registry2, fieldPathId, onChange, errorSchema } = props;
10030
10067
  const { translateString, fields: fields2, globalFormOptions } = registry2;
10031
- const [type, setType] = useState10(getTypeOfFormData(formData));
10068
+ const [type, setType] = useState11(getTypeOfFormData(formData));
10032
10069
  const uiOptions = getUiOptions(uiSchema);
10033
10070
  const typeSelectorInnerFieldPathId = useDeepCompareMemo(toFieldPathId("__internal_type_selector", globalFormOptions, fieldPathId));
10034
10071
  const schemaTitle = translateString(TranslatableString.Type);
@@ -10371,7 +10408,7 @@ function LayoutHeaderField(props) {
10371
10408
 
10372
10409
  // ../../node_modules/.pnpm/@rjsf+core@6.10.0_@rjsf+utils@6.10.0_react@19.2.4__react@19.2.4_vue@3.5.40_typescript@5.9.3_/node_modules/@rjsf/core/lib/components/fields/LayoutMultiSchemaField.js
10373
10410
  import { jsx as _jsx10 } from "react/jsx-runtime";
10374
- import { useState as useState11, useEffect as useEffect8 } from "react";
10411
+ import { useState as useState12, useEffect as useEffect9 } from "react";
10375
10412
  function getSelectedOption(options, selectorField, value) {
10376
10413
  const defaultValue = "!@#!@$@#$!@$#";
10377
10414
  const schemaOptions = options.map(({ schema }) => schema);
@@ -10398,7 +10435,7 @@ function computeEnumOptions(schema, options, schemaUtils, uiSchema, formData) {
10398
10435
  function LayoutMultiSchemaField(props) {
10399
10436
  const { name, baseType, disabled = false, formData, fieldPathId, onBlur, onChange, options, onFocus, registry: registry2, uiSchema, schema, autofocus, readonly: readonly2, required: required2, errorSchema, hideError = false } = props;
10400
10437
  const { widgets: widgets2, schemaUtils, globalUiOptions } = registry2;
10401
- const [enumOptions, setEnumOptions] = useState11(computeEnumOptions(schema, options, schemaUtils, uiSchema, formData));
10438
+ const [enumOptions, setEnumOptions] = useState12(computeEnumOptions(schema, options, schemaUtils, uiSchema, formData));
10402
10439
  const id = fieldPathId[ID_KEY];
10403
10440
  const discriminator = getDiscriminatorFieldFromSchema(schema);
10404
10441
  const FieldErrorTemplate2 = getTemplate("FieldErrorTemplate", registry2, options);
@@ -10407,7 +10444,7 @@ function LayoutMultiSchemaField(props) {
10407
10444
  const optionsHash = hashObject(options);
10408
10445
  const uiSchemaHash = uiSchema ? hashObject(uiSchema) : "";
10409
10446
  const formDataHash = formData ? hashObject(formData) : "";
10410
- useEffect8(() => {
10447
+ useEffect9(() => {
10411
10448
  setEnumOptions(computeEnumOptions(schema, options, schemaUtils, uiSchema, formData));
10412
10449
  }, [schemaHash, optionsHash, schemaUtils, uiSchemaHash, formDataHash]);
10413
10450
  const { widget = discriminator ? "radio" : "select", title = "", placeholder = "", optionsSchemaSelector: selectorField = discriminator, hideError: uiSchemaHideError, ...uiOptions } = getUiOptions(uiSchema);
@@ -10446,7 +10483,7 @@ function LayoutMultiSchemaField(props) {
10446
10483
 
10447
10484
  // ../../node_modules/.pnpm/@rjsf+core@6.10.0_@rjsf+utils@6.10.0_react@19.2.4__react@19.2.4_vue@3.5.40_typescript@5.9.3_/node_modules/@rjsf/core/lib/components/fields/MultiSchemaField.js
10448
10485
  import { jsx as _jsx11 } from "react/jsx-runtime";
10449
- import { useCallback as useCallback11, useEffect as useEffect9, useMemo as useMemo7, useRef as useRef9, useState as useState12 } from "react";
10486
+ import { useCallback as useCallback11, useEffect as useEffect10, useMemo as useMemo7, useRef as useRef10, useState as useState13 } from "react";
10450
10487
  function AnyOfField(props) {
10451
10488
  const { name, disabled = false, errorSchema, formData, fieldPathId, onBlur, onChange, onFocus, options, readonly: readonly2, registry: registry2, required: required2 = false, schema, uiSchema } = props;
10452
10489
  const { schemaUtils } = registry2;
@@ -10456,14 +10493,14 @@ function AnyOfField(props) {
10456
10493
  // oxlint-disable-next-line react-hooks/exhaustive-deps -- formDataHash is the value-stable proxy for formData
10457
10494
  [options, schemaUtils, formDataHash]
10458
10495
  );
10459
- const [selectedOption, setSelectedOption] = useState12(() => {
10496
+ const [selectedOption, setSelectedOption] = useState13(() => {
10460
10497
  const discriminator = getDiscriminatorFieldFromSchema(schema);
10461
10498
  return schemaUtils.getClosestMatchingOption(formData, retrievedOptions, 0, discriminator);
10462
10499
  });
10463
- const skipNextOptionRecalculation = useRef9(false);
10464
- const prevFormDataRef = useRef9(formData);
10465
- const prevFieldIdRef = useRef9(fieldPathId.$id);
10466
- useEffect9(() => {
10500
+ const skipNextOptionRecalculation = useRef10(false);
10501
+ const prevFormDataRef = useRef10(formData);
10502
+ const prevFieldIdRef = useRef10(fieldPathId.$id);
10503
+ useEffect10(() => {
10467
10504
  const prevFormData = prevFormDataRef.current;
10468
10505
  const prevFieldId = prevFieldIdRef.current;
10469
10506
  prevFormDataRef.current = formData;
@@ -10561,10 +10598,10 @@ function AnyOfField(props) {
10561
10598
  var MultiSchemaField_default = AnyOfField;
10562
10599
 
10563
10600
  // ../../node_modules/.pnpm/@rjsf+core@6.10.0_@rjsf+utils@6.10.0_react@19.2.4__react@19.2.4_vue@3.5.40_typescript@5.9.3_/node_modules/@rjsf/core/lib/components/fields/NullField.js
10564
- import { useEffect as useEffect10 } from "react";
10601
+ import { useEffect as useEffect11 } from "react";
10565
10602
  function NullField(props) {
10566
10603
  const { formData, onChange, fieldPathId } = props;
10567
- useEffect10(() => {
10604
+ useEffect11(() => {
10568
10605
  if (formData === void 0) {
10569
10606
  onChange(null, fieldPathId.path);
10570
10607
  }
@@ -10575,12 +10612,12 @@ var NullField_default = NullField;
10575
10612
 
10576
10613
  // ../../node_modules/.pnpm/@rjsf+core@6.10.0_@rjsf+utils@6.10.0_react@19.2.4__react@19.2.4_vue@3.5.40_typescript@5.9.3_/node_modules/@rjsf/core/lib/components/fields/NumberField.js
10577
10614
  import { jsx as _jsx12 } from "react/jsx-runtime";
10578
- import { useState as useState13, useCallback as useCallback12 } from "react";
10615
+ import { useState as useState14, useCallback as useCallback12 } from "react";
10579
10616
  var trailingCharMatcherWithPrefix = /\.([0-9]*0)*$/;
10580
10617
  var trailingCharMatcher = /[0.]0*$/;
10581
10618
  function NumberField(props) {
10582
10619
  const { registry: registry2, onChange, formData, value: initialValue } = props;
10583
- const [lastValue, setLastValue] = useState13(initialValue);
10620
+ const [lastValue, setLastValue] = useState14(initialValue);
10584
10621
  const { StringField: StringField2 } = registry2.fields;
10585
10622
  const separator = getDecimalSeparator();
10586
10623
  const escapedSeparator = separator === "." ? "\\." : separator;
@@ -10615,7 +10652,7 @@ var NumberField_default = NumberField;
10615
10652
 
10616
10653
  // ../../node_modules/.pnpm/@rjsf+core@6.10.0_@rjsf+utils@6.10.0_react@19.2.4__react@19.2.4_vue@3.5.40_typescript@5.9.3_/node_modules/@rjsf/core/lib/components/fields/ObjectField.js
10617
10654
  import { jsx as _jsx13, jsxs as _jsxs } from "react/jsx-runtime";
10618
- import { memo as memo2, useCallback as useCallback13, useMemo as useMemo9, useRef as useRef11, useState as useState14 } from "react";
10655
+ import { memo as memo2, useCallback as useCallback13, useMemo as useMemo9, useRef as useRef12, useState as useState15 } from "react";
10619
10656
 
10620
10657
  // ../../node_modules/.pnpm/markdown-to-jsx@9.10.2_react@19.2.4_vue@3.5.40_typescript@5.9.3_/node_modules/markdown-to-jsx/dist/react.js
10621
10658
  import * as i0 from "react";
@@ -13750,7 +13787,7 @@ function getAdditionalPropertyOrder(schemaProperties) {
13750
13787
  }
13751
13788
  function ObjectFieldPropertyFn(props) {
13752
13789
  const { fieldPathId, schema, registry: registry2, uiSchema, errorSchema, formData, onChange, onBlur, onFocus, disabled, readonly: readonly2, required: required2, hideError, propertyName, handleKeyRename, handleRemoveProperty, addedByAdditionalProperties } = props;
13753
- const [wasPropertyKeyModified, setWasPropertyKeyModified] = useState14(false);
13790
+ const [wasPropertyKeyModified, setWasPropertyKeyModified] = useState15(false);
13754
13791
  const { globalFormOptions, fields: fields2 } = registry2;
13755
13792
  const { SchemaField: SchemaField2 } = fields2;
13756
13793
  const innerFieldIdPathId = useDeepCompareMemo(toFieldPathId(propertyName, globalFormOptions, fieldPathId.path));
@@ -13781,14 +13818,14 @@ function ObjectField(props) {
13781
13818
  const { schema: rawSchema, uiSchema = {}, formData, errorSchema, fieldPathId, name, required: required2 = false, disabled, readonly: readonly2, hideError, onBlur, onFocus, onChange, registry: registry2, title } = props;
13782
13819
  const { fields: fields2, schemaUtils, translateString, globalUiOptions } = registry2;
13783
13820
  const { OptionalDataControlsField: OptionalDataControlsField2 } = fields2;
13784
- const formDataRef = useRef11(formData);
13821
+ const formDataRef = useRef12(formData);
13785
13822
  formDataRef.current = formData;
13786
13823
  const schema = useMemo9(() => schemaUtils.retrieveSchema(rawSchema, formData, true), [schemaUtils, rawSchema, formData]);
13787
13824
  const uiOptions = useMemo9(() => getUiOptions(uiSchema, globalUiOptions), [uiSchema, globalUiOptions]);
13788
13825
  const schemaProperties = useMemo9(() => schema.properties ?? {}, [schema.properties]);
13789
13826
  const childFieldPathId = props.childFieldPathId ?? fieldPathId;
13790
- const lastRenamedProperty = useRef11({ previousKey: "", currentKey: void 0 });
13791
- const [additionalPropertyOrder, setAdditionalPropertyOrder] = useState14(() => getAdditionalPropertyOrder(schemaProperties));
13827
+ const lastRenamedProperty = useRef12({ previousKey: "", currentKey: void 0 });
13828
+ const [additionalPropertyOrder, setAdditionalPropertyOrder] = useState15(() => getAdditionalPropertyOrder(schemaProperties));
13792
13829
  const definedPropertyOrder = useMemo9(() => {
13793
13830
  const additionalPropertySet = new Set(getAdditionalPropertyOrder(schemaProperties));
13794
13831
  return Object.keys(schemaProperties).filter((property) => !additionalPropertySet.has(property));
@@ -15743,7 +15780,7 @@ var Form = class _Form extends Component {
15743
15780
  };
15744
15781
 
15745
15782
  // src/components/SessionPluginConfigForm.tsx
15746
- import { isValidElement, useMemo as useMemo10, useState as useState15 } from "react";
15783
+ import { isValidElement, useMemo as useMemo10, useState as useState16 } from "react";
15747
15784
 
15748
15785
  // src/components/plugin-config-schema.ts
15749
15786
  function asSchema(value) {
@@ -16138,10 +16175,10 @@ function SessionPluginConfigForm({
16138
16175
  onSubmit,
16139
16176
  onCancel
16140
16177
  }) {
16141
- const [initial] = useState15(() => createConfigDraft(config2));
16142
- const [values, setValues] = useState15(initial.values);
16143
- const [removed] = useState15(() => /* @__PURE__ */ new Set());
16144
- const [draftFailure, setDraftFailure] = useState15(null);
16178
+ const [initial] = useState16(() => createConfigDraft(config2));
16179
+ const [values, setValues] = useState16(initial.values);
16180
+ const [removed] = useState16(() => /* @__PURE__ */ new Set());
16181
+ const [draftFailure, setDraftFailure] = useState16(null);
16145
16182
  const support = useMemo10(() => formSupport(config2.schema), [config2.schema]);
16146
16183
  const schema = useMemo10(() => {
16147
16184
  try {
@@ -16251,7 +16288,7 @@ function SessionPluginConfigForm({
16251
16288
  }
16252
16289
 
16253
16290
  // src/components/SessionPluginIcon.tsx
16254
- import { useEffect as useEffect11, useState as useState16 } from "react";
16291
+ import { useEffect as useEffect12, useState as useState17 } from "react";
16255
16292
  import { jsx as jsx4 } from "react/jsx-runtime";
16256
16293
  function sessionPluginLabel(plugin) {
16257
16294
  const display = typeof plugin.display_name === "string" ? plugin.display_name.trim() : "";
@@ -16277,9 +16314,9 @@ function iconBlob(client, sessionId, name, token) {
16277
16314
  return pending;
16278
16315
  }
16279
16316
  function SessionPluginIcon({ client, sessionId, plugin, size: size4 = 20, shape = "rounded", className }) {
16280
- const [url2, setUrl] = useState16(null);
16317
+ const [url2, setUrl] = useState17(null);
16281
16318
  const token = plugin.icon;
16282
- useEffect11(() => {
16319
+ useEffect12(() => {
16283
16320
  setUrl(null);
16284
16321
  if (!token) return;
16285
16322
  let alive = true;
@@ -16348,17 +16385,17 @@ function ConfigDialogState({
16348
16385
  onSaved,
16349
16386
  onClose
16350
16387
  }) {
16351
- const [config2, setConfig] = useState17(null);
16352
- const [loading, setLoading] = useState17(true);
16353
- const [loadFailure, setLoadFailure] = useState17(null);
16354
- const [saving, setSaving] = useState17(false);
16355
- const [failure, setFailure] = useState17(null);
16356
- const [fieldErrors, setFieldErrors] = useState17([]);
16357
- const [formVersion, setFormVersion] = useState17(0);
16358
- const alive = useRef12(true);
16359
- const generation = useRef12(0);
16360
- const dialog = useRef12(null);
16361
- useEffect12(() => {
16388
+ const [config2, setConfig] = useState18(null);
16389
+ const [loading, setLoading] = useState18(true);
16390
+ const [loadFailure, setLoadFailure] = useState18(null);
16391
+ const [saving, setSaving] = useState18(false);
16392
+ const [failure, setFailure] = useState18(null);
16393
+ const [fieldErrors, setFieldErrors] = useState18([]);
16394
+ const [formVersion, setFormVersion] = useState18(0);
16395
+ const alive = useRef13(true);
16396
+ const generation = useRef13(0);
16397
+ const dialog = useRef13(null);
16398
+ useEffect13(() => {
16362
16399
  const element2 = dialog.current;
16363
16400
  if (!element2 || element2.open) return;
16364
16401
  if (typeof element2.showModal === "function") element2.showModal();
@@ -16382,7 +16419,7 @@ function ConfigDialogState({
16382
16419
  if (alive.current && generation.current === current) setLoading(false);
16383
16420
  }
16384
16421
  };
16385
- useEffect12(() => {
16422
+ useEffect13(() => {
16386
16423
  alive.current = true;
16387
16424
  setConfig(null);
16388
16425
  setFailure(null);
@@ -16637,7 +16674,7 @@ function PluginConnectorList({
16637
16674
  }
16638
16675
 
16639
16676
  // src/components/use-session-plugin-activation.ts
16640
- import { useCallback as useCallback25, useEffect as useEffect13, useMemo as useMemo11, useRef as useRef13, useState as useState18 } from "react";
16677
+ import { useCallback as useCallback25, useEffect as useEffect14, useMemo as useMemo11, useRef as useRef14, useState as useState19 } from "react";
16641
16678
 
16642
16679
  // src/components/plugin-connector.ts
16643
16680
  function catalogToConnectorItems(catalog) {
@@ -16698,23 +16735,23 @@ function useSessionPluginActivation({
16698
16735
  sessionId,
16699
16736
  onChange
16700
16737
  }) {
16701
- const [plugins, setPlugins] = useState18([]);
16702
- const [catalog, setCatalog] = useState18(null);
16703
- const [loading, setLoading] = useState18(false);
16704
- const [listError, setListError] = useState18(false);
16705
- const [mutationError, setMutationError] = useState18(false);
16706
- const [inFlight, setInFlight] = useState18({});
16707
- const [configuring, setConfiguring] = useState18(null);
16708
- const alive = useRef13(true);
16709
- const generation = useRef13(0);
16710
- const mutationGenerations = useRef13(/* @__PURE__ */ new Map());
16711
- const desiredActivations = useRef13(/* @__PURE__ */ new Map());
16712
- const pendingMutations = useRef13(/* @__PURE__ */ new Map());
16713
- const submittedActivations = useRef13(/* @__PURE__ */ new Set());
16714
- const serverActive = useRef13(/* @__PURE__ */ new Set());
16715
- const lifetime = useRef13(0);
16716
- const request = useRef13(null);
16717
- const [desiredVersion, setDesiredVersion] = useState18(0);
16738
+ const [plugins, setPlugins] = useState19([]);
16739
+ const [catalog, setCatalog] = useState19(null);
16740
+ const [loading, setLoading] = useState19(false);
16741
+ const [listError, setListError] = useState19(false);
16742
+ const [mutationError, setMutationError] = useState19(false);
16743
+ const [inFlight, setInFlight] = useState19({});
16744
+ const [configuring, setConfiguring] = useState19(null);
16745
+ const alive = useRef14(true);
16746
+ const generation = useRef14(0);
16747
+ const mutationGenerations = useRef14(/* @__PURE__ */ new Map());
16748
+ const desiredActivations = useRef14(/* @__PURE__ */ new Map());
16749
+ const pendingMutations = useRef14(/* @__PURE__ */ new Map());
16750
+ const submittedActivations = useRef14(/* @__PURE__ */ new Set());
16751
+ const serverActive = useRef14(/* @__PURE__ */ new Set());
16752
+ const lifetime = useRef14(0);
16753
+ const request = useRef14(null);
16754
+ const [desiredVersion, setDesiredVersion] = useState19(0);
16718
16755
  const setDesired = useCallback25((name, value) => {
16719
16756
  if (value === null) {
16720
16757
  if (!desiredActivations.current.delete(name)) return;
@@ -16744,7 +16781,7 @@ function useSessionPluginActivation({
16744
16781
  return rest;
16745
16782
  });
16746
16783
  }, []);
16747
- useEffect13(() => {
16784
+ useEffect14(() => {
16748
16785
  alive.current = true;
16749
16786
  setPlugins([]);
16750
16787
  setCatalog(null);
@@ -16973,7 +17010,7 @@ function SessionPluginSelector(props) {
16973
17010
  return /* @__PURE__ */ jsx7(PluginSelectorState, { ...props }, props.sessionId);
16974
17011
  }
16975
17012
  function PluginSelectorState({ client, sessionId, className, side = "bottom", onChange }) {
16976
- const [open2, setOpen] = useState19(false);
17013
+ const [open2, setOpen] = useState20(false);
16977
17014
  return /* @__PURE__ */ jsxs5("div", { className: `relative text-xs ${className ?? ""}`, children: [
16978
17015
  /* @__PURE__ */ jsx7(
16979
17016
  "button",
@@ -16997,7 +17034,7 @@ function PluginSelectorList({
16997
17034
  }) {
16998
17035
  const controller = useSessionPluginActivation({ client, sessionId, onChange });
16999
17036
  const { reload } = controller;
17000
- useEffect14(() => {
17037
+ useEffect15(() => {
17001
17038
  reload();
17002
17039
  }, [reload]);
17003
17040
  return /* @__PURE__ */ jsxs5(
@@ -17037,7 +17074,7 @@ import {
17037
17074
  queuePauseReasonLabel,
17038
17075
  queuedMessageStatusLabel
17039
17076
  } from "@blade-hq/agent-client";
17040
- import { useContext as useContext3, useLayoutEffect as useLayoutEffect3, useRef as useRef14, useState as useState20 } from "react";
17077
+ import { useContext as useContext3, useLayoutEffect as useLayoutEffect3, useRef as useRef15, useState as useState21 } from "react";
17041
17078
 
17042
17079
  // ../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
17043
17080
  function r2(e2) {
@@ -20287,19 +20324,19 @@ function SessionQueuePanel({
20287
20324
  onVisibleChange,
20288
20325
  mergesWithInputBelow: mergesWithInputBelowProp
20289
20326
  }) {
20290
- const [collapsed, setCollapsed] = useState20(false);
20291
- const [editing, setEditing] = useState20(null);
20292
- const [draggingId, setDraggingId] = useState20(null);
20293
- const [dropAt, setDropAt] = useState20(null);
20294
- const draggingRef = useRef14(null);
20295
- const dropRef = useRef14(null);
20296
- const requeuePending = useRef14(false);
20297
- const [requeueing, setRequeueing] = useState20(false);
20327
+ const [collapsed, setCollapsed] = useState21(false);
20328
+ const [editing, setEditing] = useState21(null);
20329
+ const [draggingId, setDraggingId] = useState21(null);
20330
+ const [dropAt, setDropAt] = useState21(null);
20331
+ const draggingRef = useRef15(null);
20332
+ const dropRef = useRef15(null);
20333
+ const requeuePending = useRef15(false);
20334
+ const [requeueing, setRequeueing] = useState21(false);
20298
20335
  const adjacency = useContext3(QueuePanelAdjacencyContext);
20299
20336
  const mergesWithInputBelow = mergesWithInputBelowProp ?? adjacency ?? true;
20300
20337
  const items = snapshot.items;
20301
20338
  const visible = isQueuePanelVisible(snapshot, notice, Boolean(editing));
20302
- const onVisibleChangeRef = useRef14(onVisibleChange);
20339
+ const onVisibleChangeRef = useRef15(onVisibleChange);
20303
20340
  onVisibleChangeRef.current = onVisibleChange;
20304
20341
  useLayoutEffect3(() => {
20305
20342
  onVisibleChangeRef.current?.(visible);
@@ -20732,7 +20769,7 @@ function ReplayMismatchPrompt({ mismatch, className }) {
20732
20769
  }
20733
20770
 
20734
20771
  // src/components/PlanUpdateBlock.tsx
20735
- import { useEffect as useEffect15, useRef as useRef15, useState as useState21 } from "react";
20772
+ import { useEffect as useEffect16, useRef as useRef16, useState as useState22 } from "react";
20736
20773
 
20737
20774
  // src/components/display-utils.ts
20738
20775
  var TOOL_NAME_ALIASES = {
@@ -20845,10 +20882,10 @@ function PlanUpdateBlock({
20845
20882
  }) {
20846
20883
  const updateKey = `${toolCall.id}:${toolCall.arguments}`;
20847
20884
  const revealKey = autoReveal ? updateKey : null;
20848
- const [collapsed, setCollapsed] = useState21(!autoReveal);
20849
- const collapseTimerRef = useRef15(null);
20885
+ const [collapsed, setCollapsed] = useState22(!autoReveal);
20886
+ const collapseTimerRef = useRef16(null);
20850
20887
  const data = parsePlanUpdate(toolCall.arguments);
20851
- useEffect15(() => {
20888
+ useEffect16(() => {
20852
20889
  if (!revealKey) return;
20853
20890
  if (collapseTimerRef.current) clearTimeout(collapseTimerRef.current);
20854
20891
  setCollapsed(false);
@@ -20857,7 +20894,7 @@ function PlanUpdateBlock({
20857
20894
  collapseTimerRef.current = null;
20858
20895
  }, PLAN_AUTO_COLLAPSE_MS);
20859
20896
  }, [revealKey]);
20860
- useEffect15(
20897
+ useEffect16(
20861
20898
  () => () => {
20862
20899
  if (collapseTimerRef.current) clearTimeout(collapseTimerRef.current);
20863
20900
  },
@@ -20945,9 +20982,9 @@ function CurrentPlanPanel({
20945
20982
  className
20946
20983
  }) {
20947
20984
  const { current, updating } = getPlanUpdateDisplayState(messages);
20948
- const revealBaselinesRef = useRef15(/* @__PURE__ */ new Map([[sessionId, revealRevision]]));
20985
+ const revealBaselinesRef = useRef16(/* @__PURE__ */ new Map([[sessionId, revealRevision]]));
20949
20986
  const autoReveal = (revealBaselinesRef.current.get(sessionId) ?? 0) !== revealRevision;
20950
- useEffect15(() => {
20987
+ useEffect16(() => {
20951
20988
  if (!current) return;
20952
20989
  revealBaselinesRef.current.set(sessionId, revealRevision);
20953
20990
  }, [current, revealRevision, sessionId]);
@@ -20971,7 +21008,7 @@ function CurrentPlanPanel({
20971
21008
 
20972
21009
  // src/components/ChatSurface.tsx
20973
21010
  import { chatErrorForDisplay as chatErrorForDisplay2 } from "@blade-hq/agent-client";
20974
- import { useMemo as useMemo17, useState as useState34 } from "react";
21011
+ import { useMemo as useMemo17, useState as useState36 } from "react";
20975
21012
 
20976
21013
  // src/lib/random-id.ts
20977
21014
  function randomId() {
@@ -20991,6 +21028,7 @@ function randomId() {
20991
21028
 
20992
21029
  // src/components/McpAppCard.tsx
20993
21030
  import { BladeApiError } from "@blade-hq/agent-client";
21031
+ import { createContext as createContext4, useContext as useContext4, useEffect as useEffect18, useRef as useRef18, useState as useState24 } from "react";
20994
21032
 
20995
21033
  // ../../node_modules/.pnpm/@modelcontextprotocol+client@2.0.0/node_modules/@modelcontextprotocol/client/dist/chunk-Br0eD_fh.mjs
20996
21034
  var __create = Object.create;
@@ -45838,10 +45876,9 @@ function SF(G, Q) {
45838
45876
  return JSON.stringify(G) === JSON.stringify(Q);
45839
45877
  }
45840
45878
 
45841
- // src/components/McpAppCard.tsx
45842
- import { createContext as createContext4, useContext as useContext4, useEffect as useEffect16, useLayoutEffect as useLayoutEffect4, useRef as useRef16, useState as useState22 } from "react";
45879
+ // src/components/McpAppFrame.tsx
45880
+ import { useEffect as useEffect17, useLayoutEffect as useLayoutEffect4, useRef as useRef17, useState as useState23 } from "react";
45843
45881
  import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
45844
- var McpAppMessageContext = createContext4(null);
45845
45882
  function securedHtml(archive) {
45846
45883
  const ui = archive.resourceMeta.ui;
45847
45884
  const csp = ui?.csp ?? {};
@@ -45876,57 +45913,206 @@ function securedHtml(archive) {
45876
45913
  doc.head.prepend(meta3);
45877
45914
  return `<!doctype html>${doc.documentElement.outerHTML}`;
45878
45915
  }
45879
- function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: suppliedOnMessage }) {
45880
- const contextClient = useOptionalBladeClient();
45881
- const contextMessage = useContext4(McpAppMessageContext);
45882
- const client = suppliedClient ?? contextClient;
45883
- const onMessage = suppliedOnMessage ?? contextMessage;
45884
- const onMessageRef = useRef16(onMessage);
45885
- onMessageRef.current = onMessage;
45886
- const frame = useRef16(null);
45887
- const panel = useRef16(null);
45888
- const bridgeRef = useRef16(null);
45889
- const [html, setHtml] = useState22();
45890
- const [title, setTitle] = useState22("\u5DE5\u5177\u754C\u9762");
45891
- const [error61, setError] = useState22(null);
45892
- const [ready, setReady] = useState22(false);
45893
- const [expanded, setExpanded] = useState22(false);
45894
- const [height, setHeight] = useState22(360);
45916
+ function McpAppFrame(props) {
45917
+ const { html: sourceHtml, resourceMeta, title = "\u5DE5\u5177\u754C\u9762" } = props;
45918
+ const callbacks = useRef17(props);
45919
+ callbacks.current = props;
45920
+ const frame = useRef17(null);
45921
+ const panel = useRef17(null);
45922
+ const bridgeRef = useRef17(null);
45923
+ const [html, setHtml] = useState23();
45924
+ const [failure, setError] = useState23(null);
45925
+ const error61 = props.error ?? failure;
45926
+ const [ready, setReady] = useState23(false);
45927
+ const [expanded, setExpanded] = useState23(false);
45928
+ const [height, setHeight] = useState23(360);
45895
45929
  useLayoutEffect4(() => {
45896
45930
  const dialog = panel.current;
45897
45931
  if (!dialog) return;
45898
- dialog.close();
45899
- if (expanded) dialog.showModal();
45900
- else dialog.show();
45932
+ if (typeof dialog.close === "function") dialog.close();
45933
+ else dialog.removeAttribute("open");
45934
+ const show = expanded ? dialog.showModal : dialog.show;
45935
+ if (typeof show === "function") show.call(dialog);
45936
+ else dialog.setAttribute("open", "");
45901
45937
  }, [expanded]);
45902
- useEffect16(() => {
45903
- const controller = new AbortController();
45904
- let bridge;
45905
- let disposed = false;
45906
- let offChanged;
45907
- let refreshRevision = 0;
45938
+ useEffect17(() => {
45908
45939
  setError(null);
45909
45940
  setReady(false);
45910
45941
  setHtml(void 0);
45911
45942
  setExpanded(false);
45912
45943
  setHeight(360);
45944
+ if (sourceHtml === void 0) return;
45945
+ let disposed = false;
45946
+ let bridge;
45947
+ const timer = window.setTimeout(() => {
45948
+ if (!disposed && !bridge?.getAppCapabilities()) setError("\u5E94\u7528\u8FDE\u63A5\u8D85\u65F6");
45949
+ }, 2e4);
45913
45950
  const start = async () => {
45914
- if (!client || !frame.current?.contentWindow) throw new Error("\u5E94\u7528\u4F1A\u8BDD\u4E0D\u53EF\u7528");
45915
- const archive = await client.sessions.getMcpApp(sessionId, sourceId, { signal: controller.signal });
45916
- if (disposed) return;
45917
- const secured = securedHtml(archive);
45918
- setTitle(archive.plugin);
45951
+ if (!frame.current?.contentWindow) throw new Error("\u5E94\u7528\u4F1A\u8BDD\u4E0D\u53EF\u7528");
45952
+ const secured = securedHtml({ html: sourceHtml, resourceMeta });
45919
45953
  bridge = new MF(null, { name: "Blade Agent", version: "1.0.0" }, {
45920
45954
  serverTools: {},
45921
45955
  openLinks: {}
45922
45956
  }, { hostContext: { platform: "web", displayMode: "inline", availableDisplayModes: ["inline", "fullscreen"] } });
45923
45957
  bridgeRef.current = bridge;
45924
45958
  bridge.oninitialized = () => {
45925
- if (disposed) return;
45926
- offChanged?.();
45959
+ if (disposed || !bridge) return;
45927
45960
  window.clearTimeout(timer);
45928
45961
  setError(null);
45929
45962
  setReady(true);
45963
+ callbacks.current.onReady?.(bridge);
45964
+ };
45965
+ bridge.oncalltool = (params, extra) => {
45966
+ if (disposed) throw new Error("\u5E94\u7528\u5DF2\u5173\u95ED");
45967
+ if (!callbacks.current.callTool) throw new Error("\u5F53\u524D\u4F4D\u7F6E\u4E0D\u652F\u6301");
45968
+ return callbacks.current.callTool(params, extra);
45969
+ };
45970
+ bridge.onmessage = (params, extra) => {
45971
+ if (disposed) throw new Error("\u5E94\u7528\u5DF2\u5173\u95ED");
45972
+ if (!callbacks.current.sendMessage) throw new Error("\u5F53\u524D\u4F1A\u8BDD\u4E0D\u80FD\u63A5\u6536\u5E94\u7528\u6D88\u606F");
45973
+ return callbacks.current.sendMessage(params, extra);
45974
+ };
45975
+ bridge.onupdatemodelcontext = (params, extra) => {
45976
+ if (disposed) throw new Error("\u5E94\u7528\u5DF2\u5173\u95ED");
45977
+ if (!callbacks.current.updateModelContext) throw new Error("\u5F53\u524D\u4F4D\u7F6E\u4E0D\u652F\u6301");
45978
+ return callbacks.current.updateModelContext(params, extra);
45979
+ };
45980
+ bridge.onrequestdisplaymode = async (params, extra) => {
45981
+ if (callbacks.current.requestDisplayMode) return callbacks.current.requestDisplayMode(params, extra);
45982
+ const next = params.mode === "fullscreen" ? "fullscreen" : "inline";
45983
+ setExpanded(next === "fullscreen");
45984
+ bridge?.setHostContext({ displayMode: next });
45985
+ return { mode: next };
45986
+ };
45987
+ bridge.onsizechange = (params) => {
45988
+ if (callbacks.current.sizeChange) return callbacks.current.sizeChange(params);
45989
+ if (params.height && Number.isFinite(params.height)) setHeight(Math.max(120, Math.min(1200, params.height)));
45990
+ };
45991
+ bridge.onopenlink = async (params, extra) => {
45992
+ if (callbacks.current.openLink) return callbacks.current.openLink(params, extra);
45993
+ const target = new URL(params.url);
45994
+ if (!["https:", "http:"].includes(target.protocol) || target.username || target.password) throw new Error("\u94FE\u63A5\u65E0\u6548");
45995
+ window.open(target.href, "_blank", "noopener,noreferrer");
45996
+ return {};
45997
+ };
45998
+ await bridge.connect(new c(frame.current.contentWindow, frame.current.contentWindow));
45999
+ if (!disposed) setHtml(secured);
46000
+ };
46001
+ void start().catch((error62) => {
46002
+ window.clearTimeout(timer);
46003
+ if (!disposed) setError(error62 instanceof Error ? error62.message : "\u5E94\u7528\u52A0\u8F7D\u5931\u8D25");
46004
+ });
46005
+ return () => {
46006
+ disposed = true;
46007
+ window.clearTimeout(timer);
46008
+ bridgeRef.current = null;
46009
+ void bridge?.close();
46010
+ };
46011
+ }, [sourceHtml, resourceMeta]);
46012
+ useEffect17(() => {
46013
+ let disposed = false;
46014
+ if (ready && props.toolInput) void bridgeRef.current?.sendToolInput(props.toolInput).catch((error62) => {
46015
+ if (!disposed) setError(error62 instanceof Error ? error62.message : "\u5E94\u7528\u7ED3\u679C\u5237\u65B0\u5931\u8D25");
46016
+ });
46017
+ return () => {
46018
+ disposed = true;
46019
+ };
46020
+ }, [props.toolInput, ready]);
46021
+ const nativeDialog = typeof HTMLDialogElement !== "undefined" && typeof HTMLDialogElement.prototype.showModal === "function";
46022
+ const toggle = () => {
46023
+ setExpanded(!expanded);
46024
+ bridgeRef.current?.setHostContext({ displayMode: expanded ? "inline" : "fullscreen" });
46025
+ };
46026
+ return /* @__PURE__ */ jsxs10(
46027
+ "dialog",
46028
+ {
46029
+ ref: panel,
46030
+ role: "dialog",
46031
+ "aria-modal": expanded || void 0,
46032
+ onKeyDown: (event) => {
46033
+ if (!nativeDialog && expanded && event.key === "Escape") {
46034
+ event.preventDefault();
46035
+ setExpanded(false);
46036
+ bridgeRef.current?.setHostContext({ displayMode: "inline" });
46037
+ }
46038
+ },
46039
+ onCancel: () => {
46040
+ setExpanded(false);
46041
+ bridgeRef.current?.setHostContext({ displayMode: "inline" });
46042
+ },
46043
+ className: "blade-chat-mcp-app blade-mcp-app",
46044
+ part: "mcp-app",
46045
+ style: expanded ? {
46046
+ position: "fixed",
46047
+ top: 0,
46048
+ right: 0,
46049
+ bottom: 0,
46050
+ left: "auto",
46051
+ margin: 0,
46052
+ padding: 0,
46053
+ border: 0,
46054
+ width: "min(100vw, 760px)",
46055
+ height: "100%",
46056
+ maxWidth: "none",
46057
+ maxHeight: "none",
46058
+ zIndex: 80,
46059
+ background: "white",
46060
+ boxShadow: "-4px 0 20px #0002",
46061
+ display: "flex",
46062
+ flexDirection: "column"
46063
+ } : { position: "relative", margin: 0, padding: 0, width: "100%", maxWidth: "none", maxHeight: "none", border: "1px solid #d4d4d8", borderRadius: 6, overflow: "hidden", background: "white", display: nativeDialog ? void 0 : "block" },
46064
+ children: [
46065
+ /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "8px 12px", color: "#27272a" }, children: [
46066
+ /* @__PURE__ */ jsx12("span", { children: title }),
46067
+ /* @__PURE__ */ jsx12("button", { type: "button", onClick: toggle, title: expanded ? "\u6536\u8D77" : "\u5C55\u5F00", "aria-label": expanded ? "\u6536\u8D77" : "\u5C55\u5F00", style: { width: 32, height: 32, display: "grid", placeItems: "center", background: "transparent", border: 0, padding: 0 }, children: expanded ? /* @__PURE__ */ jsx12(Minimize2, { size: 16 }) : /* @__PURE__ */ jsx12(Maximize2, { size: 16 }) })
46068
+ ] }),
46069
+ error61 ? /* @__PURE__ */ jsx12("p", { role: "alert", style: { padding: 12, color: "#b91c1c" }, children: error61 }) : !ready ? /* @__PURE__ */ jsx12("output", { style: { padding: 12 }, children: "\u6B63\u5728\u52A0\u8F7D" }) : null,
46070
+ /* @__PURE__ */ jsx12(
46071
+ "iframe",
46072
+ {
46073
+ ref: frame,
46074
+ title,
46075
+ srcDoc: html,
46076
+ sandbox: "allow-scripts allow-forms",
46077
+ referrerPolicy: "no-referrer",
46078
+ style: { width: "100%", height: expanded ? "100%" : height, flex: expanded ? 1 : void 0, border: 0 }
46079
+ }
46080
+ )
46081
+ ]
46082
+ }
46083
+ );
46084
+ }
46085
+
46086
+ // src/components/McpAppCard.tsx
46087
+ import { jsx as jsx13 } from "react/jsx-runtime";
46088
+ var McpAppMessageContext = createContext4(null);
46089
+ function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: suppliedOnMessage }) {
46090
+ const contextClient = useOptionalBladeClient();
46091
+ const contextMessage = useContext4(McpAppMessageContext);
46092
+ const client = suppliedClient ?? contextClient;
46093
+ const onMessage = suppliedOnMessage ?? contextMessage;
46094
+ const onMessageRef = useRef18(onMessage);
46095
+ onMessageRef.current = onMessage;
46096
+ const [surface, setSurface] = useState24({ resourceMeta: {} });
46097
+ const [error61, setError] = useState24(null);
46098
+ useEffect18(() => {
46099
+ const controller = new AbortController();
46100
+ let disposed = false;
46101
+ let offChanged;
46102
+ let refreshRevision = 0;
46103
+ setError(null);
46104
+ setSurface({ resourceMeta: {} });
46105
+ const timer = window.setTimeout(() => {
46106
+ if (!disposed) setError("\u5E94\u7528\u8FDE\u63A5\u8D85\u65F6");
46107
+ }, 2e4);
46108
+ const start = async () => {
46109
+ if (!client) throw new Error("\u5E94\u7528\u4F1A\u8BDD\u4E0D\u53EF\u7528");
46110
+ const archive = await client.sessions.getMcpApp(sessionId, sourceId, { signal: controller.signal });
46111
+ if (disposed) return;
46112
+ const handlers = { html: archive.html, resourceMeta: archive.resourceMeta, title: archive.plugin };
46113
+ handlers.onReady = (bridge) => {
46114
+ offChanged?.();
46115
+ setError(null);
45930
46116
  const refresh = (restoreView = false) => {
45931
46117
  const revision = ++refreshRevision;
45932
46118
  void client.sessions.getMcpApp(sessionId, sourceId, { signal: controller.signal }).then(async (latest) => {
@@ -45948,7 +46134,7 @@ function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: su
45948
46134
  };
45949
46135
  const instance = randomId();
45950
46136
  const deliveredMessages = /* @__PURE__ */ new Set();
45951
- bridge.oncalltool = async (params, extra) => {
46137
+ handlers.callTool = async (params, extra) => {
45952
46138
  if (disposed) throw new Error("\u5E94\u7528\u5DF2\u5173\u95ED");
45953
46139
  const requestId = `${instance}:${String(extra.mcpReq.id)}`;
45954
46140
  const callController = new AbortController();
@@ -45969,7 +46155,7 @@ function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: su
45969
46155
  for (const signal of signals) signal.removeEventListener("abort", abort);
45970
46156
  }
45971
46157
  };
45972
- bridge.onmessage = async ({ content: content3 }, extra) => {
46158
+ handlers.sendMessage = async ({ content: content3 }, extra) => {
45973
46159
  if (disposed || !onMessageRef.current) throw new Error("\u5F53\u524D\u4F1A\u8BDD\u4E0D\u80FD\u63A5\u6536\u5E94\u7528\u6D88\u606F");
45974
46160
  const requestId = String(extra.mcpReq.id);
45975
46161
  if (deliveredMessages.has(requestId)) return {};
@@ -45984,7 +46170,7 @@ function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: su
45984
46170
  };
45985
46171
  const deliveredContextUpdates = /* @__PURE__ */ new Set();
45986
46172
  let contextUpdates = Promise.resolve();
45987
- bridge.onupdatemodelcontext = async ({ content: content3, structuredContent }, extra) => {
46173
+ handlers.updateModelContext = async ({ content: content3, structuredContent }, extra) => {
45988
46174
  if (disposed) throw new Error("\u5E94\u7528\u5DF2\u5173\u95ED");
45989
46175
  const requestId = `${instance}:${String(extra.mcpReq.id)}`;
45990
46176
  if (deliveredContextUpdates.has(requestId)) return {};
@@ -46017,98 +46203,26 @@ function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: su
46017
46203
  contextUpdates = update.catch(() => void 0);
46018
46204
  return update;
46019
46205
  };
46020
- bridge.onrequestdisplaymode = async ({ mode }) => {
46021
- const next = mode === "fullscreen" ? "fullscreen" : "inline";
46022
- setExpanded(next === "fullscreen");
46023
- bridge?.setHostContext({ displayMode: next });
46024
- return { mode: next };
46025
- };
46026
- bridge.onsizechange = ({ height: next }) => {
46027
- if (next && Number.isFinite(next)) setHeight(Math.max(120, Math.min(1200, next)));
46028
- };
46029
- bridge.onopenlink = async ({ url: url2 }) => {
46030
- const target = new URL(url2);
46031
- if (!["https:", "http:"].includes(target.protocol) || target.username || target.password) throw new Error("\u94FE\u63A5\u65E0\u6548");
46032
- window.open(target.href, "_blank", "noopener,noreferrer");
46033
- return {};
46034
- };
46035
- await bridge.connect(new c(frame.current.contentWindow, frame.current.contentWindow));
46036
- if (!disposed) setHtml(secured);
46206
+ window.clearTimeout(timer);
46207
+ setSurface(handlers);
46037
46208
  };
46038
46209
  void start().catch((failure) => {
46039
46210
  window.clearTimeout(timer);
46040
46211
  if (!disposed) setError(failure instanceof Error ? failure.message : "\u5E94\u7528\u52A0\u8F7D\u5931\u8D25");
46041
46212
  });
46042
- const timer = window.setTimeout(() => {
46043
- if (!disposed && !bridge?.getAppCapabilities()) setError("\u5E94\u7528\u8FDE\u63A5\u8D85\u65F6");
46044
- }, 2e4);
46045
46213
  return () => {
46046
46214
  disposed = true;
46215
+ window.clearTimeout(timer);
46047
46216
  controller.abort();
46048
46217
  offChanged?.();
46049
- window.clearTimeout(timer);
46050
- bridgeRef.current = null;
46051
- void bridge?.close();
46052
46218
  };
46053
46219
  }, [client, sessionId, sourceId]);
46054
- const toggle = () => {
46055
- setExpanded(!expanded);
46056
- bridgeRef.current?.setHostContext({ displayMode: expanded ? "inline" : "fullscreen" });
46057
- };
46058
- return /* @__PURE__ */ jsxs10(
46059
- "dialog",
46060
- {
46061
- ref: panel,
46062
- onCancel: () => {
46063
- setExpanded(false);
46064
- bridgeRef.current?.setHostContext({ displayMode: "inline" });
46065
- },
46066
- className: "blade-chat-mcp-app blade-mcp-app",
46067
- part: "mcp-app",
46068
- style: expanded ? {
46069
- position: "fixed",
46070
- top: 0,
46071
- right: 0,
46072
- bottom: 0,
46073
- left: "auto",
46074
- margin: 0,
46075
- padding: 0,
46076
- border: 0,
46077
- width: "min(100vw, 760px)",
46078
- height: "100%",
46079
- maxWidth: "none",
46080
- maxHeight: "none",
46081
- zIndex: 80,
46082
- background: "white",
46083
- boxShadow: "-4px 0 20px #0002",
46084
- display: "flex",
46085
- flexDirection: "column"
46086
- } : { position: "relative", margin: 0, padding: 0, width: "100%", maxWidth: "none", maxHeight: "none", border: "1px solid #d4d4d8", borderRadius: 6, overflow: "hidden", background: "white" },
46087
- children: [
46088
- /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "8px 12px", color: "#27272a" }, children: [
46089
- /* @__PURE__ */ jsx12("span", { children: title }),
46090
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: toggle, title: expanded ? "\u6536\u8D77" : "\u5C55\u5F00", "aria-label": expanded ? "\u6536\u8D77" : "\u5C55\u5F00", style: { width: 32, height: 32, display: "grid", placeItems: "center", background: "transparent", border: 0, padding: 0 }, children: expanded ? /* @__PURE__ */ jsx12(Minimize2, { size: 16 }) : /* @__PURE__ */ jsx12(Maximize2, { size: 16 }) })
46091
- ] }),
46092
- error61 ? /* @__PURE__ */ jsx12("p", { role: "alert", style: { padding: 12, color: "#b91c1c" }, children: error61 }) : !ready ? /* @__PURE__ */ jsx12("output", { style: { padding: 12 }, children: "\u6B63\u5728\u52A0\u8F7D" }) : null,
46093
- /* @__PURE__ */ jsx12(
46094
- "iframe",
46095
- {
46096
- ref: frame,
46097
- title,
46098
- srcDoc: html,
46099
- sandbox: "allow-scripts allow-forms",
46100
- referrerPolicy: "no-referrer",
46101
- style: { width: "100%", height: expanded ? "100%" : height, flex: expanded ? 1 : void 0, border: 0 }
46102
- }
46103
- )
46104
- ]
46105
- }
46106
- );
46220
+ return /* @__PURE__ */ jsx13(McpAppFrame, { ...surface, error: error61 });
46107
46221
  }
46108
46222
 
46109
46223
  // src/components/ChatInput.tsx
46110
- import { useRef as useRef17, useState as useState23 } from "react";
46111
- import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
46224
+ import { useRef as useRef19, useState as useState25 } from "react";
46225
+ import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
46112
46226
  function isImeCompositionKey(event) {
46113
46227
  return event.isComposing || event.keyCode === 229;
46114
46228
  }
@@ -46133,10 +46247,10 @@ function ChatInput({
46133
46247
  hasAttachments = false
46134
46248
  }) {
46135
46249
  const trimmed = value.trim();
46136
- const latestValue = useRef17(value);
46250
+ const latestValue = useRef19(value);
46137
46251
  latestValue.current = value;
46138
- const sending = useRef17(false);
46139
- const [isSending2, setIsSending] = useState23(false);
46252
+ const sending = useRef19(false);
46253
+ const [isSending2, setIsSending] = useState25(false);
46140
46254
  void queueKey;
46141
46255
  const canSend = !isSending2 && (trimmed.length > 0 || hasAttachments) && (!isStreaming || queueWhileRunning && !hasAttachments && !isStopping);
46142
46256
  const handleSend = async () => {
@@ -46164,7 +46278,7 @@ function ChatInput({
46164
46278
  void handleSend();
46165
46279
  }
46166
46280
  };
46167
- return /* @__PURE__ */ jsx13(
46281
+ return /* @__PURE__ */ jsx14(
46168
46282
  "div",
46169
46283
  {
46170
46284
  style: mergesWithPanelAbove ? { "--blade-chat-input-top-border": "0" } : void 0,
@@ -46186,7 +46300,7 @@ function ChatInput({
46186
46300
  innerClassName
46187
46301
  ),
46188
46302
  children: [
46189
- /* @__PURE__ */ jsx13(
46303
+ /* @__PURE__ */ jsx14(
46190
46304
  "textarea",
46191
46305
  {
46192
46306
  value,
@@ -46207,10 +46321,10 @@ function ChatInput({
46207
46321
  )
46208
46322
  }
46209
46323
  ),
46210
- /* @__PURE__ */ jsx13("div", { part: "input-toolbar", className: cn("blade-chat-input-toolbar flex shrink-0 items-center gap-2", toolbarClassName), children: isStreaming ? /* @__PURE__ */ jsxs11(Fragment5, { children: [
46211
- queueWhileRunning ? /* @__PURE__ */ jsx13("button", { type: "button", onClick: handleSend, disabled: !canSend, "aria-label": "\u52A0\u5165\u6392\u961F", title: "\u52A0\u5165\u6392\u961F", className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] disabled:opacity-40", children: /* @__PURE__ */ jsx13(ArrowUp, { size: 15 }) }) : null,
46212
- /* @__PURE__ */ jsx13("button", { type: "button", onClick: onStop, disabled: isStopping, "aria-label": isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u56DE\u590D", title: isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u56DE\u590D", className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-[hsl(var(--foreground))] transition-opacity hover:opacity-90 disabled:opacity-60", children: isStopping ? /* @__PURE__ */ jsx13(LoaderCircle, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx13(Square, { size: 12, fill: "currentColor" }) })
46213
- ] }) : /* @__PURE__ */ jsx13(
46324
+ /* @__PURE__ */ jsx14("div", { part: "input-toolbar", className: cn("blade-chat-input-toolbar flex shrink-0 items-center gap-2", toolbarClassName), children: isStreaming ? /* @__PURE__ */ jsxs11(Fragment5, { children: [
46325
+ queueWhileRunning ? /* @__PURE__ */ jsx14("button", { type: "button", onClick: handleSend, disabled: !canSend, "aria-label": "\u52A0\u5165\u6392\u961F", title: "\u52A0\u5165\u6392\u961F", className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] disabled:opacity-40", children: /* @__PURE__ */ jsx14(ArrowUp, { size: 15 }) }) : null,
46326
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: onStop, disabled: isStopping, "aria-label": isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u56DE\u590D", title: isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u56DE\u590D", className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-[hsl(var(--foreground))] transition-opacity hover:opacity-90 disabled:opacity-60", children: isStopping ? /* @__PURE__ */ jsx14(LoaderCircle, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx14(Square, { size: 12, fill: "currentColor" }) })
46327
+ ] }) : /* @__PURE__ */ jsx14(
46214
46328
  "button",
46215
46329
  {
46216
46330
  type: "button",
@@ -46219,7 +46333,7 @@ function ChatInput({
46219
46333
  "aria-label": "\u53D1\u9001\u6D88\u606F",
46220
46334
  title: "\u53D1\u9001\u6D88\u606F",
46221
46335
  className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40",
46222
- children: /* @__PURE__ */ jsx13(ArrowUp, { size: 15 })
46336
+ children: /* @__PURE__ */ jsx14(ArrowUp, { size: 15 })
46223
46337
  }
46224
46338
  ) })
46225
46339
  ]
@@ -46230,16 +46344,16 @@ function ChatInput({
46230
46344
  }
46231
46345
 
46232
46346
  // src/components/ConnectionBanner.tsx
46233
- import { useEffect as useEffect17, useRef as useRef18, useState as useState24 } from "react";
46234
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
46347
+ import { useEffect as useEffect19, useRef as useRef20, useState as useState26 } from "react";
46348
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
46235
46349
  var CONNECTION_NOTICE_DELAY_MS = 3e3;
46236
46350
  var CONNECTION_ERROR_DELAY_MS = 15e3;
46237
46351
  function useConnectionNoticePhase(connected) {
46238
- const [phase, setPhase] = useState24("hidden");
46239
- const connectedRef = useRef18(connected);
46240
- const timersRef = useRef18([]);
46352
+ const [phase, setPhase] = useState26("hidden");
46353
+ const connectedRef = useRef20(connected);
46354
+ const timersRef = useRef20([]);
46241
46355
  connectedRef.current = connected;
46242
- useEffect17(() => {
46356
+ useEffect19(() => {
46243
46357
  const clearTimers = () => {
46244
46358
  for (const timer of timersRef.current) clearTimeout(timer);
46245
46359
  timersRef.current = [];
@@ -46279,14 +46393,14 @@ function useConnectionNoticePhase(connected) {
46279
46393
  return phase;
46280
46394
  }
46281
46395
  function ConnectionBanner({ connection, className }) {
46282
- const hasConnectedRef = useRef18(connection === "connected" || connection === "reconnecting");
46396
+ const hasConnectedRef = useRef20(connection === "connected" || connection === "reconnecting");
46283
46397
  if (connection === "connected") hasConnectedRef.current = true;
46284
46398
  const connected = connection === "connected";
46285
46399
  const phase = useConnectionNoticePhase(connected);
46286
46400
  if (connected || phase === "hidden") return null;
46287
46401
  const recovering = phase === "recovering";
46288
46402
  const firstConnection = !hasConnectedRef.current;
46289
- return /* @__PURE__ */ jsx14("div", { part: "banner", className: cn("blade-chat-banner bg-[hsl(var(--background))] px-5 pt-3", className), children: /* @__PURE__ */ jsxs12(
46403
+ return /* @__PURE__ */ jsx15("div", { part: "banner", className: cn("blade-chat-banner bg-[hsl(var(--background))] px-5 pt-3", className), children: /* @__PURE__ */ jsxs12(
46290
46404
  "div",
46291
46405
  {
46292
46406
  className: cn(
@@ -46294,10 +46408,10 @@ function ConnectionBanner({ connection, className }) {
46294
46408
  recovering ? "border-amber-500/25 bg-amber-500/10 text-amber-100" : "border-rose-500/25 bg-rose-500/10 text-rose-100"
46295
46409
  ),
46296
46410
  children: [
46297
- /* @__PURE__ */ jsx14("span", { className: "mt-0.5 shrink-0", children: recovering ? /* @__PURE__ */ jsx14(LoaderCircle, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx14(TriangleAlert, { size: 14 }) }),
46411
+ /* @__PURE__ */ jsx15("span", { className: "mt-0.5 shrink-0", children: recovering ? /* @__PURE__ */ jsx15(LoaderCircle, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx15(TriangleAlert, { size: 14 }) }),
46298
46412
  /* @__PURE__ */ jsxs12("div", { className: "min-w-0", children: [
46299
- /* @__PURE__ */ jsx14("div", { className: "text-sm font-medium", children: recovering ? firstConnection ? "\u6B63\u5728\u8FDE\u63A5\u2026" : "\u6B63\u5728\u6062\u590D\u8FDE\u63A5\u2026" : "\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5" }),
46300
- /* @__PURE__ */ jsx14("div", { className: "text-xs opacity-80", children: recovering ? "\u6062\u590D\u540E\u4F1A\u81EA\u52A8\u540C\u6B65\u6700\u65B0\u6D88\u606F\uFF0C\u8BF7\u7A0D\u5019" : "\u8BF7\u68C0\u67E5\u7F51\u7EDC\u6216\u670D\u52A1\u72B6\u6001\uFF0C\u7CFB\u7EDF\u4F1A\u7EE7\u7EED\u81EA\u52A8\u91CD\u8BD5" })
46413
+ /* @__PURE__ */ jsx15("div", { className: "text-sm font-medium", children: recovering ? firstConnection ? "\u6B63\u5728\u8FDE\u63A5\u2026" : "\u6B63\u5728\u6062\u590D\u8FDE\u63A5\u2026" : "\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5" }),
46414
+ /* @__PURE__ */ jsx15("div", { className: "text-xs opacity-80", children: recovering ? "\u6062\u590D\u540E\u4F1A\u81EA\u52A8\u540C\u6B65\u6700\u65B0\u6D88\u606F\uFF0C\u8BF7\u7A0D\u5019" : "\u8BF7\u68C0\u67E5\u7F51\u7EDC\u6216\u670D\u52A1\u72B6\u6001\uFF0C\u7CFB\u7EDF\u4F1A\u7EE7\u7EED\u81EA\u52A8\u91CD\u8BD5" })
46301
46415
  ] })
46302
46416
  ]
46303
46417
  }
@@ -46305,7 +46419,7 @@ function ConnectionBanner({ connection, className }) {
46305
46419
  }
46306
46420
 
46307
46421
  // src/components/BackgroundWakeNotice.tsx
46308
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
46422
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
46309
46423
  function BackgroundWakeNotice() {
46310
46424
  return /* @__PURE__ */ jsxs13(
46311
46425
  "div",
@@ -46313,10 +46427,10 @@ function BackgroundWakeNotice() {
46313
46427
  "data-background-wakeup": true,
46314
46428
  className: "my-3 flex items-start gap-2 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.35)] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]",
46315
46429
  children: [
46316
- /* @__PURE__ */ jsx15(BellRing, { size: 14, className: "mt-0.5 shrink-0", "aria-hidden": "true" }),
46430
+ /* @__PURE__ */ jsx16(BellRing, { size: 14, className: "mt-0.5 shrink-0", "aria-hidden": "true" }),
46317
46431
  /* @__PURE__ */ jsxs13("div", { children: [
46318
- /* @__PURE__ */ jsx15("p", { className: "font-medium", children: "\u540E\u53F0\u4EFB\u52A1\u5DF2\u7ED3\u675F" }),
46319
- /* @__PURE__ */ jsx15("p", { className: "mt-0.5", children: "\u52A9\u624B\u5DF2\u81EA\u52A8\u7EE7\u7EED\u5904\u7406\u7ED3\u679C" })
46432
+ /* @__PURE__ */ jsx16("p", { className: "font-medium", children: "\u540E\u53F0\u4EFB\u52A1\u5DF2\u7ED3\u675F" }),
46433
+ /* @__PURE__ */ jsx16("p", { className: "mt-0.5", children: "\u52A9\u624B\u5DF2\u81EA\u52A8\u7EE7\u7EED\u5904\u7406\u7ED3\u679C" })
46320
46434
  ] })
46321
46435
  ]
46322
46436
  }
@@ -46327,14 +46441,14 @@ function BackgroundWakeNotice() {
46327
46441
  import { isBackgroundWakeMessage, isHiddenInternalMessage as isHiddenInternalMessage2 } from "@blade-hq/agent-client";
46328
46442
  import {
46329
46443
  useCallback as useCallback29,
46330
- useEffect as useEffect25,
46444
+ useEffect as useEffect27,
46331
46445
  useMemo as useMemo16,
46332
- useRef as useRef27,
46333
- useState as useState33
46446
+ useRef as useRef29,
46447
+ useState as useState35
46334
46448
  } from "react";
46335
46449
 
46336
46450
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
46337
- import { useCallback as useCallback26, useMemo as useMemo12, useRef as useRef19, useState as useState25 } from "react";
46451
+ import { useCallback as useCallback26, useMemo as useMemo12, useRef as useRef21, useState as useState27 } from "react";
46338
46452
  var DEFAULT_SPRING_ANIMATION = {
46339
46453
  /**
46340
46454
  * A value from 0 to 1, on how much to damp the animation.
@@ -46371,10 +46485,10 @@ globalThis.document?.addEventListener("click", () => {
46371
46485
  mouseDown = false;
46372
46486
  });
46373
46487
  var useStickToBottom = (options = {}) => {
46374
- const [escapedFromLock, updateEscapedFromLock] = useState25(false);
46375
- const [isAtBottom, updateIsAtBottom] = useState25(options.initial !== false);
46376
- const [isNearBottom, setIsNearBottom] = useState25(false);
46377
- const optionsRef = useRef19(null);
46488
+ const [escapedFromLock, updateEscapedFromLock] = useState27(false);
46489
+ const [isAtBottom, updateIsAtBottom] = useState27(options.initial !== false);
46490
+ const [isNearBottom, setIsNearBottom] = useState27(false);
46491
+ const optionsRef = useRef21(null);
46378
46492
  optionsRef.current = options;
46379
46493
  const isSelecting = useCallback26(() => {
46380
46494
  if (!mouseDown) {
@@ -46678,11 +46792,11 @@ function mergeAnimations(...animations) {
46678
46792
 
46679
46793
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/StickToBottom.js
46680
46794
  import * as React from "react";
46681
- import { createContext as createContext5, useContext as useContext5, useEffect as useEffect18, useImperativeHandle, useLayoutEffect as useLayoutEffect5, useMemo as useMemo13, useRef as useRef20 } from "react";
46795
+ import { createContext as createContext5, useContext as useContext5, useEffect as useEffect20, useImperativeHandle, useLayoutEffect as useLayoutEffect5, useMemo as useMemo13, useRef as useRef22 } from "react";
46682
46796
  var StickToBottomContext = createContext5(null);
46683
- var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect5 : useEffect18;
46797
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect5 : useEffect20;
46684
46798
  function StickToBottom({ instance, children, resize, initial, mass, damping, stiffness, targetScrollTop: currentTargetScrollTop, contextRef, ...props }) {
46685
- const customTargetScrollTop = useRef20(null);
46799
+ const customTargetScrollTop = useRef22(null);
46686
46800
  const targetScrollTop = React.useCallback((target, elements) => {
46687
46801
  const get = context?.targetScrollTop ?? currentTargetScrollTop;
46688
46802
  return get?.(target, elements) ?? target;
@@ -46761,23 +46875,23 @@ function useStickToBottomContext() {
46761
46875
  import { getServerTime } from "@blade-hq/agent-client/internal";
46762
46876
 
46763
46877
  // src/components/MessageImage.tsx
46764
- import { forwardRef as forwardRef3, useEffect as useEffect19, useImperativeHandle as useImperativeHandle2, useRef as useRef21, useState as useState26 } from "react";
46765
- import { jsx as jsx16 } from "react/jsx-runtime";
46878
+ import { forwardRef as forwardRef3, useEffect as useEffect21, useImperativeHandle as useImperativeHandle2, useRef as useRef23, useState as useState28 } from "react";
46879
+ import { jsx as jsx17 } from "react/jsx-runtime";
46766
46880
  var assetPattern = /^\/api\/(sessions|share)\/([^/]+)\/media\/([a-f0-9]{64})$/;
46767
46881
  var MessageImage = forwardRef3(function MessageImage2({ client: suppliedClient, src, original = false, alt, style, ...props }, ref) {
46768
46882
  const contextClient = useOptionalBladeClient();
46769
46883
  const client = suppliedClient ?? contextClient;
46770
- const element2 = useRef21(null);
46884
+ const element2 = useRef23(null);
46771
46885
  useImperativeHandle2(ref, () => element2.current);
46772
- const [visible, setVisible] = useState26(false);
46773
- const [result, setResult] = useState26(null);
46886
+ const [visible, setVisible] = useState28(false);
46887
+ const [result, setResult] = useState28(null);
46774
46888
  const match = src?.match(assetPattern);
46775
46889
  const scope = match?.[1];
46776
46890
  const sessionId = match?.[2];
46777
46891
  const assetId = match?.[3];
46778
46892
  const identity2 = assetId && client ? client.buildAuthedUrl(src) : "";
46779
46893
  const source = `${src}:${original}:${identity2}`;
46780
- useEffect19(() => {
46894
+ useEffect21(() => {
46781
46895
  const node3 = element2.current;
46782
46896
  if (!node3 || !assetId) return;
46783
46897
  if (original || typeof IntersectionObserver === "undefined") {
@@ -46793,7 +46907,7 @@ var MessageImage = forwardRef3(function MessageImage2({ client: suppliedClient,
46793
46907
  observer.observe(node3);
46794
46908
  return () => observer.disconnect();
46795
46909
  }, [assetId, original]);
46796
- useEffect19(() => {
46910
+ useEffect21(() => {
46797
46911
  if (!visible || !client || !sessionId || !assetId) return;
46798
46912
  let alive = true;
46799
46913
  let objectUrl = null;
@@ -46812,7 +46926,7 @@ var MessageImage = forwardRef3(function MessageImage2({ client: suppliedClient,
46812
46926
  }, [visible, client, scope, sessionId, assetId, original, source]);
46813
46927
  const current = result?.source === source && result.client === client ? result : null;
46814
46928
  const imageStyle = { aspectRatio: props.width && props.height ? `${props.width}/${props.height}` : void 0, ...style };
46815
- return /* @__PURE__ */ jsx16(
46929
+ return /* @__PURE__ */ jsx17(
46816
46930
  "img",
46817
46931
  {
46818
46932
  ...props,
@@ -46833,11 +46947,11 @@ import {
46833
46947
  getTextContent as getTextContent2,
46834
46948
  normalizeMessageContent as normalizeMessageContent2
46835
46949
  } from "@blade-hq/agent-client";
46836
- import { useEffect as useEffect23, useRef as useRef25, useState as useState31 } from "react";
46950
+ import { useEffect as useEffect25, useRef as useRef27, useState as useState33 } from "react";
46837
46951
 
46838
46952
  // src/components/AgentTaskCard.tsx
46839
- import { useEffect as useEffect20, useState as useState27 } from "react";
46840
- import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
46953
+ import { useEffect as useEffect22, useState as useState29 } from "react";
46954
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
46841
46955
  var STATUS_LABELS = {
46842
46956
  running: "\u8FDB\u884C\u4E2D",
46843
46957
  waiting_input: "\u7B49\u5F85\u56DE\u7B54",
@@ -46847,8 +46961,8 @@ var STATUS_LABELS = {
46847
46961
  };
46848
46962
  function AgentTaskCard({ title, status, activity, children, className, recordId }) {
46849
46963
  const waiting = status === "waiting_input";
46850
- const [open2, setOpen] = useState27(waiting);
46851
- useEffect20(() => {
46964
+ const [open2, setOpen] = useState29(waiting);
46965
+ useEffect22(() => {
46852
46966
  if (waiting) setOpen(true);
46853
46967
  }, [waiting]);
46854
46968
  return /* @__PURE__ */ jsxs14(
@@ -46866,28 +46980,28 @@ function AgentTaskCard({ title, status, activity, children, className, recordId
46866
46980
  ),
46867
46981
  children: [
46868
46982
  /* @__PURE__ */ jsxs14("summary", { className: "flex cursor-pointer list-none items-start gap-2.5 rounded-xl px-3 py-3 text-left outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] [&::-webkit-details-marker]:hidden", children: [
46869
- waiting ? /* @__PURE__ */ jsx17(CircleHelp, { size: 18, "aria-hidden": "true", className: "mt-0.5 shrink-0 text-amber-600 motion-safe:animate-pulse" }) : /* @__PURE__ */ jsx17(Bot, { size: 18, "aria-hidden": "true", className: "mt-0.5 shrink-0 text-[hsl(var(--primary))]" }),
46983
+ waiting ? /* @__PURE__ */ jsx18(CircleHelp, { size: 18, "aria-hidden": "true", className: "mt-0.5 shrink-0 text-amber-600 motion-safe:animate-pulse" }) : /* @__PURE__ */ jsx18(Bot, { size: 18, "aria-hidden": "true", className: "mt-0.5 shrink-0 text-[hsl(var(--primary))]" }),
46870
46984
  /* @__PURE__ */ jsxs14("span", { className: "min-w-0 flex-1", children: [
46871
46985
  /* @__PURE__ */ jsxs14("span", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
46872
- /* @__PURE__ */ jsx17("span", { children: "\u5B50\u667A\u80FD\u4F53" }),
46986
+ /* @__PURE__ */ jsx18("span", { children: "\u5B50\u667A\u80FD\u4F53" }),
46873
46987
  /* @__PURE__ */ jsxs14("span", { className: cn("inline-flex items-center gap-1", waiting && "font-semibold text-amber-600"), children: [
46874
- status === "running" ? /* @__PURE__ */ jsx17(LoaderCircle, { size: 12, "aria-hidden": "true", className: "motion-safe:animate-spin" }) : null,
46988
+ status === "running" ? /* @__PURE__ */ jsx18(LoaderCircle, { size: 12, "aria-hidden": "true", className: "motion-safe:animate-spin" }) : null,
46875
46989
  STATUS_LABELS[status]
46876
46990
  ] })
46877
46991
  ] }),
46878
- /* @__PURE__ */ jsx17("span", { className: "mt-1 block break-words text-sm font-medium text-[hsl(var(--foreground))]", children: title }),
46879
- activity ? /* @__PURE__ */ jsx17("span", { className: "mt-1 block truncate text-xs text-[hsl(var(--muted-foreground))]", title: activity, children: activity }) : null
46992
+ /* @__PURE__ */ jsx18("span", { className: "mt-1 block break-words text-sm font-medium text-[hsl(var(--foreground))]", children: title }),
46993
+ activity ? /* @__PURE__ */ jsx18("span", { className: "mt-1 block truncate text-xs text-[hsl(var(--muted-foreground))]", title: activity, children: activity }) : null
46880
46994
  ] }),
46881
- /* @__PURE__ */ jsx17(ChevronRight, { size: 15, "aria-hidden": "true", className: cn("mt-1 shrink-0 text-[hsl(var(--muted-foreground))] transition-transform motion-reduce:transition-none", open2 && "rotate-90") })
46995
+ /* @__PURE__ */ jsx18(ChevronRight, { size: 15, "aria-hidden": "true", className: cn("mt-1 shrink-0 text-[hsl(var(--muted-foreground))] transition-transform motion-reduce:transition-none", open2 && "rotate-90") })
46882
46996
  ] }),
46883
- /* @__PURE__ */ jsx17("div", { className: "min-w-0 border-t border-[hsl(var(--border))] px-3 py-2", children })
46997
+ /* @__PURE__ */ jsx18("div", { className: "min-w-0 border-t border-[hsl(var(--border))] px-3 py-2", children })
46884
46998
  ]
46885
46999
  }
46886
47000
  );
46887
47001
  }
46888
47002
 
46889
47003
  // src/components/AgentLoopBlock.tsx
46890
- import { jsx as jsx18 } from "react/jsx-runtime";
47004
+ import { jsx as jsx19 } from "react/jsx-runtime";
46891
47005
  function parseAgentDescription(argumentsJson) {
46892
47006
  try {
46893
47007
  const parsed = JSON.parse(argumentsJson);
@@ -46898,14 +47012,14 @@ function parseAgentDescription(argumentsJson) {
46898
47012
  }
46899
47013
  function AgentLoopBlock({ toolCall, className }) {
46900
47014
  const status = toolCall.status === "awaiting_answer" ? "waiting_input" : toolCall.status === "pending" ? "running" : toolCall.status === "error" ? "failed" : toolCall.status === "cancelled" ? "cancelled" : "completed";
46901
- return /* @__PURE__ */ jsx18(AgentTaskCard, { title: parseAgentDescription(toolCall.arguments), status, className, children: toolCall.result != null ? /* @__PURE__ */ jsx18("div", { className: "max-h-[400px] overflow-auto whitespace-pre-wrap break-words text-xs text-[hsl(var(--muted-foreground))]", children: formatToolResult(toolCall.result) }) : /* @__PURE__ */ jsx18("p", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: status === "waiting_input" ? "\u8BF7\u56DE\u7B54\u5BF9\u8BDD\u4E2D\u7684\u95EE\u9898\uFF0C\u5B50\u667A\u80FD\u4F53\u4F1A\u7EE7\u7EED\u5904\u7406\u3002" : status === "running" ? "\u5B50\u667A\u80FD\u4F53\u6B63\u5728\u5904\u7406\u4EFB\u52A1\u3002" : "\u6682\u65E0\u6267\u884C\u7ED3\u679C\u3002" }) });
47015
+ return /* @__PURE__ */ jsx19(AgentTaskCard, { title: parseAgentDescription(toolCall.arguments), status, className, children: toolCall.result != null ? /* @__PURE__ */ jsx19("div", { className: "max-h-[400px] overflow-auto whitespace-pre-wrap break-words text-xs text-[hsl(var(--muted-foreground))]", children: formatToolResult(toolCall.result) }) : /* @__PURE__ */ jsx19("p", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: status === "waiting_input" ? "\u8BF7\u56DE\u7B54\u5BF9\u8BDD\u4E2D\u7684\u95EE\u9898\uFF0C\u5B50\u667A\u80FD\u4F53\u4F1A\u7EE7\u7EED\u5904\u7406\u3002" : status === "running" ? "\u5B50\u667A\u80FD\u4F53\u6B63\u5728\u5904\u7406\u4EFB\u52A1\u3002" : "\u6682\u65E0\u6267\u884C\u7ED3\u679C\u3002" }) });
46902
47016
  }
46903
47017
 
46904
47018
  // src/components/MarkdownContent.tsx
46905
- import { isValidElement as isValidElement2, useMemo as useMemo14, useRef as useRef23, useState as useState28 } from "react";
47019
+ import { isValidElement as isValidElement2, useMemo as useMemo14, useRef as useRef25, useState as useState30 } from "react";
46906
47020
 
46907
47021
  // src/components/markdown/index.ts
46908
- import { createElement as createElement7, useRef as useRef22 } from "react";
47022
+ import { createElement as createElement7, useRef as useRef24 } from "react";
46909
47023
 
46910
47024
  // ../../node_modules/.pnpm/mdast-util-to-string@4.0.0/node_modules/mdast-util-to-string/lib/index.js
46911
47025
  var emptyOptions = {};
@@ -55783,10 +55897,10 @@ function MarkdownRenderer({
55783
55897
  codeBlockOverrides
55784
55898
  }) {
55785
55899
  const isStreaming = mode === "streaming";
55786
- const cacheRef = useRef22(createParseCache());
55787
- const blockCacheRef = useRef22(/* @__PURE__ */ new WeakMap());
55788
- const groupIdentityMapRef = useRef22(/* @__PURE__ */ new WeakMap());
55789
- const rendererConfigRef = useRef22(null);
55900
+ const cacheRef = useRef24(createParseCache());
55901
+ const blockCacheRef = useRef24(/* @__PURE__ */ new WeakMap());
55902
+ const groupIdentityMapRef = useRef24(/* @__PURE__ */ new WeakMap());
55903
+ const rendererConfigRef = useRef24(null);
55790
55904
  const previousConfig = rendererConfigRef.current;
55791
55905
  if (!previousConfig || previousConfig.allowedTags !== allowedTags || previousConfig.components !== components || previousConfig.rawHtmlPlugins !== rawHtmlPlugins || previousConfig.codeBlockOverrides !== codeBlockOverrides) {
55792
55906
  blockCacheRef.current = /* @__PURE__ */ new WeakMap();
@@ -55827,7 +55941,7 @@ function MarkdownRenderer({
55827
55941
  }
55828
55942
 
55829
55943
  // src/components/MarkdownContent.tsx
55830
- import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
55944
+ import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
55831
55945
  var SYSTEM_REMINDER_RE = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
55832
55946
  var INCOMPLETE_SYSTEM_REMINDER_RE = /<system-reminder>[\s\S]*$/i;
55833
55947
  function findCodeRanges(text4) {
@@ -55871,8 +55985,8 @@ function normalizeAdjacentUrlFormatting(value) {
55871
55985
  return normalized.replace(/blade-url-protected-(\d+)-marker/g, (_2, index3) => protectedSegments[Number(index3)]);
55872
55986
  }
55873
55987
  function CodeBlockPre({ children, ...props }) {
55874
- const preRef = useRef23(null);
55875
- const [copied, setCopied] = useState28(false);
55988
+ const preRef = useRef25(null);
55989
+ const [copied, setCopied] = useState30(false);
55876
55990
  const codeChild = Array.isArray(children) ? children[0] : children;
55877
55991
  const codeClassName = isValidElement2(codeChild) ? codeChild.props.className : void 0;
55878
55992
  const language = codeClassName?.match(/language-(\S+)/)?.[1] ?? "";
@@ -55885,7 +55999,7 @@ function CodeBlockPre({ children, ...props }) {
55885
55999
  };
55886
56000
  return /* @__PURE__ */ jsxs15("div", { className: "blade-chat-codeblock not-prose my-3 overflow-hidden rounded-xl border border-[hsl(var(--border))]", children: [
55887
56001
  /* @__PURE__ */ jsxs15("div", { className: "blade-chat-codeblock-header flex h-[34px] items-center justify-between border-b border-[hsl(var(--border))] bg-[hsl(var(--muted))/0.5] pl-3.5 pr-1.5", children: [
55888
- /* @__PURE__ */ jsx19("span", { className: "font-mono text-[12px] text-[hsl(var(--muted-foreground))]", children: language || "code" }),
56002
+ /* @__PURE__ */ jsx20("span", { className: "font-mono text-[12px] text-[hsl(var(--muted-foreground))]", children: language || "code" }),
55889
56003
  /* @__PURE__ */ jsxs15(
55890
56004
  "button",
55891
56005
  {
@@ -55896,13 +56010,13 @@ function CodeBlockPre({ children, ...props }) {
55896
56010
  copied ? "text-[hsl(var(--primary))]" : "text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]"
55897
56011
  ),
55898
56012
  children: [
55899
- copied ? /* @__PURE__ */ jsx19(Check, { size: 12 }) : /* @__PURE__ */ jsx19(Copy, { size: 12 }),
55900
- /* @__PURE__ */ jsx19("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
56013
+ copied ? /* @__PURE__ */ jsx20(Check, { size: 12 }) : /* @__PURE__ */ jsx20(Copy, { size: 12 }),
56014
+ /* @__PURE__ */ jsx20("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
55901
56015
  ]
55902
56016
  }
55903
56017
  )
55904
56018
  ] }),
55905
- /* @__PURE__ */ jsx19(
56019
+ /* @__PURE__ */ jsx20(
55906
56020
  "pre",
55907
56021
  {
55908
56022
  ref: preRef,
@@ -55915,9 +56029,9 @@ function CodeBlockPre({ children, ...props }) {
55915
56029
  }
55916
56030
  function ExternalAnchor({ children, href, ...props }) {
55917
56031
  if (typeof href === "string" && href.startsWith("#")) {
55918
- return /* @__PURE__ */ jsx19("a", { ...props, href, children });
56032
+ return /* @__PURE__ */ jsx20("a", { ...props, href, children });
55919
56033
  }
55920
- return /* @__PURE__ */ jsx19("a", { ...props, href, target: "_blank", rel: "noopener noreferrer", children });
56034
+ return /* @__PURE__ */ jsx20("a", { ...props, href, target: "_blank", rel: "noopener noreferrer", children });
55921
56035
  }
55922
56036
  var MARKDOWN_COMPONENTS = {
55923
56037
  pre: CodeBlockPre,
@@ -55927,7 +56041,7 @@ function MarkdownContent({ children, className, mode, sessionId }) {
55927
56041
  const resolvedChildren = useMemo14(() => {
55928
56042
  return normalizeAdjacentUrlFormatting(stripSystemReminders(children));
55929
56043
  }, [children]);
55930
- return /* @__PURE__ */ jsx19(
56044
+ return /* @__PURE__ */ jsx20(
55931
56045
  MarkdownRenderer,
55932
56046
  {
55933
56047
  className: cn("blade-chat-markdown break-words", className),
@@ -55941,14 +56055,14 @@ function MarkdownContent({ children, className, mode, sessionId }) {
55941
56055
  }
55942
56056
 
55943
56057
  // src/components/Shimmer.tsx
55944
- import { jsx as jsx20 } from "react/jsx-runtime";
56058
+ import { jsx as jsx21 } from "react/jsx-runtime";
55945
56059
  function Shimmer({ children = "\u6B63\u5728\u601D\u8003...", className }) {
55946
- return /* @__PURE__ */ jsx20("span", { className: cn("blade-shimmer-text text-sm font-medium", className), children });
56060
+ return /* @__PURE__ */ jsx21("span", { className: cn("blade-shimmer-text text-sm font-medium", className), children });
55947
56061
  }
55948
56062
 
55949
56063
  // src/components/AskUserQuestionBlock.tsx
55950
- import { useEffect as useEffect21, useMemo as useMemo15, useRef as useRef24, useState as useState29 } from "react";
55951
- import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
56064
+ import { useEffect as useEffect23, useMemo as useMemo15, useRef as useRef26, useState as useState31 } from "react";
56065
+ import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
55952
56066
  var CUSTOM_TEXTAREA_MAX_HEIGHT = 160;
55953
56067
  function resizeCustomTextarea(textarea) {
55954
56068
  textarea.style.height = "auto";
@@ -55956,12 +56070,12 @@ function resizeCustomTextarea(textarea) {
55956
56070
  textarea.style.overflowY = textarea.scrollHeight > CUSTOM_TEXTAREA_MAX_HEIGHT ? "auto" : "hidden";
55957
56071
  }
55958
56072
  function useAutoResizeTextarea(value) {
55959
- const textareaRef = useRef24(null);
55960
- useEffect21(() => {
56073
+ const textareaRef = useRef26(null);
56074
+ useEffect23(() => {
55961
56075
  const textarea = textareaRef.current;
55962
56076
  if (textarea?.value === value) resizeCustomTextarea(textarea);
55963
56077
  }, [value]);
55964
- useEffect21(() => {
56078
+ useEffect23(() => {
55965
56079
  const textarea = textareaRef.current;
55966
56080
  if (!textarea || typeof ResizeObserver === "undefined") return;
55967
56081
  let previousWidth = textarea.clientWidth;
@@ -55988,12 +56102,12 @@ function AskUserQuestionBlock({
55988
56102
  className,
55989
56103
  optionClassName
55990
56104
  }) {
55991
- const [selections, setSelections] = useState29(/* @__PURE__ */ new Map());
55992
- const [customTexts, setCustomTexts] = useState29(/* @__PURE__ */ new Map());
55993
- const [usingCustom, setUsingCustom] = useState29(/* @__PURE__ */ new Set());
55994
- const [note, setNote] = useState29("");
55995
- const [submitted, setSubmitted] = useState29(false);
55996
- useEffect21(() => {
56105
+ const [selections, setSelections] = useState31(/* @__PURE__ */ new Map());
56106
+ const [customTexts, setCustomTexts] = useState31(/* @__PURE__ */ new Map());
56107
+ const [usingCustom, setUsingCustom] = useState31(/* @__PURE__ */ new Set());
56108
+ const [note, setNote] = useState31("");
56109
+ const [submitted, setSubmitted] = useState31(false);
56110
+ useEffect23(() => {
55997
56111
  if (sessionStatus === "failed" || sessionStatus === "interrupted") {
55998
56112
  setSubmitted(false);
55999
56113
  }
@@ -56106,7 +56220,7 @@ ${parts.join("\n")}`,
56106
56220
  data.source_loop.description,
56107
56221
  "\u300D\u5728\u7B49\u5F85\u4F60\u7684\u56DE\u7B54"
56108
56222
  ] }),
56109
- data.questions.map((q2, qIdx) => /* @__PURE__ */ jsx21(
56223
+ data.questions.map((q2, qIdx) => /* @__PURE__ */ jsx22(
56110
56224
  QuestionCard,
56111
56225
  {
56112
56226
  question: q2,
@@ -56122,7 +56236,7 @@ ${parts.join("\n")}`,
56122
56236
  },
56123
56237
  q2.question
56124
56238
  )),
56125
- /* @__PURE__ */ jsx21(
56239
+ /* @__PURE__ */ jsx22(
56126
56240
  NoteField,
56127
56241
  {
56128
56242
  answered,
@@ -56131,7 +56245,7 @@ ${parts.join("\n")}`,
56131
56245
  onChange: setNote
56132
56246
  }
56133
56247
  ),
56134
- !answered && !submitted && onAnswer && /* @__PURE__ */ jsx21(
56248
+ !answered && !submitted && onAnswer && /* @__PURE__ */ jsx22(
56135
56249
  "button",
56136
56250
  {
56137
56251
  type: "button",
@@ -56148,7 +56262,7 @@ ${parts.join("\n")}`,
56148
56262
  disabled: true,
56149
56263
  className: "flex w-full items-center justify-center gap-2 rounded-lg bg-[hsl(var(--primary))] px-4 py-2 text-xs font-semibold text-[hsl(var(--primary-foreground))] opacity-80",
56150
56264
  children: [
56151
- /* @__PURE__ */ jsx21(LoaderCircle, { size: 14, className: "animate-spin" }),
56265
+ /* @__PURE__ */ jsx22(LoaderCircle, { size: 14, className: "animate-spin" }),
56152
56266
  "\u786E\u8BA4\u4E2D"
56153
56267
  ]
56154
56268
  }
@@ -56173,21 +56287,21 @@ function QuestionCard({
56173
56287
  const customTextareaRef = useAutoResizeTextarea(customText);
56174
56288
  return /* @__PURE__ */ jsxs16("div", { children: [
56175
56289
  /* @__PURE__ */ jsxs16("div", { className: cn("flex items-start gap-2", answered ? "mb-2" : "mb-3"), children: [
56176
- /* @__PURE__ */ jsx21(
56290
+ /* @__PURE__ */ jsx22(
56177
56291
  MessageSquareMore,
56178
56292
  {
56179
56293
  size: answered ? 12 : 13,
56180
56294
  className: "mt-0.5 shrink-0 text-[hsl(var(--primary))]"
56181
56295
  }
56182
56296
  ),
56183
- /* @__PURE__ */ jsx21(
56297
+ /* @__PURE__ */ jsx22(
56184
56298
  "div",
56185
56299
  {
56186
56300
  className: cn(
56187
56301
  "min-w-0 flex-1 font-medium text-[hsl(var(--foreground))]",
56188
56302
  answered ? "text-xs" : "text-sm"
56189
56303
  ),
56190
- children: /* @__PURE__ */ jsx21(MarkdownContent, { className: "blade-chat-prose", children: question.question })
56304
+ children: /* @__PURE__ */ jsx22(MarkdownContent, { className: "blade-chat-prose", children: question.question })
56191
56305
  }
56192
56306
  )
56193
56307
  ] }),
@@ -56210,14 +56324,14 @@ function QuestionCard({
56210
56324
  optionClassName
56211
56325
  ),
56212
56326
  children: [
56213
- multi && /* @__PURE__ */ jsx21(
56327
+ multi && /* @__PURE__ */ jsx22(
56214
56328
  "div",
56215
56329
  {
56216
56330
  className: cn(
56217
56331
  "mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition-colors",
56218
56332
  isSel && !answered ? "border-[hsl(var(--primary-foreground)/0.6)] bg-[hsl(var(--primary-foreground)/0.2)]" : isSel ? "border-[hsl(var(--primary)/0.45)] bg-[hsl(var(--primary)/0.12)]" : "border-[hsl(var(--border))]"
56219
56333
  ),
56220
- children: isSel && /* @__PURE__ */ jsx21(
56334
+ children: isSel && /* @__PURE__ */ jsx22(
56221
56335
  Check,
56222
56336
  {
56223
56337
  size: 9,
@@ -56227,8 +56341,8 @@ function QuestionCard({
56227
56341
  }
56228
56342
  ),
56229
56343
  /* @__PURE__ */ jsxs16("div", { className: "min-w-0", children: [
56230
- /* @__PURE__ */ jsx21("div", { className: cn("font-medium", answered ? "text-xs" : "text-[13px]"), children: opt.label }),
56231
- opt.description && /* @__PURE__ */ jsx21(
56344
+ /* @__PURE__ */ jsx22("div", { className: cn("font-medium", answered ? "text-xs" : "text-[13px]"), children: opt.label }),
56345
+ opt.description && /* @__PURE__ */ jsx22(
56232
56346
  "div",
56233
56347
  {
56234
56348
  className: cn(
@@ -56255,8 +56369,8 @@ function QuestionCard({
56255
56369
  answered && "cursor-default opacity-70"
56256
56370
  ),
56257
56371
  children: [
56258
- /* @__PURE__ */ jsx21("span", { className: "shrink-0 pt-1 text-xs text-[hsl(var(--muted-foreground))]", children: "\u5176\u4ED6\uFF1A" }),
56259
- /* @__PURE__ */ jsx21(
56372
+ /* @__PURE__ */ jsx22("span", { className: "shrink-0 pt-1 text-xs text-[hsl(var(--muted-foreground))]", children: "\u5176\u4ED6\uFF1A" }),
56373
+ /* @__PURE__ */ jsx22(
56260
56374
  "textarea",
56261
56375
  {
56262
56376
  ref: customTextareaRef,
@@ -56298,8 +56412,8 @@ function NoteField({
56298
56412
  readOnly && "cursor-default opacity-70"
56299
56413
  ),
56300
56414
  children: [
56301
- /* @__PURE__ */ jsx21("span", { className: "mb-1.5 block text-xs text-[hsl(var(--muted-foreground))]", children: "\u8865\u5145\u8BF4\u660E\uFF08\u53EF\u9009\uFF09" }),
56302
- /* @__PURE__ */ jsx21(
56415
+ /* @__PURE__ */ jsx22("span", { className: "mb-1.5 block text-xs text-[hsl(var(--muted-foreground))]", children: "\u8865\u5145\u8BF4\u660E\uFF08\u53EF\u9009\uFF09" }),
56416
+ /* @__PURE__ */ jsx22(
56303
56417
  "textarea",
56304
56418
  {
56305
56419
  ref: textareaRef,
@@ -56388,7 +56502,7 @@ function normalizeOptionItem(value) {
56388
56502
  }
56389
56503
 
56390
56504
  // src/components/ToolCallBlock.tsx
56391
- import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
56505
+ import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
56392
56506
  function resolveAskQuestionState({
56393
56507
  toolStatus,
56394
56508
  hasAnswerData,
@@ -56415,7 +56529,7 @@ function ToolCallBlock({
56415
56529
  const customQuestion = normalizedName === "AskUserQuestion" ? renderers?.askUserQuestion : void 0;
56416
56530
  const customToolCall = normalizedName === "AskUserQuestion" && customQuestion ? null : renderers?.toolCall?.(toolCall);
56417
56531
  if (customToolCall !== null && customToolCall !== void 0) {
56418
- return /* @__PURE__ */ jsx22(Fragment7, { children: customToolCall });
56532
+ return /* @__PURE__ */ jsx23(Fragment7, { children: customToolCall });
56419
56533
  }
56420
56534
  if (normalizedName === "AskUserQuestion") {
56421
56535
  const askData = parseAskUserQuestion(typeof toolCall.result === "string" ? toolCall.result : null) ?? parseAskUserQuestion(buildAskUserPayload(toolCall.arguments));
@@ -56437,9 +56551,9 @@ function ToolCallBlock({
56437
56551
  };
56438
56552
  const customAsk = customQuestion?.(answerProps);
56439
56553
  if (customAsk !== null && customAsk !== void 0) {
56440
- return /* @__PURE__ */ jsx22(Fragment7, { children: customAsk });
56554
+ return /* @__PURE__ */ jsx23(Fragment7, { children: customAsk });
56441
56555
  }
56442
- return /* @__PURE__ */ jsx22(
56556
+ return /* @__PURE__ */ jsx23(
56443
56557
  AskUserQuestionBlock,
56444
56558
  {
56445
56559
  ...answerProps,
@@ -56458,8 +56572,8 @@ function ToolCallBlock({
56458
56572
  classNames?.askCard
56459
56573
  ),
56460
56574
  children: [
56461
- /* @__PURE__ */ jsx22(LoaderCircle, { size: 14, className: "animate-spin" }),
56462
- /* @__PURE__ */ jsx22("span", { children: "\u6B63\u5728\u51C6\u5907\u95EE\u9898\u2026" })
56575
+ /* @__PURE__ */ jsx23(LoaderCircle, { size: 14, className: "animate-spin" }),
56576
+ /* @__PURE__ */ jsx23("span", { children: "\u6B63\u5728\u51C6\u5907\u95EE\u9898\u2026" })
56463
56577
  ]
56464
56578
  }
56465
56579
  );
@@ -56476,11 +56590,11 @@ function ToolCallBlock({
56476
56590
  classNames?.askCard
56477
56591
  ),
56478
56592
  children: [
56479
- /* @__PURE__ */ jsx22("div", { className: "font-semibold", children: "\u9009\u62E9\u9898\u5185\u5BB9\u6682\u65F6\u65E0\u6CD5\u663E\u793A" }),
56480
- /* @__PURE__ */ jsx22("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: errorDetail?.message ?? "\u6536\u5230\u7684\u4EA4\u4E92\u6570\u636E\u4E0D\u5B8C\u6574\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002" }),
56593
+ /* @__PURE__ */ jsx23("div", { className: "font-semibold", children: "\u9009\u62E9\u9898\u5185\u5BB9\u6682\u65F6\u65E0\u6CD5\u663E\u793A" }),
56594
+ /* @__PURE__ */ jsx23("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: errorDetail?.message ?? "\u6536\u5230\u7684\u4EA4\u4E92\u6570\u636E\u4E0D\u5B8C\u6574\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002" }),
56481
56595
  errorDetail?.detail ? /* @__PURE__ */ jsxs17("details", { className: "mt-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
56482
- /* @__PURE__ */ jsx22("summary", { className: "cursor-pointer", children: "\u67E5\u770B\u5177\u4F53\u539F\u56E0" }),
56483
- /* @__PURE__ */ jsx22("div", { className: "mt-1 break-words font-mono", children: errorDetail.detail })
56596
+ /* @__PURE__ */ jsx23("summary", { className: "cursor-pointer", children: "\u67E5\u770B\u5177\u4F53\u539F\u56E0" }),
56597
+ /* @__PURE__ */ jsx23("div", { className: "mt-1 break-words font-mono", children: errorDetail.detail })
56484
56598
  ] }) : null
56485
56599
  ]
56486
56600
  }
@@ -56501,17 +56615,17 @@ function buildAskUserPayload(argumentsJson) {
56501
56615
 
56502
56616
  // src/components/ToolUiCardView.tsx
56503
56617
  import { resolveToolUiCardContent } from "@blade-hq/agent-client";
56504
- import { useEffect as useEffect22, useState as useState30 } from "react";
56505
- import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
56618
+ import { useEffect as useEffect24, useState as useState32 } from "react";
56619
+ import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
56506
56620
  function ToolUiCardView({ card, sessionId }) {
56507
- if (card.mcpApp) return sessionId ? /* @__PURE__ */ jsx23(McpAppCard, { sessionId, sourceId: card.mcpApp.sourceId }) : null;
56621
+ if (card.mcpApp) return sessionId ? /* @__PURE__ */ jsx24(McpAppCard, { sessionId, sourceId: card.mcpApp.sourceId }) : null;
56508
56622
  const resolved = resolveToolUiCardContent(card);
56509
56623
  if (!resolved) return null;
56510
56624
  if (resolved.type === "resource-file") {
56511
- return sessionId ? /* @__PURE__ */ jsx23(FileCard, { card, sessionId, path: resolved.content }, `${sessionId}:${resolved.content}`) : null;
56625
+ return sessionId ? /* @__PURE__ */ jsx24(FileCard, { card, sessionId, path: resolved.content }, `${sessionId}:${resolved.content}`) : null;
56512
56626
  }
56513
56627
  const sandbox = resolved.type === "resource-uri" ? "allow-scripts allow-same-origin" : "allow-scripts";
56514
- return /* @__PURE__ */ jsx23(
56628
+ return /* @__PURE__ */ jsx24(
56515
56629
  "iframe",
56516
56630
  {
56517
56631
  title: card.title ?? "\u5DE5\u5177\u754C\u9762",
@@ -56528,10 +56642,10 @@ function ToolUiCardView({ card, sessionId }) {
56528
56642
  }
56529
56643
  function FileCard({ card, sessionId, path: path2 }) {
56530
56644
  const client = useBladeClient();
56531
- const [html, setHtml] = useState30(null);
56532
- const [failed, setFailed] = useState30(false);
56533
- const [refreshVersion, setRefreshVersion] = useState30(0);
56534
- useEffect22(() => {
56645
+ const [html, setHtml] = useState32(null);
56646
+ const [failed, setFailed] = useState32(false);
56647
+ const [refreshVersion, setRefreshVersion] = useState32(0);
56648
+ useEffect24(() => {
56535
56649
  const abort = new AbortController();
56536
56650
  setHtml(null);
56537
56651
  setFailed(false);
@@ -56551,7 +56665,7 @@ function FileCard({ card, sessionId, path: path2 }) {
56551
56665
  `${client.options.baseUrl.replace(/\/$/, "")}/`
56552
56666
  ).href;
56553
56667
  return /* @__PURE__ */ jsxs18("div", { children: [
56554
- /* @__PURE__ */ jsx23("div", { className: "flex justify-end py-2", children: /* @__PURE__ */ jsx23(
56668
+ /* @__PURE__ */ jsx24("div", { className: "flex justify-end py-2", children: /* @__PURE__ */ jsx24(
56555
56669
  "button",
56556
56670
  {
56557
56671
  type: "button",
@@ -56561,7 +56675,7 @@ function FileCard({ card, sessionId, path: path2 }) {
56561
56675
  children: "\u5237\u65B0"
56562
56676
  }
56563
56677
  ) }),
56564
- failed ? /* @__PURE__ */ jsx23("p", { role: "alert", children: "\u65E0\u6CD5\u6253\u5F00\u6587\u4EF6\uFF0C\u6587\u4EF6\u53EF\u80FD\u5DF2\u79FB\u52A8\u6216\u5220\u9664\u3002" }) : html === null ? /* @__PURE__ */ jsx23("p", { children: "\u6B63\u5728\u6253\u5F00\u6587\u4EF6\u2026" }) : /* @__PURE__ */ jsx23(
56678
+ failed ? /* @__PURE__ */ jsx24("p", { role: "alert", children: "\u65E0\u6CD5\u6253\u5F00\u6587\u4EF6\uFF0C\u6587\u4EF6\u53EF\u80FD\u5DF2\u79FB\u52A8\u6216\u5220\u9664\u3002" }) : html === null ? /* @__PURE__ */ jsx24("p", { children: "\u6B63\u5728\u6253\u5F00\u6587\u4EF6\u2026" }) : /* @__PURE__ */ jsx24(
56565
56679
  "iframe",
56566
56680
  {
56567
56681
  title: card.title ?? "\u6587\u4EF6\u9884\u89C8",
@@ -56591,13 +56705,13 @@ ${html}`;
56591
56705
  }
56592
56706
 
56593
56707
  // src/components/AssistantTurnBlock.tsx
56594
- import { jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
56708
+ import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
56595
56709
  function ThinkingBlock({
56596
56710
  reasoning,
56597
56711
  isStreaming,
56598
56712
  className
56599
56713
  }) {
56600
- const [open2, setOpen] = useState31(false);
56714
+ const [open2, setOpen] = useState33(false);
56601
56715
  if (!isStreaming) return null;
56602
56716
  return /* @__PURE__ */ jsxs19("div", { part: "thinking", className: cn("blade-chat-thinking ml-4 text-xs", className), children: [
56603
56717
  /* @__PURE__ */ jsxs19(
@@ -56608,8 +56722,8 @@ function ThinkingBlock({
56608
56722
  "aria-expanded": open2,
56609
56723
  className: "group/thinking inline-flex items-center gap-1 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
56610
56724
  children: [
56611
- /* @__PURE__ */ jsx24(Shimmer, { className: "text-xs", children: "\u6B63\u5728\u601D\u8003" }),
56612
- /* @__PURE__ */ jsx24(
56725
+ /* @__PURE__ */ jsx25(Shimmer, { className: "text-xs", children: "\u6B63\u5728\u601D\u8003" }),
56726
+ /* @__PURE__ */ jsx25(
56613
56727
  ChevronRight,
56614
56728
  {
56615
56729
  size: 14,
@@ -56622,7 +56736,7 @@ function ThinkingBlock({
56622
56736
  ]
56623
56737
  }
56624
56738
  ),
56625
- open2 ? /* @__PURE__ */ jsx24("div", { className: "mt-1.5 whitespace-pre-wrap text-xs leading-[22px] text-[hsl(var(--muted-foreground))]", children: reasoning }) : null
56739
+ open2 ? /* @__PURE__ */ jsx25("div", { className: "mt-1.5 whitespace-pre-wrap text-xs leading-[22px] text-[hsl(var(--muted-foreground))]", children: reasoning }) : null
56626
56740
  ] });
56627
56741
  }
56628
56742
  function getMessageText(message) {
@@ -56686,6 +56800,8 @@ function getExecutionDurationMs({
56686
56800
  isStreaming,
56687
56801
  now = null
56688
56802
  }) {
56803
+ const runDuration = getChatRunDuration(messages, isStreaming ? now : null);
56804
+ if (runDuration !== null) return runDuration;
56689
56805
  const knownDuration = messages.reduce(
56690
56806
  (total, message) => {
56691
56807
  if (typeof message.duration_ms === "number" && message.duration_ms > 0) {
@@ -56814,7 +56930,7 @@ function ExecutionToolRow({
56814
56930
  "size-3.5 shrink-0",
56815
56931
  failed ? "text-red-500" : "text-[hsl(var(--muted-foreground))]"
56816
56932
  );
56817
- const icon = toolCall.status === "pending" ? /* @__PURE__ */ jsx24(LoaderCircle, { className: cn(iconClass, "animate-spin"), "aria-hidden": "true" }) : toolCall.status === "error" ? /* @__PURE__ */ jsx24(CircleAlert, { className: iconClass, "aria-hidden": "true" }) : toolCall.status === "cancelled" ? /* @__PURE__ */ jsx24(X, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "WebSearch" || normalizedName === "WebFetch" ? /* @__PURE__ */ jsx24(Earth, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Bash" || normalizedName === "BgBash" ? /* @__PURE__ */ jsx24(Terminal, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Write" || normalizedName === "Edit" || normalizedName === "MultiEdit" ? /* @__PURE__ */ jsx24(FilePenLine, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Read" || normalizedName === "ReadSkill" || normalizedName === "get_skill_content" ? /* @__PURE__ */ jsx24(BookOpen, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Grep" || normalizedName === "Glob" || normalizedName === "search_skills" ? /* @__PURE__ */ jsx24(Search, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Agent" ? /* @__PURE__ */ jsx24(Bot, { className: iconClass, "aria-hidden": "true" }) : /* @__PURE__ */ jsx24(Wrench, { className: iconClass, "aria-hidden": "true" });
56933
+ const icon = toolCall.status === "pending" ? /* @__PURE__ */ jsx25(LoaderCircle, { className: cn(iconClass, "animate-spin"), "aria-hidden": "true" }) : toolCall.status === "error" ? /* @__PURE__ */ jsx25(CircleAlert, { className: iconClass, "aria-hidden": "true" }) : toolCall.status === "cancelled" ? /* @__PURE__ */ jsx25(X, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "WebSearch" || normalizedName === "WebFetch" ? /* @__PURE__ */ jsx25(Earth, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Bash" || normalizedName === "BgBash" ? /* @__PURE__ */ jsx25(Terminal, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Write" || normalizedName === "Edit" || normalizedName === "MultiEdit" ? /* @__PURE__ */ jsx25(FilePenLine, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Read" || normalizedName === "ReadSkill" || normalizedName === "get_skill_content" ? /* @__PURE__ */ jsx25(BookOpen, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Grep" || normalizedName === "Glob" || normalizedName === "search_skills" ? /* @__PURE__ */ jsx25(Search, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Agent" ? /* @__PURE__ */ jsx25(Bot, { className: iconClass, "aria-hidden": "true" }) : /* @__PURE__ */ jsx25(Wrench, { className: iconClass, "aria-hidden": "true" });
56818
56934
  const rowClassName = cn(
56819
56935
  "flex min-w-0 items-center gap-1 min-h-7 text-xs leading-5",
56820
56936
  failed ? "text-red-500" : "text-[hsl(var(--muted-foreground))]"
@@ -56828,7 +56944,7 @@ function ExecutionToolRow({
56828
56944
  title: label,
56829
56945
  children: [
56830
56946
  icon,
56831
- /* @__PURE__ */ jsx24("span", { className: "min-w-0 truncate", children: label })
56947
+ /* @__PURE__ */ jsx25("span", { className: "min-w-0 truncate", children: label })
56832
56948
  ]
56833
56949
  }
56834
56950
  );
@@ -56877,12 +56993,12 @@ function AssistantTurnBlock({
56877
56993
  )
56878
56994
  );
56879
56995
  const activeQuestionId = questionToolCalls.filter((toolCall) => toolCall.status === "pending").at(-1)?.id;
56880
- const [displayMode, setDisplayMode] = useState31(
56996
+ const [displayMode, setDisplayMode] = useState33(
56881
56997
  () => isStreaming || hasActionableToolCall ? "detail" : "compact"
56882
56998
  );
56883
- const userSelectedDisplayModeRef = useRef25(false);
56884
- const wasStreamingRef = useRef25(isStreaming);
56885
- useEffect23(() => {
56999
+ const userSelectedDisplayModeRef = useRef27(false);
57000
+ const wasStreamingRef = useRef27(isStreaming);
57001
+ useEffect25(() => {
56886
57002
  if (wasStreamingRef.current && !isStreaming && !userSelectedDisplayModeRef.current) {
56887
57003
  setDisplayMode(hasActionableToolCall ? "detail" : "compact");
56888
57004
  }
@@ -56890,22 +57006,23 @@ function AssistantTurnBlock({
56890
57006
  }, [hasActionableToolCall, isStreaming]);
56891
57007
  const effectiveMode = resolveTurnDisplayMode({ isStreaming, displayMode });
56892
57008
  const client = useOptionalBladeClient();
56893
- const executionDurationMs = getExecutionDurationMs({ messages, isStreaming });
56894
- const [clock, setClock] = useState31(() => performance.now());
56895
- const hasLiveStartTime = messages.some(
56896
- (message) => message.timestamp != null && Number.isFinite(Date.parse(message.timestamp))
56897
- );
56898
- useEffect23(() => {
56899
- if (!isStreaming || !hasLiveStartTime) return;
56900
- const timer = window.setInterval(() => setClock(performance.now()), 1e3);
56901
- return () => window.clearInterval(timer);
56902
- }, [hasLiveStartTime, isStreaming]);
56903
- const liveExecutionDurationMs = isStreaming ? getExecutionDurationMs({
57009
+ const clockNow = isStreaming ? sessionId ? getServerTime(client) : Date.now() : null;
57010
+ const executionDurationMs = getExecutionDurationMs({
56904
57011
  messages,
56905
57012
  isStreaming,
56906
- // Direct LLM mode has no Blade session and generates its own local timestamps.
56907
- now: sessionId ? getServerTime(client, clock) : Date.now()
56908
- }) : executionDurationMs;
57013
+ now: clockNow
57014
+ });
57015
+ const chatRun = getChatRun(messages);
57016
+ const isTimerRunning = isStreaming && (!chatRun || chatRun.status === "incomplete");
57017
+ const runningDurationMs = useLiveExecutionDuration({
57018
+ turnKey: `${sessionId ?? ""}:${messages[0]?.entry_id ?? ""}:${chatRun?.run_id ?? ""}`,
57019
+ isStreaming: isTimerRunning,
57020
+ initialDurationMs: executionDurationMs,
57021
+ isInitialDurationReady: clockNow !== null && messages.some(
57022
+ (message) => message.chat_run?.started_at != null && Number.isFinite(Date.parse(message.chat_run.started_at)) || message.chat_run == null && message.timestamp != null && Number.isFinite(Date.parse(message.timestamp))
57023
+ )
57024
+ });
57025
+ const liveExecutionDurationMs = isTimerRunning ? runningDurationMs : executionDurationMs;
56909
57026
  const memoryRefs = collectMemoryRefs(messages);
56910
57027
  const inlineToolUiCards = collectInlineToolUiCards(messages);
56911
57028
  if (!hasExecutionProcess) {
@@ -56916,15 +57033,15 @@ function AssistantTurnBlock({
56916
57033
  part: "assistant-turn",
56917
57034
  className: cn("blade-chat-assistant-turn flex flex-col gap-3", classNames?.assistantTurn),
56918
57035
  children: [
56919
- memoryRefs.length > 0 ? /* @__PURE__ */ jsx24(MemoryRefsHint, { refs: memoryRefs, className: classNames?.memoryRefs }) : null,
56920
- hasInterrupted && /* @__PURE__ */ jsx24("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
56921
- hasFailedWithoutContent && /* @__PURE__ */ jsx24("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
57036
+ memoryRefs.length > 0 ? /* @__PURE__ */ jsx25(MemoryRefsHint, { refs: memoryRefs, className: classNames?.memoryRefs }) : null,
57037
+ hasInterrupted && /* @__PURE__ */ jsx25("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
57038
+ hasFailedWithoutContent && /* @__PURE__ */ jsx25("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
56922
57039
  messages.map((message, index3) => {
56923
- return hasRenderableMessageContent(message) ? /* @__PURE__ */ jsx24(
57040
+ return hasRenderableMessageContent(message) ? /* @__PURE__ */ jsx25(
56924
57041
  "div",
56925
57042
  {
56926
57043
  className: "flex flex-col gap-3",
56927
- children: /* @__PURE__ */ jsx24(
57044
+ children: /* @__PURE__ */ jsx25(
56928
57045
  AssistantMessageContent,
56929
57046
  {
56930
57047
  message,
@@ -56938,7 +57055,7 @@ function AssistantTurnBlock({
56938
57055
  message.entry_id ?? `${message.timestamp ?? "assistant"}-${index3}`
56939
57056
  ) : null;
56940
57057
  }),
56941
- inlineToolUiCards.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "flex flex-col gap-3", children: inlineToolUiCards.map((entry) => /* @__PURE__ */ jsx24(ToolUiCardView, { card: entry.card, sessionId }, entry.key)) }) : null
57058
+ inlineToolUiCards.length > 0 ? /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-3", children: inlineToolUiCards.map((entry) => /* @__PURE__ */ jsx25(ToolUiCardView, { card: entry.card, sessionId }, entry.key)) }) : null
56942
57059
  ]
56943
57060
  }
56944
57061
  );
@@ -56950,16 +57067,16 @@ function AssistantTurnBlock({
56950
57067
  part: "assistant-turn",
56951
57068
  className: cn("blade-chat-assistant-turn flex flex-col gap-3", classNames?.assistantTurn),
56952
57069
  children: [
56953
- memoryRefs.length > 0 ? /* @__PURE__ */ jsx24(MemoryRefsHint, { refs: memoryRefs, className: classNames?.memoryRefs }) : null,
56954
- hasInterrupted && /* @__PURE__ */ jsx24("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
56955
- hasFailedWithoutContent && /* @__PURE__ */ jsx24("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
57070
+ memoryRefs.length > 0 ? /* @__PURE__ */ jsx25(MemoryRefsHint, { refs: memoryRefs, className: classNames?.memoryRefs }) : null,
57071
+ hasInterrupted && /* @__PURE__ */ jsx25("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
57072
+ hasFailedWithoutContent && /* @__PURE__ */ jsx25("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
56956
57073
  /* @__PURE__ */ jsxs19("div", { className: "flex w-full items-start gap-2.5", children: [
56957
- /* @__PURE__ */ jsx24(
57074
+ /* @__PURE__ */ jsx25(
56958
57075
  "span",
56959
57076
  {
56960
57077
  className: "grid size-[30px] shrink-0 place-items-center rounded-full bg-[hsl(var(--muted)/0.55)] text-[hsl(var(--foreground))]",
56961
57078
  "aria-hidden": "true",
56962
- children: /* @__PURE__ */ jsx24(Bot, { size: 16 })
57079
+ children: /* @__PURE__ */ jsx25(Bot, { size: 16 })
56963
57080
  }
56964
57081
  ),
56965
57082
  /* @__PURE__ */ jsxs19("div", { className: "min-w-0 flex-1 pt-0.5", children: [
@@ -56976,14 +57093,14 @@ function AssistantTurnBlock({
56976
57093
  "data-testid": "assistant-execution-summary",
56977
57094
  className: "inline-flex min-w-0 max-w-full select-none items-center gap-1 bg-transparent p-0 text-left text-xs leading-[22px] text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
56978
57095
  children: [
56979
- /* @__PURE__ */ jsx24("span", { className: "min-w-0 truncate", children: executionSummaryLabel({
57096
+ /* @__PURE__ */ jsx25("span", { className: "min-w-0 truncate", children: executionSummaryLabel({
56980
57097
  messages,
56981
57098
  isStreaming,
56982
57099
  durationMs: liveExecutionDurationMs,
56983
57100
  sessionStatus,
56984
57101
  askAnswers
56985
57102
  }) }),
56986
- /* @__PURE__ */ jsx24(
57103
+ /* @__PURE__ */ jsx25(
56987
57104
  ChevronRight,
56988
57105
  {
56989
57106
  size: 14,
@@ -56998,10 +57115,10 @@ function AssistantTurnBlock({
56998
57115
  ]
56999
57116
  }
57000
57117
  ),
57001
- /* @__PURE__ */ jsx24("div", { className: "mt-3 h-px w-full bg-[hsl(var(--border)/0.75)]" })
57118
+ /* @__PURE__ */ jsx25("div", { className: "mt-3 h-px w-full bg-[hsl(var(--border)/0.75)]" })
57002
57119
  ] })
57003
57120
  ] }),
57004
- effectiveMode === "detail" ? /* @__PURE__ */ jsx24("div", { className: "ml-10 flex flex-col gap-1", children: messages.map((message, index3) => {
57121
+ effectiveMode === "detail" ? /* @__PURE__ */ jsx25("div", { className: "ml-10 flex flex-col gap-1", children: messages.map((message, index3) => {
57005
57122
  const isLast = index3 === messages.length - 1;
57006
57123
  const streamingThis = isStreaming && isLast;
57007
57124
  const text4 = getMessageText(message);
@@ -57016,7 +57133,7 @@ function AssistantTurnBlock({
57016
57133
  {
57017
57134
  className: "flex flex-col gap-1",
57018
57135
  children: [
57019
- showReasoning && message.reasoning ? /* @__PURE__ */ jsx24(
57136
+ showReasoning && message.reasoning ? /* @__PURE__ */ jsx25(
57020
57137
  ThinkingBlock,
57021
57138
  {
57022
57139
  reasoning: message.reasoning,
@@ -57025,7 +57142,7 @@ function AssistantTurnBlock({
57025
57142
  }
57026
57143
  ) : null,
57027
57144
  orderedParts.length > 0 ? orderedParts.map(
57028
- (part) => part.type === "text" ? /* @__PURE__ */ jsx24(
57145
+ (part) => part.type === "text" ? /* @__PURE__ */ jsx25(
57029
57146
  AssistantMessageContent,
57030
57147
  {
57031
57148
  message: { ...message, content: part.content, tool_calls: turnToolCalls },
@@ -57036,9 +57153,9 @@ function AssistantTurnBlock({
57036
57153
  renderers
57037
57154
  },
57038
57155
  part.key
57039
- ) : /* @__PURE__ */ jsx24("div", { className: "flex flex-col gap-1", children: part.toolCalls.map((toolCall) => {
57156
+ ) : /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-1", children: part.toolCalls.map((toolCall) => {
57040
57157
  const custom2 = renderers?.toolCall?.(toolCall);
57041
- return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */ jsx24("div", { children: custom2 }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx24(AgentLoopBlock, { toolCall, className: classNames?.agentLoop }, toolCall.id) : /* @__PURE__ */ jsx24(
57158
+ return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */ jsx25("div", { children: custom2 }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx25(AgentLoopBlock, { toolCall, className: classNames?.agentLoop }, toolCall.id) : /* @__PURE__ */ jsx25(
57042
57159
  ExecutionToolRow,
57043
57160
  {
57044
57161
  toolCall,
@@ -57047,7 +57164,7 @@ function AssistantTurnBlock({
57047
57164
  toolCall.id
57048
57165
  );
57049
57166
  }) }, part.key)
57050
- ) : hasRenderableMessageContent(message) && message !== finalMessage ? /* @__PURE__ */ jsx24(
57167
+ ) : hasRenderableMessageContent(message) && message !== finalMessage ? /* @__PURE__ */ jsx25(
57051
57168
  AssistantMessageContent,
57052
57169
  {
57053
57170
  message,
@@ -57058,9 +57175,9 @@ function AssistantTurnBlock({
57058
57175
  renderers
57059
57176
  }
57060
57177
  ) : null,
57061
- orderedParts.length === 0 && toolCalls.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "flex flex-col gap-1", children: toolCalls.map((toolCall) => {
57178
+ orderedParts.length === 0 && toolCalls.length > 0 ? /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-1", children: toolCalls.map((toolCall) => {
57062
57179
  const custom2 = renderers?.toolCall?.(toolCall);
57063
- return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */ jsx24("div", { children: custom2 }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx24(AgentLoopBlock, { toolCall, className: classNames?.agentLoop }, toolCall.id) : /* @__PURE__ */ jsx24(
57180
+ return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */ jsx25("div", { children: custom2 }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx25(AgentLoopBlock, { toolCall, className: classNames?.agentLoop }, toolCall.id) : /* @__PURE__ */ jsx25(
57064
57181
  ExecutionToolRow,
57065
57182
  {
57066
57183
  toolCall,
@@ -57069,14 +57186,14 @@ function AssistantTurnBlock({
57069
57186
  toolCall.id
57070
57187
  );
57071
57188
  }) }) : null,
57072
- messageToolUiCards.map((entry) => /* @__PURE__ */ jsx24(ToolUiCardView, { card: entry.card, sessionId }, entry.key))
57189
+ messageToolUiCards.map((entry) => /* @__PURE__ */ jsx25(ToolUiCardView, { card: entry.card, sessionId }, entry.key))
57073
57190
  ]
57074
57191
  },
57075
57192
  message.entry_id ?? `${message.timestamp ?? "assistant"}-${index3}`
57076
57193
  );
57077
57194
  }) }) : null,
57078
- effectiveMode === "compact" && inlineToolUiCards.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "ml-10 flex flex-col gap-3", children: inlineToolUiCards.map((entry) => /* @__PURE__ */ jsx24(ToolUiCardView, { card: entry.card, sessionId }, entry.key)) }) : null,
57079
- finalMessage && (effectiveMode === "compact" || finalOrderedParts.length === 0) ? /* @__PURE__ */ jsx24("div", { className: "ml-10", children: /* @__PURE__ */ jsx24(
57195
+ effectiveMode === "compact" && inlineToolUiCards.length > 0 ? /* @__PURE__ */ jsx25("div", { className: "ml-10 flex flex-col gap-3", children: inlineToolUiCards.map((entry) => /* @__PURE__ */ jsx25(ToolUiCardView, { card: entry.card, sessionId }, entry.key)) }) : null,
57196
+ finalMessage && (effectiveMode === "compact" || finalOrderedParts.length === 0) ? /* @__PURE__ */ jsx25("div", { className: "ml-10", children: /* @__PURE__ */ jsx25(
57080
57197
  AssistantMessageContent,
57081
57198
  {
57082
57199
  message: finalMessage,
@@ -57086,7 +57203,7 @@ function AssistantTurnBlock({
57086
57203
  renderers
57087
57204
  }
57088
57205
  ) }) : null,
57089
- questionToolCalls.map((toolCall) => /* @__PURE__ */ jsx24(
57206
+ questionToolCalls.map((toolCall) => /* @__PURE__ */ jsx25(
57090
57207
  ToolCallBlock,
57091
57208
  {
57092
57209
  toolCall,
@@ -57112,22 +57229,22 @@ function collectMemoryRefs(messages) {
57112
57229
  return [...refs.values()];
57113
57230
  }
57114
57231
  function MemoryRefsHint({ refs, className }) {
57115
- const [expanded, setExpanded] = useState31(false);
57232
+ const [expanded, setExpanded] = useState33(false);
57116
57233
  const label = refs.some((ref) => ref.skill_name) ? "\u53C2\u8003\u4E86\u8BE5\u6280\u80FD\u7684\u5386\u53F2\u7ECF\u9A8C" : "\u53C2\u8003\u4E86\u5386\u53F2\u7ECF\u9A8C";
57117
57234
  return /* @__PURE__ */ jsxs19("div", { part: "memory-refs", className: cn("blade-chat-memory-refs ml-1 w-full max-w-[680px]", className), children: [
57118
57235
  /* @__PURE__ */ jsxs19("button", { type: "button", onClick: () => setExpanded((value) => !value), className: "inline-flex h-8 items-center gap-1.5 rounded-lg border border-[hsl(var(--primary)/0.22)] bg-[hsl(var(--primary)/0.07)] px-3 text-xs font-medium text-[hsl(var(--primary))]", children: [
57119
- /* @__PURE__ */ jsx24(BookOpen, { size: 12 }),
57236
+ /* @__PURE__ */ jsx25(BookOpen, { size: 12 }),
57120
57237
  /* @__PURE__ */ jsxs19("span", { children: [
57121
57238
  label,
57122
57239
  "\uFF08",
57123
57240
  refs.length,
57124
57241
  "\uFF09"
57125
57242
  ] }),
57126
- /* @__PURE__ */ jsx24(ChevronRight, { size: 10, className: cn("transition-transform", expanded && "rotate-90") })
57243
+ /* @__PURE__ */ jsx25(ChevronRight, { size: 10, className: cn("transition-transform", expanded && "rotate-90") })
57127
57244
  ] }),
57128
- expanded ? /* @__PURE__ */ jsx24("div", { className: "mt-2 flex flex-col gap-2 rounded-xl border border-[hsl(var(--border)/0.8)] bg-[hsl(var(--muted)/0.28)] p-2.5", children: refs.map((ref) => /* @__PURE__ */ jsxs19("div", { className: "rounded-lg border border-[hsl(var(--border)/0.55)] bg-[hsl(var(--background)/0.72)] px-3 py-2.5 text-xs", children: [
57129
- /* @__PURE__ */ jsx24("p", { className: "line-clamp-2 break-words leading-5", children: ref.content_preview }),
57130
- ref.skill_name ? /* @__PURE__ */ jsx24("span", { className: "mt-1 inline-flex text-[10px] text-[hsl(var(--primary))]", children: ref.skill_name }) : null
57245
+ expanded ? /* @__PURE__ */ jsx25("div", { className: "mt-2 flex flex-col gap-2 rounded-xl border border-[hsl(var(--border)/0.8)] bg-[hsl(var(--muted)/0.28)] p-2.5", children: refs.map((ref) => /* @__PURE__ */ jsxs19("div", { className: "rounded-lg border border-[hsl(var(--border)/0.55)] bg-[hsl(var(--background)/0.72)] px-3 py-2.5 text-xs", children: [
57246
+ /* @__PURE__ */ jsx25("p", { className: "line-clamp-2 break-words leading-5", children: ref.content_preview }),
57247
+ ref.skill_name ? /* @__PURE__ */ jsx25("span", { className: "mt-1 inline-flex text-[10px] text-[hsl(var(--primary))]", children: ref.skill_name }) : null
57131
57248
  ] }, ref.id)) }) : null
57132
57249
  ] });
57133
57250
  }
@@ -57143,9 +57260,9 @@ function AssistantMessageContent({
57143
57260
  const imageParts = getImageParts(message.content);
57144
57261
  const fileParts = getFileParts(message.content);
57145
57262
  const failed = message.status === "failed";
57146
- const failedBadge = failed ? /* @__PURE__ */ jsx24("div", { className: "w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }) : null;
57263
+ const failedBadge = failed ? /* @__PURE__ */ jsx25("div", { className: "w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }) : null;
57147
57264
  const customText = text4 ? renderers?.assistantText?.({ message, streaming, compact, sessionId }) : void 0;
57148
- const textContent = text4 ? customText ?? /* @__PURE__ */ jsx24(
57265
+ const textContent = text4 ? customText ?? /* @__PURE__ */ jsx25(
57149
57266
  "div",
57150
57267
  {
57151
57268
  part: "assistant-text",
@@ -57154,7 +57271,7 @@ function AssistantMessageContent({
57154
57271
  compact ? "text-xs leading-[22px] text-[hsl(var(--foreground))]" : "text-[15px] leading-8 text-[hsl(var(--foreground))]",
57155
57272
  classNames?.assistantText
57156
57273
  ),
57157
- children: /* @__PURE__ */ jsx24(
57274
+ children: /* @__PURE__ */ jsx25(
57158
57275
  MarkdownContent,
57159
57276
  {
57160
57277
  mode: streaming ? "streaming" : "static",
@@ -57174,7 +57291,7 @@ function AssistantMessageContent({
57174
57291
  }
57175
57292
  return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-3", children: [
57176
57293
  failedBadge,
57177
- imageParts.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx24(
57294
+ imageParts.length > 0 ? /* @__PURE__ */ jsx25("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx25(
57178
57295
  MessageImage,
57179
57296
  {
57180
57297
  src: part.image_url.url,
@@ -57185,7 +57302,7 @@ function AssistantMessageContent({
57185
57302
  },
57186
57303
  part.image_url.url
57187
57304
  )) }) : null,
57188
- fileParts.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "flex flex-wrap gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs19(
57305
+ fileParts.length > 0 ? /* @__PURE__ */ jsx25("div", { className: "flex flex-wrap gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs19(
57189
57306
  "div",
57190
57307
  {
57191
57308
  part: "file-card",
@@ -57195,8 +57312,8 @@ function AssistantMessageContent({
57195
57312
  ),
57196
57313
  title: part.name,
57197
57314
  children: [
57198
- /* @__PURE__ */ jsx24(FileText, { size: 12, className: "blade-chat-file-card-icon shrink-0" }),
57199
- /* @__PURE__ */ jsx24("span", { className: "blade-chat-file-card-name max-w-56 truncate", children: part.name })
57315
+ /* @__PURE__ */ jsx25(FileText, { size: 12, className: "blade-chat-file-card-icon shrink-0" }),
57316
+ /* @__PURE__ */ jsx25("span", { className: "blade-chat-file-card-name max-w-56 truncate", children: part.name })
57200
57317
  ]
57201
57318
  },
57202
57319
  `${part.name}-${part.data.slice(0, 32)}`
@@ -57207,7 +57324,7 @@ function AssistantMessageContent({
57207
57324
 
57208
57325
  // src/components/RenderErrorBoundary.tsx
57209
57326
  import { Component as Component2 } from "react";
57210
- import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
57327
+ import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
57211
57328
  function getFirstComponentName(componentStack) {
57212
57329
  const match = componentStack.match(/\n\s+at\s+([^\s(]+)/);
57213
57330
  return match?.[1] ?? null;
@@ -57240,8 +57357,8 @@ var RenderErrorBoundary = class extends Component2 {
57240
57357
  return children;
57241
57358
  }
57242
57359
  const componentName = getFirstComponentName(componentStack);
57243
- return /* @__PURE__ */ jsx25("div", { className: "blade-chat-render-error rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs20("div", { className: "flex items-start gap-2", children: [
57244
- /* @__PURE__ */ jsx25(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
57360
+ return /* @__PURE__ */ jsx26("div", { className: "blade-chat-render-error rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs20("div", { className: "flex items-start gap-2", children: [
57361
+ /* @__PURE__ */ jsx26(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
57245
57362
  /* @__PURE__ */ jsxs20("div", { className: "min-w-0 flex-1", children: [
57246
57363
  /* @__PURE__ */ jsxs20("div", { className: "font-medium", children: [
57247
57364
  label,
@@ -57251,15 +57368,15 @@ var RenderErrorBoundary = class extends Component2 {
57251
57368
  componentName ? `\u7EC4\u4EF6\uFF1A${componentName}\u3002` : null,
57252
57369
  error61.message || "\u53D1\u751F\u4E86\u672A\u9884\u671F\u7684\u6E32\u67D3\u9519\u8BEF\u3002"
57253
57370
  ] }),
57254
- details ? /* @__PURE__ */ jsx25("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
57371
+ details ? /* @__PURE__ */ jsx26("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
57255
57372
  ] })
57256
57373
  ] }) });
57257
57374
  }
57258
57375
  };
57259
57376
 
57260
57377
  // src/components/PostChatFollowupBlock.tsx
57261
- import { useCallback as useCallback28, useEffect as useEffect24, useRef as useRef26, useState as useState32 } from "react";
57262
- import { Fragment as Fragment8, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
57378
+ import { useCallback as useCallback28, useEffect as useEffect26, useRef as useRef28, useState as useState34 } from "react";
57379
+ import { Fragment as Fragment8, jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
57263
57380
  function emitInteraction(callback, event) {
57264
57381
  try {
57265
57382
  callback?.(event);
@@ -57278,7 +57395,7 @@ function ArtifactCard({
57278
57395
  onArtifactOpened
57279
57396
  }) {
57280
57397
  const client = useBladeClient();
57281
- const [downloading, setDownloading] = useState32(false);
57398
+ const [downloading, setDownloading] = useState34(false);
57282
57399
  const name = artifact.label || basename(artifact.target);
57283
57400
  if (artifact.kind === "link") {
57284
57401
  return /* @__PURE__ */ jsxs21(
@@ -57292,9 +57409,9 @@ function ArtifactCard({
57292
57409
  ${artifact.target}`,
57293
57410
  className: "group relative flex min-w-0 items-center gap-1.5 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2 py-1.5 text-xs text-[hsl(var(--card-foreground))] hover:bg-[hsl(var(--accent))]",
57294
57411
  children: [
57295
- /* @__PURE__ */ jsx26(Globe, { size: 15, className: "shrink-0 text-[hsl(var(--primary))]" }),
57296
- /* @__PURE__ */ jsx26("span", { className: "min-w-0 flex-1 truncate font-medium", children: name }),
57297
- /* @__PURE__ */ jsx26(ArrowUpRight, { size: 13, className: "absolute right-2 opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" })
57412
+ /* @__PURE__ */ jsx27(Globe, { size: 15, className: "shrink-0 text-[hsl(var(--primary))]" }),
57413
+ /* @__PURE__ */ jsx27("span", { className: "min-w-0 flex-1 truncate font-medium", children: name }),
57414
+ /* @__PURE__ */ jsx27(ArrowUpRight, { size: 13, className: "absolute right-2 opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" })
57298
57415
  ]
57299
57416
  }
57300
57417
  );
@@ -57329,7 +57446,7 @@ ${artifact.target}`,
57329
57446
  setDownloading(false);
57330
57447
  }
57331
57448
  };
57332
- return /* @__PURE__ */ jsx26(
57449
+ return /* @__PURE__ */ jsx27(
57333
57450
  "a",
57334
57451
  {
57335
57452
  href: downloadUrl,
@@ -57384,15 +57501,15 @@ function ResultFeedback({
57384
57501
  onFeedbackSaved
57385
57502
  }) {
57386
57503
  const client = useBladeClient();
57387
- const [saved, setSaved] = useState32(savedFeedback ?? null);
57388
- const [helpful, setHelpful] = useState32(savedFeedback?.helpful ?? null);
57389
- const [reason, setReason] = useState32(savedFeedback?.reason ?? null);
57390
- const [saving, setSaving] = useState32(false);
57391
- const [saveError, setSaveError] = useState32(false);
57392
- const reportedShown = useRef26(false);
57393
- const latestChoice = useRef26(null);
57504
+ const [saved, setSaved] = useState34(savedFeedback ?? null);
57505
+ const [helpful, setHelpful] = useState34(savedFeedback?.helpful ?? null);
57506
+ const [reason, setReason] = useState34(savedFeedback?.reason ?? null);
57507
+ const [saving, setSaving] = useState34(false);
57508
+ const [saveError, setSaveError] = useState34(false);
57509
+ const reportedShown = useRef28(false);
57510
+ const latestChoice = useRef28(null);
57394
57511
  const eligible = followup.feedback_eligible === true && Boolean(sessionId) && !isViewer;
57395
- useEffect24(() => {
57512
+ useEffect26(() => {
57396
57513
  if (!eligible || reportedShown.current) return;
57397
57514
  reportedShown.current = true;
57398
57515
  emitInteraction(onInteraction, {
@@ -57401,7 +57518,7 @@ function ResultFeedback({
57401
57518
  assistantEntryId: followup.assistant_entry_id
57402
57519
  });
57403
57520
  }, [eligible, followup.assistant_entry_id, onInteraction, sessionId]);
57404
- useEffect24(() => {
57521
+ useEffect26(() => {
57405
57522
  if (!savedFeedback || latestChoice.current) return;
57406
57523
  setSaved(savedFeedback);
57407
57524
  setHelpful(savedFeedback.helpful);
@@ -57448,9 +57565,9 @@ function ResultFeedback({
57448
57565
  "aria-label": "\u7ED3\u679C\u53CD\u9988",
57449
57566
  className: "flex flex-col gap-2 border-t border-[hsl(var(--border))] pt-3",
57450
57567
  children: [
57451
- /* @__PURE__ */ jsx26("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u76EE\u524D\u7684\u6574\u4F53\u7ED3\u679C\u6709\u5E2E\u52A9\u5417\uFF1F" }),
57568
+ /* @__PURE__ */ jsx27("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u76EE\u524D\u7684\u6574\u4F53\u7ED3\u679C\u6709\u5E2E\u52A9\u5417\uFF1F" }),
57452
57569
  /* @__PURE__ */ jsxs21("div", { className: "flex flex-wrap gap-1.5", children: [
57453
- /* @__PURE__ */ jsx26(
57570
+ /* @__PURE__ */ jsx27(
57454
57571
  "button",
57455
57572
  {
57456
57573
  type: "button",
@@ -57461,7 +57578,7 @@ function ResultFeedback({
57461
57578
  children: "\u6709\u5E2E\u52A9"
57462
57579
  }
57463
57580
  ),
57464
- /* @__PURE__ */ jsx26(
57581
+ /* @__PURE__ */ jsx27(
57465
57582
  "button",
57466
57583
  {
57467
57584
  type: "button",
@@ -57473,7 +57590,7 @@ function ResultFeedback({
57473
57590
  }
57474
57591
  )
57475
57592
  ] }),
57476
- helpful === false ? /* @__PURE__ */ jsx26("div", { className: "flex flex-wrap gap-1.5", "aria-label": "\u6CA1\u5E2E\u52A9\u7684\u4E3B\u8981\u539F\u56E0", children: FEEDBACK_REASONS.map((item) => /* @__PURE__ */ jsx26(
57593
+ helpful === false ? /* @__PURE__ */ jsx27("div", { className: "flex flex-wrap gap-1.5", "aria-label": "\u6CA1\u5E2E\u52A9\u7684\u4E3B\u8981\u539F\u56E0", children: FEEDBACK_REASONS.map((item) => /* @__PURE__ */ jsx27(
57477
57594
  "button",
57478
57595
  {
57479
57596
  type: "button",
@@ -57486,8 +57603,8 @@ function ResultFeedback({
57486
57603
  item.value
57487
57604
  )) }) : null,
57488
57605
  saveError ? /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--destructive))]", children: [
57489
- /* @__PURE__ */ jsx26("span", { children: "\u53CD\u9988\u6682\u672A\u4FDD\u5B58\uFF0C\u53EF\u91CD\u8BD5" }),
57490
- /* @__PURE__ */ jsx26(
57606
+ /* @__PURE__ */ jsx27("span", { children: "\u53CD\u9988\u6682\u672A\u4FDD\u5B58\uFF0C\u53EF\u91CD\u8BD5" }),
57607
+ /* @__PURE__ */ jsx27(
57491
57608
  "button",
57492
57609
  {
57493
57610
  type: "button",
@@ -57499,7 +57616,7 @@ function ResultFeedback({
57499
57616
  children: "\u91CD\u8BD5"
57500
57617
  }
57501
57618
  )
57502
- ] }) : saved ? /* @__PURE__ */ jsx26("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539" }) : null
57619
+ ] }) : saved ? /* @__PURE__ */ jsx27("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539" }) : null
57503
57620
  ]
57504
57621
  }
57505
57622
  );
@@ -57515,14 +57632,14 @@ function PostChatFollowupBlock({
57515
57632
  className,
57516
57633
  suggestionClassName
57517
57634
  }) {
57518
- const [expanded, setExpanded] = useState32(false);
57519
- const adopted = useRef26(/* @__PURE__ */ new Set());
57520
- const reportedSuggestions = useRef26(false);
57521
- const reportedArtifacts = useRef26(/* @__PURE__ */ new Set());
57522
- const openedArtifacts = useRef26(/* @__PURE__ */ new Set());
57635
+ const [expanded, setExpanded] = useState34(false);
57636
+ const adopted = useRef28(/* @__PURE__ */ new Set());
57637
+ const reportedSuggestions = useRef28(false);
57638
+ const reportedArtifacts = useRef28(/* @__PURE__ */ new Set());
57639
+ const openedArtifacts = useRef28(/* @__PURE__ */ new Set());
57523
57640
  const artifacts = followup.final_artifacts ?? [];
57524
57641
  const visibleArtifacts = expanded ? artifacts : artifacts.slice(0, 3);
57525
- useEffect24(() => {
57642
+ useEffect26(() => {
57526
57643
  if (!reportedSuggestions.current && followup.suggestions.length > 0) {
57527
57644
  reportedSuggestions.current = true;
57528
57645
  emitInteraction(onInteraction, {
@@ -57579,12 +57696,12 @@ function PostChatFollowupBlock({
57579
57696
  children: [
57580
57697
  followup.recaption || artifacts.length > 0 ? /* @__PURE__ */ jsxs21("section", { "aria-label": "\u672C\u8F6E\u5C0F\u7ED3", className: "flex flex-col gap-2", children: [
57581
57698
  /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-1.5 text-xs font-medium text-[hsl(var(--muted-foreground))]", children: [
57582
- /* @__PURE__ */ jsx26(Sparkles, { size: 14 }),
57699
+ /* @__PURE__ */ jsx27(Sparkles, { size: 14 }),
57583
57700
  "\u672C\u8F6E\u5C0F\u7ED3"
57584
57701
  ] }),
57585
- followup.recaption ? /* @__PURE__ */ jsx26("p", { className: "text-[13px] leading-5", children: followup.recaption }) : null,
57702
+ followup.recaption ? /* @__PURE__ */ jsx27("p", { className: "text-[13px] leading-5", children: followup.recaption }) : null,
57586
57703
  artifacts.length > 0 ? /* @__PURE__ */ jsxs21(Fragment8, { children: [
57587
- /* @__PURE__ */ jsx26("div", { className: "grid max-w-full grid-cols-3 gap-1.5", children: visibleArtifacts.map((artifact, artifactIndex) => /* @__PURE__ */ jsx26(
57704
+ /* @__PURE__ */ jsx27("div", { className: "grid max-w-full grid-cols-3 gap-1.5", children: visibleArtifacts.map((artifact, artifactIndex) => /* @__PURE__ */ jsx27(
57588
57705
  ArtifactCard,
57589
57706
  {
57590
57707
  artifact,
@@ -57605,14 +57722,14 @@ function PostChatFollowupBlock({
57605
57722
  className: "flex w-fit items-center gap-0.5 text-[11px] text-[hsl(var(--muted-foreground))]",
57606
57723
  children: [
57607
57724
  expanded ? "\u6536\u8D77" : `\u5C55\u5F00 ${artifacts.length - 3} \u4E2A`,
57608
- /* @__PURE__ */ jsx26(ChevronDown, { size: 13, className: expanded ? "rotate-180" : void 0 })
57725
+ /* @__PURE__ */ jsx27(ChevronDown, { size: 13, className: expanded ? "rotate-180" : void 0 })
57609
57726
  ]
57610
57727
  }
57611
57728
  ) : null
57612
57729
  ] }) : null
57613
57730
  ] }) : null,
57614
57731
  followup.suggestions.length > 0 ? /* @__PURE__ */ jsxs21("section", { "aria-label": "\u4E0B\u4E00\u6B65\u5EFA\u8BAE", className: "flex flex-col gap-1.5", children: [
57615
- /* @__PURE__ */ jsx26("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
57732
+ /* @__PURE__ */ jsx27("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
57616
57733
  followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */ jsxs21(
57617
57734
  "button",
57618
57735
  {
@@ -57636,14 +57753,14 @@ function PostChatFollowupBlock({
57636
57753
  suggestionClassName
57637
57754
  ),
57638
57755
  children: [
57639
- /* @__PURE__ */ jsx26("span", { children: suggestion }),
57640
- /* @__PURE__ */ jsx26(ArrowRight, { size: 14, className: "ml-auto shrink-0" })
57756
+ /* @__PURE__ */ jsx27("span", { children: suggestion }),
57757
+ /* @__PURE__ */ jsx27(ArrowRight, { size: 14, className: "ml-auto shrink-0" })
57641
57758
  ]
57642
57759
  },
57643
57760
  suggestion
57644
57761
  ))
57645
57762
  ] }) : null,
57646
- /* @__PURE__ */ jsx26(
57763
+ /* @__PURE__ */ jsx27(
57647
57764
  ResultFeedback,
57648
57765
  {
57649
57766
  followup,
@@ -57720,31 +57837,31 @@ function parseWhatIfPrompt(text4) {
57720
57837
  }
57721
57838
 
57722
57839
  // src/components/WhatIfUserBubble.tsx
57723
- import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
57840
+ import { jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
57724
57841
  function WhatIfUserBubble({ parsed, onQuoteClick }) {
57725
57842
  const { fromStep, quotes, userText } = parsed;
57726
57843
  return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col items-end gap-2", children: [
57727
57844
  /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.5)] px-2.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: [
57728
- /* @__PURE__ */ jsx27(RefreshCcw, { size: 10 }),
57729
- /* @__PURE__ */ jsx27("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
57845
+ /* @__PURE__ */ jsx28(RefreshCcw, { size: 10 }),
57846
+ /* @__PURE__ */ jsx28("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
57730
57847
  ] }),
57731
- quotes.length > 0 && /* @__PURE__ */ jsx27("div", { className: "flex max-w-[min(72vw,42rem)] flex-col items-stretch gap-2", children: quotes.map((quote, index3) => {
57848
+ quotes.length > 0 && /* @__PURE__ */ jsx28("div", { className: "flex max-w-[min(72vw,42rem)] flex-col items-stretch gap-2", children: quotes.map((quote, index3) => {
57732
57849
  const clickable = quote.stepNumber != null && !!onQuoteClick;
57733
57850
  const label = quote.stepNumber != null ? `\u6B65\u9AA4${quote.stepNumber} \xB7 ${quote.label}` : quote.label;
57734
57851
  return /* @__PURE__ */ jsxs22("div", { className: "rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card)/0.8)] px-3 py-2 text-left", children: [
57735
57852
  /* @__PURE__ */ jsxs22("button", { type: "button", disabled: !clickable, onClick: () => clickable && onQuoteClick(quote.stepNumber), className: "inline-flex max-w-full items-center gap-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] disabled:cursor-default", title: clickable ? "\u8DF3\u8F6C\u5230\u5BF9\u5E94\u6B65\u9AA4\u5361\u7247" : void 0, children: [
57736
- /* @__PURE__ */ jsx27("span", { children: "\u21B3" }),
57737
- /* @__PURE__ */ jsx27("span", { className: "truncate", children: label })
57853
+ /* @__PURE__ */ jsx28("span", { children: "\u21B3" }),
57854
+ /* @__PURE__ */ jsx28("span", { className: "truncate", children: label })
57738
57855
  ] }),
57739
- quote.snapshot ? /* @__PURE__ */ jsx27("div", { className: "mt-1 border-l-2 border-[hsl(var(--accent-foreground)/0.35)] pl-2 text-xs leading-relaxed text-[hsl(var(--foreground)/0.8)]", children: /* @__PURE__ */ jsx27(MarkdownContent, { className: "blade-chat-prose", children: quote.snapshot }) }) : null
57856
+ quote.snapshot ? /* @__PURE__ */ jsx28("div", { className: "mt-1 border-l-2 border-[hsl(var(--accent-foreground)/0.35)] pl-2 text-xs leading-relaxed text-[hsl(var(--foreground)/0.8)]", children: /* @__PURE__ */ jsx28(MarkdownContent, { className: "blade-chat-prose", children: quote.snapshot }) }) : null
57740
57857
  ] }, `${quote.stepNumber ?? "x"}-${index3}`);
57741
57858
  }) }),
57742
- userText && /* @__PURE__ */ jsx27("div", { className: "rounded-2xl border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-4 py-2.5 text-sm leading-relaxed text-[hsl(var(--user-msg-fg))]", children: /* @__PURE__ */ jsx27(MarkdownContent, { className: "blade-chat-prose", children: userText }) })
57859
+ userText && /* @__PURE__ */ jsx28("div", { className: "rounded-2xl border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-4 py-2.5 text-sm leading-relaxed text-[hsl(var(--user-msg-fg))]", children: /* @__PURE__ */ jsx28(MarkdownContent, { className: "blade-chat-prose", children: userText }) })
57743
57860
  ] });
57744
57861
  }
57745
57862
 
57746
57863
  // src/components/UserMessageBubble.tsx
57747
- import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
57864
+ import { jsx as jsx29, jsxs as jsxs23 } from "react/jsx-runtime";
57748
57865
  function isUserMessage(message) {
57749
57866
  return message.role === "user";
57750
57867
  }
@@ -57759,17 +57876,17 @@ function UserMessageBubble({ message, classNames, renderers }) {
57759
57876
  const whatifParsed = text4 && imageParts.length === 0 && fileParts.length === 0 ? parseWhatIfPrompt(text4) : null;
57760
57877
  const customBubble = renderers?.userMessage?.({ message });
57761
57878
  if (whatifParsed) {
57762
- return /* @__PURE__ */ jsx28("div", { part: "user-row", className: cn("blade-chat-user-row flex justify-end", classNames?.userMessage), children: /* @__PURE__ */ jsx28("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: customBubble ?? /* @__PURE__ */ jsx28(
57879
+ return /* @__PURE__ */ jsx29("div", { part: "user-row", className: cn("blade-chat-user-row flex justify-end", classNames?.userMessage), children: /* @__PURE__ */ jsx29("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: customBubble ?? /* @__PURE__ */ jsx29(
57763
57880
  "div",
57764
57881
  {
57765
57882
  part: "user-bubble",
57766
57883
  className: cn("blade-chat-user-bubble", classNames?.userBubble),
57767
- children: /* @__PURE__ */ jsx28(WhatIfUserBubble, { parsed: whatifParsed })
57884
+ children: /* @__PURE__ */ jsx29(WhatIfUserBubble, { parsed: whatifParsed })
57768
57885
  }
57769
57886
  ) }) });
57770
57887
  }
57771
- return /* @__PURE__ */ jsx28("div", { part: "user-row", className: cn("blade-chat-user-row flex justify-end", classNames?.userMessage), children: /* @__PURE__ */ jsxs23("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: [
57772
- imageParts.length > 0 && /* @__PURE__ */ jsx28("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx28(
57888
+ return /* @__PURE__ */ jsx29("div", { part: "user-row", className: cn("blade-chat-user-row flex justify-end", classNames?.userMessage), children: /* @__PURE__ */ jsxs23("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: [
57889
+ imageParts.length > 0 && /* @__PURE__ */ jsx29("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx29(
57773
57890
  MessageImage,
57774
57891
  {
57775
57892
  src: part.image_url.url,
@@ -57780,7 +57897,7 @@ function UserMessageBubble({ message, classNames, renderers }) {
57780
57897
  },
57781
57898
  part.image_url.url
57782
57899
  )) }),
57783
- fileParts.length > 0 && /* @__PURE__ */ jsx28("div", { className: "flex flex-col items-end gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs23(
57900
+ fileParts.length > 0 && /* @__PURE__ */ jsx29("div", { className: "flex flex-col items-end gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs23(
57784
57901
  "div",
57785
57902
  {
57786
57903
  part: "file-card",
@@ -57789,13 +57906,13 @@ function UserMessageBubble({ message, classNames, renderers }) {
57789
57906
  classNames?.fileCard
57790
57907
  ),
57791
57908
  children: [
57792
- /* @__PURE__ */ jsx28(FileText, { size: 12, className: "blade-chat-file-card-icon shrink-0" }),
57793
- /* @__PURE__ */ jsx28("span", { className: "blade-chat-file-card-name max-w-56 truncate", title: part.name, children: part.name })
57909
+ /* @__PURE__ */ jsx29(FileText, { size: 12, className: "blade-chat-file-card-icon shrink-0" }),
57910
+ /* @__PURE__ */ jsx29("span", { className: "blade-chat-file-card-name max-w-56 truncate", title: part.name, children: part.name })
57794
57911
  ]
57795
57912
  },
57796
57913
  `${part.name}-${part.data.length}`
57797
57914
  )) }),
57798
- text4 && (customBubble ?? /* @__PURE__ */ jsx28(
57915
+ text4 && (customBubble ?? /* @__PURE__ */ jsx29(
57799
57916
  "div",
57800
57917
  {
57801
57918
  part: "user-bubble",
@@ -57803,12 +57920,12 @@ function UserMessageBubble({ message, classNames, renderers }) {
57803
57920
  "blade-chat-user-bubble max-w-full rounded-[20px] rounded-br-[6px] border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-[18px] py-[13px] text-sm leading-[1.65] text-[hsl(var(--user-msg-fg))]",
57804
57921
  classNames?.userBubble
57805
57922
  ),
57806
- children: /* @__PURE__ */ jsx28(MarkdownContent, { className: "blade-chat-prose", children: text4 })
57923
+ children: /* @__PURE__ */ jsx29(MarkdownContent, { className: "blade-chat-prose", children: text4 })
57807
57924
  }
57808
57925
  )),
57809
57926
  text4 && isSending(message) && /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-1 pr-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))/0.85]", children: [
57810
- /* @__PURE__ */ jsx28(LoaderCircle, { size: 11, className: "animate-spin", "aria-hidden": "true" }),
57811
- /* @__PURE__ */ jsx28("span", { children: "\u53D1\u9001\u4E2D" })
57927
+ /* @__PURE__ */ jsx29(LoaderCircle, { size: 11, className: "animate-spin", "aria-hidden": "true" }),
57928
+ /* @__PURE__ */ jsx29("span", { children: "\u53D1\u9001\u4E2D" })
57812
57929
  ] })
57813
57930
  ] }) });
57814
57931
  }
@@ -57817,11 +57934,11 @@ function ErrorMessageBlock({
57817
57934
  className
57818
57935
  }) {
57819
57936
  const text4 = chatErrorForDisplay(getTextContent3(message.content));
57820
- return /* @__PURE__ */ jsx28("div", { part: "error-row", className: cn("blade-chat-error-row flex min-w-0 justify-start", className), children: /* @__PURE__ */ jsx28("div", { className: "blade-chat-error-block min-w-0 max-w-full whitespace-pre-wrap break-words border-l-[3px] border-[hsl(var(--border))] px-3 py-1 text-left text-sm leading-7 text-[hsl(var(--muted-foreground))] [overflow-wrap:anywhere]", children: text4 }) });
57937
+ return /* @__PURE__ */ jsx29("div", { part: "error-row", className: cn("blade-chat-error-row flex min-w-0 justify-start", className), children: /* @__PURE__ */ jsx29("div", { className: "blade-chat-error-block min-w-0 max-w-full whitespace-pre-wrap break-words border-l-[3px] border-[hsl(var(--border))] px-3 py-1 text-left text-sm leading-7 text-[hsl(var(--muted-foreground))] [overflow-wrap:anywhere]", children: text4 }) });
57821
57938
  }
57822
57939
 
57823
57940
  // src/components/MessageList.tsx
57824
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
57941
+ import { jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
57825
57942
  function parseModeChange(message) {
57826
57943
  if (message.kind !== "mode_change" || typeof message.content !== "string") {
57827
57944
  return null;
@@ -57899,10 +58016,10 @@ function MessageList({
57899
58016
  const contentReveal = useTypewriterReveal(revealContentText, isRevealLive, revealTargetKey);
57900
58017
  const reasoningReveal = useTypewriterReveal(revealReasoningText, isRevealLive, revealTargetKey);
57901
58018
  const isRevealingAny = contentReveal.isRevealing || reasoningReveal.isRevealing;
57902
- useEffect25(() => {
58019
+ useEffect27(() => {
57903
58020
  onRevealingChange?.(isRevealingAny);
57904
58021
  }, [isRevealingAny, onRevealingChange]);
57905
- useEffect25(() => {
58022
+ useEffect27(() => {
57906
58023
  if (isStopping) {
57907
58024
  contentReveal.flushNow();
57908
58025
  reasoningReveal.flushNow();
@@ -57989,8 +58106,8 @@ function MessageList({
57989
58106
  }
57990
58107
  return blocks;
57991
58108
  }, [visibleRootMessages, isStreaming, isRevealingAny]);
57992
- const rootRef = useRef27(null);
57993
- const stopAutoScrollRef = useRef27(null);
58109
+ const rootRef = useRef29(null);
58110
+ const stopAutoScrollRef = useRef29(null);
57994
58111
  const {
57995
58112
  items: turnNavItems,
57996
58113
  activeEntryId: activeNavTurnId,
@@ -58010,7 +58127,7 @@ function MessageList({
58010
58127
  isEntryLoaded: (entryId) => findEntryRow(rootRef.current, entryId) !== null,
58011
58128
  beforeSeek: () => stopAutoScrollRef.current?.()
58012
58129
  });
58013
- const [viewportNavTurnId, setViewportNavTurnId] = useState33(null);
58130
+ const [viewportNavTurnId, setViewportNavTurnId] = useState35(null);
58014
58131
  const latestNavTurnId = turnNavItems.at(-1)?.id ?? null;
58015
58132
  return /* @__PURE__ */ jsxs24(
58016
58133
  "div",
@@ -58019,8 +58136,8 @@ function MessageList({
58019
58136
  part: "messages",
58020
58137
  className: cn("blade-chat-messages relative min-h-0 flex-1", classNames?.messageList),
58021
58138
  children: [
58022
- isStreaming || isRevealingAny ? /* @__PURE__ */ jsx29("output", { className: "sr-only", children: "\u6B63\u5728\u751F\u6210\u56DE\u590D" }) : null,
58023
- /* @__PURE__ */ jsx29(
58139
+ isStreaming || isRevealingAny ? /* @__PURE__ */ jsx30("output", { className: "sr-only", children: "\u6B63\u5728\u751F\u6210\u56DE\u590D" }) : null,
58140
+ /* @__PURE__ */ jsx30(
58024
58141
  TurnNavRail,
58025
58142
  {
58026
58143
  items: turnNavItems,
@@ -58038,23 +58155,23 @@ function MessageList({
58038
58155
  initial: "instant",
58039
58156
  resize: "instant",
58040
58157
  children: [
58041
- /* @__PURE__ */ jsx29(StickToBottom.Content, { part: "messages-scroll", className: cn("blade-chat-messages-scroll", classNames?.messagesScroll), children: /* @__PURE__ */ jsxs24("div", { part: "messages-content", className: cn("blade-chat-messages-content mx-auto max-w-[748px]", classNames?.messagesContent), children: [
58042
- historyPaging && (historyPaging.hasOlder || historyPaging.loading) ? /* @__PURE__ */ jsx29(LoadOlderSentinel, { ...historyPaging }) : null,
58158
+ /* @__PURE__ */ jsx30(StickToBottom.Content, { part: "messages-scroll", className: cn("blade-chat-messages-scroll", classNames?.messagesScroll), children: /* @__PURE__ */ jsxs24("div", { part: "messages-content", className: cn("blade-chat-messages-content mx-auto max-w-[748px]", classNames?.messagesContent), children: [
58159
+ historyPaging && (historyPaging.hasOlder || historyPaging.loading) ? /* @__PURE__ */ jsx30(LoadOlderSentinel, { ...historyPaging }) : null,
58043
58160
  /* @__PURE__ */ jsxs24("div", { className: "flex min-w-0 flex-col", children: [
58044
58161
  renderBlocks.length === 0 ? emptyState ?? /* @__PURE__ */ jsxs24("div", { part: "empty", className: cn("blade-chat-empty", classNames?.empty), children: [
58045
- /* @__PURE__ */ jsx29(MessageSquare, { size: 40, strokeWidth: 1.5 }),
58046
- /* @__PURE__ */ jsx29("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
58047
- /* @__PURE__ */ jsx29("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
58162
+ /* @__PURE__ */ jsx30(MessageSquare, { size: 40, strokeWidth: 1.5 }),
58163
+ /* @__PURE__ */ jsx30("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
58164
+ /* @__PURE__ */ jsx30("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
58048
58165
  ] }) : renderBlocks.map((block) => {
58049
58166
  if (block.type === "message") {
58050
- return /* @__PURE__ */ jsx29("div", { "data-entry-id": block.message.entry_id, children: isBackgroundWakeMessage(block.message) ? /* @__PURE__ */ jsx29(BackgroundWakeNotice, {}) : isUserMessage(block.message) ? /* @__PURE__ */ jsx29(
58167
+ return /* @__PURE__ */ jsx30("div", { "data-entry-id": block.message.entry_id, children: isBackgroundWakeMessage(block.message) ? /* @__PURE__ */ jsx30(BackgroundWakeNotice, {}) : isUserMessage(block.message) ? /* @__PURE__ */ jsx30(
58051
58168
  UserMessageBubble,
58052
58169
  {
58053
58170
  message: block.message,
58054
58171
  classNames,
58055
58172
  renderers
58056
58173
  }
58057
- ) : isErrorMessage(block.message) ? /* @__PURE__ */ jsx29(
58174
+ ) : isErrorMessage(block.message) ? /* @__PURE__ */ jsx30(
58058
58175
  ErrorMessageBlock,
58059
58176
  {
58060
58177
  message: block.message,
@@ -58072,14 +58189,14 @@ function MessageList({
58072
58189
  (message) => message.entry_id === postChatFollowup.assistant_entry_id
58073
58190
  )
58074
58191
  );
58075
- return /* @__PURE__ */ jsx29("div", { "data-entry-id": displayMessages[0]?.entry_id, children: /* @__PURE__ */ jsxs24(
58192
+ return /* @__PURE__ */ jsx30("div", { "data-entry-id": displayMessages[0]?.entry_id, children: /* @__PURE__ */ jsxs24(
58076
58193
  RenderErrorBoundary,
58077
58194
  {
58078
58195
  label: "\u52A9\u624B\u6D88\u606F",
58079
58196
  details: block.key,
58080
58197
  resetKey: getMessageResetSignature(displayMessages),
58081
58198
  children: [
58082
- /* @__PURE__ */ jsx29(
58199
+ /* @__PURE__ */ jsx30(
58083
58200
  AssistantTurnBlock,
58084
58201
  {
58085
58202
  messages: displayMessages,
@@ -58093,8 +58210,8 @@ function MessageList({
58093
58210
  sessionId
58094
58211
  }
58095
58212
  ),
58096
- blockFeedback && !hasActiveFollowup ? /* @__PURE__ */ jsx29(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
58097
- hasActiveFollowup && postChatFollowup ? /* @__PURE__ */ jsx29(
58213
+ blockFeedback && !hasActiveFollowup ? /* @__PURE__ */ jsx30(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
58214
+ hasActiveFollowup && postChatFollowup ? /* @__PURE__ */ jsx30(
58098
58215
  PostChatFollowupBlock,
58099
58216
  {
58100
58217
  followup: postChatFollowup,
@@ -58118,19 +58235,19 @@ function MessageList({
58118
58235
  {
58119
58236
  className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]",
58120
58237
  children: [
58121
- /* @__PURE__ */ jsx29(Layers, { size: 12 }),
58122
- /* @__PURE__ */ jsx29("span", { children: "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
58238
+ /* @__PURE__ */ jsx30(Layers, { size: 12 }),
58239
+ /* @__PURE__ */ jsx30("span", { children: "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
58123
58240
  ]
58124
58241
  },
58125
58242
  block.key
58126
58243
  );
58127
58244
  }
58128
- return /* @__PURE__ */ jsx29(PlanningDivider, { kind: block.kind }, block.key);
58245
+ return /* @__PURE__ */ jsx30(PlanningDivider, { kind: block.kind }, block.key);
58129
58246
  }),
58130
- sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */ jsx29("div", { className: "flex", children: /* @__PURE__ */ jsx29("div", { className: "rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }) }) : null
58247
+ sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */ jsx30("div", { className: "flex", children: /* @__PURE__ */ jsx30("div", { className: "rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }) }) : null
58131
58248
  ] })
58132
58249
  ] }) }),
58133
- /* @__PURE__ */ jsx29(
58250
+ /* @__PURE__ */ jsx30(
58134
58251
  PinLatestUserMessage,
58135
58252
  {
58136
58253
  userMessageCount: userMessages.length,
@@ -58140,9 +58257,9 @@ function MessageList({
58140
58257
  },
58141
58258
  sessionId ?? "no-session"
58142
58259
  ),
58143
- /* @__PURE__ */ jsx29(ScrollToBottomButton, { className: classNames?.scrollToBottom }),
58144
- /* @__PURE__ */ jsx29(StopAutoScrollBridge, { stopRef: stopAutoScrollRef }),
58145
- /* @__PURE__ */ jsx29(
58260
+ /* @__PURE__ */ jsx30(ScrollToBottomButton, { className: classNames?.scrollToBottom }),
58261
+ /* @__PURE__ */ jsx30(StopAutoScrollBridge, { stopRef: stopAutoScrollRef }),
58262
+ /* @__PURE__ */ jsx30(
58146
58263
  ViewportTurnBridge,
58147
58264
  {
58148
58265
  rootRef,
@@ -58164,10 +58281,10 @@ function LoadOlderSentinel({
58164
58281
  loadOlder
58165
58282
  }) {
58166
58283
  const { contentRef, scrollRef } = useStickToBottomContext();
58167
- const sentinelRef = useRef27(null);
58168
- const stateRef = useRef27({ hasOlder, loading, loadOlder });
58284
+ const sentinelRef = useRef29(null);
58285
+ const stateRef = useRef29({ hasOlder, loading, loadOlder });
58169
58286
  stateRef.current = { hasOlder, loading, loadOlder };
58170
- useEffect25(() => {
58287
+ useEffect27(() => {
58171
58288
  const sentinel = sentinelRef.current;
58172
58289
  const scroller = scrollRef.current;
58173
58290
  if (!sentinel || !scroller || typeof IntersectionObserver === "undefined") return;
@@ -58226,7 +58343,7 @@ function LoadOlderSentinel({
58226
58343
  observer.disconnect();
58227
58344
  };
58228
58345
  }, [contentRef, scrollRef]);
58229
- return /* @__PURE__ */ jsx29("div", { ref: sentinelRef, "data-history-sentinel": true, className: "flex h-6 items-center justify-center", children: loading ? /* @__PURE__ */ jsx29("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u52A0\u8F7D\u66F4\u65E9\u6D88\u606F\u2026" }) : null });
58346
+ return /* @__PURE__ */ jsx30("div", { ref: sentinelRef, "data-history-sentinel": true, className: "flex h-6 items-center justify-center", children: loading ? /* @__PURE__ */ jsx30("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u52A0\u8F7D\u66F4\u65E9\u6D88\u606F\u2026" }) : null });
58230
58347
  }
58231
58348
  function PinLatestUserMessage({
58232
58349
  userMessageCount,
@@ -58235,8 +58352,8 @@ function PinLatestUserMessage({
58235
58352
  targetKey
58236
58353
  }) {
58237
58354
  const { contentRef, scrollRef, scrollToBottom, stopScroll } = useStickToBottomContext();
58238
- const previousCountRef = useRef27(userMessageCount);
58239
- const spacerHeightRef = useRef27(0);
58355
+ const previousCountRef = useRef29(userMessageCount);
58356
+ const spacerHeightRef = useRef29(0);
58240
58357
  const getScrollElement = useCallback29(() => scrollRef.current, [scrollRef]);
58241
58358
  const getContentElement = useCallback29(() => contentRef.current, [contentRef]);
58242
58359
  const getTargetElement = useCallback29(() => {
@@ -58278,7 +58395,7 @@ function PinLatestUserMessage({
58278
58395
  stopAutoScroll: stopScroll,
58279
58396
  scrollToBottom
58280
58397
  });
58281
- useEffect25(() => {
58398
+ useEffect27(() => {
58282
58399
  if (userMessageCount > previousCountRef.current && !shouldPinLatestUser) {
58283
58400
  scrollToBottom("instant");
58284
58401
  }
@@ -58288,9 +58405,9 @@ function PinLatestUserMessage({
58288
58405
  }
58289
58406
  function ScrollToBottomButton({ className }) {
58290
58407
  const { isAtBottom, scrollToBottom } = useStickToBottomContext();
58291
- const [visible, setVisible] = useState33(false);
58292
- const hideTimerRef = useRef27(null);
58293
- useEffect25(() => {
58408
+ const [visible, setVisible] = useState35(false);
58409
+ const hideTimerRef = useRef29(null);
58410
+ useEffect27(() => {
58294
58411
  if (isAtBottom) {
58295
58412
  if (!hideTimerRef.current) {
58296
58413
  hideTimerRef.current = setTimeout(() => {
@@ -58333,20 +58450,20 @@ function ScrollToBottomButton({ className }) {
58333
58450
  className
58334
58451
  ),
58335
58452
  children: [
58336
- /* @__PURE__ */ jsx29(ChevronDown, { size: 14 }),
58337
- /* @__PURE__ */ jsx29("span", { className: "blade-chat-scroll-bottom-label", children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
58453
+ /* @__PURE__ */ jsx30(ChevronDown, { size: 14 }),
58454
+ /* @__PURE__ */ jsx30("span", { className: "blade-chat-scroll-bottom-label", children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
58338
58455
  ]
58339
58456
  }
58340
58457
  );
58341
58458
  }
58342
58459
  function PlanningDivider({ kind }) {
58343
58460
  return /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-3 py-1", children: [
58344
- /* @__PURE__ */ jsx29("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
58461
+ /* @__PURE__ */ jsx30("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
58345
58462
  /* @__PURE__ */ jsxs24("div", { className: "inline-flex items-center gap-1.5 rounded-full border border-amber-500/30 bg-amber-500/10 px-3 py-1 text-[11px] text-amber-300", children: [
58346
- /* @__PURE__ */ jsx29(Lightbulb, { size: 12 }),
58347
- /* @__PURE__ */ jsx29("span", { children: kind === "enter" ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
58463
+ /* @__PURE__ */ jsx30(Lightbulb, { size: 12 }),
58464
+ /* @__PURE__ */ jsx30("span", { children: kind === "enter" ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
58348
58465
  ] }),
58349
- /* @__PURE__ */ jsx29("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
58466
+ /* @__PURE__ */ jsx30("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
58350
58467
  ] });
58351
58468
  }
58352
58469
  function findEntryRow(root, entryId) {
@@ -58362,13 +58479,13 @@ function ViewportTurnBridge({
58362
58479
  onActiveChange
58363
58480
  }) {
58364
58481
  const { scrollRef } = useStickToBottomContext();
58365
- const itemsRef = useRef27(items);
58366
- const updateRef = useRef27(null);
58367
- useEffect25(() => {
58482
+ const itemsRef = useRef29(items);
58483
+ const updateRef = useRef29(null);
58484
+ useEffect27(() => {
58368
58485
  itemsRef.current = items;
58369
58486
  updateRef.current?.();
58370
58487
  }, [items]);
58371
- useEffect25(() => {
58488
+ useEffect27(() => {
58372
58489
  const scroller = scrollRef.current;
58373
58490
  const root = rootRef.current;
58374
58491
  if (!scroller || !root) return;
@@ -58412,7 +58529,7 @@ function ViewportTurnBridge({
58412
58529
  var VIEWPORT_ACTIVE_OFFSET = 8;
58413
58530
  function StopAutoScrollBridge({ stopRef }) {
58414
58531
  const { stopScroll } = useStickToBottomContext();
58415
- useEffect25(() => {
58532
+ useEffect27(() => {
58416
58533
  stopRef.current = stopScroll;
58417
58534
  return () => {
58418
58535
  stopRef.current = null;
@@ -58422,7 +58539,7 @@ function StopAutoScrollBridge({ stopRef }) {
58422
58539
  }
58423
58540
 
58424
58541
  // src/components/ChatSurface.tsx
58425
- import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
58542
+ import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
58426
58543
  function themeAttr(theme) {
58427
58544
  return theme === "dark" ? "dark" : void 0;
58428
58545
  }
@@ -58462,7 +58579,7 @@ function ChatSurface({
58462
58579
  onRevealingChange,
58463
58580
  isReplay
58464
58581
  }) {
58465
- const [pending, setPending] = useState34([]);
58582
+ const [pending, setPending] = useState36([]);
58466
58583
  const currentPending = pending.filter((item) => item.sessionId === sessionId);
58467
58584
  const sendWithApps = async (text4) => {
58468
58585
  const content3 = [...currentPending.map((item) => `[${item.label}]
@@ -58480,7 +58597,7 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58480
58597
  return current ? parsePlanUpdate(current.arguments) : null;
58481
58598
  }, [messages, renderers?.planUpdate]);
58482
58599
  const customPlan = planForRenderer ? renderers?.planUpdate?.({ plan: planForRenderer, running: isStreaming, sessionId }) : void 0;
58483
- return /* @__PURE__ */ jsx30(McpAppMessageContext.Provider, { value: (message) => {
58600
+ return /* @__PURE__ */ jsx31(McpAppMessageContext.Provider, { value: (message) => {
58484
58601
  if (!sessionId || message.sessionId !== sessionId || isViewer) throw new Error("\u5F53\u524D\u4F1A\u8BDD\u4E0D\u80FD\u63A5\u6536\u5E94\u7528\u6D88\u606F");
58485
58602
  setPending((items) => [...items, { ...message, sessionId, id: randomId() }]);
58486
58603
  }, children: /* @__PURE__ */ jsxs25(
@@ -58493,7 +58610,7 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58493
58610
  classNames?.root
58494
58611
  ),
58495
58612
  children: [
58496
- /* @__PURE__ */ jsx30(ConnectionBanner, { connection, className: classNames?.banner }),
58613
+ /* @__PURE__ */ jsx31(ConnectionBanner, { connection, className: classNames?.banner }),
58497
58614
  banner,
58498
58615
  errorMessage && /* @__PURE__ */ jsxs25(
58499
58616
  "div",
@@ -58501,13 +58618,13 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58501
58618
  part: "error-bar",
58502
58619
  className: cn("blade-chat-error-bar flex items-start gap-2 border-b px-4 py-3 text-sm", classNames?.errorBar),
58503
58620
  children: [
58504
- /* @__PURE__ */ jsx30(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
58505
- /* @__PURE__ */ jsx30("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: chatErrorForDisplay2(errorMessage) })
58621
+ /* @__PURE__ */ jsx31(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
58622
+ /* @__PURE__ */ jsx31("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: chatErrorForDisplay2(errorMessage) })
58506
58623
  ]
58507
58624
  }
58508
58625
  ),
58509
58626
  slots?.header,
58510
- /* @__PURE__ */ jsx30(
58627
+ /* @__PURE__ */ jsx31(
58511
58628
  MessageList,
58512
58629
  {
58513
58630
  messages,
@@ -58533,7 +58650,7 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58533
58650
  turnNavigation
58534
58651
  }
58535
58652
  ),
58536
- showPlanUpdates ? customPlan ?? /* @__PURE__ */ jsx30(
58653
+ showPlanUpdates ? customPlan ?? /* @__PURE__ */ jsx31(
58537
58654
  CurrentPlanPanel,
58538
58655
  {
58539
58656
  messages,
@@ -58544,15 +58661,15 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58544
58661
  }
58545
58662
  ) : null,
58546
58663
  beforeInput,
58547
- /* @__PURE__ */ jsx30(QueuePanelAdjacencyContext.Provider, { value: currentPending.length === 0, children: queuePanel }),
58664
+ /* @__PURE__ */ jsx31(QueuePanelAdjacencyContext.Provider, { value: currentPending.length === 0, children: queuePanel }),
58548
58665
  currentPending.map((item) => /* @__PURE__ */ jsxs25("div", { style: { display: "flex", gap: 8, padding: "8px 16px" }, children: [
58549
58666
  /* @__PURE__ */ jsxs25("details", { style: { flex: 1, minWidth: 0 }, children: [
58550
- /* @__PURE__ */ jsx30("summary", { children: item.label }),
58551
- /* @__PURE__ */ jsx30("pre", { style: { whiteSpace: "pre-wrap", overflowWrap: "anywhere" }, children: item.content })
58667
+ /* @__PURE__ */ jsx31("summary", { children: item.label }),
58668
+ /* @__PURE__ */ jsx31("pre", { style: { whiteSpace: "pre-wrap", overflowWrap: "anywhere" }, children: item.content })
58552
58669
  ] }),
58553
- /* @__PURE__ */ jsx30("button", { type: "button", "aria-label": "\u79FB\u9664\u5F85\u53D1\u9001\u5185\u5BB9", title: "\u79FB\u9664", onClick: () => setPending((items) => items.filter((other) => other.id !== item.id)), children: /* @__PURE__ */ jsx30(X, { size: 16 }) })
58670
+ /* @__PURE__ */ jsx31("button", { type: "button", "aria-label": "\u79FB\u9664\u5F85\u53D1\u9001\u5185\u5BB9", title: "\u79FB\u9664", onClick: () => setPending((items) => items.filter((other) => other.id !== item.id)), children: /* @__PURE__ */ jsx31(X, { size: 16 }) })
58554
58671
  ] }, item.id)),
58555
- /* @__PURE__ */ jsx30(
58672
+ /* @__PURE__ */ jsx31(
58556
58673
  ChatInput,
58557
58674
  {
58558
58675
  value: inputText,
@@ -58579,13 +58696,13 @@ ${item.content}`), text4].filter(Boolean).join("\n\n");
58579
58696
  }
58580
58697
 
58581
58698
  // src/components/AgentChat.tsx
58582
- import { Fragment as Fragment9, jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
58699
+ import { Fragment as Fragment9, jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
58583
58700
  function isUnauthorizedError(error61) {
58584
58701
  return error61 instanceof BladeApiError2 && error61.status === 401;
58585
58702
  }
58586
58703
  function LoginCard({ client, onLoggedIn }) {
58587
- const [loggingIn, setLoggingIn] = useState35(false);
58588
- const [loginError, setLoginError] = useState35(null);
58704
+ const [loggingIn, setLoggingIn] = useState37(false);
58705
+ const [loginError, setLoginError] = useState37(null);
58589
58706
  const handleLogin = async () => {
58590
58707
  setLoggingIn(true);
58591
58708
  setLoginError(null);
@@ -58598,11 +58715,11 @@ function LoginCard({ client, onLoggedIn }) {
58598
58715
  setLoggingIn(false);
58599
58716
  }
58600
58717
  };
58601
- return /* @__PURE__ */ jsx31("div", { className: "blade-chat-login flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs26("div", { className: "flex w-full max-w-sm flex-col items-center gap-4 rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-6 py-8 text-center", children: [
58602
- /* @__PURE__ */ jsx31(LockKeyhole, { size: 28, className: "text-[hsl(var(--muted-foreground))]" }),
58603
- /* @__PURE__ */ jsx31("div", { className: "text-base font-medium text-[hsl(var(--foreground))]", children: "\u9700\u8981\u767B\u5F55\u540E\u4F7F\u7528" }),
58604
- /* @__PURE__ */ jsx31("div", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u767B\u5F55\u540E\u5373\u53EF\u4E0E\u667A\u80FD\u4F53\u5BF9\u8BDD\uFF0C\u4F60\u7684\u4F1A\u8BDD\u5185\u5BB9\u4EC5\u81EA\u5DF1\u53EF\u89C1\u3002" }),
58605
- /* @__PURE__ */ jsx31(
58718
+ return /* @__PURE__ */ jsx32("div", { className: "blade-chat-login flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs26("div", { className: "flex w-full max-w-sm flex-col items-center gap-4 rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-6 py-8 text-center", children: [
58719
+ /* @__PURE__ */ jsx32(LockKeyhole, { size: 28, className: "text-[hsl(var(--muted-foreground))]" }),
58720
+ /* @__PURE__ */ jsx32("div", { className: "text-base font-medium text-[hsl(var(--foreground))]", children: "\u9700\u8981\u767B\u5F55\u540E\u4F7F\u7528" }),
58721
+ /* @__PURE__ */ jsx32("div", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u767B\u5F55\u540E\u5373\u53EF\u4E0E\u667A\u80FD\u4F53\u5BF9\u8BDD\uFF0C\u4F60\u7684\u4F1A\u8BDD\u5185\u5BB9\u4EC5\u81EA\u5DF1\u53EF\u89C1\u3002" }),
58722
+ /* @__PURE__ */ jsx32(
58606
58723
  "button",
58607
58724
  {
58608
58725
  type: "button",
@@ -58612,21 +58729,21 @@ function LoginCard({ client, onLoggedIn }) {
58612
58729
  children: loggingIn ? "\u767B\u5F55\u4E2D\u2026" : "\u767B\u5F55"
58613
58730
  }
58614
58731
  ),
58615
- loginError && /* @__PURE__ */ jsx31("div", { className: "text-xs text-[hsl(var(--destructive))]", children: loginError })
58732
+ loginError && /* @__PURE__ */ jsx32("div", { className: "text-xs text-[hsl(var(--destructive))]", children: loginError })
58616
58733
  ] }) });
58617
58734
  }
58618
58735
  function AgentChat(props) {
58619
58736
  const client = useBladeClient();
58620
- const [attempt, setAttempt] = useState35(0);
58621
- const [needLogin, setNeedLogin] = useState35(() => !client.hasToken());
58737
+ const [attempt, setAttempt] = useState37(0);
58738
+ const [needLogin, setNeedLogin] = useState37(() => !client.hasToken());
58622
58739
  if (needLogin) {
58623
- return /* @__PURE__ */ jsx31(
58740
+ return /* @__PURE__ */ jsx32(
58624
58741
  "div",
58625
58742
  {
58626
58743
  "data-theme": themeAttr(props.theme),
58627
58744
  part: "root",
58628
58745
  className: cn("blade-chat flex min-h-0 flex-1 flex-col", props.classNames?.root),
58629
- children: /* @__PURE__ */ jsx31(
58746
+ children: /* @__PURE__ */ jsx32(
58630
58747
  LoginCard,
58631
58748
  {
58632
58749
  client,
@@ -58639,7 +58756,7 @@ function AgentChat(props) {
58639
58756
  }
58640
58757
  );
58641
58758
  }
58642
- return /* @__PURE__ */ jsx31(ChatSessionView, { ...props, onUnauthorized: () => setNeedLogin(true) }, attempt);
58759
+ return /* @__PURE__ */ jsx32(ChatSessionView, { ...props, onUnauthorized: () => setNeedLogin(true) }, attempt);
58643
58760
  }
58644
58761
  function ChatSessionView({
58645
58762
  sessionId,
@@ -58657,7 +58774,7 @@ function ChatSessionView({
58657
58774
  onUnauthorized
58658
58775
  }) {
58659
58776
  const client = useBladeClient();
58660
- const [planRevealRevisions, setPlanRevealRevisions] = useState35(
58777
+ const [planRevealRevisions, setPlanRevealRevisions] = useState37(
58661
58778
  () => /* @__PURE__ */ new Map()
58662
58779
  );
58663
58780
  const handleSessionConnected = useCallback30((connectedSession) => {
@@ -58678,24 +58795,24 @@ function ChatSessionView({
58678
58795
  onSessionConnected: handleSessionConnected
58679
58796
  });
58680
58797
  const replay = useReplay(session);
58681
- const [stopRequested, setStopRequested] = useState35(false);
58682
- const [isRevealing, setIsRevealing] = useState35(false);
58683
- const [inputText, setInputText] = useState35("");
58684
- const [queueNotice, setQueueNotice] = useState35(null);
58685
- const [queuePendingItemId, setQueuePendingItemId] = useState35(null);
58686
- const [queuePanelVisible, setQueuePanelVisible] = useState35(false);
58687
- const [resultFeedback, setResultFeedback] = useState35([]);
58688
- const [timelineRewrite, setTimelineRewrite] = useState35(0);
58798
+ const [stopRequested, setStopRequested] = useState37(false);
58799
+ const [isRevealing, setIsRevealing] = useState37(false);
58800
+ const [inputText, setInputText] = useState37("");
58801
+ const [queueNotice, setQueueNotice] = useState37(null);
58802
+ const [queuePendingItemId, setQueuePendingItemId] = useState37(null);
58803
+ const [queuePanelVisible, setQueuePanelVisible] = useState37(false);
58804
+ const [resultFeedback, setResultFeedback] = useState37([]);
58805
+ const [timelineRewrite, setTimelineRewrite] = useState37(0);
58689
58806
  const resolvedSessionId = session?.sessionId;
58690
58807
  const isViewer = state?.viewerRole === "viewer";
58691
58808
  const canUseQueue = !isViewer;
58692
- const onSessionReadyRef = useRef28(onSessionReady);
58693
- const readySessionRef = useRef28(null);
58809
+ const onSessionReadyRef = useRef30(onSessionReady);
58810
+ const readySessionRef = useRef30(null);
58694
58811
  const hasOnSessionReady = onSessionReady !== void 0;
58695
- useEffect26(() => {
58812
+ useEffect28(() => {
58696
58813
  onSessionReadyRef.current = onSessionReady;
58697
58814
  }, [onSessionReady]);
58698
- useEffect26(() => {
58815
+ useEffect28(() => {
58699
58816
  setResultFeedback([]);
58700
58817
  if (!resolvedSessionId || isViewer) return;
58701
58818
  let cancelled = false;
@@ -58730,13 +58847,13 @@ function ChatSessionView({
58730
58847
  saved
58731
58848
  ]);
58732
58849
  }, []);
58733
- useEffect26(() => {
58850
+ useEffect28(() => {
58734
58851
  const handler = onSessionReadyRef.current;
58735
58852
  if (!session || !hasOnSessionReady || !handler || readySessionRef.current === session) return;
58736
58853
  readySessionRef.current = session;
58737
58854
  handler(session);
58738
58855
  }, [session, hasOnSessionReady]);
58739
- useEffect26(() => {
58856
+ useEffect28(() => {
58740
58857
  if (!session) return;
58741
58858
  const offAttach = session.on("attachRequested", ({ label, content: content3 }) => {
58742
58859
  setInputText((prev) => `${prev ? `${prev}
@@ -58756,12 +58873,12 @@ ${content3}`);
58756
58873
  offRewind();
58757
58874
  };
58758
58875
  }, [session]);
58759
- useEffect26(() => {
58876
+ useEffect28(() => {
58760
58877
  if (isUnauthorizedError(error61)) {
58761
58878
  onUnauthorized();
58762
58879
  }
58763
58880
  }, [error61, onUnauthorized]);
58764
- useEffect26(() => {
58881
+ useEffect28(() => {
58765
58882
  if (!session || !commands) return;
58766
58883
  const unsubscribes = Object.entries(commands).map(
58767
58884
  ([action, handler]) => session.onCommand(action, (payload) => handler(payload))
@@ -58827,7 +58944,7 @@ ${content3}`);
58827
58944
  next[to] = item.id;
58828
58945
  handleQueueReorder(next);
58829
58946
  };
58830
- return /* @__PURE__ */ jsx31(
58947
+ return /* @__PURE__ */ jsx32(
58831
58948
  ChatSurface,
58832
58949
  {
58833
58950
  theme,
@@ -58838,8 +58955,8 @@ ${content3}`);
58838
58955
  placeholder,
58839
58956
  connection: state?.connection ?? "connecting",
58840
58957
  banner: /* @__PURE__ */ jsxs26(Fragment9, { children: [
58841
- resolvedSessionId && !isViewer && (sessionPluginControls ? sessionPluginControls(resolvedSessionId) : /* @__PURE__ */ jsx31(SessionPluginSelector, { client, sessionId: resolvedSessionId })),
58842
- /* @__PURE__ */ jsx31(
58958
+ resolvedSessionId && !isViewer && (sessionPluginControls ? sessionPluginControls(resolvedSessionId) : /* @__PURE__ */ jsx32(SessionPluginSelector, { client, sessionId: resolvedSessionId })),
58959
+ /* @__PURE__ */ jsx32(
58843
58960
  ReplayBar,
58844
58961
  {
58845
58962
  isReplay: replay.isReplay,
@@ -58849,7 +58966,7 @@ ${content3}`);
58849
58966
  onExit: () => void replay.exitToAutonomous()
58850
58967
  }
58851
58968
  ),
58852
- /* @__PURE__ */ jsx31(ReplayMismatchPrompt, { mismatch: replay.mismatch })
58969
+ /* @__PURE__ */ jsx32(ReplayMismatchPrompt, { mismatch: replay.mismatch })
58853
58970
  ] }),
58854
58971
  errorMessage,
58855
58972
  messages: state?.messages ?? [],
@@ -58861,7 +58978,7 @@ ${content3}`);
58861
58978
  planRevealRevision,
58862
58979
  queuePanel: (
58863
58980
  // 只读身份不能操作队列,藏起来免得每个按钮都弹冲突。
58864
- canUseQueue ? /* @__PURE__ */ jsx31(
58981
+ canUseQueue ? /* @__PURE__ */ jsx32(
58865
58982
  SessionQueuePanel,
58866
58983
  {
58867
58984
  rootClassName: classNames?.queuePanel,
@@ -58933,11 +59050,11 @@ ${content3}`);
58933
59050
  }
58934
59051
 
58935
59052
  // src/components/LlmChat.tsx
58936
- import { useEffect as useEffect27, useMemo as useMemo19, useState as useState37 } from "react";
59053
+ import { useEffect as useEffect29, useMemo as useMemo19, useState as useState39 } from "react";
58937
59054
 
58938
59055
  // src/components/LlmAdvancedSettings.tsx
58939
- import { useState as useState36 } from "react";
58940
- import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
59056
+ import { useState as useState38 } from "react";
59057
+ import { jsx as jsx33, jsxs as jsxs27 } from "react/jsx-runtime";
58941
59058
  var FIELDS = [
58942
59059
  { id: "baseURL", label: "\u6A21\u578B\u670D\u52A1\u5730\u5740", placeholder: "http://\u5185\u7F51\u5730\u5740/v1" },
58943
59060
  { id: "model", label: "\u6A21\u578B", placeholder: "\u6A21\u578B\u540D\u79F0" },
@@ -58983,8 +59100,8 @@ function writeOverride(settings, baseURL, override) {
58983
59100
  }
58984
59101
  function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onChange }) {
58985
59102
  const normalized = normalizeAdvanced(settings);
58986
- const [open2, setOpen] = useState36(false);
58987
- const [draft, setDraft] = useState36(override);
59103
+ const [open2, setOpen] = useState38(false);
59104
+ const [draft, setDraft] = useState38(override);
58988
59105
  if (!normalized) return null;
58989
59106
  const fields2 = FIELDS.filter((field) => normalized[field.id]);
58990
59107
  const dirty = Object.keys(override).length > 0;
@@ -58999,16 +59116,16 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
58999
59116
  },
59000
59117
  className: "flex items-center gap-1.5 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
59001
59118
  children: [
59002
- /* @__PURE__ */ jsx32(Settings2, { size: 13 }),
59119
+ /* @__PURE__ */ jsx33(Settings2, { size: 13 }),
59003
59120
  "\u9AD8\u7EA7\u8BBE\u7F6E",
59004
- dirty && /* @__PURE__ */ jsx32("span", { className: "text-[hsl(var(--primary))]", children: "\uFF08\u5DF2\u81EA\u5B9A\u4E49\uFF09" })
59121
+ dirty && /* @__PURE__ */ jsx33("span", { className: "text-[hsl(var(--primary))]", children: "\uFF08\u5DF2\u81EA\u5B9A\u4E49\uFF09" })
59005
59122
  ]
59006
59123
  }
59007
59124
  ),
59008
59125
  open2 && /* @__PURE__ */ jsxs27("div", { className: "mt-2 flex flex-col gap-2", children: [
59009
59126
  fields2.map((field) => /* @__PURE__ */ jsxs27("label", { className: "flex flex-col gap-1", children: [
59010
- /* @__PURE__ */ jsx32("span", { className: "text-[hsl(var(--muted-foreground))]", children: field.label }),
59011
- /* @__PURE__ */ jsx32(
59127
+ /* @__PURE__ */ jsx33("span", { className: "text-[hsl(var(--muted-foreground))]", children: field.label }),
59128
+ /* @__PURE__ */ jsx33(
59012
59129
  "input",
59013
59130
  {
59014
59131
  type: field.secret ? "password" : "text",
@@ -59019,9 +59136,9 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
59019
59136
  }
59020
59137
  )
59021
59138
  ] }, field.id)),
59022
- normalized.apiKey && /* @__PURE__ */ jsx32("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u5BC6\u94A5\u4F1A\u5B58\u5728\u8FD9\u53F0\u6D4F\u89C8\u5668\u91CC\u3002\u53EA\u5728\u4F60\u4FE1\u5F97\u8FC7\u8FD9\u53F0\u673A\u5668\u65F6\u586B\u3002" }),
59139
+ normalized.apiKey && /* @__PURE__ */ jsx33("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u5BC6\u94A5\u4F1A\u5B58\u5728\u8FD9\u53F0\u6D4F\u89C8\u5668\u91CC\u3002\u53EA\u5728\u4F60\u4FE1\u5F97\u8FC7\u8FD9\u53F0\u673A\u5668\u65F6\u586B\u3002" }),
59023
59140
  /* @__PURE__ */ jsxs27("div", { className: "flex gap-2", children: [
59024
- /* @__PURE__ */ jsx32(
59141
+ /* @__PURE__ */ jsx33(
59025
59142
  "button",
59026
59143
  {
59027
59144
  type: "button",
@@ -59036,7 +59153,7 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
59036
59153
  children: "\u4FDD\u5B58"
59037
59154
  }
59038
59155
  ),
59039
- /* @__PURE__ */ jsx32(
59156
+ /* @__PURE__ */ jsx33(
59040
59157
  "button",
59041
59158
  {
59042
59159
  type: "button",
@@ -59055,7 +59172,7 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
59055
59172
  }
59056
59173
 
59057
59174
  // src/components/LlmChat.tsx
59058
- import { jsx as jsx33 } from "react/jsx-runtime";
59175
+ import { jsx as jsx34 } from "react/jsx-runtime";
59059
59176
  function LlmChat({
59060
59177
  classNames,
59061
59178
  renderers,
@@ -59067,12 +59184,12 @@ function LlmChat({
59067
59184
  onOverrideChange,
59068
59185
  ...options
59069
59186
  }) {
59070
- const [override, setOverride] = useState37(() => readOverride(advanced, options.baseURL));
59187
+ const [override, setOverride] = useState39(() => readOverride(advanced, options.baseURL));
59071
59188
  const effective = { ...options, ...override };
59072
59189
  const { messages, isStreaming, error: error61, send, stop, reset } = useLlmChat(effective);
59073
- const [inputText, setInputText] = useState37("");
59074
- const [stopRequested, setStopRequested] = useState37(false);
59075
- const [isRevealing, setIsRevealing] = useState37(false);
59190
+ const [inputText, setInputText] = useState39("");
59191
+ const [stopRequested, setStopRequested] = useState39(false);
59192
+ const [isRevealing, setIsRevealing] = useState39(false);
59076
59193
  const isStreamingDisplay = isStreaming || isRevealing;
59077
59194
  const handle = useMemo19(
59078
59195
  () => ({
@@ -59083,10 +59200,10 @@ ${text4}` : text4),
59083
59200
  }),
59084
59201
  [send, reset]
59085
59202
  );
59086
- useEffect27(() => {
59203
+ useEffect29(() => {
59087
59204
  onReady?.(handle);
59088
59205
  }, [handle, onReady]);
59089
- return /* @__PURE__ */ jsx33(
59206
+ return /* @__PURE__ */ jsx34(
59090
59207
  ChatSurface,
59091
59208
  {
59092
59209
  theme,
@@ -59112,7 +59229,7 @@ ${text4}` : text4),
59112
59229
  setStopRequested(true);
59113
59230
  stop();
59114
59231
  },
59115
- beforeInput: advanced ? /* @__PURE__ */ jsx33(
59232
+ beforeInput: advanced ? /* @__PURE__ */ jsx34(
59116
59233
  LlmAdvancedSettingsBar,
59117
59234
  {
59118
59235
  settings: advanced,
@@ -59130,14 +59247,14 @@ ${text4}` : text4),
59130
59247
  }
59131
59248
 
59132
59249
  // src/components/ChatView.tsx
59133
- import { jsx as jsx34 } from "react/jsx-runtime";
59250
+ import { jsx as jsx35 } from "react/jsx-runtime";
59134
59251
  function ChatView(props) {
59135
59252
  const { mode, llm, onLlmReady, ...rest } = props;
59136
59253
  if (mode === "llm") {
59137
59254
  if (!llm) {
59138
59255
  throw new Error('ChatView: mode="llm" \u9700\u8981\u540C\u65F6\u4F20 llm={{ baseURL, model }}');
59139
59256
  }
59140
- return /* @__PURE__ */ jsx34(
59257
+ return /* @__PURE__ */ jsx35(
59141
59258
  LlmChat,
59142
59259
  {
59143
59260
  ...llm,
@@ -59150,11 +59267,11 @@ function ChatView(props) {
59150
59267
  }
59151
59268
  );
59152
59269
  }
59153
- return /* @__PURE__ */ jsx34(AgentChat, { ...rest });
59270
+ return /* @__PURE__ */ jsx35(AgentChat, { ...rest });
59154
59271
  }
59155
59272
 
59156
59273
  // src/components/ConnectorPanel.tsx
59157
- import { useCallback as useCallback31, useEffect as useEffect28, useMemo as useMemo20, useRef as useRef29, useState as useState38 } from "react";
59274
+ import { useCallback as useCallback31, useEffect as useEffect30, useMemo as useMemo20, useRef as useRef31, useState as useState40 } from "react";
59158
59275
 
59159
59276
  // src/components/connector-panel-types.ts
59160
59277
  function selectionFromItem(item) {
@@ -59176,12 +59293,12 @@ function triggerSummary(items) {
59176
59293
  }
59177
59294
 
59178
59295
  // src/components/ConnectorPanel.tsx
59179
- import { Fragment as Fragment10, jsx as jsx35, jsxs as jsxs28 } from "react/jsx-runtime";
59296
+ import { Fragment as Fragment10, jsx as jsx36, jsxs as jsxs28 } from "react/jsx-runtime";
59180
59297
  function PanelDivider() {
59181
- return /* @__PURE__ */ jsx35("div", { className: "my-1 border-[hsl(var(--border))] border-t" });
59298
+ return /* @__PURE__ */ jsx36("div", { className: "my-1 border-[hsl(var(--border))] border-t" });
59182
59299
  }
59183
59300
  function PanelTitle({ children }) {
59184
- return /* @__PURE__ */ jsx35("div", { className: "px-3 pt-1 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children });
59301
+ return /* @__PURE__ */ jsx36("div", { className: "px-3 pt-1 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children });
59185
59302
  }
59186
59303
  function ConnectorPanel({
59187
59304
  client,
@@ -59194,12 +59311,13 @@ function ConnectorPanel({
59194
59311
  renderComputerSection,
59195
59312
  renderExternalAccounts,
59196
59313
  renderFooterActions,
59314
+ visibleSections = ["plugins", "computers", "accounts"],
59197
59315
  className
59198
59316
  }) {
59199
- const [query, setQuery] = useState38("");
59200
- const [pendingCatalog, setPendingCatalog] = useState38(null);
59201
- const [pendingLoading, setPendingLoading] = useState38(false);
59202
- const [pendingError, setPendingError] = useState38(false);
59317
+ const [query, setQuery] = useState40("");
59318
+ const [pendingCatalog, setPendingCatalog] = useState40(null);
59319
+ const [pendingLoading, setPendingLoading] = useState40(false);
59320
+ const [pendingError, setPendingError] = useState40(false);
59203
59321
  const activation = useSessionPluginActivation({
59204
59322
  client,
59205
59323
  // 首页不会走这个分支:待选在下面自己处理开关,不碰会话接口。
@@ -59207,7 +59325,7 @@ function ConnectorPanel({
59207
59325
  onChange: onPluginsChanged
59208
59326
  });
59209
59327
  const { reload, items: sessionItems } = activation;
59210
- useEffect28(() => {
59328
+ useEffect30(() => {
59211
59329
  if (sessionId) reload();
59212
59330
  }, [reload, sessionId]);
59213
59331
  const loadPendingCatalog = useCallback31(async () => {
@@ -59222,7 +59340,7 @@ function ConnectorPanel({
59222
59340
  setPendingLoading(false);
59223
59341
  }
59224
59342
  }, [client]);
59225
- useEffect28(() => {
59343
+ useEffect30(() => {
59226
59344
  if (sessionId) return;
59227
59345
  void loadPendingCatalog();
59228
59346
  }, [loadPendingCatalog, sessionId]);
@@ -59253,20 +59371,20 @@ function ConnectorPanel({
59253
59371
  () => items.filter((item) => item.active),
59254
59372
  [items]
59255
59373
  );
59256
- const onSelectedChangeRef = useRef29(onSelectedChange);
59374
+ const onSelectedChangeRef = useRef31(onSelectedChange);
59257
59375
  onSelectedChangeRef.current = onSelectedChange;
59258
- const latestSelected = useRef29(selectedItems);
59376
+ const latestSelected = useRef31(selectedItems);
59259
59377
  latestSelected.current = selectedItems;
59260
59378
  const reportSelected = useCallback31(() => {
59261
59379
  onSelectedChangeRef.current?.(latestSelected.current);
59262
59380
  }, []);
59263
59381
  const selectedNames = selectedItems.map((item) => item.name).join("\0");
59264
- useEffect28(reportSelected, [reportSelected, selectedNames]);
59382
+ useEffect30(reportSelected, [reportSelected, selectedNames]);
59265
59383
  const failed = sessionId ? activation.listError : pendingError;
59266
59384
  return /* @__PURE__ */ jsxs28("div", { className, children: [
59267
59385
  /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-2 border-[hsl(var(--border))] border-b px-3 py-2", children: [
59268
- /* @__PURE__ */ jsx35(Search, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]", "aria-hidden": "true" }),
59269
- /* @__PURE__ */ jsx35(
59386
+ /* @__PURE__ */ jsx36(Search, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]", "aria-hidden": "true" }),
59387
+ /* @__PURE__ */ jsx36(
59270
59388
  "input",
59271
59389
  {
59272
59390
  value: query,
@@ -59277,65 +59395,67 @@ function ConnectorPanel({
59277
59395
  }
59278
59396
  )
59279
59397
  ] }),
59280
- renderComputerSection ? /* @__PURE__ */ jsxs28(Fragment10, { children: [
59281
- /* @__PURE__ */ jsx35(PanelTitle, { children: "\u7535\u8111" }),
59398
+ visibleSections.includes("computers") && renderComputerSection ? /* @__PURE__ */ jsxs28(Fragment10, { children: [
59399
+ /* @__PURE__ */ jsx36(PanelTitle, { children: "\u7535\u8111" }),
59282
59400
  renderComputerSection(query)
59283
59401
  ] }) : null,
59284
- /* @__PURE__ */ jsx35(PanelDivider, {}),
59285
- /* @__PURE__ */ jsx35(PanelTitle, { children: "\u63D2\u4EF6" }),
59286
- !sessionId ? (
59287
- // 首页没有会话,开关只记下「这条消息要带上谁」:不说清楚,用户会以为已经
59288
- // 生效(issue 明确要求「明确为待选,不宣称已经激活」)。
59289
- /* @__PURE__ */ jsx35("div", { className: "px-3 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: "\u5148\u9009\u4E2D\uFF0C\u53D1\u9001\u8FD9\u6761\u6D88\u606F\u65F6\u4F1A\u4E00\u5E76\u542F\u7528" })
59290
- ) : null,
59291
- (sessionId ? activation.loading : pendingLoading) && visibleItems.length === 0 ? /* @__PURE__ */ jsxs28("div", { className: "px-3 py-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
59292
- /* @__PURE__ */ jsx35(LoaderCircle, { size: 12, className: "mr-1 inline animate-spin" }),
59293
- "\u6B63\u5728\u83B7\u53D6\u63D2\u4EF6\u2026"
59402
+ visibleSections.includes("plugins") ? /* @__PURE__ */ jsxs28(Fragment10, { children: [
59403
+ /* @__PURE__ */ jsx36(PanelDivider, {}),
59404
+ /* @__PURE__ */ jsx36(PanelTitle, { children: "\u63D2\u4EF6" }),
59405
+ !sessionId ? (
59406
+ // 首页没有会话,开关只记下「这条消息要带上谁」:不说清楚,用户会以为已经
59407
+ // 生效(issue 明确要求「明确为待选,不宣称已经激活」)。
59408
+ /* @__PURE__ */ jsx36("div", { className: "px-3 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: "\u5148\u9009\u4E2D\uFF0C\u53D1\u9001\u8FD9\u6761\u6D88\u606F\u65F6\u4F1A\u4E00\u5E76\u542F\u7528" })
59409
+ ) : null,
59410
+ (sessionId ? activation.loading : pendingLoading) && visibleItems.length === 0 ? /* @__PURE__ */ jsxs28("div", { className: "px-3 py-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
59411
+ /* @__PURE__ */ jsx36(LoaderCircle, { size: 12, className: "mr-1 inline animate-spin" }),
59412
+ "\u6B63\u5728\u83B7\u53D6\u63D2\u4EF6\u2026"
59413
+ ] }) : null,
59414
+ failed ? /* @__PURE__ */ jsx36(
59415
+ "button",
59416
+ {
59417
+ type: "button",
59418
+ onClick: () => sessionId ? reload() : void loadPendingCatalog(),
59419
+ className: "px-3 py-1.5 text-left text-[11px] text-[hsl(var(--muted-foreground))] underline",
59420
+ children: "\u63D2\u4EF6\u5217\u8868\u6682\u4E0D\u53EF\u7528\uFF0C\u70B9\u51FB\u91CD\u8BD5"
59421
+ }
59422
+ ) : null,
59423
+ /* @__PURE__ */ jsx36(
59424
+ PluginConnectorList,
59425
+ {
59426
+ client,
59427
+ sessionId,
59428
+ items: visibleItems,
59429
+ inFlight: activation.inFlight,
59430
+ busy: sessionId ? activation.busy : pendingLoading,
59431
+ mutationError: sessionId ? activation.mutationError : false,
59432
+ onToggle: toggle,
59433
+ onRetry: activation.retry,
59434
+ onEditConfig: activation.editConfig,
59435
+ configuring: sessionId ? activation.configuring : null,
59436
+ onConfigSaved: activation.onConfigSaved,
59437
+ onConfigClose: activation.onConfigClose,
59438
+ disabledReason: sessionId ? null : pendingDisabledReason,
59439
+ unavailableText: failed ? null : query.trim() ? "\u6CA1\u6709\u5339\u914D\u7684\u63D2\u4EF6" : null,
59440
+ emptyText: sessionId ? "\u5C1A\u672A\u5B89\u88C5\u63D2\u4EF6" : "\u5C1A\u672A\u5B89\u88C5\u63D2\u4EF6\uFF0C\u53BB\u5E94\u7528\u5E02\u573A\u6DFB\u52A0\u4E00\u4E2A",
59441
+ draft: !sessionId
59442
+ }
59443
+ )
59294
59444
  ] }) : null,
59295
- failed ? /* @__PURE__ */ jsx35(
59296
- "button",
59297
- {
59298
- type: "button",
59299
- onClick: () => sessionId ? reload() : void loadPendingCatalog(),
59300
- className: "px-3 py-1.5 text-left text-[11px] text-[hsl(var(--muted-foreground))] underline",
59301
- children: "\u63D2\u4EF6\u5217\u8868\u6682\u4E0D\u53EF\u7528\uFF0C\u70B9\u51FB\u91CD\u8BD5"
59302
- }
59303
- ) : null,
59304
- /* @__PURE__ */ jsx35(
59305
- PluginConnectorList,
59306
- {
59307
- client,
59308
- sessionId,
59309
- items: visibleItems,
59310
- inFlight: activation.inFlight,
59311
- busy: sessionId ? activation.busy : pendingLoading,
59312
- mutationError: sessionId ? activation.mutationError : false,
59313
- onToggle: toggle,
59314
- onRetry: activation.retry,
59315
- onEditConfig: activation.editConfig,
59316
- configuring: sessionId ? activation.configuring : null,
59317
- onConfigSaved: activation.onConfigSaved,
59318
- onConfigClose: activation.onConfigClose,
59319
- disabledReason: sessionId ? null : pendingDisabledReason,
59320
- unavailableText: failed ? null : query.trim() ? "\u6CA1\u6709\u5339\u914D\u7684\u63D2\u4EF6" : null,
59321
- emptyText: sessionId ? "\u5C1A\u672A\u5B89\u88C5\u63D2\u4EF6" : "\u5C1A\u672A\u5B89\u88C5\u63D2\u4EF6\uFF0C\u53BB\u5E94\u7528\u5E02\u573A\u6DFB\u52A0\u4E00\u4E2A",
59322
- draft: !sessionId
59323
- }
59324
- ),
59325
- renderExternalAccounts ? /* @__PURE__ */ jsxs28(Fragment10, { children: [
59326
- /* @__PURE__ */ jsx35(PanelDivider, {}),
59327
- /* @__PURE__ */ jsx35(PanelTitle, { children: "\u5916\u90E8\u8D26\u53F7" }),
59445
+ visibleSections.includes("accounts") && renderExternalAccounts ? /* @__PURE__ */ jsxs28(Fragment10, { children: [
59446
+ /* @__PURE__ */ jsx36(PanelDivider, {}),
59447
+ /* @__PURE__ */ jsx36(PanelTitle, { children: "\u5916\u90E8\u8D26\u53F7" }),
59328
59448
  renderExternalAccounts(query)
59329
59449
  ] }) : null,
59330
59450
  renderFooterActions ? /* @__PURE__ */ jsxs28(Fragment10, { children: [
59331
- /* @__PURE__ */ jsx35(PanelDivider, {}),
59451
+ /* @__PURE__ */ jsx36(PanelDivider, {}),
59332
59452
  renderFooterActions()
59333
59453
  ] }) : null
59334
59454
  ] });
59335
59455
  }
59336
59456
 
59337
59457
  // src/components/PluginTriggerStack.tsx
59338
- import { jsx as jsx36, jsxs as jsxs29 } from "react/jsx-runtime";
59458
+ import { jsx as jsx37, jsxs as jsxs29 } from "react/jsx-runtime";
59339
59459
  var AVATAR_SIZE = 20;
59340
59460
  function hueOf(name) {
59341
59461
  let hash2 = 0;
@@ -59359,7 +59479,7 @@ function PluginTriggerStack({ client, sessionId, summary, className }) {
59359
59479
  summary.visible.map((item) => {
59360
59480
  const label = item.displayName?.trim() || item.name;
59361
59481
  const tone = AVATAR_PALETTE[hueOf(item.name) % AVATAR_PALETTE.length];
59362
- return item.icon ? /* @__PURE__ */ jsx36(
59482
+ return item.icon ? /* @__PURE__ */ jsx37(
59363
59483
  SessionPluginIcon,
59364
59484
  {
59365
59485
  client,
@@ -59370,7 +59490,7 @@ function PluginTriggerStack({ client, sessionId, summary, className }) {
59370
59490
  className: ring
59371
59491
  },
59372
59492
  item.name
59373
- ) : /* @__PURE__ */ jsx36(
59493
+ ) : /* @__PURE__ */ jsx37(
59374
59494
  "span",
59375
59495
  {
59376
59496
  title: label,
@@ -59400,7 +59520,7 @@ import {
59400
59520
  getContextDisplayState,
59401
59521
  getContextGroupDisplayState
59402
59522
  } from "@blade-hq/agent-client";
59403
- import { jsx as jsx37, jsxs as jsxs30 } from "react/jsx-runtime";
59523
+ import { jsx as jsx38, jsxs as jsxs30 } from "react/jsx-runtime";
59404
59524
  function ContextCard({ context, className }) {
59405
59525
  const display = getContextDisplayState(context);
59406
59526
  return /* @__PURE__ */ jsxs30(
@@ -59409,7 +59529,7 @@ function ContextCard({ context, className }) {
59409
59529
  className: `blade-chat-context-card group/context-card overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`,
59410
59530
  children: [
59411
59531
  /* @__PURE__ */ jsxs30("summary", { className: "blade-chat-context-summary flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 [&::-webkit-details-marker]:hidden", children: [
59412
- /* @__PURE__ */ jsx37(
59532
+ /* @__PURE__ */ jsx38(
59413
59533
  Layers,
59414
59534
  {
59415
59535
  size: 15,
@@ -59418,10 +59538,10 @@ function ContextCard({ context, className }) {
59418
59538
  }
59419
59539
  ),
59420
59540
  /* @__PURE__ */ jsxs30("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
59421
- /* @__PURE__ */ jsx37("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
59422
- /* @__PURE__ */ jsx37("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
59541
+ /* @__PURE__ */ jsx38("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
59542
+ /* @__PURE__ */ jsx38("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
59423
59543
  ] }),
59424
- /* @__PURE__ */ jsx37(
59544
+ /* @__PURE__ */ jsx38(
59425
59545
  ChevronDown,
59426
59546
  {
59427
59547
  size: 14,
@@ -59430,7 +59550,7 @@ function ContextCard({ context, className }) {
59430
59550
  }
59431
59551
  )
59432
59552
  ] }),
59433
- /* @__PURE__ */ jsx37("div", { className: "blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: display.detail })
59553
+ /* @__PURE__ */ jsx38("div", { className: "blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: display.detail })
59434
59554
  ]
59435
59555
  }
59436
59556
  );
@@ -59441,7 +59561,7 @@ function ContextGroupCard({ contexts, className }) {
59441
59561
  const group = single ? null : getContextGroupDisplayState(contexts);
59442
59562
  return /* @__PURE__ */ jsxs30("details", { className: `blade-chat-context-card group/context-group overflow-hidden rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`, children: [
59443
59563
  /* @__PURE__ */ jsxs30("summary", { className: "blade-chat-context-summary flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 [&::-webkit-details-marker]:hidden", children: [
59444
- /* @__PURE__ */ jsx37(
59564
+ /* @__PURE__ */ jsx38(
59445
59565
  Layers,
59446
59566
  {
59447
59567
  size: 15,
@@ -59450,10 +59570,10 @@ function ContextGroupCard({ contexts, className }) {
59450
59570
  }
59451
59571
  ),
59452
59572
  /* @__PURE__ */ jsxs30("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
59453
- /* @__PURE__ */ jsx37("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: single ? single.title : `${group?.title} \xB7 ${group?.count} \u9879` }),
59454
- /* @__PURE__ */ jsx37("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: single ? single.summary : group?.summary })
59573
+ /* @__PURE__ */ jsx38("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: single ? single.title : `${group?.title} \xB7 ${group?.count} \u9879` }),
59574
+ /* @__PURE__ */ jsx38("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: single ? single.summary : group?.summary })
59455
59575
  ] }),
59456
- /* @__PURE__ */ jsx37(
59576
+ /* @__PURE__ */ jsx38(
59457
59577
  ChevronDown,
59458
59578
  {
59459
59579
  size: 14,
@@ -59462,7 +59582,7 @@ function ContextGroupCard({ contexts, className }) {
59462
59582
  }
59463
59583
  )
59464
59584
  ] }),
59465
- single ? /* @__PURE__ */ jsx37("div", { className: "blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: single.detail }) : /* @__PURE__ */ jsx37("div", { className: "blade-chat-context-group-items flex flex-col gap-1.5 border-t border-[hsl(var(--border))] p-2", children: contexts.map((context) => /* @__PURE__ */ jsx37(
59585
+ single ? /* @__PURE__ */ jsx38("div", { className: "blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: single.detail }) : /* @__PURE__ */ jsx38("div", { className: "blade-chat-context-group-items flex flex-col gap-1.5 border-t border-[hsl(var(--border))] p-2", children: contexts.map((context) => /* @__PURE__ */ jsx38(
59466
59586
  ContextCard,
59467
59587
  {
59468
59588
  context
@@ -59473,8 +59593,8 @@ function ContextGroupCard({ contexts, className }) {
59473
59593
  }
59474
59594
 
59475
59595
  // src/components/SessionMemoryToggle.tsx
59476
- import { useCallback as useCallback32, useEffect as useEffect29, useRef as useRef30, useState as useState39, useSyncExternalStore as useSyncExternalStore2 } from "react";
59477
- import { jsx as jsx38, jsxs as jsxs31 } from "react/jsx-runtime";
59596
+ import { useCallback as useCallback32, useEffect as useEffect31, useRef as useRef32, useState as useState41, useSyncExternalStore as useSyncExternalStore2 } from "react";
59597
+ import { jsx as jsx39, jsxs as jsxs31 } from "react/jsx-runtime";
59478
59598
  var saveStates = /* @__PURE__ */ new WeakMap();
59479
59599
  function getSaveState(client, sessionId) {
59480
59600
  let clientStates = saveStates.get(client);
@@ -59531,10 +59651,10 @@ function SessionMemoryToggle({
59531
59651
  getSaving,
59532
59652
  getSaving
59533
59653
  );
59534
- const [draftEnabled, setDraftEnabled] = useState39(enabled);
59535
- const activeSessionIdRef = useRef30(sessionId);
59654
+ const [draftEnabled, setDraftEnabled] = useState41(enabled);
59655
+ const activeSessionIdRef = useRef32(sessionId);
59536
59656
  activeSessionIdRef.current = sessionId;
59537
- useEffect29(() => {
59657
+ useEffect31(() => {
59538
59658
  setDraftEnabled(enabled);
59539
59659
  }, [enabled, sessionId]);
59540
59660
  const update = useCallback32(
@@ -59564,8 +59684,8 @@ function SessionMemoryToggle({
59564
59684
  [client, enabled, onError, onSaved, sessionId]
59565
59685
  );
59566
59686
  return /* @__PURE__ */ jsxs31("label", { className: cn("flex items-center justify-between", className), children: [
59567
- /* @__PURE__ */ jsx38("span", { className: labelClassName, children: label }),
59568
- /* @__PURE__ */ jsx38(
59687
+ /* @__PURE__ */ jsx39("span", { className: labelClassName, children: label }),
59688
+ /* @__PURE__ */ jsx39(
59569
59689
  "input",
59570
59690
  {
59571
59691
  type: "checkbox",
@@ -59676,7 +59796,7 @@ function useComposedRefs(...refs) {
59676
59796
 
59677
59797
  // ../../node_modules/.pnpm/@radix-ui+react-context@1.1.2_@types+react@19.2.14_react@19.2.4/node_modules/@radix-ui/react-context/dist/index.mjs
59678
59798
  import * as React3 from "react";
59679
- import { jsx as jsx39 } from "react/jsx-runtime";
59799
+ import { jsx as jsx40 } from "react/jsx-runtime";
59680
59800
  function createContextScope(scopeName, createContextScopeDeps = []) {
59681
59801
  let defaultContexts = [];
59682
59802
  function createContext32(rootComponentName, defaultContext) {
@@ -59687,7 +59807,7 @@ function createContextScope(scopeName, createContextScopeDeps = []) {
59687
59807
  const { scope, children, ...context } = props;
59688
59808
  const Context = scope?.[scopeName]?.[index3] || BaseContext;
59689
59809
  const value = React3.useMemo(() => context, Object.values(context));
59690
- return /* @__PURE__ */ jsx39(Context.Provider, { value, children });
59810
+ return /* @__PURE__ */ jsx40(Context.Provider, { value, children });
59691
59811
  };
59692
59812
  Provider2.displayName = rootComponentName + "Provider";
59693
59813
  function useContext22(consumerName, scope) {
@@ -59744,7 +59864,7 @@ import * as ReactDOM from "react-dom";
59744
59864
 
59745
59865
  // ../../node_modules/.pnpm/@radix-ui+react-slot@1.2.3_@types+react@19.2.14_react@19.2.4/node_modules/@radix-ui/react-slot/dist/index.mjs
59746
59866
  import * as React4 from "react";
59747
- import { Fragment as Fragment22, jsx as jsx40 } from "react/jsx-runtime";
59867
+ import { Fragment as Fragment22, jsx as jsx41 } from "react/jsx-runtime";
59748
59868
  // @__NO_SIDE_EFFECTS__
59749
59869
  function createSlot(ownerName) {
59750
59870
  const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
@@ -59762,9 +59882,9 @@ function createSlot(ownerName) {
59762
59882
  return child;
59763
59883
  }
59764
59884
  });
59765
- return /* @__PURE__ */ jsx40(SlotClone, { ...slotProps, ref: forwardedRef, children: React4.isValidElement(newElement) ? React4.cloneElement(newElement, void 0, newChildren) : null });
59885
+ return /* @__PURE__ */ jsx41(SlotClone, { ...slotProps, ref: forwardedRef, children: React4.isValidElement(newElement) ? React4.cloneElement(newElement, void 0, newChildren) : null });
59766
59886
  }
59767
- return /* @__PURE__ */ jsx40(SlotClone, { ...slotProps, ref: forwardedRef, children });
59887
+ return /* @__PURE__ */ jsx41(SlotClone, { ...slotProps, ref: forwardedRef, children });
59768
59888
  });
59769
59889
  Slot2.displayName = `${ownerName}.Slot`;
59770
59890
  return Slot2;
@@ -59790,7 +59910,7 @@ var SLOTTABLE_IDENTIFIER = /* @__PURE__ */ Symbol("radix.slottable");
59790
59910
  // @__NO_SIDE_EFFECTS__
59791
59911
  function createSlottable(ownerName) {
59792
59912
  const Slottable2 = ({ children }) => {
59793
- return /* @__PURE__ */ jsx40(Fragment22, { children });
59913
+ return /* @__PURE__ */ jsx41(Fragment22, { children });
59794
59914
  };
59795
59915
  Slottable2.displayName = `${ownerName}.Slottable`;
59796
59916
  Slottable2.__radixId = SLOTTABLE_IDENTIFIER;
@@ -59838,7 +59958,7 @@ function getElementRef(element2) {
59838
59958
  }
59839
59959
 
59840
59960
  // ../../node_modules/.pnpm/@radix-ui+react-primitive@2.1.3_@types+react-dom@19.2.3_@types+react@19.2.14__@types+re_1181ea5061ec9212248424669240e4ec/node_modules/@radix-ui/react-primitive/dist/index.mjs
59841
- import { jsx as jsx41 } from "react/jsx-runtime";
59961
+ import { jsx as jsx42 } from "react/jsx-runtime";
59842
59962
  var NODES = [
59843
59963
  "a",
59844
59964
  "button",
@@ -59866,7 +59986,7 @@ var Primitive = NODES.reduce((primitive, node3) => {
59866
59986
  if (typeof window !== "undefined") {
59867
59987
  window[/* @__PURE__ */ Symbol.for("radix-ui")] = true;
59868
59988
  }
59869
- return /* @__PURE__ */ jsx41(Comp, { ...primitiveProps, ref: forwardedRef });
59989
+ return /* @__PURE__ */ jsx42(Comp, { ...primitiveProps, ref: forwardedRef });
59870
59990
  });
59871
59991
  Node2.displayName = `Primitive.${node3}`;
59872
59992
  return { ...primitive, [node3]: Node2 };
@@ -59901,7 +60021,7 @@ function useEscapeKeydown(onEscapeKeyDownProp, ownerDocument = globalThis?.docum
59901
60021
  }
59902
60022
 
59903
60023
  // ../../node_modules/.pnpm/@radix-ui+react-dismissable-layer@1.1.11_@types+react-dom@19.2.3_@types+react@19.2.14___3d3960154a4c07d09bb90cb341135fc5/node_modules/@radix-ui/react-dismissable-layer/dist/index.mjs
59904
- import { jsx as jsx42 } from "react/jsx-runtime";
60024
+ import { jsx as jsx43 } from "react/jsx-runtime";
59905
60025
  var DISMISSABLE_LAYER_NAME = "DismissableLayer";
59906
60026
  var CONTEXT_UPDATE = "dismissableLayer.update";
59907
60027
  var POINTER_DOWN_OUTSIDE = "dismissableLayer.pointerDownOutside";
@@ -59989,7 +60109,7 @@ var DismissableLayer = React8.forwardRef(
59989
60109
  document.addEventListener(CONTEXT_UPDATE, handleUpdate);
59990
60110
  return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
59991
60111
  }, []);
59992
- return /* @__PURE__ */ jsx42(
60112
+ return /* @__PURE__ */ jsx43(
59993
60113
  Primitive.div,
59994
60114
  {
59995
60115
  ...layerProps,
@@ -60023,7 +60143,7 @@ var DismissableLayerBranch = React8.forwardRef((props, forwardedRef) => {
60023
60143
  };
60024
60144
  }
60025
60145
  }, [context.branches]);
60026
- return /* @__PURE__ */ jsx42(Primitive.div, { ...props, ref: composedRefs });
60146
+ return /* @__PURE__ */ jsx43(Primitive.div, { ...props, ref: composedRefs });
60027
60147
  });
60028
60148
  DismissableLayerBranch.displayName = BRANCH_NAME;
60029
60149
  function usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis?.document) {
@@ -62057,11 +62177,11 @@ var arrow3 = (options, deps) => {
62057
62177
 
62058
62178
  // ../../node_modules/.pnpm/@radix-ui+react-arrow@1.1.7_@types+react-dom@19.2.3_@types+react@19.2.14__@types+react@_e05f2c19a58a99fddf374207b5e3778c/node_modules/@radix-ui/react-arrow/dist/index.mjs
62059
62179
  import * as React12 from "react";
62060
- import { jsx as jsx43 } from "react/jsx-runtime";
62180
+ import { jsx as jsx44 } from "react/jsx-runtime";
62061
62181
  var NAME = "Arrow";
62062
62182
  var Arrow = React12.forwardRef((props, forwardedRef) => {
62063
62183
  const { children, width = 10, height = 5, ...arrowProps } = props;
62064
- return /* @__PURE__ */ jsx43(
62184
+ return /* @__PURE__ */ jsx44(
62065
62185
  Primitive.svg,
62066
62186
  {
62067
62187
  ...arrowProps,
@@ -62070,7 +62190,7 @@ var Arrow = React12.forwardRef((props, forwardedRef) => {
62070
62190
  height,
62071
62191
  viewBox: "0 0 30 10",
62072
62192
  preserveAspectRatio: "none",
62073
- children: props.asChild ? children : /* @__PURE__ */ jsx43("polygon", { points: "0,0 30,0 15,10" })
62193
+ children: props.asChild ? children : /* @__PURE__ */ jsx44("polygon", { points: "0,0 30,0 15,10" })
62074
62194
  }
62075
62195
  );
62076
62196
  });
@@ -62115,14 +62235,14 @@ function useSize(element2) {
62115
62235
  }
62116
62236
 
62117
62237
  // ../../node_modules/.pnpm/@radix-ui+react-popper@1.2.8_@types+react-dom@19.2.3_@types+react@19.2.14__@types+react_13e0521d8aea7ebfbfb8bee1fb615c05/node_modules/@radix-ui/react-popper/dist/index.mjs
62118
- import { jsx as jsx44 } from "react/jsx-runtime";
62238
+ import { jsx as jsx45 } from "react/jsx-runtime";
62119
62239
  var POPPER_NAME = "Popper";
62120
62240
  var [createPopperContext, createPopperScope] = createContextScope(POPPER_NAME);
62121
62241
  var [PopperProvider, usePopperContext] = createPopperContext(POPPER_NAME);
62122
62242
  var Popper = (props) => {
62123
62243
  const { __scopePopper, children } = props;
62124
62244
  const [anchor2, setAnchor] = React14.useState(null);
62125
- return /* @__PURE__ */ jsx44(PopperProvider, { scope: __scopePopper, anchor: anchor2, onAnchorChange: setAnchor, children });
62245
+ return /* @__PURE__ */ jsx45(PopperProvider, { scope: __scopePopper, anchor: anchor2, onAnchorChange: setAnchor, children });
62126
62246
  };
62127
62247
  Popper.displayName = POPPER_NAME;
62128
62248
  var ANCHOR_NAME = "PopperAnchor";
@@ -62140,7 +62260,7 @@ var PopperAnchor = React14.forwardRef(
62140
62260
  context.onAnchorChange(anchorRef.current);
62141
62261
  }
62142
62262
  });
62143
- return virtualRef ? null : /* @__PURE__ */ jsx44(Primitive.div, { ...anchorProps, ref: composedRefs });
62263
+ return virtualRef ? null : /* @__PURE__ */ jsx45(Primitive.div, { ...anchorProps, ref: composedRefs });
62144
62264
  }
62145
62265
  );
62146
62266
  PopperAnchor.displayName = ANCHOR_NAME;
@@ -62233,7 +62353,7 @@ var PopperContent = React14.forwardRef(
62233
62353
  useLayoutEffect22(() => {
62234
62354
  if (content3) setContentZIndex(window.getComputedStyle(content3).zIndex);
62235
62355
  }, [content3]);
62236
- return /* @__PURE__ */ jsx44(
62356
+ return /* @__PURE__ */ jsx45(
62237
62357
  "div",
62238
62358
  {
62239
62359
  ref: refs.setFloating,
@@ -62257,7 +62377,7 @@ var PopperContent = React14.forwardRef(
62257
62377
  }
62258
62378
  },
62259
62379
  dir: props.dir,
62260
- children: /* @__PURE__ */ jsx44(
62380
+ children: /* @__PURE__ */ jsx45(
62261
62381
  PopperContentProvider,
62262
62382
  {
62263
62383
  scope: __scopePopper,
@@ -62266,7 +62386,7 @@ var PopperContent = React14.forwardRef(
62266
62386
  arrowX,
62267
62387
  arrowY,
62268
62388
  shouldHideArrow: cannotCenterArrow,
62269
- children: /* @__PURE__ */ jsx44(
62389
+ children: /* @__PURE__ */ jsx45(
62270
62390
  Primitive.div,
62271
62391
  {
62272
62392
  "data-side": placedSide,
@@ -62303,7 +62423,7 @@ var PopperArrow = React14.forwardRef(function PopperArrow2(props, forwardedRef)
62303
62423
  // we have to use an extra wrapper because `ResizeObserver` (used by `useSize`)
62304
62424
  // doesn't report size as we'd expect on SVG elements.
62305
62425
  // it reports their bounding box which is effectively the largest path inside the SVG.
62306
- /* @__PURE__ */ jsx44(
62426
+ /* @__PURE__ */ jsx45(
62307
62427
  "span",
62308
62428
  {
62309
62429
  ref: contentContext.onArrowChange,
@@ -62326,7 +62446,7 @@ var PopperArrow = React14.forwardRef(function PopperArrow2(props, forwardedRef)
62326
62446
  }[contentContext.placedSide],
62327
62447
  visibility: contentContext.shouldHideArrow ? "hidden" : void 0
62328
62448
  },
62329
- children: /* @__PURE__ */ jsx44(
62449
+ children: /* @__PURE__ */ jsx45(
62330
62450
  Root,
62331
62451
  {
62332
62452
  ...arrowProps,
@@ -62389,14 +62509,14 @@ var Arrow2 = PopperArrow;
62389
62509
  // ../../node_modules/.pnpm/@radix-ui+react-portal@1.1.9_@types+react-dom@19.2.3_@types+react@19.2.14__@types+react_7668895bec2444446faa4e0f4eb5244b/node_modules/@radix-ui/react-portal/dist/index.mjs
62390
62510
  import * as React15 from "react";
62391
62511
  import ReactDOM3 from "react-dom";
62392
- import { jsx as jsx45 } from "react/jsx-runtime";
62512
+ import { jsx as jsx46 } from "react/jsx-runtime";
62393
62513
  var PORTAL_NAME = "Portal";
62394
62514
  var Portal = React15.forwardRef((props, forwardedRef) => {
62395
62515
  const { container: containerProp, ...portalProps } = props;
62396
62516
  const [mounted, setMounted] = React15.useState(false);
62397
62517
  useLayoutEffect22(() => setMounted(true), []);
62398
62518
  const container = containerProp || mounted && globalThis?.document?.body;
62399
- return container ? ReactDOM3.createPortal(/* @__PURE__ */ jsx45(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
62519
+ return container ? ReactDOM3.createPortal(/* @__PURE__ */ jsx46(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
62400
62520
  });
62401
62521
  Portal.displayName = PORTAL_NAME;
62402
62522
 
@@ -62596,7 +62716,7 @@ function isFunction(value) {
62596
62716
 
62597
62717
  // ../../node_modules/.pnpm/@radix-ui+react-visually-hidden@1.2.3_@types+react-dom@19.2.3_@types+react@19.2.14__@ty_fa89646d7248b32d1762bf88948f6339/node_modules/@radix-ui/react-visually-hidden/dist/index.mjs
62598
62718
  import * as React18 from "react";
62599
- import { jsx as jsx46 } from "react/jsx-runtime";
62719
+ import { jsx as jsx47 } from "react/jsx-runtime";
62600
62720
  var VISUALLY_HIDDEN_STYLES = Object.freeze({
62601
62721
  // See: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden.scss
62602
62722
  position: "absolute",
@@ -62613,7 +62733,7 @@ var VISUALLY_HIDDEN_STYLES = Object.freeze({
62613
62733
  var NAME2 = "VisuallyHidden";
62614
62734
  var VisuallyHidden = React18.forwardRef(
62615
62735
  (props, forwardedRef) => {
62616
- return /* @__PURE__ */ jsx46(
62736
+ return /* @__PURE__ */ jsx47(
62617
62737
  Primitive.span,
62618
62738
  {
62619
62739
  ...props,
@@ -62627,7 +62747,7 @@ VisuallyHidden.displayName = NAME2;
62627
62747
  var Root3 = VisuallyHidden;
62628
62748
 
62629
62749
  // ../../node_modules/.pnpm/@radix-ui+react-tooltip@1.2.8_@types+react-dom@19.2.3_@types+react@19.2.14__@types+reac_9074d9fb06315b089b2bee17c4c65951/node_modules/@radix-ui/react-tooltip/dist/index.mjs
62630
- import { jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
62750
+ import { jsx as jsx48, jsxs as jsxs32 } from "react/jsx-runtime";
62631
62751
  var [createTooltipContext, createTooltipScope] = createContextScope("Tooltip", [
62632
62752
  createPopperScope
62633
62753
  ]);
@@ -62651,7 +62771,7 @@ var TooltipProvider = (props) => {
62651
62771
  const skipDelayTimer = skipDelayTimerRef.current;
62652
62772
  return () => window.clearTimeout(skipDelayTimer);
62653
62773
  }, []);
62654
- return /* @__PURE__ */ jsx47(
62774
+ return /* @__PURE__ */ jsx48(
62655
62775
  TooltipProviderContextProvider,
62656
62776
  {
62657
62777
  scope: __scopeTooltip,
@@ -62742,7 +62862,7 @@ var Tooltip = (props) => {
62742
62862
  }
62743
62863
  };
62744
62864
  }, []);
62745
- return /* @__PURE__ */ jsx47(Root2, { ...popperScope, children: /* @__PURE__ */ jsx47(
62865
+ return /* @__PURE__ */ jsx48(Root2, { ...popperScope, children: /* @__PURE__ */ jsx48(
62746
62866
  TooltipContextProvider,
62747
62867
  {
62748
62868
  scope: __scopeTooltip,
@@ -62786,7 +62906,7 @@ var TooltipTrigger = React19.forwardRef(
62786
62906
  React19.useEffect(() => {
62787
62907
  return () => document.removeEventListener("pointerup", handlePointerUp);
62788
62908
  }, [handlePointerUp]);
62789
- return /* @__PURE__ */ jsx47(Anchor, { asChild: true, ...popperScope, children: /* @__PURE__ */ jsx47(
62909
+ return /* @__PURE__ */ jsx48(Anchor, { asChild: true, ...popperScope, children: /* @__PURE__ */ jsx48(
62790
62910
  Primitive.button,
62791
62911
  {
62792
62912
  "aria-describedby": context.open ? context.contentId : void 0,
@@ -62828,7 +62948,7 @@ var [PortalProvider, usePortalContext] = createTooltipContext(PORTAL_NAME2, {
62828
62948
  var TooltipPortal = (props) => {
62829
62949
  const { __scopeTooltip, forceMount, children, container } = props;
62830
62950
  const context = useTooltipContext(PORTAL_NAME2, __scopeTooltip);
62831
- return /* @__PURE__ */ jsx47(PortalProvider, { scope: __scopeTooltip, forceMount, children: /* @__PURE__ */ jsx47(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx47(Portal, { asChild: true, container, children }) }) });
62951
+ return /* @__PURE__ */ jsx48(PortalProvider, { scope: __scopeTooltip, forceMount, children: /* @__PURE__ */ jsx48(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx48(Portal, { asChild: true, container, children }) }) });
62832
62952
  };
62833
62953
  TooltipPortal.displayName = PORTAL_NAME2;
62834
62954
  var CONTENT_NAME2 = "TooltipContent";
@@ -62837,7 +62957,7 @@ var TooltipContent = React19.forwardRef(
62837
62957
  const portalContext = usePortalContext(CONTENT_NAME2, props.__scopeTooltip);
62838
62958
  const { forceMount = portalContext.forceMount, side = "top", ...contentProps } = props;
62839
62959
  const context = useTooltipContext(CONTENT_NAME2, props.__scopeTooltip);
62840
- return /* @__PURE__ */ jsx47(Presence, { present: forceMount || context.open, children: context.disableHoverableContent ? /* @__PURE__ */ jsx47(TooltipContentImpl, { side, ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx47(TooltipContentHoverable, { side, ...contentProps, ref: forwardedRef }) });
62960
+ return /* @__PURE__ */ jsx48(Presence, { present: forceMount || context.open, children: context.disableHoverableContent ? /* @__PURE__ */ jsx48(TooltipContentImpl, { side, ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx48(TooltipContentHoverable, { side, ...contentProps, ref: forwardedRef }) });
62841
62961
  }
62842
62962
  );
62843
62963
  var TooltipContentHoverable = React19.forwardRef((props, forwardedRef) => {
@@ -62899,7 +63019,7 @@ var TooltipContentHoverable = React19.forwardRef((props, forwardedRef) => {
62899
63019
  return () => document.removeEventListener("pointermove", handleTrackPointerGrace);
62900
63020
  }
62901
63021
  }, [trigger, content3, pointerGraceArea, onClose, handleRemoveGraceArea]);
62902
- return /* @__PURE__ */ jsx47(TooltipContentImpl, { ...props, ref: composedRefs });
63022
+ return /* @__PURE__ */ jsx48(TooltipContentImpl, { ...props, ref: composedRefs });
62903
63023
  });
62904
63024
  var [VisuallyHiddenContentContextProvider, useVisuallyHiddenContentContext] = createTooltipContext(TOOLTIP_NAME, { isInside: false });
62905
63025
  var Slottable = createSlottable("TooltipContent");
@@ -62930,7 +63050,7 @@ var TooltipContentImpl = React19.forwardRef(
62930
63050
  return () => window.removeEventListener("scroll", handleScroll, { capture: true });
62931
63051
  }
62932
63052
  }, [context.trigger, onClose]);
62933
- return /* @__PURE__ */ jsx47(
63053
+ return /* @__PURE__ */ jsx48(
62934
63054
  DismissableLayer,
62935
63055
  {
62936
63056
  asChild: true,
@@ -62958,8 +63078,8 @@ var TooltipContentImpl = React19.forwardRef(
62958
63078
  }
62959
63079
  },
62960
63080
  children: [
62961
- /* @__PURE__ */ jsx47(Slottable, { children }),
62962
- /* @__PURE__ */ jsx47(VisuallyHiddenContentContextProvider, { scope: __scopeTooltip, isInside: true, children: /* @__PURE__ */ jsx47(Root3, { id: context.contentId, role: "tooltip", children: ariaLabel || children }) })
63081
+ /* @__PURE__ */ jsx48(Slottable, { children }),
63082
+ /* @__PURE__ */ jsx48(VisuallyHiddenContentContextProvider, { scope: __scopeTooltip, isInside: true, children: /* @__PURE__ */ jsx48(Root3, { id: context.contentId, role: "tooltip", children: ariaLabel || children }) })
62963
63083
  ]
62964
63084
  }
62965
63085
  )
@@ -62977,7 +63097,7 @@ var TooltipArrow = React19.forwardRef(
62977
63097
  ARROW_NAME2,
62978
63098
  __scopeTooltip
62979
63099
  );
62980
- return visuallyHiddenContentContext.isInside ? null : /* @__PURE__ */ jsx47(Arrow2, { ...popperScope, ...arrowProps, ref: forwardedRef });
63100
+ return visuallyHiddenContentContext.isInside ? null : /* @__PURE__ */ jsx48(Arrow2, { ...popperScope, ...arrowProps, ref: forwardedRef });
62981
63101
  }
62982
63102
  );
62983
63103
  TooltipArrow.displayName = ARROW_NAME2;
@@ -63103,8 +63223,8 @@ var Portal2 = TooltipPortal;
63103
63223
  var Content2 = TooltipContent;
63104
63224
 
63105
63225
  // src/components/SessionBranchPicker.tsx
63106
- import { useMemo as useMemo26, useState as useState49 } from "react";
63107
- import { jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
63226
+ import { useMemo as useMemo26, useState as useState51 } from "react";
63227
+ import { jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
63108
63228
  var ROW_HEIGHT = 32;
63109
63229
  var SVG_WIDTH = 44;
63110
63230
  function SessionBranchPicker({
@@ -63112,8 +63232,8 @@ function SessionBranchPicker({
63112
63232
  disabled = false,
63113
63233
  onCheckout
63114
63234
  }) {
63115
- const [checkoutError, setCheckoutError] = useState49(null);
63116
- const [pendingNodeId, setPendingNodeId] = useState49(null);
63235
+ const [checkoutError, setCheckoutError] = useState51(null);
63236
+ const [pendingNodeId, setPendingNodeId] = useState51(null);
63117
63237
  const hasHistory = tree.nodes.length > 0;
63118
63238
  const layout = useMemo26(() => buildLayoutNodes(tree), [tree]);
63119
63239
  const nodeMap = useMemo26(() => new Map(tree.nodes.map((node3) => [node3.id, node3])), [tree]);
@@ -63144,9 +63264,9 @@ function SessionBranchPicker({
63144
63264
  }
63145
63265
  if (!hasHistory) return null;
63146
63266
  return /* @__PURE__ */ jsxs33(Provider, { delayDuration: 200, children: [
63147
- checkoutError ? /* @__PURE__ */ jsx48("p", { role: "alert", className: "mb-2 text-xs text-destructive", children: checkoutError }) : null,
63148
- /* @__PURE__ */ jsx48("div", { className: "flex max-h-52 justify-center overflow-x-auto overflow-y-auto", children: /* @__PURE__ */ jsxs33("div", { className: "relative", style: { height: graphHeight, width: graphWidth }, children: [
63149
- /* @__PURE__ */ jsx48(
63267
+ checkoutError ? /* @__PURE__ */ jsx49("p", { role: "alert", className: "mb-2 text-xs text-destructive", children: checkoutError }) : null,
63268
+ /* @__PURE__ */ jsx49("div", { className: "flex max-h-52 justify-center overflow-x-auto overflow-y-auto", children: /* @__PURE__ */ jsxs33("div", { className: "relative", style: { height: graphHeight, width: graphWidth }, children: [
63269
+ /* @__PURE__ */ jsx49(
63150
63270
  "svg",
63151
63271
  {
63152
63272
  "aria-hidden": "true",
@@ -63160,7 +63280,7 @@ function SessionBranchPicker({
63160
63280
  return null;
63161
63281
  }
63162
63282
  const childStroke = node3.isActive ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))";
63163
- return /* @__PURE__ */ jsx48(
63283
+ return /* @__PURE__ */ jsx49(
63164
63284
  "path",
63165
63285
  {
63166
63286
  d: buildEdgePath(
@@ -63181,12 +63301,12 @@ function SessionBranchPicker({
63181
63301
  })
63182
63302
  }
63183
63303
  ),
63184
- /* @__PURE__ */ jsx48("div", { className: "relative z-0 h-full", children: layout.nodes.map((node3) => {
63304
+ /* @__PURE__ */ jsx49("div", { className: "relative z-0 h-full", children: layout.nodes.map((node3) => {
63185
63305
  const isPendingNode = pendingNodeId === node3.id;
63186
63306
  const color2 = node3.isActive ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))";
63187
63307
  const previewText = node3.isVirtual ? isPendingNode ? "\u5207\u6362\u4E2D..." : "" : isPendingNode ? "\u5207\u6362\u4E2D..." : node3.preview;
63188
63308
  const shouldShowTooltip = !node3.isVirtual || Boolean(previewText);
63189
- const button = /* @__PURE__ */ jsx48(
63309
+ const button = /* @__PURE__ */ jsx49(
63190
63310
  "button",
63191
63311
  {
63192
63312
  type: "button",
@@ -63202,7 +63322,7 @@ function SessionBranchPicker({
63202
63322
  top: node3.row * ROW_HEIGHT,
63203
63323
  left: getColumnX(node3.column) - 12
63204
63324
  },
63205
- children: /* @__PURE__ */ jsx48("span", { "aria-hidden": "true", className: "absolute left-0 top-0 h-8 w-6", children: /* @__PURE__ */ jsx48(
63325
+ children: /* @__PURE__ */ jsx49("span", { "aria-hidden": "true", className: "absolute left-0 top-0 h-8 w-6", children: /* @__PURE__ */ jsx49(
63206
63326
  "svg",
63207
63327
  {
63208
63328
  "aria-hidden": "true",
@@ -63212,7 +63332,7 @@ function SessionBranchPicker({
63212
63332
  height: ROW_HEIGHT,
63213
63333
  viewBox: `0 0 24 ${ROW_HEIGHT}`,
63214
63334
  fill: "none",
63215
- children: node3.isVirtual ? /* @__PURE__ */ jsx48(
63335
+ children: node3.isVirtual ? /* @__PURE__ */ jsx49(
63216
63336
  "circle",
63217
63337
  {
63218
63338
  cx: 12,
@@ -63225,8 +63345,8 @@ function SessionBranchPicker({
63225
63345
  opacity: 0.7
63226
63346
  }
63227
63347
  ) : /* @__PURE__ */ jsxs33("g", { children: [
63228
- node3.isCurrent ? /* @__PURE__ */ jsx48("circle", { cx: 12, cy: ROW_HEIGHT / 2, r: 9, fill: color2, opacity: 0.18 }) : null,
63229
- /* @__PURE__ */ jsx48(
63348
+ node3.isCurrent ? /* @__PURE__ */ jsx49("circle", { cx: 12, cy: ROW_HEIGHT / 2, r: 9, fill: color2, opacity: 0.18 }) : null,
63349
+ /* @__PURE__ */ jsx49(
63230
63350
  "circle",
63231
63351
  {
63232
63352
  cx: 12,
@@ -63241,11 +63361,11 @@ function SessionBranchPicker({
63241
63361
  }
63242
63362
  );
63243
63363
  if (!shouldShowTooltip) {
63244
- return /* @__PURE__ */ jsx48("div", { children: button }, node3.id);
63364
+ return /* @__PURE__ */ jsx49("div", { children: button }, node3.id);
63245
63365
  }
63246
63366
  return /* @__PURE__ */ jsxs33(Root32, { children: [
63247
- /* @__PURE__ */ jsx48(Trigger, { asChild: true, children: button }),
63248
- /* @__PURE__ */ jsx48(Portal2, { children: /* @__PURE__ */ jsx48(
63367
+ /* @__PURE__ */ jsx49(Trigger, { asChild: true, children: button }),
63368
+ /* @__PURE__ */ jsx49(Portal2, { children: /* @__PURE__ */ jsx49(
63249
63369
  Content2,
63250
63370
  {
63251
63371
  side: "right",
@@ -63411,6 +63531,7 @@ export {
63411
63531
  MarkdownContent,
63412
63532
  MarkdownRenderer,
63413
63533
  McpAppCard,
63534
+ McpAppFrame,
63414
63535
  MemoryRefsHint,
63415
63536
  MessageImage,
63416
63537
  PLAN_AUTO_COLLAPSE_MS,
@@ -63435,6 +63556,8 @@ export {
63435
63556
  classifyAgentComputerLaunchOutcome,
63436
63557
  collectMemoryRefs,
63437
63558
  filterConnectorItems,
63559
+ getChatRun,
63560
+ getChatRunDuration,
63438
63561
  getPlanUpdateDisplayState,
63439
63562
  isAgentComputerCommand,
63440
63563
  isAgentComputerToolCall,
@@ -63453,6 +63576,7 @@ export {
63453
63576
  turnNavItemsFromMessages,
63454
63577
  useAgentSession,
63455
63578
  useBladeClient,
63579
+ useLiveExecutionDuration,
63456
63580
  useLlmChat,
63457
63581
  useMessagePin,
63458
63582
  useReplay,