@blade-hq/agent-kit 0.5.32 → 0.5.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/{SkillStatusBar-CvgcEiSi.d.ts → SkillStatusBar-Dp93pqlP.d.ts} +14 -3
  2. package/dist/{blade-client-DoodJJDz.d.ts → blade-client-DS7lV19a.d.ts} +4 -1
  3. package/dist/{chunk-FXEELOLI.js → chunk-7TS36PDU.js} +132 -73
  4. package/dist/chunk-7TS36PDU.js.map +1 -0
  5. package/dist/{chunk-ZWO6YBLA.js → chunk-DQXXSHCR.js} +5 -3
  6. package/dist/chunk-DQXXSHCR.js.map +1 -0
  7. package/dist/{chunk-QMOW3TDA.js → chunk-II2PTBJI.js} +14 -4
  8. package/dist/chunk-II2PTBJI.js.map +1 -0
  9. package/dist/{chunk-CFW62YND.js → chunk-IRHXGYY3.js} +3 -3
  10. package/dist/{chunk-YPFIWC45.js → chunk-KSYNFNF4.js} +2 -2
  11. package/dist/{chunk-EAZ7AGFY.js → chunk-LVWRKH45.js} +2 -2
  12. package/dist/client/index.d.ts +28 -1
  13. package/dist/client/index.js +1 -1
  14. package/dist/react/api/vibe-coding.d.ts +2 -2
  15. package/dist/react/api/vibe-coding.js +2 -2
  16. package/dist/react/components/chat/index.d.ts +3 -3
  17. package/dist/react/components/chat/index.js +5 -5
  18. package/dist/react/components/plan/index.js +4 -4
  19. package/dist/react/components/session/index.js +3 -3
  20. package/dist/react/components/workspace/index.d.ts +2 -2
  21. package/dist/react/components/workspace/index.js +3 -3
  22. package/dist/react/index.d.ts +9 -5
  23. package/dist/react/index.js +6 -6
  24. package/dist/{sessions-DFGsAOPa.d.ts → sessions-DaddUdO6.d.ts} +4 -1
  25. package/package.json +1 -1
  26. package/dist/chunk-FXEELOLI.js.map +0 -1
  27. package/dist/chunk-QMOW3TDA.js.map +0 -1
  28. package/dist/chunk-ZWO6YBLA.js.map +0 -1
  29. /package/dist/{chunk-CFW62YND.js.map → chunk-IRHXGYY3.js.map} +0 -0
  30. /package/dist/{chunk-YPFIWC45.js.map → chunk-KSYNFNF4.js.map} +0 -0
  31. /package/dist/{chunk-EAZ7AGFY.js.map → chunk-LVWRKH45.js.map} +0 -0
@@ -8,7 +8,7 @@ import {
8
8
  getCodeLanguageFromFilename,
9
9
  parseAskUserQuestion,
10
10
  useHighlightedCodeHtml
11
- } from "./chunk-CFW62YND.js";
11
+ } from "./chunk-IRHXGYY3.js";
12
12
  import {
13
13
  Collapsible,
14
14
  CollapsibleContent,
@@ -16,7 +16,7 @@ import {
16
16
  } from "./chunk-H62LH2AG.js";
17
17
  import {
18
18
  resolveSessionFilePreviewTarget
19
- } from "./chunk-EAZ7AGFY.js";
19
+ } from "./chunk-LVWRKH45.js";
20
20
  import {
21
21
  apiFetchResponse,
22
22
  buildMessageContent,
@@ -60,7 +60,7 @@ import {
60
60
  useUiBridgeStore,
61
61
  useUiStore,
62
62
  writeFile
63
- } from "./chunk-QMOW3TDA.js";
63
+ } from "./chunk-II2PTBJI.js";
64
64
  import {
65
65
  registerBridgeIframe,
66
66
  tapBridgeEvent
@@ -69,7 +69,7 @@ import {
69
69
  ModelOption,
70
70
  ModelsConfig,
71
71
  ModelsResource
72
- } from "./chunk-ZWO6YBLA.js";
72
+ } from "./chunk-DQXXSHCR.js";
73
73
  import {
74
74
  cn,
75
75
  copyToClipboard
@@ -81,7 +81,7 @@ import {
81
81
  // src/react/components/chat/ChatView.tsx
82
82
  import { CircleAlert as CircleAlert2 } from "lucide-react";
83
83
  import { Eye } from "lucide-react";
84
- import { useCallback as useCallback13, useMemo as useMemo18 } from "react";
84
+ import { useCallback as useCallback13, useMemo as useMemo19 } from "react";
85
85
 
86
86
  // src/react/hooks/use-chat.ts
87
87
  import { useCallback, useEffect, useRef, useState } from "react";
@@ -198,6 +198,7 @@ import {
198
198
  Paperclip,
199
199
  Plus,
200
200
  Rocket,
201
+ RotateCcw,
201
202
  Scissors,
202
203
  Send,
203
204
  Sparkles as Sparkles2,
@@ -209,7 +210,7 @@ import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
209
210
  import {
210
211
  useEffect as useEffect7,
211
212
  useEffectEvent as useEffectEvent2,
212
- useMemo as useMemo7,
213
+ useMemo as useMemo8,
213
214
  useRef as useRef5,
214
215
  useState as useState8
215
216
  } from "react";
@@ -1327,8 +1328,8 @@ var SkillCompletionMenu = forwardRef2(
1327
1328
  );
1328
1329
 
1329
1330
  // src/react/components/chat/BackgroundTasksPill.tsx
1330
- import { FileText, Square, Terminal } from "lucide-react";
1331
- import { useState as useState7 } from "react";
1331
+ import { Check, FileText, Square, Terminal } from "lucide-react";
1332
+ import { useMemo as useMemo5, useState as useState7 } from "react";
1332
1333
 
1333
1334
  // src/react/hooks/use-background-tasks.ts
1334
1335
  import { useQuery as useQuery2 } from "@tanstack/react-query";
@@ -1354,6 +1355,8 @@ function useBackgroundTasks(sessionId) {
1354
1355
 
1355
1356
  // src/react/components/chat/BackgroundTasksPill.tsx
1356
1357
  import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1358
+ var FAILED_STATES = /* @__PURE__ */ new Set(["failed", "timeout", "lost"]);
1359
+ var EMPTY_IDS = [];
1357
1360
  function formatStartedAt(value) {
1358
1361
  if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
1359
1362
  return "\u542F\u52A8\u65F6\u95F4\u672A\u77E5";
@@ -1377,10 +1380,16 @@ function statusClass(status) {
1377
1380
  }
1378
1381
  function BackgroundTasksPill({ sessionId }) {
1379
1382
  const { data: tasks } = useBackgroundTasks(sessionId);
1383
+ const dismissed = useBackgroundStore((s) => s.dismissedTaskIds[sessionId] ?? EMPTY_IDS);
1384
+ const dismissTask = useBackgroundStore((s) => s.dismissTask);
1380
1385
  const [open, setOpen] = useState7(false);
1381
1386
  const [logTask, setLogTask] = useState7(null);
1382
- if (tasks.length === 0) return null;
1383
- const runningCount = tasks.filter((task) => task.status === "running").length;
1387
+ const visibleTasks = useMemo5(
1388
+ () => tasks.filter((task) => !dismissed.includes(task.id)),
1389
+ [tasks, dismissed]
1390
+ );
1391
+ if (visibleTasks.length === 0) return null;
1392
+ const runningCount = visibleTasks.filter((task) => task.status === "running").length;
1384
1393
  const openTaskLog = async (task) => {
1385
1394
  const title = `${task.id} ${task.description || task.command || "\u540E\u53F0\u4EFB\u52A1"}`;
1386
1395
  setLogTask({ id: task.id, title, output: "", loading: true, error: null });
@@ -1444,7 +1453,7 @@ function BackgroundTasksPill({ sessionId }) {
1444
1453
  children: [
1445
1454
  /* @__PURE__ */ jsx5(Terminal, { size: 13 }),
1446
1455
  "\u540E\u53F0\u4EFB\u52A1 ",
1447
- tasks.length,
1456
+ visibleTasks.length,
1448
1457
  runningCount > 0 ? /* @__PURE__ */ jsxs4("span", { children: [
1449
1458
  "\u8FD0\u884C\u4E2D ",
1450
1459
  runningCount
@@ -1452,7 +1461,7 @@ function BackgroundTasksPill({ sessionId }) {
1452
1461
  ]
1453
1462
  }
1454
1463
  ),
1455
- open ? /* @__PURE__ */ jsx5("div", { className: "absolute bottom-full left-0 z-40 mb-2 w-[min(24rem,calc(100vw-2rem))] rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-2 text-xs text-[hsl(var(--popover-foreground))] shadow-xl", children: /* @__PURE__ */ jsx5("div", { className: "max-h-72 space-y-2 overflow-y-auto", children: tasks.map((task) => /* @__PURE__ */ jsxs4("div", { className: "rounded-lg border border-[hsl(var(--border))] p-2", children: [
1464
+ open ? /* @__PURE__ */ jsx5("div", { className: "absolute bottom-full left-0 z-40 mb-2 w-[min(24rem,calc(100vw-2rem))] rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-2 text-xs text-[hsl(var(--popover-foreground))] shadow-xl", children: /* @__PURE__ */ jsx5("div", { className: "max-h-72 space-y-2 overflow-y-auto", children: visibleTasks.map((task) => /* @__PURE__ */ jsxs4("div", { className: "rounded-lg border border-[hsl(var(--border))] p-2", children: [
1456
1465
  /* @__PURE__ */ jsx5("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
1457
1466
  /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
1458
1467
  /* @__PURE__ */ jsx5("span", { className: "font-mono font-semibold", children: task.id }),
@@ -1485,6 +1494,17 @@ function BackgroundTasksPill({ sessionId }) {
1485
1494
  "\u505C\u6B62"
1486
1495
  ]
1487
1496
  }
1497
+ ) : FAILED_STATES.has(task.status) ? /* @__PURE__ */ jsxs4(
1498
+ "button",
1499
+ {
1500
+ type: "button",
1501
+ onClick: () => dismissTask(sessionId, task.id),
1502
+ className: "inline-flex h-6 items-center gap-1 rounded-md border border-[hsl(var(--border))] px-2 text-[11px] hover:bg-[hsl(var(--accent))]",
1503
+ children: [
1504
+ /* @__PURE__ */ jsx5(Check, { size: 11 }),
1505
+ "\u786E\u8BA4"
1506
+ ]
1507
+ }
1488
1508
  ) : null
1489
1509
  ] })
1490
1510
  ] }, task.id)) }) }) : null
@@ -1590,7 +1610,7 @@ function FileSizeLimitDialog({
1590
1610
  // src/react/components/chat/SkillStatusBar.tsx
1591
1611
  import { useQuery as useQuery5 } from "@tanstack/react-query";
1592
1612
  import { RefreshCw } from "lucide-react";
1593
- import { useMemo as useMemo6 } from "react";
1613
+ import { useMemo as useMemo7 } from "react";
1594
1614
 
1595
1615
  // src/react/hooks/use-context-stats.ts
1596
1616
  import { useQuery as useQuery3 } from "@tanstack/react-query";
@@ -1639,7 +1659,7 @@ function useSkillStats(sessionId) {
1639
1659
  }
1640
1660
 
1641
1661
  // src/react/hooks/use-token-pressure.ts
1642
- import { useMemo as useMemo5 } from "react";
1662
+ import { useMemo as useMemo6 } from "react";
1643
1663
  function clampRatio(value) {
1644
1664
  return Math.min(1, Math.max(0, value));
1645
1665
  }
@@ -1657,7 +1677,7 @@ function resolveLevel(ratio, compactionRatio) {
1657
1677
  }
1658
1678
  function useTokenPressure(sessionId) {
1659
1679
  const { data } = useContextStats(sessionId);
1660
- return useMemo5(() => {
1680
+ return useMemo6(() => {
1661
1681
  const ratio = data.context_window > 0 ? clampRatio(data.tokens_used / data.context_window) : 0;
1662
1682
  return {
1663
1683
  ratio,
@@ -1810,7 +1830,7 @@ function SkillStatusBar({
1810
1830
  const hasEverConnected = useConnectionStore((state) => state.hasEverConnected);
1811
1831
  const statsReady = !loading && !error;
1812
1832
  const skillStoreConnected = statsReady && skillStats.remote_connected;
1813
- const connectionMeta = useMemo6(
1833
+ const connectionMeta = useMemo7(
1814
1834
  () => getConnectionMeta(
1815
1835
  connectionStatus,
1816
1836
  reconnectAttempt,
@@ -1830,7 +1850,7 @@ function SkillStatusBar({
1830
1850
  text: skillStoreConnected ? `\u5DF2\u5B89\u88C5 ${skillStats.installed_skill_count} \u4E2A\u6280\u80FD` : "\u5C1A\u672A\u767B\u5F55\u6280\u80FD\u5546\u5E97"
1831
1851
  }
1832
1852
  ].filter((item) => item.key !== "total" || skillStats.remote_configured);
1833
- const tokenSummary = useMemo6(() => {
1853
+ const tokenSummary = useMemo7(() => {
1834
1854
  return {
1835
1855
  detail: /* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
1836
1856
  /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-3 border-t border-slate-800 pt-1", children: [
@@ -2046,6 +2066,7 @@ var SkillMention = Mention2.extend({
2046
2066
 
2047
2067
  // src/react/components/chat/ChatInput.tsx
2048
2068
  import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2069
+ var DOUBLE_ESCAPE_MS = 450;
2049
2070
  function getEditorText(editor) {
2050
2071
  return editor?.getText({ blockSeparator: "\n" }) ?? "";
2051
2072
  }
@@ -2685,7 +2706,9 @@ function ChatInput({
2685
2706
  skillStatusBarInnerClassName,
2686
2707
  onResyncSkills,
2687
2708
  isResyncingSkills = false,
2688
- inputLabel = "\u8F93\u5165\u6D88\u606F"
2709
+ inputLabel = "\u8F93\u5165\u6D88\u606F",
2710
+ onDoubleEscape,
2711
+ composerHint
2689
2712
  }) {
2690
2713
  const resolvedInputLabel = inputLabel?.trim() || "\u8F93\u5165\u6D88\u606F";
2691
2714
  const [input, setInputInternal] = useState8(externalDraft?.value ?? "");
@@ -2734,10 +2757,11 @@ function ChatInput({
2734
2757
  const fileInputRef = useRef5(null);
2735
2758
  const folderInputRef = useRef5(null);
2736
2759
  const editorRef = useRef5(null);
2760
+ const lastEscapeAtRef = useRef5(0);
2737
2761
  const localImageUrlsRef = useRef5(/* @__PURE__ */ new Map());
2738
2762
  const activeSessionId = useSessionStore((state) => state.activeSessionId);
2739
2763
  const sessions = useSessionStore((state) => state.sessions);
2740
- const activeSessionModel = useMemo7(
2764
+ const activeSessionModel = useMemo8(
2741
2765
  () => sessions.find((session) => session.id === activeSessionId)?.model ?? null,
2742
2766
  [activeSessionId, sessions]
2743
2767
  );
@@ -2836,7 +2860,8 @@ function ChatInput({
2836
2860
  navigateUp: inputHistory.navigateUp,
2837
2861
  navigateDown: inputHistory.navigateDown,
2838
2862
  isNavigatingHistory: inputHistory.isNavigating,
2839
- handleSubmit: stableHandleSubmit
2863
+ handleSubmit: stableHandleSubmit,
2864
+ onDoubleEscape
2840
2865
  }));
2841
2866
  const syncEditorState = (editorInstance) => {
2842
2867
  const value = getEditorText(editorInstance);
@@ -3066,6 +3091,18 @@ function ChatInput({
3066
3091
  replaceEditorText(editorRef.current, nextEntry);
3067
3092
  return true;
3068
3093
  }
3094
+ if (state.onDoubleEscape && event.key === "Escape" && !event.isComposing && !event.repeat) {
3095
+ const now = Date.now();
3096
+ if (now - lastEscapeAtRef.current <= DOUBLE_ESCAPE_MS) {
3097
+ lastEscapeAtRef.current = 0;
3098
+ event.preventDefault();
3099
+ const rect = editorRef.current?.view.dom.getBoundingClientRect() ?? null;
3100
+ state.onDoubleEscape(rect);
3101
+ return true;
3102
+ }
3103
+ lastEscapeAtRef.current = now;
3104
+ return false;
3105
+ }
3069
3106
  if (event.key === "Enter" && !event.shiftKey && !event.isComposing) {
3070
3107
  event.preventDefault();
3071
3108
  if (state.connectionStatus !== "connected") {
@@ -3560,6 +3597,23 @@ function ChatInput({
3560
3597
  ]
3561
3598
  }
3562
3599
  ),
3600
+ onDoubleEscape ? /* @__PURE__ */ jsxs8(
3601
+ "button",
3602
+ {
3603
+ type: "button",
3604
+ onClick: () => {
3605
+ actionMenuRef.current?.removeAttribute("open");
3606
+ onDoubleEscape(
3607
+ editorRef.current?.view.dom.getBoundingClientRect() ?? null
3608
+ );
3609
+ },
3610
+ className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
3611
+ children: [
3612
+ /* @__PURE__ */ jsx9(RotateCcw, { size: 13 }),
3613
+ "\u56DE\u5230\u4E4B\u524D\u7684\u67D0\u4E00\u6B65"
3614
+ ]
3615
+ }
3616
+ ) : null,
3563
3617
  onCommand ? /* @__PURE__ */ jsxs8(Fragment2, { children: [
3564
3618
  /* @__PURE__ */ jsxs8(
3565
3619
  "button",
@@ -3699,7 +3753,8 @@ function ChatInput({
3699
3753
  /* @__PURE__ */ jsxs8("div", { className: "space-y-0.5", children: [
3700
3754
  /* @__PURE__ */ jsx9("div", { children: "Shift+Enter \u6362\u884C" }),
3701
3755
  /* @__PURE__ */ jsx9("div", { children: "/ \u8C03\u7528\u6280\u80FD" }),
3702
- /* @__PURE__ */ jsx9("div", { children: "@ \u5F15\u7528\u6587\u4EF6" })
3756
+ /* @__PURE__ */ jsx9("div", { children: "@ \u5F15\u7528\u6587\u4EF6" }),
3757
+ composerHint && /* @__PURE__ */ jsx9("div", { children: composerHint })
3703
3758
  ] })
3704
3759
  ] }) })
3705
3760
  ] }),
@@ -3813,13 +3868,13 @@ import {
3813
3868
  useCallback as useCallback12,
3814
3869
  useEffect as useEffect17,
3815
3870
  useEffectEvent as useEffectEvent4,
3816
- useMemo as useMemo17,
3871
+ useMemo as useMemo18,
3817
3872
  useRef as useRef13,
3818
3873
  useState as useState21
3819
3874
  } from "react";
3820
3875
 
3821
3876
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
3822
- import { useCallback as useCallback7, useMemo as useMemo8, useRef as useRef6, useState as useState9 } from "react";
3877
+ import { useCallback as useCallback7, useMemo as useMemo9, useRef as useRef6, useState as useState9 } from "react";
3823
3878
  var DEFAULT_SPRING_ANIMATION = {
3824
3879
  /**
3825
3880
  * A value from 0 to 1, on how much to damp the animation.
@@ -3880,7 +3935,7 @@ var useStickToBottom = (options = {}) => {
3880
3935
  state.escapedFromLock = escapedFromLock2;
3881
3936
  updateEscapedFromLock(escapedFromLock2);
3882
3937
  }, []);
3883
- const state = useMemo8(() => {
3938
+ const state = useMemo9(() => {
3884
3939
  let lastCalculation;
3885
3940
  return {
3886
3941
  escapedFromLock,
@@ -4163,7 +4218,7 @@ function mergeAnimations(...animations) {
4163
4218
 
4164
4219
  // ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/StickToBottom.js
4165
4220
  import * as React from "react";
4166
- import { createContext, useContext, useEffect as useEffect8, useImperativeHandle as useImperativeHandle3, useLayoutEffect, useMemo as useMemo9, useRef as useRef7 } from "react";
4221
+ import { createContext, useContext, useEffect as useEffect8, useImperativeHandle as useImperativeHandle3, useLayoutEffect, useMemo as useMemo10, useRef as useRef7 } from "react";
4167
4222
  var StickToBottomContext = createContext(null);
4168
4223
  var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect8;
4169
4224
  function StickToBottom({ instance, children, resize, initial, mass, damping, stiffness, targetScrollTop: currentTargetScrollTop, contextRef, ...props }) {
@@ -4181,7 +4236,7 @@ function StickToBottom({ instance, children, resize, initial, mass, damping, sti
4181
4236
  targetScrollTop
4182
4237
  });
4183
4238
  const { scrollRef, contentRef, scrollToBottom, stopScroll, isAtBottom, escapedFromLock, state } = instance ?? defaultInstance;
4184
- const context = useMemo9(() => ({
4239
+ const context = useMemo10(() => ({
4185
4240
  scrollToBottom,
4186
4241
  stopScroll,
4187
4242
  scrollRef,
@@ -4243,8 +4298,8 @@ function useStickToBottomContext() {
4243
4298
  }
4244
4299
 
4245
4300
  // src/react/components/chat/AssistantTurnBlock.tsx
4246
- import { AlertCircle, BookOpen, Check as Check4, ChevronRight as ChevronRight5 } from "lucide-react";
4247
- import { memo as memo3, useCallback as useCallback11, useEffect as useEffect15, useMemo as useMemo15, useRef as useRef12, useState as useState18 } from "react";
4301
+ import { AlertCircle, BookOpen, Check as Check5, ChevronRight as ChevronRight5 } from "lucide-react";
4302
+ import { memo as memo3, useCallback as useCallback11, useEffect as useEffect15, useMemo as useMemo16, useRef as useRef12, useState as useState18 } from "react";
4248
4303
 
4249
4304
  // src/react/routes.ts
4250
4305
  var MEMORIES_ROUTE = "/memories";
@@ -4261,7 +4316,7 @@ import {
4261
4316
  useCallback as useCallback9,
4262
4317
  useContext as useContext2,
4263
4318
  useEffect as useEffect9,
4264
- useMemo as useMemo11,
4319
+ useMemo as useMemo12,
4265
4320
  useRef as useRef8,
4266
4321
  useState as useState10
4267
4322
  } from "react";
@@ -4270,7 +4325,7 @@ import { Streamdown } from "streamdown";
4270
4325
 
4271
4326
  // src/react/components/ai-elements/shimmer.tsx
4272
4327
  import { motion } from "motion/react";
4273
- import { memo, useMemo as useMemo10 } from "react";
4328
+ import { memo, useMemo as useMemo11 } from "react";
4274
4329
  import { jsx as jsx11 } from "react/jsx-runtime";
4275
4330
  var motionComponentCache = /* @__PURE__ */ new Map();
4276
4331
  var getMotionComponent = (element) => {
@@ -4291,7 +4346,7 @@ var ShimmerComponent = ({
4291
4346
  const MotionComponent = getMotionComponent(
4292
4347
  Component2
4293
4348
  );
4294
- const dynamicSpread = useMemo10(
4349
+ const dynamicSpread = useMemo11(
4295
4350
  () => (children?.length ?? 0) * spread,
4296
4351
  [children, spread]
4297
4352
  );
@@ -4368,7 +4423,7 @@ var Reasoning = memo2(
4368
4423
  },
4369
4424
  [setIsOpen]
4370
4425
  );
4371
- const contextValue = useMemo11(
4426
+ const contextValue = useMemo12(
4372
4427
  () => ({ duration, isOpen, isStreaming, setIsOpen }),
4373
4428
  [duration, isOpen, isStreaming, setIsOpen]
4374
4429
  );
@@ -4525,8 +4580,8 @@ ReasoningTrigger.displayName = "ReasoningTrigger";
4525
4580
  ReasoningContent.displayName = "ReasoningContent";
4526
4581
 
4527
4582
  // src/react/components/chat/AgentLoopBlock.tsx
4528
- import { Bot, Check as Check3, ChevronRight as ChevronRight4, FileText as FileText6, Loader2 as Loader25, MessageSquareMore as MessageSquareMore2 } from "lucide-react";
4529
- import { useEffect as useEffect14, useMemo as useMemo14, useState as useState17 } from "react";
4583
+ import { Bot, Check as Check4, ChevronRight as ChevronRight4, FileText as FileText6, Loader2 as Loader25, MessageSquareMore as MessageSquareMore2 } from "lucide-react";
4584
+ import { useEffect as useEffect14, useMemo as useMemo15, useState as useState17 } from "react";
4530
4585
 
4531
4586
  // src/react/components/chat/ResourceIframe.tsx
4532
4587
  import { useEffect as useEffect10, useEffectEvent as useEffectEvent3, useRef as useRef9, useState as useState11 } from "react";
@@ -4657,8 +4712,8 @@ function ResourceIframe({ ui, sessionId }) {
4657
4712
  }
4658
4713
 
4659
4714
  // src/react/components/chat/ToolCallBlock.tsx
4660
- import { Check, ChevronRight as ChevronRight3, Loader2 as Loader23, MessageSquareMore, PanelRightOpen, X as X4 } from "lucide-react";
4661
- import { useMemo as useMemo12, useState as useState14 } from "react";
4715
+ import { Check as Check2, ChevronRight as ChevronRight3, Loader2 as Loader23, MessageSquareMore, PanelRightOpen, X as X4 } from "lucide-react";
4716
+ import { useMemo as useMemo13, useState as useState14 } from "react";
4662
4717
 
4663
4718
  // src/react/components/chat/tool-renderers/shared.tsx
4664
4719
  import { jsx as jsx14 } from "react/jsx-runtime";
@@ -4988,7 +5043,7 @@ function FileEditRenderer({ toolCall }) {
4988
5043
  import { useState as useState13 } from "react";
4989
5044
 
4990
5045
  // src/react/components/chat/ImageLightbox.tsx
4991
- import { ChevronLeft, ChevronRight as ChevronRight2, Download as Download2, ExternalLink, Minus, Plus as Plus2, RotateCcw, X as X3 } from "lucide-react";
5046
+ import { ChevronLeft, ChevronRight as ChevronRight2, Download as Download2, ExternalLink, Minus, Plus as Plus2, RotateCcw as RotateCcw2, X as X3 } from "lucide-react";
4992
5047
  import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRef10, useState as useState12 } from "react";
4993
5048
  import { createPortal as createPortal3 } from "react-dom";
4994
5049
  import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
@@ -5219,7 +5274,7 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
5219
5274
  type: "button",
5220
5275
  onClick: reset,
5221
5276
  className: "rounded-full p-1.5 text-white/80 transition-colors hover:bg-white/10 hover:text-white",
5222
- children: /* @__PURE__ */ jsx17(RotateCcw, { size: 16 })
5277
+ children: /* @__PURE__ */ jsx17(RotateCcw2, { size: 16 })
5223
5278
  }
5224
5279
  ),
5225
5280
  showNav && /* @__PURE__ */ jsxs13(Fragment4, { children: [
@@ -5669,7 +5724,7 @@ function ToolCallBlock({
5669
5724
  const resolvedAnswerData = answerData ?? storedAnswerData;
5670
5725
  const resolvedAnswered = answered ?? (!!resolvedAnswerData && resolvedSessionStatus !== "waiting_for_input");
5671
5726
  const resolvedOnAnswer = onAnswer ?? answerCallback;
5672
- const uiMeta = useMemo12(() => {
5727
+ const uiMeta = useMemo13(() => {
5673
5728
  const block = turnBlocks?.find(
5674
5729
  (item) => item.type === "tool_ui" && item.tool_call_id === toolCall.id && isUiMeta(item.content)
5675
5730
  );
@@ -5707,7 +5762,7 @@ function ToolCallBlock({
5707
5762
  const borderWidthClass = level === 2 ? "border-l-[2px]" : "border-l-[3px]";
5708
5763
  const indentClass = level === 2 ? "ml-3" : "ml-4";
5709
5764
  const toneClass = tone === "red" ? "border-l-[hsl(var(--muted-foreground)/0.5)]" : tone === "amber" ? "border-l-amber-400" : tone === "blue" ? "border-l-blue-500" : "border-l-[hsl(var(--primary))]";
5710
- const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx21(Loader23, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx21(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx21(X4, { size: 11 }) : /* @__PURE__ */ jsx21(Check, { size: 11 });
5765
+ const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx21(Loader23, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx21(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx21(X4, { size: 11 }) : /* @__PURE__ */ jsx21(Check2, { size: 11 });
5711
5766
  const statusTextClass = tone === "red" ? "text-[hsl(var(--muted-foreground))]" : tone === "amber" ? "text-amber-300" : tone === "blue" ? "text-blue-300" : "text-[hsl(var(--primary))]";
5712
5767
  return /* @__PURE__ */ jsxs17("div", { className: cn(indentClass, "text-xs", customization?.classNames?.toolCall), children: [
5713
5768
  /* @__PURE__ */ jsxs17("div", { className: cn(borderWidthClass, toneClass, "flex items-center gap-2 px-3 py-2"), children: [
@@ -6153,7 +6208,7 @@ function MessageFileAttachmentList({
6153
6208
  }
6154
6209
 
6155
6210
  // src/react/components/chat/MessageActions.tsx
6156
- import { Check as Check2, Copy } from "lucide-react";
6211
+ import { Check as Check3, Copy } from "lucide-react";
6157
6212
  import { useState as useState15 } from "react";
6158
6213
  import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
6159
6214
  function MessageActions({ content, className }) {
@@ -6175,7 +6230,7 @@ function MessageActions({ content, className }) {
6175
6230
  copied ? "text-[hsl(var(--primary))]" : "text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] hover:bg-[hsl(var(--accent))]"
6176
6231
  ),
6177
6232
  children: [
6178
- copied ? /* @__PURE__ */ jsx25(Check2, { size: 12 }) : /* @__PURE__ */ jsx25(Copy, { size: 12 }),
6233
+ copied ? /* @__PURE__ */ jsx25(Check3, { size: 12 }) : /* @__PURE__ */ jsx25(Copy, { size: 12 }),
6179
6234
  /* @__PURE__ */ jsx25("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
6180
6235
  ]
6181
6236
  }
@@ -6227,14 +6282,14 @@ function TextAttachmentPills({ attachments, onPreview }) {
6227
6282
  import { RefreshCcw } from "lucide-react";
6228
6283
 
6229
6284
  // src/react/components/chat/whatif-quote-context.tsx
6230
- import { createContext as createContext3, useContext as useContext3, useMemo as useMemo13 } from "react";
6285
+ import { createContext as createContext3, useContext as useContext3, useMemo as useMemo14 } from "react";
6231
6286
  import { jsx as jsx27 } from "react/jsx-runtime";
6232
6287
  var WhatIfQuoteContext = createContext3({});
6233
6288
  function WhatIfQuoteProvider({
6234
6289
  onJumpToStep,
6235
6290
  children
6236
6291
  }) {
6237
- const value = useMemo13(() => ({ onJumpToStep }), [onJumpToStep]);
6292
+ const value = useMemo14(() => ({ onJumpToStep }), [onJumpToStep]);
6238
6293
  return /* @__PURE__ */ jsx27(WhatIfQuoteContext.Provider, { value, children });
6239
6294
  }
6240
6295
  function useWhatIfQuoteContext() {
@@ -6531,7 +6586,7 @@ function stripFileExtension(fileName) {
6531
6586
  function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6532
6587
  const agentLoops = useChatStore((state) => state.agentLoops[sessionId] ?? EMPTY_AGENT_LOOPS);
6533
6588
  const messages = useChatStore((state) => state.messages[sessionId] ?? EMPTY_MESSAGES2);
6534
- const loopEntry = useMemo14(() => {
6589
+ const loopEntry = useMemo15(() => {
6535
6590
  for (const [loopName, info] of Object.entries(agentLoops)) {
6536
6591
  if (info.toolCallId === toolCall.id) {
6537
6592
  return { loopName, info };
@@ -6539,24 +6594,24 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6539
6594
  }
6540
6595
  return null;
6541
6596
  }, [agentLoops, toolCall.id]);
6542
- const childMessages = useMemo14(() => {
6597
+ const childMessages = useMemo15(() => {
6543
6598
  if (!loopEntry) return [];
6544
6599
  return messages.filter((message) => (message.loop_name ?? "root") === loopEntry.loopName);
6545
6600
  }, [loopEntry, messages]);
6546
- const loopToolCalls = useMemo14(
6601
+ const loopToolCalls = useMemo15(
6547
6602
  () => childMessages.flatMap((message) => message.tool_calls ?? []),
6548
6603
  [childMessages]
6549
6604
  );
6550
- const visibleLoopToolCalls = useMemo14(
6605
+ const visibleLoopToolCalls = useMemo15(
6551
6606
  () => loopToolCalls.filter((childToolCall) => formatToolName(childToolCall.name) !== "Agent"),
6552
6607
  [loopToolCalls]
6553
6608
  );
6554
- const hasAwaitingAnswer = useMemo14(
6609
+ const hasAwaitingAnswer = useMemo15(
6555
6610
  () => visibleLoopToolCalls.some((childToolCall) => childToolCall.status === "awaiting_answer"),
6556
6611
  [visibleLoopToolCalls]
6557
6612
  );
6558
6613
  const [expanded, setExpanded] = useState17(hasAwaitingAnswer);
6559
- const completedToolLabels = useMemo14(
6614
+ const completedToolLabels = useMemo15(
6560
6615
  () => visibleLoopToolCalls.flatMap((childToolCall) => {
6561
6616
  const isCompleted = childToolCall.status === "done" || childToolCall.status !== "pending" && childToolCall.status !== "awaiting_answer" && childToolCall.status !== "error" && childToolCall.status !== "cancelled";
6562
6617
  if (!isCompleted) return [];
@@ -6584,7 +6639,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6584
6639
  }),
6585
6640
  [visibleLoopToolCalls]
6586
6641
  );
6587
- const inlineToolUiBlocks = useMemo14(
6642
+ const inlineToolUiBlocks = useMemo15(
6588
6643
  () => childMessages.flatMap(
6589
6644
  (message) => (message.blocks ?? []).flatMap(
6590
6645
  (block, index) => block.type === "tool_ui" && block.tool_call_id && isUiMeta(block.content) && block.content.target === "inline" ? [{ key: `${message.entry_id ?? message.timestamp ?? "message"}-${block.tool_call_id}-${index}`, ui: block.content }] : []
@@ -6694,7 +6749,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
6694
6749
  "aria-expanded": expanded,
6695
6750
  className: "flex min-w-0 flex-1 items-center gap-2 text-left focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
6696
6751
  children: /* @__PURE__ */ jsxs25("span", { className: "min-w-0 flex items-center gap-2", children: [
6697
- /* @__PURE__ */ jsx30(Check3, { size: 14, className: "shrink-0 text-emerald-500" }),
6752
+ /* @__PURE__ */ jsx30(Check4, { size: 14, className: "shrink-0 text-emerald-500" }),
6698
6753
  /* @__PURE__ */ jsx30("span", { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: description })
6699
6754
  ] })
6700
6755
  }
@@ -7047,12 +7102,12 @@ function AssistantTurnBlockBase({
7047
7102
  customization
7048
7103
  }) {
7049
7104
  const messages = Array.isArray(rawMessages) ? rawMessages : [];
7050
- const allToolCalls = useMemo15(() => messages.flatMap((m) => m.tool_calls ?? []), [messages]);
7051
- const hasAgentToolCall = useMemo15(
7105
+ const allToolCalls = useMemo16(() => messages.flatMap((m) => m.tool_calls ?? []), [messages]);
7106
+ const hasAgentToolCall = useMemo16(
7052
7107
  () => allToolCalls.some((toolCall) => formatToolName(toolCall.name) === "Agent"),
7053
7108
  [allToolCalls]
7054
7109
  );
7055
- const hasActionableToolCall = useMemo15(
7110
+ const hasActionableToolCall = useMemo16(
7056
7111
  () => allToolCalls.some(
7057
7112
  (tc) => tc.status === "error" || tc.status === "cancelled" || formatToolName(tc.name) === "AskUserQuestion" && tc.status === "awaiting_answer"
7058
7113
  ),
@@ -7074,12 +7129,12 @@ function AssistantTurnBlockBase({
7074
7129
  const agentLoops = useChatStore(
7075
7130
  (state) => hasAgentToolCall ? state.agentLoops[sessionId] ?? EMPTY_AGENT_LOOPS2 : EMPTY_AGENT_LOOPS2
7076
7131
  );
7077
- const turnMessages = useMemo15(
7132
+ const turnMessages = useMemo16(
7078
7133
  () => hasAgentToolCall ? collectTurnMessages({ rootMessages: messages, sessionMessages, agentLoops }) : messages,
7079
7134
  [agentLoops, hasAgentToolCall, messages, sessionMessages]
7080
7135
  );
7081
- const resourceBlocks = useMemo15(() => getInlineResourceBlocks(turnMessages), [turnMessages]);
7082
- const finalMessage = useMemo15(() => getLastTextMessage(turnMessages), [turnMessages]);
7136
+ const resourceBlocks = useMemo16(() => getInlineResourceBlocks(turnMessages), [turnMessages]);
7137
+ const finalMessage = useMemo16(() => getLastTextMessage(turnMessages), [turnMessages]);
7083
7138
  const hasInterruptedState = messages.some((message) => message.status === "interrupted");
7084
7139
  const effectiveMode = resolveTurnDisplayMode({ isStreaming, displayMode });
7085
7140
  const memoryRefs = Array.isArray(messages[0]?.memory_refs) ? messages[0].memory_refs : [];
@@ -7327,7 +7382,7 @@ function CompactToolGroupBlock({
7327
7382
  /* @__PURE__ */ jsx31(AlertCircle, { size: 11 }),
7328
7383
  /* @__PURE__ */ jsx31("span", { children: "\u5931\u8D25" })
7329
7384
  ] }) : /* @__PURE__ */ jsxs26("span", { className: "flex shrink-0 items-center gap-1 text-[10px] text-[hsl(var(--primary))]", children: [
7330
- /* @__PURE__ */ jsx31(Check4, { size: 11 }),
7385
+ /* @__PURE__ */ jsx31(Check5, { size: 11 }),
7331
7386
  /* @__PURE__ */ jsx31("span", { children: "\u5B8C\u6210" })
7332
7387
  ] }),
7333
7388
  /* @__PURE__ */ jsx31("span", { className: "min-w-0 shrink-0 font-medium text-[hsl(var(--foreground))]", children: title })
@@ -7431,7 +7486,7 @@ function AssistantText({
7431
7486
  },
7432
7487
  [sessionId]
7433
7488
  );
7434
- const cardCtx = useMemo15(
7489
+ const cardCtx = useMemo16(
7435
7490
  () => ({ sessionId, messageId, sendMessage }),
7436
7491
  [sessionId, messageId, sendMessage]
7437
7492
  );
@@ -7710,7 +7765,7 @@ import {
7710
7765
  TerminalSquare,
7711
7766
  WandSparkles
7712
7767
  } from "lucide-react";
7713
- import { useEffect as useEffect16, useMemo as useMemo16, useState as useState20 } from "react";
7768
+ import { useEffect as useEffect16, useMemo as useMemo17, useState as useState20 } from "react";
7714
7769
  import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
7715
7770
  var EMPTY_EVENTS = [];
7716
7771
  function formatElapsedDuration(durationMs) {
@@ -7813,9 +7868,9 @@ function StickyStatusBar({
7813
7868
  onJumpToLatest
7814
7869
  }) {
7815
7870
  const events = useRuntimeStore((state) => state.events[sessionId] ?? EMPTY_EVENTS);
7816
- const startedAt = useMemo16(() => getTurnStartedAt(events), [events]);
7871
+ const startedAt = useMemo17(() => getTurnStartedAt(events), [events]);
7817
7872
  const elapsedDuration = useElapsedDuration(startedAt, isStreaming && isLastTurn);
7818
- const action = useMemo16(() => getCurrentAction(messages), [messages]);
7873
+ const action = useMemo17(() => getCurrentAction(messages), [messages]);
7819
7874
  if (!isStreaming || !isLastTurn) {
7820
7875
  return null;
7821
7876
  }
@@ -7978,10 +8033,10 @@ function MessageList({
7978
8033
  const agentLoops = useChatStore((state) => state.agentLoops[sessionId]);
7979
8034
  const askAnswers = useChatStore((state) => state.askAnswers[sessionId]);
7980
8035
  const sessionIsStreaming = useChatStore((state) => !!state.isStreaming[sessionId]);
7981
- const agentLoopNameSet = useMemo17(() => new Set(Object.keys(agentLoops ?? {})), [agentLoops]);
8036
+ const agentLoopNameSet = useMemo18(() => new Set(Object.keys(agentLoops ?? {})), [agentLoops]);
7982
8037
  const assistantMessagesCacheRef = useRef13(/* @__PURE__ */ new Map());
7983
8038
  const stickContextRef = useRef13(null);
7984
- const renderBlocks = useMemo17(() => {
8039
+ const renderBlocks = useMemo18(() => {
7985
8040
  const stableAssistantMessages = (key, buffer) => {
7986
8041
  const previous = assistantMessagesCacheRef.current.get(key);
7987
8042
  if (previous && previous.length === buffer.length && previous.every((message, index) => message === buffer[index])) {
@@ -8072,13 +8127,13 @@ function MessageList({
8072
8127
  }
8073
8128
  return blocks;
8074
8129
  }, [agentLoopNameSet, messages, sessionIsStreaming]);
8075
- const hasInterruptedTurn = useMemo17(
8130
+ const hasInterruptedTurn = useMemo18(
8076
8131
  () => renderBlocks.some(
8077
8132
  (block) => block.type === "assistant_turn" && block.messages.some((message) => message.status === "interrupted")
8078
8133
  ),
8079
8134
  [renderBlocks]
8080
8135
  );
8081
- const lastTurnId = useMemo17(() => {
8136
+ const lastTurnId = useMemo18(() => {
8082
8137
  for (let index = renderBlocks.length - 1; index >= 0; index -= 1) {
8083
8138
  const block = renderBlocks[index];
8084
8139
  if (block.type === "assistant_turn") return block.anchorId;
@@ -8086,14 +8141,14 @@ function MessageList({
8086
8141
  }
8087
8142
  return null;
8088
8143
  }, [renderBlocks]);
8089
- const turnNavItems = useMemo17(
8144
+ const turnNavItems = useMemo18(
8090
8145
  () => renderBlocks.filter((block) => block.type === "assistant_turn").map((block) => ({
8091
8146
  id: block.anchorId,
8092
8147
  title: block.railTitle
8093
8148
  })),
8094
8149
  [renderBlocks]
8095
8150
  );
8096
- const stickyTurn = useMemo17(
8151
+ const stickyTurn = useMemo18(
8097
8152
  () => renderBlocks.find(
8098
8153
  (block) => block.type === "assistant_turn" && block.anchorId === lastTurnId && block.isStreaming
8099
8154
  ) ?? null,
@@ -8103,7 +8158,7 @@ function MessageList({
8103
8158
  const scrollContainerRef = useRef13(null);
8104
8159
  const frameRef = useRef13(null);
8105
8160
  const [activeTurnId, setActiveTurnId] = useState21(lastTurnId);
8106
- const layoutSignature = useMemo17(
8161
+ const layoutSignature = useMemo18(
8107
8162
  () => getMessagesMeasureSignature(messages),
8108
8163
  [messages]
8109
8164
  );
@@ -8403,6 +8458,8 @@ function ChatView({
8403
8458
  onResyncSkills,
8404
8459
  isResyncingSkills = false,
8405
8460
  inputLabel,
8461
+ onDoubleEscape,
8462
+ composerHint,
8406
8463
  classNames,
8407
8464
  components,
8408
8465
  renderers
@@ -8434,7 +8491,7 @@ function ChatView({
8434
8491
  },
8435
8492
  [send]
8436
8493
  );
8437
- const customization = useMemo18(
8494
+ const customization = useMemo19(
8438
8495
  () => ({ classNames, components, renderers }),
8439
8496
  [classNames, components, renderers]
8440
8497
  );
@@ -8482,7 +8539,9 @@ function ChatView({
8482
8539
  skillStatusBarInnerClassName: classNames?.skillStatusBarInner,
8483
8540
  onResyncSkills,
8484
8541
  isResyncingSkills,
8485
- inputLabel
8542
+ inputLabel,
8543
+ onDoubleEscape,
8544
+ composerHint
8486
8545
  }
8487
8546
  )
8488
8547
  ] });
@@ -8539,4 +8598,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
8539
8598
  * Licensed under the MIT License. See License.txt in the project root for license information.
8540
8599
  *--------------------------------------------------------------------------------------------*)
8541
8600
  */
8542
- //# sourceMappingURL=chunk-FXEELOLI.js.map
8601
+ //# sourceMappingURL=chunk-7TS36PDU.js.map