@blade-hq/agent-react 2612.0.0-beta.40 → 2612.0.0-beta.43

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.
@@ -3,7 +3,7 @@ import {
3
3
  PluginTriggerStack,
4
4
  selectionFromItem,
5
5
  triggerSummary
6
- } from "./chunk-KUZPP6OU.js";
6
+ } from "./chunk-S3AC4DZF.js";
7
7
  import {
8
8
  Archive,
9
9
  BookOpen,
@@ -28,15 +28,19 @@ import {
28
28
  Lightbulb,
29
29
  ListPlus,
30
30
  LoaderCircle,
31
+ MODEL_REASONING_LEVELS_KEY,
31
32
  Mic,
32
33
  Music,
34
+ PREFERRED_MODEL_KEY,
33
35
  Paperclip,
34
36
  Play,
35
37
  Plug,
36
38
  Plus,
39
+ RichInputServicesProvider,
37
40
  Rocket,
38
41
  RotateCcw,
39
42
  Scissors,
43
+ Search,
40
44
  Send,
41
45
  Share2,
42
46
  Sparkles,
@@ -47,6 +51,7 @@ import {
47
51
  cn,
48
52
  cn2,
49
53
  dist_exports2 as dist_exports,
54
+ fetchClientQuery,
50
55
  getInputHistoryGeneration,
51
56
  getPluginSuggestionItems,
52
57
  isQueueShortcut,
@@ -54,17 +59,39 @@ import {
54
59
  onInputCachesReset,
55
60
  pluginRefsForSend,
56
61
  queueShortcutLabel,
62
+ refreshClientQuery,
63
+ refreshClientSessionSkills,
57
64
  sendToSession,
65
+ setClientQueryData,
66
+ useBackgroundTaskList,
58
67
  useBladeClient,
59
68
  useChatEnvironment,
60
69
  useChatRenderMode,
61
70
  useChatSessionDetail,
71
+ useClientBackgroundTasks,
72
+ useClientContextStats,
73
+ useClientModelCatalog,
74
+ useClientModelPreferences,
75
+ useClientQuery,
76
+ useClientSessionModel,
77
+ useClientSessionSkills,
78
+ useClientSkillStats,
79
+ useComposerConnection,
80
+ useComposerConnectionInfo,
81
+ useContextStats,
62
82
  useCurrentChatSessionId,
63
83
  useEffectEvent,
84
+ useModelCatalog,
85
+ useModelPreferences,
64
86
  usePortalContainer,
87
+ useRefreshWhenRunEnds,
88
+ useRichInputServices,
89
+ useSessionDataInvalidation,
65
90
  useSessionHandle,
66
- useSessionState
67
- } from "./chunk-5S4H3CJD.js";
91
+ useSessionSkills,
92
+ useSessionSource,
93
+ useSkillStats
94
+ } from "./chunk-42P352DI.js";
68
95
  import {
69
96
  __commonJS,
70
97
  __require,
@@ -90,7 +117,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
90
117
  "The result of getSnapshot should be cached to avoid an infinite loop"
91
118
  ), didWarnUncachedGetSnapshot = true);
92
119
  }
93
- cachedValue = useState12({
120
+ cachedValue = useState13({
94
121
  inst: { value, getSnapshot }
95
122
  });
96
123
  var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
@@ -128,7 +155,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
128
155
  return getSnapshot();
129
156
  }
130
157
  "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
131
- var React2 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is, useState12 = React2.useState, useEffect10 = React2.useEffect, useLayoutEffect3 = React2.useLayoutEffect, useDebugValue3 = React2.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
158
+ var React2 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is, useState13 = React2.useState, useEffect10 = React2.useEffect, useLayoutEffect3 = React2.useLayoutEffect, useDebugValue3 = React2.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
132
159
  exports.useSyncExternalStore = void 0 !== React2.useSyncExternalStore ? React2.useSyncExternalStore : shim;
133
160
  "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
134
161
  })();
@@ -156,14 +183,14 @@ var require_with_selector_development = __commonJS({
156
183
  return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
157
184
  }
158
185
  "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
159
- var React2 = __require("react"), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore5 = shim.useSyncExternalStore, useRef10 = React2.useRef, useEffect10 = React2.useEffect, useMemo9 = React2.useMemo, useDebugValue3 = React2.useDebugValue;
186
+ var React2 = __require("react"), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore5 = shim.useSyncExternalStore, useRef8 = React2.useRef, useEffect10 = React2.useEffect, useMemo8 = React2.useMemo, useDebugValue3 = React2.useDebugValue;
160
187
  exports.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
161
- var instRef = useRef10(null);
188
+ var instRef = useRef8(null);
162
189
  if (null === instRef.current) {
163
190
  var inst = { hasValue: false, value: null };
164
191
  instRef.current = inst;
165
192
  } else inst = instRef.current;
166
- instRef = useMemo9(
193
+ instRef = useMemo8(
167
194
  function() {
168
195
  function memoizedSelector(nextSnapshot) {
169
196
  if (!hasMemo) {
@@ -227,7 +254,7 @@ var require_with_selector = __commonJS({
227
254
  });
228
255
 
229
256
  // src/rich-input/BackgroundTasksPill.tsx
230
- import { useMemo as useMemo2, useState } from "react";
257
+ import { useMemo, useState } from "react";
231
258
 
232
259
  // src/chat/runtime/background-task-dismissals.ts
233
260
  import { useSyncExternalStore } from "react";
@@ -264,330 +291,6 @@ function useDismissedBackgroundTasks(sessionId) {
264
291
  );
265
292
  }
266
293
 
267
- // src/rich-input/services.tsx
268
- import { useMemo, useRef as useRef2 } from "react";
269
-
270
- // src/chat/runtime/input-services.tsx
271
- import { createContext, useContext } from "react";
272
- import { jsx } from "react/jsx-runtime";
273
- function parseModelReasoningLevels(value) {
274
- if (!value) return {};
275
- try {
276
- const parsed = JSON.parse(value);
277
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {};
278
- return Object.fromEntries(
279
- Object.entries(parsed).filter(
280
- (entry) => Boolean(entry[0]) && typeof entry[1] === "string" && Boolean(entry[1])
281
- )
282
- );
283
- } catch {
284
- return {};
285
- }
286
- }
287
- var RichInputServicesContext = createContext({});
288
- function RichInputServicesProvider({ value, children }) {
289
- return /* @__PURE__ */ jsx(RichInputServicesContext.Provider, { value, children });
290
- }
291
- function useRichInputServices() {
292
- return useContext(RichInputServicesContext);
293
- }
294
-
295
- // src/rich-input/lib/session-data.ts
296
- import { useEffect as useEffect2, useRef } from "react";
297
-
298
- // src/rich-input/lib/client-query.ts
299
- import { useCallback, useEffect, useSyncExternalStore as useSyncExternalStore2 } from "react";
300
- var EMPTY = { data: void 0, error: null, isLoading: false, isFetching: false };
301
- var caches = /* @__PURE__ */ new WeakMap();
302
- function entryFor(client, key) {
303
- let cache = caches.get(client);
304
- if (!cache) {
305
- const created = /* @__PURE__ */ new Map();
306
- cache = created;
307
- caches.set(client, created);
308
- onInputCachesReset(client, () => {
309
- for (const [key2, entry2] of created) {
310
- entry2.request = null;
311
- entry2.fetchedAt = 0;
312
- update(entry2, EMPTY);
313
- const load = loadersFor(client).get(key2);
314
- if (load && entry2.listeners.size > 0) void fetchClientQuery(client, key2, load, { force: true }).catch(() => {
315
- });
316
- }
317
- });
318
- }
319
- let entry = cache.get(key);
320
- if (!entry) {
321
- entry = { snapshot: EMPTY, fetchedAt: 0, request: null, listeners: /* @__PURE__ */ new Set() };
322
- cache.set(key, entry);
323
- }
324
- return entry;
325
- }
326
- function update(entry, patch) {
327
- entry.snapshot = { ...entry.snapshot, ...patch };
328
- for (const listener of [...entry.listeners]) listener();
329
- }
330
- function fetchClientQuery(client, key, load, { staleMs = 3e4, force = false } = {}) {
331
- const entry = entryFor(client, key);
332
- if (entry.request) return entry.request;
333
- if (!force && entry.snapshot.data !== void 0 && Date.now() - entry.fetchedAt < staleMs) {
334
- return Promise.resolve(entry.snapshot.data);
335
- }
336
- const request = Promise.resolve().then(() => load(client));
337
- entry.request = request;
338
- update(entry, { isFetching: true, isLoading: entry.snapshot.data === void 0 });
339
- request.then(
340
- (data) => {
341
- if (entry.request !== request) return;
342
- entry.request = null;
343
- entry.fetchedAt = Date.now();
344
- update(entry, { data, error: null, isFetching: false, isLoading: false });
345
- },
346
- (error) => {
347
- if (entry.request !== request) return;
348
- entry.request = null;
349
- update(entry, { error, isFetching: false, isLoading: false });
350
- }
351
- );
352
- return request;
353
- }
354
- function setClientQueryData(client, key, updater) {
355
- const entry = entryFor(client, key);
356
- if (entry.snapshot.data === void 0) return;
357
- update(entry, { data: updater(entry.snapshot.data) });
358
- }
359
- function useClientQuery(key, load, { staleMs = 3e4 } = {}) {
360
- const client = useBladeClient();
361
- const subscribe = useCallback(
362
- (listener) => {
363
- if (!key) return () => {
364
- };
365
- const entry = entryFor(client, key);
366
- entry.listeners.add(listener);
367
- return () => {
368
- entry.listeners.delete(listener);
369
- };
370
- },
371
- [client, key]
372
- );
373
- const snapshot = useSyncExternalStore2(
374
- subscribe,
375
- () => key ? entryFor(client, key).snapshot : EMPTY,
376
- () => key ? entryFor(client, key).snapshot : EMPTY
377
- );
378
- if (key) loadersFor(client).set(key, load);
379
- useEffect(() => {
380
- if (!key) return;
381
- const registered = loadersFor(client).get(key);
382
- if (registered) void fetchClientQuery(client, key, registered, { staleMs }).catch(() => {
383
- });
384
- }, [client, key, staleMs]);
385
- const refetch = useCallback(async () => {
386
- if (!key) return void 0;
387
- const registered = loadersFor(client).get(key);
388
- if (!registered) return void 0;
389
- return fetchClientQuery(client, key, registered, { force: true }).catch(() => void 0);
390
- }, [client, key]);
391
- return { ...snapshot, refetch };
392
- }
393
- var loaderRegistry = /* @__PURE__ */ new WeakMap();
394
- function loadersFor(client) {
395
- let loaders = loaderRegistry.get(client);
396
- if (!loaders) {
397
- loaders = /* @__PURE__ */ new Map();
398
- loaderRegistry.set(client, loaders);
399
- }
400
- return loaders;
401
- }
402
- function refreshClientQuery(client, key) {
403
- const entry = caches.get(client)?.get(key);
404
- if (!entry) return;
405
- entry.fetchedAt = 0;
406
- const load = loadersFor(client).get(key);
407
- if (load && entry.listeners.size > 0) void fetchClientQuery(client, key, load, { force: true }).catch(() => {
408
- });
409
- }
410
-
411
- // src/rich-input/lib/session-data.ts
412
- var sessionPath = (sessionId, rest) => `/api/sessions/${encodeURIComponent(sessionId)}/${rest}`;
413
- function useRefreshWhenRunEnds(sessionId, keys3) {
414
- const client = useBladeClient();
415
- const streaming = useSessionState(sessionId, (state3) => state3.isStreaming);
416
- const wasStreaming = useRef(streaming);
417
- useEffect2(() => {
418
- if (wasStreaming.current && !streaming) {
419
- for (const key of keys3) refreshClientQuery(client, key);
420
- }
421
- wasStreaming.current = streaming;
422
- });
423
- }
424
- function useClientSessionSkills(sessionId) {
425
- const key = sessionId ? `session-skills:${sessionId}` : null;
426
- const query = useClientQuery(
427
- key,
428
- (client) => client.json("GET", sessionPath(sessionId ?? "", "skills"))
429
- );
430
- useRefreshWhenRunEnds(sessionId, key ? [key] : []);
431
- return { data: query.data, loading: query.isLoading, error: query.error };
432
- }
433
- function useClientSkillStats(sessionId) {
434
- const key = sessionId ? `skill-stats:${sessionId}` : null;
435
- const query = useClientQuery(key, (client) => client.json("GET", sessionPath(sessionId ?? "", "skill-stats")), {
436
- staleMs: 3e5
437
- });
438
- useRefreshWhenRunEnds(sessionId, key ? [key] : []);
439
- return { data: query.data, loading: query.isLoading, error: query.error };
440
- }
441
- function useClientContextStats(sessionId) {
442
- const key = sessionId ? `context-stats:${sessionId}` : null;
443
- const query = useClientQuery(
444
- key,
445
- (client) => client.json("GET", sessionPath(sessionId ?? "", "context-stats"))
446
- );
447
- useRefreshWhenRunEnds(sessionId, key ? [key] : []);
448
- return { data: query.data, loading: query.isLoading, error: query.error };
449
- }
450
- function useClientBackgroundTasks(sessionId) {
451
- const client = useBladeClient();
452
- const key = sessionId ? `background-tasks:${sessionId}` : null;
453
- const query = useClientQuery(key, (c) => c.sessions.listBackgroundTasks(sessionId ?? ""));
454
- const session = useSessionHandle(sessionId);
455
- useEffect2(() => {
456
- if (!session || !key) return;
457
- return session.on("backgroundTask", () => refreshClientQuery(client, key));
458
- }, [client, key, session]);
459
- return { data: query.data, loading: query.isLoading, error: query.error };
460
- }
461
- function refreshClientSessionSkills(client, sessionId) {
462
- refreshClientQuery(client, `session-skills:${sessionId}`);
463
- refreshClientQuery(client, `skill-stats:${sessionId}`);
464
- }
465
- function useClientSessionModel(sessionId) {
466
- const key = sessionId ? `session-detail:${sessionId}` : null;
467
- const query = useClientQuery(key, (client) => client.sessions.getSession(sessionId ?? ""));
468
- useRefreshWhenRunEnds(sessionId, key ? [key] : []);
469
- return query.data?.model ?? null;
470
- }
471
-
472
- // src/rich-input/model/model-data.ts
473
- var EMPTY_MODELS = [];
474
- var EMPTY_IDS = [];
475
- var CATALOG_KEY = "model-catalog";
476
- function useClientModelCatalog() {
477
- const { data, isLoading, isFetching, refetch } = useClientQuery(
478
- CATALOG_KEY,
479
- (client) => client.json("GET", "/api/config/models"),
480
- { staleMs: 0 }
481
- );
482
- return {
483
- models: data?.models ?? EMPTY_MODELS,
484
- defaultModel: data?.default ?? "",
485
- thinkingAvailable: data?.thinkingAvailable ?? false,
486
- unavailableProviderIds: data?.unavailableProviderIds ?? EMPTY_IDS,
487
- unavailableModelIds: data?.unavailableModelIds ?? EMPTY_IDS,
488
- isLoading,
489
- isFetching,
490
- refresh: async () => {
491
- await refetch();
492
- }
493
- };
494
- }
495
- var PREFERRED_MODEL_KEY = "preferred_model";
496
- var MODEL_REASONING_LEVELS_KEY = "llm.model_thinking_preferences";
497
- var PREFERENCES_KEY = "model-preferences";
498
- function loadPreferences(client) {
499
- const query = new URLSearchParams();
500
- query.append("key", PREFERRED_MODEL_KEY);
501
- query.append("key", MODEL_REASONING_LEVELS_KEY);
502
- return client.json("GET", `/api/user/preferences?${query.toString()}`).then((response) => response.values ?? {});
503
- }
504
- async function writePreference(client, key, value) {
505
- const previous = await fetchClientQuery(client, PREFERENCES_KEY, loadPreferences, { staleMs: 6e4 }).catch(
506
- () => ({})
507
- );
508
- setClientQueryData(client, PREFERENCES_KEY, (current) => ({ ...current, [key]: value }));
509
- try {
510
- await client.json("PUT", `/api/user/preferences/${encodeURIComponent(key)}`, { value });
511
- } catch {
512
- setClientQueryData(client, PREFERENCES_KEY, (current) => ({ ...current, [key]: previous[key] ?? null }));
513
- }
514
- }
515
- var EMPTY_LEVELS = {};
516
- function useClientModelPreferences() {
517
- const client = useBladeClient();
518
- const { data } = useClientQuery(PREFERENCES_KEY, loadPreferences, { staleMs: 6e4 });
519
- const rawLevels = data?.[MODEL_REASONING_LEVELS_KEY] ?? null;
520
- const reasoningLevels = rawLevels ? parseModelReasoningLevels(rawLevels) : EMPTY_LEVELS;
521
- return {
522
- preferredModel: data?.[PREFERRED_MODEL_KEY] ?? null,
523
- setPreferredModel: (modelId) => void writePreference(client, PREFERRED_MODEL_KEY, modelId),
524
- reasoningLevels,
525
- setReasoningLevel: (modelId, level) => {
526
- if (!modelId) return;
527
- void writePreference(
528
- client,
529
- MODEL_REASONING_LEVELS_KEY,
530
- JSON.stringify({ ...reasoningLevels, [modelId]: level })
531
- );
532
- }
533
- };
534
- }
535
-
536
- // src/rich-input/services.tsx
537
- function useModelCatalog() {
538
- const use = useRichInputServices().useModelCatalog ?? useClientModelCatalog;
539
- return use();
540
- }
541
- function useModelPreferences() {
542
- const use = useRichInputServices().useModelPreferences ?? useClientModelPreferences;
543
- return use();
544
- }
545
- function useSessionConnection(sessionId) {
546
- const connection = useSessionState(sessionId, (state3) => state3.connection);
547
- const status = sessionId ? connection : "connected";
548
- const everConnected = useRef2(false);
549
- if (status === "connected") everConnected.current = true;
550
- return { status, reconnectAttempt: 0, hasEverConnected: everConnected.current };
551
- }
552
- function useComposerConnectionInfo(sessionId) {
553
- const use = useRichInputServices().useConnection ?? useSessionConnection;
554
- return use(sessionId);
555
- }
556
- function useComposerConnection(sessionId) {
557
- return useComposerConnectionInfo(sessionId).status;
558
- }
559
- function useSessionSkills(sessionId) {
560
- const use = useRichInputServices().useSessionSkills ?? useClientSessionSkills;
561
- return use(sessionId);
562
- }
563
- function useSkillStats(sessionId) {
564
- const use = useRichInputServices().useSkillStats ?? useClientSkillStats;
565
- return use(sessionId);
566
- }
567
- function useContextStats(sessionId) {
568
- const use = useRichInputServices().useContextStats ?? useClientContextStats;
569
- return use(sessionId);
570
- }
571
- function useBackgroundTaskList(sessionId) {
572
- const use = useRichInputServices().useBackgroundTasks ?? useClientBackgroundTasks;
573
- return use(sessionId);
574
- }
575
- function useClientSessionDataInvalidation() {
576
- const client = useBladeClient();
577
- return useMemo(
578
- () => ({
579
- filesUploaded: (_sessionId) => {
580
- },
581
- pluginsChanged: (sessionId) => refreshClientSessionSkills(client, sessionId)
582
- }),
583
- [client]
584
- );
585
- }
586
- function useSessionDataInvalidation() {
587
- const use = useRichInputServices().useSessionDataInvalidation ?? useClientSessionDataInvalidation;
588
- return use();
589
- }
590
-
591
294
  // src/rich-input/lib/background-tasks-view.ts
592
295
  var LIVE_STATUSES = /* @__PURE__ */ new Set(["starting", "running", "cancelling"]);
593
296
  var ATTENTION_STATUSES = /* @__PURE__ */ new Set(["failed", "lost"]);
@@ -647,7 +350,7 @@ function formatStartedAt(value, now = /* @__PURE__ */ new Date()) {
647
350
  }
648
351
 
649
352
  // src/rich-input/BackgroundTasksPill.tsx
650
- import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
353
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
651
354
  var NO_TASKS = [];
652
355
  function TaskCard({
653
356
  task,
@@ -657,8 +360,8 @@ function TaskCard({
657
360
  }) {
658
361
  return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-[hsl(var(--border))] p-2", children: [
659
362
  /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
660
- /* @__PURE__ */ jsx2("div", { className: "min-w-0 break-words text-[hsl(var(--foreground))]", children: task.description || task.command }),
661
- /* @__PURE__ */ jsx2(
363
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 break-words text-[hsl(var(--foreground))]", children: task.description || task.command }),
364
+ /* @__PURE__ */ jsx(
662
365
  "span",
663
366
  {
664
367
  className: cn(
@@ -669,10 +372,10 @@ function TaskCard({
669
372
  }
670
373
  )
671
374
  ] }),
672
- task.status === "lost" ? /* @__PURE__ */ jsx2("div", { className: "mt-1 text-[11px] text-[hsl(var(--swf-warning))]", children: "\u5E73\u53F0\u91CD\u542F\u540E\u8DDF\u4E22\u4E86\uFF0C\u7A0B\u5E8F\u53EF\u80FD\u4ECD\u5728\u8FD0\u884C" }) : null,
375
+ task.status === "lost" ? /* @__PURE__ */ jsx("div", { className: "mt-1 text-[11px] text-[hsl(var(--swf-warning))]", children: "\u5E73\u53F0\u91CD\u542F\u540E\u8DDF\u4E22\u4E86\uFF0C\u7A0B\u5E8F\u53EF\u80FD\u4ECD\u5728\u8FD0\u884C" }) : null,
673
376
  /* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center gap-1.5 text-[10px] text-[hsl(var(--muted-foreground))]/60", children: [
674
- /* @__PURE__ */ jsx2("span", { children: formatStartedAt(task.started_at) }),
675
- /* @__PURE__ */ jsx2("span", { className: "truncate font-mono", children: task.id })
377
+ /* @__PURE__ */ jsx("span", { children: formatStartedAt(task.started_at) }),
378
+ /* @__PURE__ */ jsx("span", { className: "truncate font-mono", children: task.id })
676
379
  ] }),
677
380
  /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-1.5", children: [
678
381
  /* @__PURE__ */ jsxs(
@@ -682,7 +385,7 @@ function TaskCard({
682
385
  onClick: onOpenLog,
683
386
  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))]",
684
387
  children: [
685
- /* @__PURE__ */ jsx2(FileText, { size: 12 }),
388
+ /* @__PURE__ */ jsx(FileText, { size: 12 }),
686
389
  "\u65E5\u5FD7"
687
390
  ]
688
391
  }
@@ -694,7 +397,7 @@ function TaskCard({
694
397
  onClick: onStop,
695
398
  className: "inline-flex h-6 items-center gap-1 rounded-[6px] border border-[hsl(var(--swf-danger)/0.35)] px-2 text-[11px] text-[hsl(var(--swf-danger))] hover:bg-[hsl(var(--swf-danger-soft))]",
696
399
  children: [
697
- /* @__PURE__ */ jsx2(Square, { size: 10 }),
400
+ /* @__PURE__ */ jsx(Square, { size: 10 }),
698
401
  "\u505C\u6B62"
699
402
  ]
700
403
  }
@@ -706,7 +409,7 @@ function TaskCard({
706
409
  onClick: onDismiss,
707
410
  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))]",
708
411
  children: [
709
- /* @__PURE__ */ jsx2(EyeOff, { size: 12 }),
412
+ /* @__PURE__ */ jsx(EyeOff, { size: 12 }),
710
413
  "\u9690\u85CF"
711
414
  ]
712
415
  }
@@ -723,7 +426,7 @@ function BackgroundTasksPill({ sessionId }) {
723
426
  const [historyOverride, setHistoryOverride] = useState(null);
724
427
  const [logTask, setLogTask] = useState(null);
725
428
  const [logDialogOpen, setLogDialogOpen] = useState(false);
726
- const { activeTasks, historyTasks, runningCount, attentionCount } = useMemo2(
429
+ const { activeTasks, historyTasks, runningCount, attentionCount } = useMemo(
727
430
  () => splitTasks(tasks, dismissed),
728
431
  [tasks, dismissed]
729
432
  );
@@ -769,7 +472,7 @@ function BackgroundTasksPill({ sessionId }) {
769
472
  closePanel();
770
473
  };
771
474
  return /* @__PURE__ */ jsxs(Fragment, { children: [
772
- /* @__PURE__ */ jsx2(
475
+ /* @__PURE__ */ jsx(
773
476
  Dialog,
774
477
  {
775
478
  open: logDialogOpen,
@@ -784,10 +487,10 @@ function BackgroundTasksPill({ sessionId }) {
784
487
  children: [
785
488
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 border-b border-[hsl(var(--border))] px-4 py-3", children: [
786
489
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
787
- /* @__PURE__ */ jsx2(DialogTitle, { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: logTask?.title }),
788
- /* @__PURE__ */ jsx2("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u540E\u53F0\u4EFB\u52A1\u65E5\u5FD7" })
490
+ /* @__PURE__ */ jsx(DialogTitle, { className: "truncate text-sm font-medium text-[hsl(var(--foreground))]", children: logTask?.title }),
491
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u540E\u53F0\u4EFB\u52A1\u65E5\u5FD7" })
789
492
  ] }),
790
- /* @__PURE__ */ jsx2(
493
+ /* @__PURE__ */ jsx(
791
494
  "button",
792
495
  {
793
496
  type: "button",
@@ -797,7 +500,7 @@ function BackgroundTasksPill({ sessionId }) {
797
500
  }
798
501
  )
799
502
  ] }),
800
- /* @__PURE__ */ jsx2("pre", { className: "min-h-64 flex-1 overflow-auto whitespace-pre-wrap p-4 font-mono text-xs leading-5 text-[hsl(var(--foreground))]", children: logTask?.loading ? "\u52A0\u8F7D\u4E2D..." : logTask?.error || logTask?.output })
503
+ /* @__PURE__ */ jsx("pre", { className: "min-h-64 flex-1 overflow-auto whitespace-pre-wrap p-4 font-mono text-xs leading-5 text-[hsl(var(--foreground))]", children: logTask?.loading ? "\u52A0\u8F7D\u4E2D..." : logTask?.error || logTask?.output })
801
504
  ]
802
505
  }
803
506
  )
@@ -819,8 +522,8 @@ function BackgroundTasksPill({ sessionId }) {
819
522
  title: summary,
820
523
  className: "relative flex h-9 w-9 shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
821
524
  children: [
822
- /* @__PURE__ */ jsx2(Terminal, { size: 16 }),
823
- runningCount > 0 ? /* @__PURE__ */ jsx2("span", { className: "absolute right-1 top-1 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-[hsl(var(--muted))] px-1 text-[9px] font-medium leading-none text-[hsl(var(--muted-foreground))]", children: runningCount }) : attentionCount > 0 ? /* @__PURE__ */ jsx2(
525
+ /* @__PURE__ */ jsx(Terminal, { size: 16 }),
526
+ runningCount > 0 ? /* @__PURE__ */ jsx("span", { className: "absolute right-1 top-1 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-[hsl(var(--muted))] px-1 text-[9px] font-medium leading-none text-[hsl(var(--muted-foreground))]", children: runningCount }) : attentionCount > 0 ? /* @__PURE__ */ jsx(
824
527
  "span",
825
528
  {
826
529
  "data-attention-dot": "true",
@@ -830,8 +533,8 @@ function BackgroundTasksPill({ sessionId }) {
830
533
  ]
831
534
  }
832
535
  ),
833
- open ? /* @__PURE__ */ jsx2("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-[var(--swf-shadow-overlay)] before:absolute before:inset-x-0 before:top-full before:h-2 before:content-['']", children: /* @__PURE__ */ jsxs("div", { className: "max-h-72 space-y-2 overflow-y-auto", children: [
834
- activeTasks.map((task) => /* @__PURE__ */ jsx2(
536
+ open ? /* @__PURE__ */ jsx("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-[var(--swf-shadow-overlay)] before:absolute before:inset-x-0 before:top-full before:h-2 before:content-['']", children: /* @__PURE__ */ jsxs("div", { className: "max-h-72 space-y-2 overflow-y-auto", children: [
537
+ activeTasks.map((task) => /* @__PURE__ */ jsx(
835
538
  TaskCard,
836
539
  {
837
540
  task,
@@ -856,7 +559,7 @@ function BackgroundTasksPill({ sessionId }) {
856
559
  "aria-expanded": historyOpen,
857
560
  className: "flex w-full items-center gap-1 px-1 py-1 text-[11px] text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
858
561
  children: [
859
- /* @__PURE__ */ jsx2(
562
+ /* @__PURE__ */ jsx(
860
563
  ChevronDown,
861
564
  {
862
565
  size: 12,
@@ -869,7 +572,7 @@ function BackgroundTasksPill({ sessionId }) {
869
572
  ]
870
573
  }
871
574
  ),
872
- historyOpen ? /* @__PURE__ */ jsx2("div", { className: "mt-2 space-y-2", children: historyTasks.map((task) => /* @__PURE__ */ jsx2(
575
+ historyOpen ? /* @__PURE__ */ jsx("div", { className: "mt-2 space-y-2", children: historyTasks.map((task) => /* @__PURE__ */ jsx(
873
576
  TaskCard,
874
577
  {
875
578
  task,
@@ -12247,7 +11950,7 @@ function resolveSelection(view, doc3, parsedSel) {
12247
11950
  }
12248
11951
  function isMarkChange(cur, prev) {
12249
11952
  let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks;
12250
- let added = curMarks, removed = prevMarks, type, mark, update2;
11953
+ let added = curMarks, removed = prevMarks, type, mark, update;
12251
11954
  for (let i = 0; i < prevMarks.length; i++)
12252
11955
  added = prevMarks[i].removeFromSet(added);
12253
11956
  for (let i = 0; i < curMarks.length; i++)
@@ -12255,17 +11958,17 @@ function isMarkChange(cur, prev) {
12255
11958
  if (added.length == 1 && removed.length == 0) {
12256
11959
  mark = added[0];
12257
11960
  type = "add";
12258
- update2 = (node) => node.mark(mark.addToSet(node.marks));
11961
+ update = (node) => node.mark(mark.addToSet(node.marks));
12259
11962
  } else if (added.length == 0 && removed.length == 1) {
12260
11963
  mark = removed[0];
12261
11964
  type = "remove";
12262
- update2 = (node) => node.mark(mark.removeFromSet(node.marks));
11965
+ update = (node) => node.mark(mark.removeFromSet(node.marks));
12263
11966
  } else {
12264
11967
  return null;
12265
11968
  }
12266
11969
  let updated = [];
12267
11970
  for (let i = 0; i < prev.childCount; i++)
12268
- updated.push(update2(prev.child(i)));
11971
+ updated.push(update(prev.child(i)));
12269
11972
  if (Fragment2.from(updated).eq(cur))
12270
11973
  return { mark, type };
12271
11974
  }
@@ -19102,7 +18805,7 @@ var TopicAssetMention = index_default.extend({
19102
18805
  class: "file-mention-pill topic-asset-mention-pill",
19103
18806
  "data-topic-id": node.attrs.topic_id,
19104
18807
  "data-path": node.attrs.path,
19105
- title: `\u4E3B\u9898\u8D44\u4EA7\uFF1A${node.attrs.path}`
18808
+ title: `\u5DE5\u4F5C\u7A7A\u95F4\u8D44\u4EA7\uFF1A${node.attrs.path}`
19106
18809
  }, `@${node.attrs.path}`]
19107
18810
  };
19108
18811
  },
@@ -19119,7 +18822,7 @@ var TopicAssetMention = index_default.extend({
19119
18822
 
19120
18823
  // src/chat/runtime/composer-channels.ts
19121
18824
  import { normalizeTopicAssetRefs as normalizeTopicAssetRefs2 } from "@blade-hq/agent-client";
19122
- import { useSyncExternalStore as useSyncExternalStore3 } from "react";
18825
+ import { useSyncExternalStore as useSyncExternalStore2 } from "react";
19123
18826
  function buildSignalId() {
19124
18827
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
19125
18828
  return crypto.randomUUID();
@@ -19141,8 +18844,8 @@ var state2 = {
19141
18844
  rewindDrafts: {}
19142
18845
  };
19143
18846
  var listeners2 = /* @__PURE__ */ new Set();
19144
- function setState(update2) {
19145
- const next = update2(state2);
18847
+ function setState(update) {
18848
+ const next = update(state2);
19146
18849
  if (next === state2) return;
19147
18850
  state2 = next;
19148
18851
  for (const listener of [...listeners2]) listener();
@@ -19246,7 +18949,7 @@ var composerChannels = {
19246
18949
  }
19247
18950
  };
19248
18951
  function useComposerChannels(selector) {
19249
- return useSyncExternalStore3(
18952
+ return useSyncExternalStore2(
19250
18953
  composerChannels.subscribe,
19251
18954
  () => selector(state2),
19252
18955
  () => selector(state2)
@@ -19260,7 +18963,7 @@ async function getTopicAssetSuggestionItems(client, topicId, query) {
19260
18963
  const result = await client.chatGroups.listAssets(topicId);
19261
18964
  return result.items.filter((asset) => !asset.is_dir && asset.path.toLowerCase().includes(query.toLowerCase())).map((asset) => ({ kind: "topicAsset", topic_id: topicId, path: asset.path, name: asset.path }));
19262
18965
  } catch {
19263
- return [{ kind: "topicAssetError", message: "\u4E3B\u9898\u8D44\u4EA7\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165 @ \u91CD\u8BD5" }];
18966
+ return [{ kind: "topicAssetError", message: "\u5DE5\u4F5C\u7A7A\u95F4\u8D44\u4EA7\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165 @ \u91CD\u8BD5" }];
19264
18967
  }
19265
18968
  }
19266
18969
  function queueTopicAssetReference(sessionId, ref) {
@@ -19268,7 +18971,7 @@ function queueTopicAssetReference(sessionId, ref) {
19268
18971
  }
19269
18972
 
19270
18973
  // src/rich-input/use-dismiss-skill-suggestions-on-mode-change.ts
19271
- import { useEffect as useEffect3, useRef as useRef3 } from "react";
18974
+ import { useEffect, useRef } from "react";
19272
18975
 
19273
18976
  // src/rich-input/extensions/skill-mention.ts
19274
18977
  var skillMentionSuggestionKey = new PluginKey("skillMentionSuggestion");
@@ -19352,8 +19055,8 @@ var SkillMention = index_default.extend({
19352
19055
  // src/rich-input/use-dismiss-skill-suggestions-on-mode-change.ts
19353
19056
  function useDismissSkillSuggestionsOnModeChange(editor) {
19354
19057
  const renderMode = useChatRenderMode();
19355
- const previousRef = useRef3(renderMode);
19356
- useEffect3(() => {
19058
+ const previousRef = useRef(renderMode);
19059
+ useEffect(() => {
19357
19060
  if (previousRef.current === renderMode) return;
19358
19061
  previousRef.current = renderMode;
19359
19062
  if (editor && !editor.isDestroyed && skillMentionSuggestionKey.getState(editor.state)?.active) {
@@ -19364,12 +19067,12 @@ function useDismissSkillSuggestionsOnModeChange(editor) {
19364
19067
 
19365
19068
  // ../../node_modules/.pnpm/@tiptap+react@3.20.4_@floating-ui+dom@1.7.6_@tiptap+core@3.20.4_@tiptap+pm@3.20.4__@tip_1ce9f35538141630e675758ebf46eb2f/node_modules/@tiptap/react/dist/index.js
19366
19069
  var import_shim = __toESM(require_shim(), 1);
19367
- import { createContext as createContext2, useContext as useContext2, useMemo as useMemo3 } from "react";
19070
+ import { createContext, useContext, useMemo as useMemo2 } from "react";
19368
19071
  import React, { forwardRef } from "react";
19369
19072
  import ReactDOM from "react-dom";
19370
- import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
19073
+ import { Fragment as Fragment3, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
19371
19074
  var import_shim2 = __toESM(require_shim(), 1);
19372
- import { useDebugValue as useDebugValue2, useEffect as useEffect22, useRef as useRef4, useState as useState2 } from "react";
19075
+ import { useDebugValue as useDebugValue2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
19373
19076
 
19374
19077
  // ../../node_modules/.pnpm/fast-equals@5.4.0/node_modules/fast-equals/dist/es/index.mjs
19375
19078
  var { getOwnPropertyNames, getOwnPropertySymbols } = Object;
@@ -19811,10 +19514,10 @@ function createCustomEqual(options = {}) {
19811
19514
 
19812
19515
  // ../../node_modules/.pnpm/@tiptap+react@3.20.4_@floating-ui+dom@1.7.6_@tiptap+core@3.20.4_@tiptap+pm@3.20.4__@tip_1ce9f35538141630e675758ebf46eb2f/node_modules/@tiptap/react/dist/index.js
19813
19516
  var import_with_selector = __toESM(require_with_selector(), 1);
19814
- import { useDebugValue, useEffect as useEffect4, useLayoutEffect, useState as useState3 } from "react";
19517
+ import { useDebugValue, useEffect as useEffect3, useLayoutEffect, useState as useState3 } from "react";
19815
19518
  import { jsx as jsx22, jsxs as jsxs22 } from "react/jsx-runtime";
19816
- import { createContext as createContext22, createElement, useContext as useContext22 } from "react";
19817
- import { jsx as jsx32 } from "react/jsx-runtime";
19519
+ import { createContext as createContext2, createElement, useContext as useContext2 } from "react";
19520
+ import { jsx as jsx3 } from "react/jsx-runtime";
19818
19521
  import React3 from "react";
19819
19522
  import { jsx as jsx4 } from "react/jsx-runtime";
19820
19523
  import React4 from "react";
@@ -19844,7 +19547,7 @@ var Portals = ({ contentComponent }) => {
19844
19547
  contentComponent.getSnapshot,
19845
19548
  contentComponent.getServerSnapshot
19846
19549
  );
19847
- return /* @__PURE__ */ jsx3(Fragment3, { children: Object.values(renderers) });
19550
+ return /* @__PURE__ */ jsx2(Fragment3, { children: Object.values(renderers) });
19848
19551
  };
19849
19552
  function getInstance() {
19850
19553
  const subscribers = /* @__PURE__ */ new Set();
@@ -19965,8 +19668,8 @@ var PureEditorContent = class extends React.Component {
19965
19668
  render() {
19966
19669
  const { editor, innerRef, ...rest } = this.props;
19967
19670
  return /* @__PURE__ */ jsxs2(Fragment3, { children: [
19968
- /* @__PURE__ */ jsx3("div", { ref: mergeRefs(innerRef, this.editorContentRef), ...rest }),
19969
- (editor == null ? void 0 : editor.contentComponent) && /* @__PURE__ */ jsx3(Portals, { contentComponent: editor.contentComponent })
19671
+ /* @__PURE__ */ jsx2("div", { ref: mergeRefs(innerRef, this.editorContentRef), ...rest }),
19672
+ (editor == null ? void 0 : editor.contentComponent) && /* @__PURE__ */ jsx2(Portals, { contentComponent: editor.contentComponent })
19970
19673
  ] });
19971
19674
  }
19972
19675
  };
@@ -19983,7 +19686,7 @@ var EditorContentWithKey = forwardRef(
19983
19686
  }
19984
19687
  );
19985
19688
  var EditorContent = React.memo(EditorContentWithKey);
19986
- var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect4;
19689
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect3;
19987
19690
  var EditorStateManager = class {
19988
19691
  constructor(initialEditor) {
19989
19692
  this.transactionNumber = 0;
@@ -20291,7 +19994,7 @@ var EditorInstanceManager = class _EditorInstanceManager {
20291
19994
  }
20292
19995
  };
20293
19996
  function useEditor(options = {}, deps = []) {
20294
- const mostRecentOptions = useRef4(options);
19997
+ const mostRecentOptions = useRef2(options);
20295
19998
  mostRecentOptions.current = options;
20296
19999
  const [instanceManager] = useState2(() => new EditorInstanceManager(mostRecentOptions));
20297
20000
  const editor = (0, import_shim2.useSyncExternalStore)(
@@ -20300,7 +20003,7 @@ function useEditor(options = {}, deps = []) {
20300
20003
  instanceManager.getServerSnapshot
20301
20004
  );
20302
20005
  useDebugValue2(editor);
20303
- useEffect22(instanceManager.onRender(deps));
20006
+ useEffect2(instanceManager.onRender(deps));
20304
20007
  useEditorState({
20305
20008
  editor,
20306
20009
  selector: ({ transactionNumber }) => {
@@ -20315,18 +20018,18 @@ function useEditor(options = {}, deps = []) {
20315
20018
  });
20316
20019
  return editor;
20317
20020
  }
20318
- var EditorContext = createContext2({
20021
+ var EditorContext = createContext({
20319
20022
  editor: null
20320
20023
  });
20321
20024
  var EditorConsumer = EditorContext.Consumer;
20322
- var ReactNodeViewContext = createContext22({
20025
+ var ReactNodeViewContext = createContext2({
20323
20026
  onDragStart: () => {
20324
20027
  },
20325
20028
  nodeViewContentChildren: void 0,
20326
20029
  nodeViewContentRef: () => {
20327
20030
  }
20328
20031
  });
20329
- var useReactNodeView = () => useContext22(ReactNodeViewContext);
20032
+ var useReactNodeView = () => useContext2(ReactNodeViewContext);
20330
20033
  var NodeViewWrapper = React3.forwardRef((props, ref) => {
20331
20034
  const { onDragStart } = useReactNodeView();
20332
20035
  const Tag = props.as || "div";
@@ -25389,8 +25092,8 @@ var index_default2 = StarterKit;
25389
25092
 
25390
25093
  // src/rich-input/ChatInput.tsx
25391
25094
  import {
25392
- useEffect as useEffect9,
25393
- useRef as useRef9,
25095
+ useEffect as useEffect8,
25096
+ useRef as useRef7,
25394
25097
  useState as useState11
25395
25098
  } from "react";
25396
25099
  import { createRoot } from "react-dom/client";
@@ -25405,7 +25108,7 @@ function skillDisplayName(skill) {
25405
25108
  }
25406
25109
 
25407
25110
  // src/rich-input/voice/use-tiptap-voice-input.ts
25408
- import { useCallback as useCallback2, useEffect as useEffect5, useRef as useRef5 } from "react";
25111
+ import { useCallback, useEffect as useEffect4, useRef as useRef3 } from "react";
25409
25112
  var IDLE_VOICE = {
25410
25113
  status: "idle",
25411
25114
  error: null,
@@ -25421,8 +25124,8 @@ function useNoVoiceInput() {
25421
25124
  function useTiptapVoiceInput(options) {
25422
25125
  const { editorRef, workletUrl, onError } = options;
25423
25126
  const useVoiceInput2 = options.useVoiceInput ?? useNoVoiceInput;
25424
- const partialRangeRef = useRef5(null);
25425
- const lastPartialLenRef = useRef5(0);
25127
+ const partialRangeRef = useRef3(null);
25128
+ const lastPartialLenRef = useRef3(0);
25426
25129
  const handlePartial = useEffectEvent((text) => {
25427
25130
  const ed = editorRef.current;
25428
25131
  if (!ed) return;
@@ -25472,18 +25175,18 @@ function useTiptapVoiceInput(options) {
25472
25175
  onError: handleError
25473
25176
  });
25474
25177
  const isRecording = voice.status === "recording";
25475
- useEffect5(() => {
25178
+ useEffect4(() => {
25476
25179
  const ed = editorRef.current;
25477
25180
  if (!ed) return;
25478
25181
  ed.setEditable(!isRecording);
25479
25182
  }, [isRecording, editorRef]);
25480
- useEffect5(() => {
25183
+ useEffect4(() => {
25481
25184
  if (voice.status === "idle" || voice.status === "error") {
25482
25185
  partialRangeRef.current = null;
25483
25186
  lastPartialLenRef.current = 0;
25484
25187
  }
25485
25188
  }, [voice.status]);
25486
- const toggle = useCallback2(() => {
25189
+ const toggle = useCallback(() => {
25487
25190
  if (voice.status === "recording" || voice.status === "starting") {
25488
25191
  void voice.stop();
25489
25192
  } else {
@@ -25540,7 +25243,7 @@ function VoiceWaveform({ level, color = "currentColor", size = 16 }) {
25540
25243
  }
25541
25244
 
25542
25245
  // src/rich-input/model/resolve-model.ts
25543
- import { useMemo as useMemo4 } from "react";
25246
+ import { useMemo as useMemo3 } from "react";
25544
25247
  var MODEL_LOADING_SEND_HINT = "\u6B63\u5728\u52A0\u8F7D\u6A21\u578B\u914D\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u518D\u53D1\u9001";
25545
25248
  function gateSendWhileModelLoading(isModelLoading, hasContent) {
25546
25249
  if (!isModelLoading) return { blocked: false };
@@ -25609,7 +25312,7 @@ function resolveModelChoice({
25609
25312
  function useResolvedModel(activeSessionModel) {
25610
25313
  const { models, defaultModel, thinkingAvailable, isLoading, unavailableProviderIds, unavailableModelIds } = useModelCatalog();
25611
25314
  const { preferredModel } = useModelPreferences();
25612
- const resolved = useMemo4(() => {
25315
+ const resolved = useMemo3(() => {
25613
25316
  return resolveModelChoice({
25614
25317
  activeSessionModel,
25615
25318
  preferredModel,
@@ -25643,17 +25346,21 @@ function useReasoningLevelPreference(modelId) {
25643
25346
  }
25644
25347
 
25645
25348
  // src/rich-input/model/use-composer-model.ts
25646
- import { useEffect as useEffect6, useRef as useRef6, useState as useState4 } from "react";
25349
+ import { useEffect as useEffect5, useRef as useRef4, useState as useState4 } from "react";
25647
25350
  function useInjectedSessionModel(sessionId) {
25648
25351
  return useChatSessionDetail(sessionId)?.model ?? null;
25649
25352
  }
25650
25353
  function useComposerModel(activeSessionId) {
25651
25354
  const [newSessionModelSelection, setNewSessionModelSelection] = useState4(null);
25652
- const newSessionModelSelectionRef = useRef6(null);
25355
+ const newSessionModelSelectionRef = useRef4(null);
25653
25356
  const { setPreferredModel } = useModelPreferences();
25654
25357
  const { models: modelCatalog } = useModelCatalog();
25655
25358
  const useSessionModel = useChatEnvironment().useSessionDetail ? useInjectedSessionModel : useClientSessionModel;
25656
25359
  const activeSessionModel = useSessionModel(activeSessionId);
25360
+ const session = useSessionHandle(activeSessionId);
25361
+ const source = useSessionSource();
25362
+ const [selectingSession, setSelectingSession] = useState4(null);
25363
+ const selectingRef = useRef4(null);
25657
25364
  const sharedModelDraft = useComposerChannels(
25658
25365
  (state3) => activeSessionId ? state3.modelDrafts[activeSessionId] : void 0
25659
25366
  );
@@ -25668,18 +25375,18 @@ function useComposerModel(activeSessionId) {
25668
25375
  isLoading
25669
25376
  } = useResolvedModel(resolveComposerModel(activeSessionId, activeSessionModel, explicitModelSelection));
25670
25377
  const { reasoningLevelPreference, setReasoningLevelPreference } = useReasoningLevelPreference(selectedModel);
25671
- useEffect6(() => {
25378
+ useEffect5(() => {
25672
25379
  if (!activeSessionId || !newSessionModelSelectionRef.current) return;
25673
25380
  newSessionModelSelectionRef.current = null;
25674
25381
  setNewSessionModelSelection(null);
25675
25382
  }, [activeSessionId]);
25676
- useEffect6(() => {
25383
+ useEffect5(() => {
25677
25384
  if (!activeSessionId || !sharedModelDraft || isLoading || modelCatalog.length === 0) return;
25678
25385
  if (!modelCatalog.some((model) => model.id === sharedModelDraft)) {
25679
25386
  composerChannels.clearModelDraft(activeSessionId);
25680
25387
  }
25681
25388
  }, [activeSessionId, sharedModelDraft, isLoading, modelCatalog]);
25682
- useEffect6(() => {
25389
+ useEffect5(() => {
25683
25390
  if (!activeSessionId || sharedModelDraft !== activeSessionModel) return;
25684
25391
  composerChannels.clearModelDraft(activeSessionId);
25685
25392
  }, [activeSessionId, activeSessionModel, sharedModelDraft]);
@@ -25687,7 +25394,7 @@ function useComposerModel(activeSessionId) {
25687
25394
  return {
25688
25395
  selectedModel,
25689
25396
  hasAvailableModel,
25690
- isLoading,
25397
+ isLoading: isLoading || !!activeSessionId && (selectingSession === activeSessionId || !session),
25691
25398
  availabilityMessage: modelAvailabilityMessage,
25692
25399
  thinkingAvailable,
25693
25400
  reasoningLevels,
@@ -25695,7 +25402,22 @@ function useComposerModel(activeSessionId) {
25695
25402
  setReasoningLevel: setReasoningLevelPreference,
25696
25403
  selectModel(model) {
25697
25404
  if (activeSessionId) {
25405
+ if (selectingRef.current === activeSessionId) return;
25406
+ selectingRef.current = activeSessionId;
25407
+ setSelectingSession(activeSessionId);
25698
25408
  composerChannels.setModelDraft(activeSessionId, model);
25409
+ const select = (ready) => ready.selectModel(model);
25410
+ const pending = source.whenReady ? source.whenReady(activeSessionId, select) : session ? select(session) : Promise.resolve(false);
25411
+ void pending.catch(() => false).then((ok) => {
25412
+ if (!ok && composerChannels.getState().modelDrafts[activeSessionId] === model) {
25413
+ composerChannels.clearModelDraft(activeSessionId);
25414
+ }
25415
+ }).finally(() => {
25416
+ if (selectingRef.current === activeSessionId) {
25417
+ selectingRef.current = null;
25418
+ setSelectingSession(null);
25419
+ }
25420
+ });
25699
25421
  } else {
25700
25422
  const selection = { sessionId: activeSessionId, model };
25701
25423
  newSessionModelSelectionRef.current = selection;
@@ -25759,7 +25481,7 @@ function PopoverContent({
25759
25481
  }
25760
25482
 
25761
25483
  // src/rich-input/ModelSelector.tsx
25762
- import { useMemo as useMemo5, useState as useState5 } from "react";
25484
+ import { useMemo as useMemo4, useState as useState5 } from "react";
25763
25485
  import { jsx as jsx12, jsxs as jsxs3 } from "react/jsx-runtime";
25764
25486
  var inputModalityLabels = {
25765
25487
  text: "\u6587\u672C",
@@ -25801,7 +25523,7 @@ function ModelSelector({
25801
25523
  }
25802
25524
  void refresh();
25803
25525
  }
25804
- const filteredModels = useMemo5(() => {
25526
+ const filteredModels = useMemo4(() => {
25805
25527
  const normalized = query.trim().toLowerCase();
25806
25528
  if (!normalized) return models;
25807
25529
  return models.filter(
@@ -25934,7 +25656,7 @@ function ModelSelector({
25934
25656
  }
25935
25657
 
25936
25658
  // src/rich-input/SkillStatusBar.tsx
25937
- import { useMemo as useMemo6 } from "react";
25659
+ import { useMemo as useMemo5 } from "react";
25938
25660
 
25939
25661
  // src/chat/lib/skill-visibility.ts
25940
25662
  function visibleSkills(skills, mode) {
@@ -26112,7 +25834,7 @@ function SkillStatusBar({
26112
25834
  const { status: connectionStatus, reconnectAttempt, hasEverConnected } = useComposerConnectionInfo(sessionId);
26113
25835
  const statsReady = !loading && !error;
26114
25836
  const skillStoreConnected = statsReady && skillStats.remote_connected;
26115
- const connectionMeta = useMemo6(
25837
+ const connectionMeta = useMemo5(
26116
25838
  () => getConnectionMeta(
26117
25839
  connectionStatus,
26118
25840
  reconnectAttempt,
@@ -26132,7 +25854,7 @@ function SkillStatusBar({
26132
25854
  text: skillStoreConnected ? `\u5DF2\u5B89\u88C5 ${skillStats.installed_skill_count} \u4E2A\u6280\u80FD` : "\u5C1A\u672A\u767B\u5F55\u6280\u80FD\u5546\u5E97"
26133
25855
  }
26134
25856
  ].filter((item) => item.key !== "total" || skillStats.remote_configured);
26135
- const tokenSummary = useMemo6(() => {
25857
+ const tokenSummary = useMemo5(() => {
26136
25858
  if (mode !== "developer") return null;
26137
25859
  if (contextStatsLoading || contextStatsError || !contextStats) {
26138
25860
  return {
@@ -26219,11 +25941,72 @@ function SkillStatusBar({
26219
25941
  ] }) }) });
26220
25942
  }
26221
25943
 
25944
+ // src/rich-input/InputActionSubmenu.tsx
25945
+ import { useSyncExternalStore as useSyncExternalStore4 } from "react";
25946
+ import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
25947
+ var narrowQuery = "(max-width: 639px)";
25948
+ function subscribeToViewport(onChange) {
25949
+ const media = window.matchMedia(narrowQuery);
25950
+ media.addEventListener("change", onChange);
25951
+ return () => media.removeEventListener("change", onChange);
25952
+ }
25953
+ var isNarrowViewport = () => window.matchMedia(narrowQuery).matches;
25954
+ function InputActionSubmenu({ label, icon, open, onOpenChange, children, disabled = false }) {
25955
+ const narrow = useSyncExternalStore4(subscribeToViewport, isNarrowViewport, () => false);
25956
+ return /* @__PURE__ */ jsxs6(dist_exports.Root, { open, onOpenChange, children: [
25957
+ /* @__PURE__ */ jsx15(dist_exports.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
25958
+ "button",
25959
+ {
25960
+ type: "button",
25961
+ disabled,
25962
+ onClick: (event) => {
25963
+ event.preventDefault();
25964
+ onOpenChange(true);
25965
+ },
25966
+ onPointerEnter: (event) => {
25967
+ if (event.pointerType === "mouse" && !disabled) onOpenChange(true);
25968
+ },
25969
+ onKeyDown: (event) => {
25970
+ if (event.key === "ArrowRight") {
25971
+ event.preventDefault();
25972
+ onOpenChange(true);
25973
+ }
25974
+ },
25975
+ className: "flex w-full items-center gap-2 rounded-lg px-3 py-2.5 text-left text-sm text-[hsl(var(--popover-foreground))] outline-none hover:bg-[hsl(var(--accent))] focus-visible:bg-[hsl(var(--accent))] disabled:opacity-50 data-[state=open]:bg-[hsl(var(--accent))]",
25976
+ children: [
25977
+ icon,
25978
+ /* @__PURE__ */ jsx15("span", { children: label }),
25979
+ /* @__PURE__ */ jsx15(ChevronRight, { size: 14, className: "ml-auto", "aria-hidden": "true" })
25980
+ ]
25981
+ }
25982
+ ) }),
25983
+ /* @__PURE__ */ jsx15(dist_exports.Portal, { children: /* @__PURE__ */ jsx15(
25984
+ dist_exports.Content,
25985
+ {
25986
+ side: narrow ? "bottom" : "right",
25987
+ align: "start",
25988
+ sideOffset: 8,
25989
+ collisionPadding: 12,
25990
+ "aria-label": label,
25991
+ onEscapeKeyDown: (event) => event.stopPropagation(),
25992
+ onKeyDown: (event) => {
25993
+ if (event.key === "ArrowLeft" && !(event.target instanceof HTMLInputElement || event.target instanceof HTMLSelectElement)) {
25994
+ event.preventDefault();
25995
+ onOpenChange(false);
25996
+ }
25997
+ },
25998
+ className: "z-50 max-h-[min(70vh,var(--radix-popover-content-available-height))] w-[min(320px,calc(100vw-2rem))] overflow-y-auto rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-1 text-xs text-[hsl(var(--popover-foreground))] shadow-[var(--swf-shadow-overlay)] outline-none",
25999
+ children
26000
+ }
26001
+ ) })
26002
+ ] });
26003
+ }
26004
+
26222
26005
  // src/rich-input/ConnectButton.tsx
26223
26006
  import { useState as useState6 } from "react";
26224
26007
 
26225
26008
  // src/rich-input/lib/skill-suggestions.ts
26226
- var sessionPath2 = (sessionId, rest) => `/api/sessions/${encodeURIComponent(sessionId)}/${rest}`;
26009
+ var sessionPath = (sessionId, rest) => `/api/sessions/${encodeURIComponent(sessionId)}/${rest}`;
26227
26010
  function toItem(skill) {
26228
26011
  return {
26229
26012
  type: "skill",
@@ -26240,12 +26023,12 @@ var cachesByClient = /* @__PURE__ */ new WeakMap();
26240
26023
  function cachesFor(client) {
26241
26024
  const existing = cachesByClient.get(client);
26242
26025
  if (existing) return existing;
26243
- const caches2 = { requests: /* @__PURE__ */ new Map(), searchSeq: 0 };
26244
- cachesByClient.set(client, caches2);
26026
+ const caches = { requests: /* @__PURE__ */ new Map(), searchSeq: 0 };
26027
+ cachesByClient.set(client, caches);
26245
26028
  onInputCachesReset(client, () => {
26246
- if (cachesByClient.get(client) === caches2) cachesByClient.delete(client);
26029
+ if (cachesByClient.get(client) === caches) cachesByClient.delete(client);
26247
26030
  });
26248
- return caches2;
26031
+ return caches;
26249
26032
  }
26250
26033
  function cached(client, key, load) {
26251
26034
  const { requests } = cachesFor(client);
@@ -26267,7 +26050,7 @@ async function loadSessionSkills({ client, sessionId, renderMode }) {
26267
26050
  const skills = await cached(
26268
26051
  client,
26269
26052
  `session-skills:${sessionId}`,
26270
- () => client.json("GET", sessionPath2(sessionId, "skills"))
26053
+ () => client.json("GET", sessionPath(sessionId, "skills"))
26271
26054
  );
26272
26055
  return visibleSkills(skills, renderMode);
26273
26056
  } catch {
@@ -26318,14 +26101,14 @@ async function getSkillSuggestions(query, options) {
26318
26101
  if (!trimmed) {
26319
26102
  return getDefaultSuggestions(options);
26320
26103
  }
26321
- const caches2 = cachesFor(options.client);
26322
- const seq = ++caches2.searchSeq;
26104
+ const caches = cachesFor(options.client);
26105
+ const seq = ++caches.searchSeq;
26323
26106
  const q = trimmed.toLowerCase();
26324
26107
  const sessionMatches = (await loadSessionSkills(options)).filter(
26325
26108
  (skill) => skill.skill_id.toLowerCase().includes(q) || skill.description.toLowerCase().includes(q)
26326
26109
  ).map(toItem);
26327
26110
  await new Promise((resolve) => setTimeout(resolve, SEARCH_DEBOUNCE_MS));
26328
- if (seq !== caches2.searchSeq) return sessionMatches;
26111
+ if (seq !== caches.searchSeq) return sessionMatches;
26329
26112
  try {
26330
26113
  const seen = new Set(sessionMatches.map((item) => item.skillId));
26331
26114
  const { client, renderMode } = options;
@@ -26342,7 +26125,7 @@ async function getSkillSuggestions(query, options) {
26342
26125
  }
26343
26126
 
26344
26127
  // src/rich-input/ConnectButton.tsx
26345
- import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
26128
+ import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
26346
26129
  function ConnectButton({
26347
26130
  sessionId,
26348
26131
  open,
@@ -26352,7 +26135,8 @@ function ConnectButton({
26352
26135
  pendingPluginsDisabledReason,
26353
26136
  pendingComputers,
26354
26137
  onPendingComputersChange,
26355
- onPluginsChanged
26138
+ onPluginsChanged,
26139
+ variant = "icon"
26356
26140
  }) {
26357
26141
  const client = useBladeClient();
26358
26142
  const { ConnectorComputerSection, ConnectorAccountsSection } = useRichInputServices();
@@ -26368,60 +26152,73 @@ function ConnectButton({
26368
26152
  const summary = triggerSummary(triggerItems);
26369
26153
  const triggerCls = summary.total === 0 ? "w-9 p-0 text-[hsl(var(--muted-foreground))]" : summary.total === 1 ? "w-9 p-0" : "px-1";
26370
26154
  const selectedLabels = sessionId === null ? (pendingPlugins ?? []).map((item) => item.displayName?.trim() || item.name) : selectedItems.map((item) => item.display_name?.trim() || item.name);
26371
- return /* @__PURE__ */ jsxs6(dist_exports.Root, { open: isOpen, onOpenChange: setOpen, children: [
26372
- /* @__PURE__ */ jsx15(dist_exports.Trigger, { asChild: true, children: /* @__PURE__ */ jsx15(
26155
+ const panel = /* @__PURE__ */ jsx16(
26156
+ ConnectorPanel,
26157
+ {
26158
+ client,
26159
+ sessionId,
26160
+ pendingPlugins,
26161
+ onPendingPluginsChange,
26162
+ pendingDisabledReason: pendingPluginsDisabledReason,
26163
+ onPluginsChanged: () => {
26164
+ if (sessionId) {
26165
+ invalidateSlashSuggestions(client, sessionId);
26166
+ invalidation.pluginsChanged(sessionId);
26167
+ }
26168
+ onPluginsChanged?.();
26169
+ },
26170
+ onSelectedChange: setSelectedItems,
26171
+ renderComputerSection: ConnectorComputerSection ? (query) => /* @__PURE__ */ jsx16(
26172
+ ConnectorComputerSection,
26173
+ {
26174
+ sessionId,
26175
+ query,
26176
+ pendingSelection: pendingComputers,
26177
+ onPendingSelectionChange: onPendingComputersChange,
26178
+ closePanel: () => setOpen(false)
26179
+ }
26180
+ ) : void 0,
26181
+ renderExternalAccounts: ConnectorAccountsSection ? (query) => /* @__PURE__ */ jsx16(ConnectorAccountsSection, { query, closePanel: () => setOpen(false) }) : void 0
26182
+ }
26183
+ );
26184
+ if (variant === "submenu") {
26185
+ return /* @__PURE__ */ jsx16(
26186
+ InputActionSubmenu,
26187
+ {
26188
+ label: summary.total ? `\u8FDE\u63A5\u5668 \xB7 \u5DF2\u9009 ${summary.total}` : "\u8FDE\u63A5\u5668",
26189
+ icon: /* @__PURE__ */ jsx16(Plug, { size: 16, "aria-hidden": "true" }),
26190
+ open: isOpen,
26191
+ onOpenChange: setOpen,
26192
+ children: panel
26193
+ }
26194
+ );
26195
+ }
26196
+ return /* @__PURE__ */ jsxs7(dist_exports.Root, { open: isOpen, onOpenChange: setOpen, children: [
26197
+ /* @__PURE__ */ jsx16(dist_exports.Trigger, { asChild: true, children: /* @__PURE__ */ jsx16(
26373
26198
  "button",
26374
26199
  {
26375
26200
  type: "button",
26376
26201
  "aria-label": summary.total > 0 ? `\u8FDE\u63A5\u5668\uFF1A\u5DF2\u9009 ${summary.total} \u4E2A\u63D2\u4EF6` : "\u8FDE\u63A5\u5668",
26377
26202
  title: selectedLabels.length > 0 ? `\u8FDE\u63A5\u5668\uFF1A${selectedLabels.join("\u3001")}` : "\u8FDE\u63A5\u5668",
26378
26203
  className: `flex h-9 shrink-0 cursor-pointer items-center justify-center rounded-full border border-[hsl(var(--border))] transition-colors hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))] ${triggerCls}`,
26379
- children: summary.total === 0 ? /* @__PURE__ */ jsx15(Plug, { size: 14, "aria-hidden": "true" }) : /* @__PURE__ */ jsx15(PluginTriggerStack, { client, sessionId, summary })
26204
+ children: summary.total === 0 ? /* @__PURE__ */ jsx16(Plug, { size: 14, "aria-hidden": "true" }) : /* @__PURE__ */ jsx16(PluginTriggerStack, { client, sessionId, summary })
26380
26205
  }
26381
26206
  ) }),
26382
- /* @__PURE__ */ jsx15(dist_exports.Portal, { children: /* @__PURE__ */ jsx15(
26207
+ /* @__PURE__ */ jsx16(dist_exports.Portal, { children: /* @__PURE__ */ jsx16(
26383
26208
  dist_exports.Content,
26384
26209
  {
26385
26210
  side: "top",
26386
26211
  align: "start",
26387
26212
  sideOffset: 8,
26388
26213
  className: "z-50 w-[min(320px,calc(100vw-2rem))] origin-(--radix-popover-content-transform-origin) overflow-hidden rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] text-[11px] text-[hsl(var(--popover-foreground))] shadow-[var(--swf-shadow-overlay)] outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
26389
- children: /* @__PURE__ */ jsx15("div", { className: "max-h-[min(70vh,32rem)] overflow-y-auto", children: /* @__PURE__ */ jsx15(
26390
- ConnectorPanel,
26391
- {
26392
- client,
26393
- sessionId,
26394
- pendingPlugins,
26395
- onPendingPluginsChange,
26396
- pendingDisabledReason: pendingPluginsDisabledReason,
26397
- onPluginsChanged: () => {
26398
- if (sessionId) {
26399
- invalidateSlashSuggestions(client, sessionId);
26400
- invalidation.pluginsChanged(sessionId);
26401
- }
26402
- onPluginsChanged?.();
26403
- },
26404
- onSelectedChange: setSelectedItems,
26405
- renderComputerSection: ConnectorComputerSection ? (query) => /* @__PURE__ */ jsx15(
26406
- ConnectorComputerSection,
26407
- {
26408
- sessionId,
26409
- query,
26410
- pendingSelection: pendingComputers,
26411
- onPendingSelectionChange: onPendingComputersChange,
26412
- closePanel: () => setOpen(false)
26413
- }
26414
- ) : void 0,
26415
- renderExternalAccounts: ConnectorAccountsSection ? (query) => /* @__PURE__ */ jsx15(ConnectorAccountsSection, { query, closePanel: () => setOpen(false) }) : void 0
26416
- }
26417
- ) })
26214
+ children: /* @__PURE__ */ jsx16("div", { className: "max-h-[min(70vh,32rem)] overflow-y-auto", children: panel })
26418
26215
  }
26419
26216
  ) })
26420
26217
  ] });
26421
26218
  }
26422
26219
 
26423
26220
  // src/rich-input/voice/use-voice-input.ts
26424
- import { useCallback as useCallback3, useEffect as useEffect7, useRef as useRef7, useState as useState7 } from "react";
26221
+ import { useCallback as useCallback2, useEffect as useEffect6, useRef as useRef5, useState as useState7 } from "react";
26425
26222
 
26426
26223
  // src/rich-input/voice/voice-input-support.ts
26427
26224
  function isIpHost(hostname) {
@@ -26469,25 +26266,25 @@ function matchesRequest(data, requestId) {
26469
26266
  }
26470
26267
  function useVoiceInput(options) {
26471
26268
  const client = useBladeClient();
26472
- const clientRef = useRef7(client);
26269
+ const clientRef = useRef5(client);
26473
26270
  clientRef.current = client;
26474
- const getSocket = useCallback3(() => clientRef.current.socket(), []);
26271
+ const getSocket = useCallback2(() => clientRef.current.socket(), []);
26475
26272
  const [status, setStatus] = useState7("idle");
26476
26273
  const [error, setError] = useState7(null);
26477
26274
  const [level, setLevel] = useState7(0);
26478
- const sessionRef = useRef7(null);
26479
- const stoppingRef = useRef7(false);
26480
- const startAbortRef = useRef7(null);
26481
- const optionsRef = useRef7(options);
26275
+ const sessionRef = useRef5(null);
26276
+ const stoppingRef = useRef5(false);
26277
+ const startAbortRef = useRef5(null);
26278
+ const optionsRef = useRef5(options);
26482
26279
  optionsRef.current = options;
26483
- const reportError = useCallback3((err) => {
26280
+ const reportError = useCallback2((err) => {
26484
26281
  const payload = typeof err === "string" ? { title: err } : err;
26485
26282
  setError(payload.title);
26486
26283
  setStatus("error");
26487
26284
  setLevel(0);
26488
26285
  optionsRef.current.onError?.(payload);
26489
26286
  }, []);
26490
- const disposeSession = useCallback3((s) => {
26287
+ const disposeSession = useCallback2((s) => {
26491
26288
  if (s.disposed) return;
26492
26289
  s.disposed = true;
26493
26290
  const socket = getSocket();
@@ -26512,7 +26309,7 @@ function useVoiceInput(options) {
26512
26309
  } catch {
26513
26310
  }
26514
26311
  }, [getSocket]);
26515
- const stop = useCallback3(async () => {
26312
+ const stop = useCallback2(async () => {
26516
26313
  startAbortRef.current?.abort();
26517
26314
  const s = sessionRef.current;
26518
26315
  if (!s || stoppingRef.current) {
@@ -26559,7 +26356,7 @@ function useVoiceInput(options) {
26559
26356
  setLevel(0);
26560
26357
  setStatus((prev) => prev === "error" ? "error" : "idle");
26561
26358
  }, [disposeSession, getSocket]);
26562
- const start = useCallback3(async () => {
26359
+ const start = useCallback2(async () => {
26563
26360
  if (sessionRef.current || startAbortRef.current && !startAbortRef.current.signal.aborted || stoppingRef.current) {
26564
26361
  return;
26565
26362
  }
@@ -26733,7 +26530,7 @@ function useVoiceInput(options) {
26733
26530
  if (startAbortRef.current === abort) startAbortRef.current = null;
26734
26531
  }
26735
26532
  }, [reportError, disposeSession, getSocket]);
26736
- useEffect7(() => {
26533
+ useEffect6(() => {
26737
26534
  return () => {
26738
26535
  startAbortRef.current?.abort();
26739
26536
  const s = sessionRef.current;
@@ -26751,7 +26548,7 @@ function useVoiceInput(options) {
26751
26548
  }
26752
26549
 
26753
26550
  // src/rich-input/use-reference-candidates.ts
26754
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef8 } from "react";
26551
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef6 } from "react";
26755
26552
 
26756
26553
  // src/rich-input/lib/reference-candidates.ts
26757
26554
  function createReferenceCandidateController(getScope, sources, timeoutMs = 300) {
@@ -26849,7 +26646,7 @@ function useReferenceCandidates(getScope, sources) {
26849
26646
  const plugins = useEffectEvent((query) => sources.plugins?.(query) ?? Promise.resolve([]));
26850
26647
  const topics = useEffectEvent(sources.topics);
26851
26648
  const files = useEffectEvent(sources.files);
26852
- const ref = useRef8(null);
26649
+ const ref = useRef6(null);
26853
26650
  if (!ref.current) ref.current = createReferenceCandidateController(readScope, { plugins, topics, files });
26854
26651
  const controller = ref.current;
26855
26652
  const [client, identity, session, topic] = getScope();
@@ -26859,7 +26656,7 @@ function useReferenceCandidates(getScope, sources) {
26859
26656
  }
26860
26657
 
26861
26658
  // src/rich-input/use-input-history.ts
26862
- import { useCallback as useCallback4, useEffect as useEffect8, useMemo as useMemo7, useState as useState8 } from "react";
26659
+ import { useCallback as useCallback3, useEffect as useEffect7, useMemo as useMemo6, useState as useState8 } from "react";
26863
26660
 
26864
26661
  // src/rich-input/lib/input-history-document.ts
26865
26662
  import { normalizeTopicAssetRefs as normalizeTopicAssetRefs3 } from "@blade-hq/agent-client";
@@ -26949,17 +26746,17 @@ function readEntries(storageKey) {
26949
26746
  }
26950
26747
  function useInputHistory(sessionId, client) {
26951
26748
  const [generation, setGeneration] = useState8(getInputHistoryGeneration);
26952
- const storageKey = useMemo7(() => getStorageKey(sessionId), [sessionId]);
26749
+ const storageKey = useMemo6(() => getStorageKey(sessionId), [sessionId]);
26953
26750
  const [entries, setEntries] = useState8([]);
26954
26751
  const [cursor, setCursor] = useState8(null);
26955
26752
  const [draft, setDraft] = useState8(emptyEntry);
26956
- useEffect8(() => {
26753
+ useEffect7(() => {
26957
26754
  setGeneration(getInputHistoryGeneration());
26958
26755
  setEntries(readEntries(storageKey));
26959
26756
  setCursor(null);
26960
26757
  setDraft(emptyEntry());
26961
26758
  }, [storageKey, client]);
26962
- useEffect8(() => {
26759
+ useEffect7(() => {
26963
26760
  if (!client) return;
26964
26761
  return onInputCachesReset(client, () => {
26965
26762
  setGeneration(getInputHistoryGeneration());
@@ -26968,7 +26765,7 @@ function useInputHistory(sessionId, client) {
26968
26765
  setDraft(emptyEntry());
26969
26766
  });
26970
26767
  }, [client]);
26971
- const persistEntries = useCallback4(
26768
+ const persistEntries = useCallback3(
26972
26769
  (nextEntries) => {
26973
26770
  if (generation !== getInputHistoryGeneration() || typeof window === "undefined" || !storageKey) {
26974
26771
  return;
@@ -26980,7 +26777,7 @@ function useInputHistory(sessionId, client) {
26980
26777
  },
26981
26778
  [storageKey, generation]
26982
26779
  );
26983
- const addEntry = useCallback4(
26780
+ const addEntry = useCallback3(
26984
26781
  (value) => {
26985
26782
  if (generation !== getInputHistoryGeneration()) return;
26986
26783
  const document2 = copyEditorDocument(value);
@@ -26996,7 +26793,7 @@ function useInputHistory(sessionId, client) {
26996
26793
  },
26997
26794
  [persistEntries, generation]
26998
26795
  );
26999
- const navigateUp = useCallback4(
26796
+ const navigateUp = useCallback3(
27000
26797
  (currentDraft = emptyEntry().document) => {
27001
26798
  if (generation !== getInputHistoryGeneration() || entries.length === 0) {
27002
26799
  return null;
@@ -27010,7 +26807,7 @@ function useInputHistory(sessionId, client) {
27010
26807
  },
27011
26808
  [cursor, entries, generation]
27012
26809
  );
27013
- const navigateDown = useCallback4(() => {
26810
+ const navigateDown = useCallback3(() => {
27014
26811
  if (generation !== getInputHistoryGeneration() || cursor == null) {
27015
26812
  return null;
27016
26813
  }
@@ -27092,7 +26889,7 @@ function getUnsupportedImageFiles(files, supportsImage) {
27092
26889
  }
27093
26890
 
27094
26891
  // src/rich-input/FileCompletionMenu.tsx
27095
- import { forwardRef as forwardRef2, useCallback as useCallback5, useImperativeHandle, useMemo as useMemo8, useState as useState9 } from "react";
26892
+ import { forwardRef as forwardRef2, useCallback as useCallback4, useImperativeHandle, useMemo as useMemo7, useState as useState9 } from "react";
27096
26893
 
27097
26894
  // src/rich-input/lib/user-home.ts
27098
26895
  var CACHE_TTL_MS2 = 15e3;
@@ -27100,12 +26897,12 @@ var cachesByClient2 = /* @__PURE__ */ new WeakMap();
27100
26897
  function cachesFor2(client) {
27101
26898
  const existing = cachesByClient2.get(client);
27102
26899
  if (existing) return existing;
27103
- const caches2 = { dirs: /* @__PURE__ */ new Map() };
27104
- cachesByClient2.set(client, caches2);
26900
+ const caches = { dirs: /* @__PURE__ */ new Map() };
26901
+ cachesByClient2.set(client, caches);
27105
26902
  onInputCachesReset(client, () => {
27106
- if (cachesByClient2.get(client) === caches2) cachesByClient2.delete(client);
26903
+ if (cachesByClient2.get(client) === caches) cachesByClient2.delete(client);
27107
26904
  });
27108
- return caches2;
26905
+ return caches;
27109
26906
  }
27110
26907
  function listUserHomeDir(client, dirPath) {
27111
26908
  const { dirs } = cachesFor2(client);
@@ -27120,7 +26917,7 @@ function listUserHomeDir(client, dirPath) {
27120
26917
  }
27121
26918
 
27122
26919
  // src/rich-input/FileCompletionMenu.tsx
27123
- import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
26920
+ import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
27124
26921
  var ROOT_DIR = ".";
27125
26922
  function installSuggestionOutsideDismiss(container, onDismiss) {
27126
26923
  const onPointerDown = (event) => {
@@ -27248,11 +27045,11 @@ async function getUserHomeSuggestionItems(client, query) {
27248
27045
  var FileCompletionMenu = forwardRef2(
27249
27046
  function FileCompletionMenu2({ command: command2, editor, items, onExit, query, range, scope = "session", sessionId: sessionIdProp }, ref) {
27250
27047
  const sessionId = sessionIdProp ?? null;
27251
- const { dirPath, filterQuery } = useMemo8(
27048
+ const { dirPath, filterQuery } = useMemo7(
27252
27049
  () => scope === "userHome" ? { dirPath: query, filterQuery: "" } : parseSuggestionQuery(query),
27253
27050
  [query, scope]
27254
27051
  );
27255
- const { pluginItems, pluginError, fileItems, topicItems, topicError } = useMemo8(() => {
27052
+ const { pluginItems, pluginError, fileItems, topicItems, topicError } = useMemo7(() => {
27256
27053
  let pluginError2;
27257
27054
  const pluginItems2 = [];
27258
27055
  const files = [];
@@ -27267,7 +27064,7 @@ var FileCompletionMenu = forwardRef2(
27267
27064
  }
27268
27065
  return { pluginItems: pluginItems2, pluginError: pluginError2, fileItems: files, topicItems: topicItems2, topicError: topicError2 };
27269
27066
  }, [items]);
27270
- return /* @__PURE__ */ jsx16(
27067
+ return /* @__PURE__ */ jsx17(
27271
27068
  FileCompletionMenuContent,
27272
27069
  {
27273
27070
  ref,
@@ -27290,13 +27087,13 @@ var FileCompletionMenu = forwardRef2(
27290
27087
  );
27291
27088
  var FileCompletionMenuContent = forwardRef2(function FileCompletionMenuContent2({ command: command2, editor, filterQuery, items, pluginItems, pluginError, topicItems, topicError, onExit, range, scope, sessionId }, ref) {
27292
27089
  const [rawSelectedIndex, setRawSelectedIndex] = useState9(0);
27293
- const filteredEntries = useMemo8(() => filterEntries(items, filterQuery), [filterQuery, items]);
27294
- const navigableItems = useMemo8(
27090
+ const filteredEntries = useMemo7(() => filterEntries(items, filterQuery), [filterQuery, items]);
27091
+ const navigableItems = useMemo7(
27295
27092
  () => [...pluginItems, ...topicItems, ...filteredEntries],
27296
27093
  [filteredEntries, pluginItems, topicItems]
27297
27094
  );
27298
27095
  const selectedIndex = navigableItems.length === 0 ? 0 : Math.min(rawSelectedIndex, navigableItems.length - 1);
27299
- const handleSelect = useCallback5(
27096
+ const handleSelect = useCallback4(
27300
27097
  (entry) => {
27301
27098
  if (isPluginSuggestionItem(entry) || isTopicAssetSuggestionItem(entry)) {
27302
27099
  command2(entry);
@@ -27361,9 +27158,9 @@ var FileCompletionMenuContent = forwardRef2(function FileCompletionMenuContent2(
27361
27158
  };
27362
27159
  const showGroupLabels = pluginItems.length > 0 || topicItems.length > 0 || Boolean(topicError);
27363
27160
  const fileEmptyLabel = scope === "session" && !sessionId ? "\u6682\u65E0\u4F1A\u8BDD" : filteredEntries.length === 0 ? "\u6CA1\u6709\u6587\u4EF6" : null;
27364
- return /* @__PURE__ */ jsxs7("div", { className: "max-h-64 overflow-y-auto rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] py-1 shadow-[var(--swf-shadow-overlay)]", children: [
27365
- pluginError ? /* @__PURE__ */ jsx16("output", { className: "block px-3 py-2 text-xs text-muted-foreground", children: pluginError }) : null,
27366
- pluginItems.map((item, index) => /* @__PURE__ */ jsxs7(
27161
+ return /* @__PURE__ */ jsxs8("div", { className: "max-h-64 overflow-y-auto rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] py-1 shadow-[var(--swf-shadow-overlay)]", children: [
27162
+ pluginError ? /* @__PURE__ */ jsx17("output", { className: "block px-3 py-2 text-xs text-muted-foreground", children: pluginError }) : null,
27163
+ pluginItems.map((item, index) => /* @__PURE__ */ jsxs8(
27367
27164
  "button",
27368
27165
  {
27369
27166
  ref: selectedRef(index),
@@ -27374,31 +27171,31 @@ var FileCompletionMenuContent = forwardRef2(function FileCompletionMenuContent2(
27374
27171
  handleSelect(item);
27375
27172
  },
27376
27173
  children: [
27377
- item.icon ? /* @__PURE__ */ jsx16("img", { src: item.icon, alt: "", width: 16, height: 16, className: "shrink-0" }) : /* @__PURE__ */ jsx16(BookOpen, { size: 14 }),
27378
- /* @__PURE__ */ jsx16("span", { className: "truncate", children: item.label }),
27379
- /* @__PURE__ */ jsx16("span", { className: "ml-auto truncate text-xs text-muted-foreground", children: item.display_name })
27174
+ item.icon ? /* @__PURE__ */ jsx17("img", { src: item.icon, alt: "", width: 16, height: 16, className: "shrink-0" }) : /* @__PURE__ */ jsx17(BookOpen, { size: 14 }),
27175
+ /* @__PURE__ */ jsx17("span", { className: "truncate", children: item.label }),
27176
+ /* @__PURE__ */ jsx17("span", { className: "ml-auto truncate text-xs text-muted-foreground", children: item.display_name })
27380
27177
  ]
27381
27178
  },
27382
27179
  `${item.plugin}:${item.server}:${item.id}`
27383
27180
  )),
27384
- topicItems.length > 0 || topicError ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
27385
- /* @__PURE__ */ jsx16("div", { className: "px-3 pt-1 pb-0.5 text-xs font-medium text-muted-foreground", children: "\u4E3B\u9898\u8D44\u4EA7" }),
27386
- topicError ? /* @__PURE__ */ jsx16("output", { className: "block px-3 py-2 text-xs text-muted-foreground", children: topicError }) : null,
27181
+ topicItems.length > 0 || topicError ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
27182
+ /* @__PURE__ */ jsx17("div", { className: "px-3 pt-1 pb-0.5 text-xs font-medium text-muted-foreground", children: "\u5DE5\u4F5C\u7A7A\u95F4\u8D44\u4EA7" }),
27183
+ topicError ? /* @__PURE__ */ jsx17("output", { className: "block px-3 py-2 text-xs text-muted-foreground", children: topicError }) : null,
27387
27184
  topicItems.map((item, topicIndex) => {
27388
27185
  const index = pluginItems.length + topicIndex;
27389
- return /* @__PURE__ */ jsxs7("button", { ref: selectedRef(index), type: "button", title: item.path, className: rowClassName(index), onMouseDown: (event) => {
27186
+ return /* @__PURE__ */ jsxs8("button", { ref: selectedRef(index), type: "button", title: item.path, className: rowClassName(index), onMouseDown: (event) => {
27390
27187
  event.preventDefault();
27391
27188
  handleSelect(item);
27392
27189
  }, children: [
27393
- /* @__PURE__ */ jsx16(File, { size: 14, className: "shrink-0 text-muted-foreground" }),
27394
- /* @__PURE__ */ jsx16("span", { className: "truncate", children: item.path })
27190
+ /* @__PURE__ */ jsx17(File, { size: 14, className: "shrink-0 text-muted-foreground" }),
27191
+ /* @__PURE__ */ jsx17("span", { className: "truncate", children: item.path })
27395
27192
  ] }, `${item.topic_id}:${item.path}`);
27396
27193
  })
27397
27194
  ] }) : null,
27398
- showGroupLabels ? /* @__PURE__ */ jsx16("div", { className: "px-3 pt-1 pb-0.5 text-[10px] font-medium uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u6587\u4EF6" }) : null,
27399
- fileEmptyLabel ? /* @__PURE__ */ jsx16("div", { className: "px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: fileEmptyLabel }) : filteredEntries.map((entry, fileIndex) => {
27195
+ showGroupLabels ? /* @__PURE__ */ jsx17("div", { className: "px-3 pt-1 pb-0.5 text-[10px] font-medium uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u6587\u4EF6" }) : null,
27196
+ fileEmptyLabel ? /* @__PURE__ */ jsx17("div", { className: "px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: fileEmptyLabel }) : filteredEntries.map((entry, fileIndex) => {
27400
27197
  const index = pluginItems.length + topicItems.length + fileIndex;
27401
- return /* @__PURE__ */ jsxs7(
27198
+ return /* @__PURE__ */ jsxs8(
27402
27199
  "button",
27403
27200
  {
27404
27201
  ref: selectedRef(index),
@@ -27409,9 +27206,9 @@ var FileCompletionMenuContent = forwardRef2(function FileCompletionMenuContent2(
27409
27206
  },
27410
27207
  className: rowClassName(index),
27411
27208
  children: [
27412
- entry.is_dir ? /* @__PURE__ */ jsx16(Folder, { size: 14, className: "shrink-0 text-[hsl(var(--primary))]" }) : /* @__PURE__ */ jsx16(File, { size: 14, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
27413
- /* @__PURE__ */ jsx16("span", { className: "truncate", children: entry.name }),
27414
- entry.is_dir && /* @__PURE__ */ jsx16(ChevronRight, { size: 12, className: "ml-auto shrink-0 opacity-40" })
27209
+ entry.is_dir ? /* @__PURE__ */ jsx17(Folder, { size: 14, className: "shrink-0 text-[hsl(var(--primary))]" }) : /* @__PURE__ */ jsx17(File, { size: 14, className: "shrink-0 text-[hsl(var(--muted-foreground))]" }),
27210
+ /* @__PURE__ */ jsx17("span", { className: "truncate", children: entry.name }),
27211
+ entry.is_dir && /* @__PURE__ */ jsx17(ChevronRight, { size: 12, className: "ml-auto shrink-0 opacity-40" })
27415
27212
  ]
27416
27213
  },
27417
27214
  entry.path
@@ -27421,13 +27218,13 @@ var FileCompletionMenuContent = forwardRef2(function FileCompletionMenuContent2(
27421
27218
  });
27422
27219
 
27423
27220
  // src/rich-input/SkillCompletionMenu.tsx
27424
- import { forwardRef as forwardRef3, useCallback as useCallback6, useImperativeHandle as useImperativeHandle2, useState as useState10 } from "react";
27425
- import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
27221
+ import { forwardRef as forwardRef3, useCallback as useCallback5, useImperativeHandle as useImperativeHandle2, useState as useState10 } from "react";
27222
+ import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
27426
27223
  var SkillCompletionMenu = forwardRef3(
27427
27224
  function SkillCompletionMenu2({ command: command2, items }, ref) {
27428
27225
  const [rawSelectedIndex, setRawSelectedIndex] = useState10(0);
27429
27226
  const selectedIndex = items.length === 0 ? 0 : Math.min(rawSelectedIndex, items.length - 1);
27430
- const handleSelect = useCallback6(
27227
+ const handleSelect = useCallback5(
27431
27228
  (item) => {
27432
27229
  command2(item);
27433
27230
  },
@@ -27469,10 +27266,10 @@ var SkillCompletionMenu = forwardRef3(
27469
27266
  );
27470
27267
  const commandItems = items.filter((item) => item.type === "command");
27471
27268
  const skillItems = items.filter((item) => item.type === "skill");
27472
- return /* @__PURE__ */ jsx17("div", { className: "max-h-64 overflow-y-auto rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] py-1 shadow-[var(--swf-shadow-overlay)]", children: items.length === 0 ? /* @__PURE__ */ jsx17("div", { className: "px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6CA1\u6709\u5339\u914D\u7684\u547D\u4EE4\u6216\u6280\u80FD" }) : /* @__PURE__ */ jsxs8("div", { children: [
27473
- commandItems.length > 0 ? /* @__PURE__ */ jsxs8("div", { className: "px-2 pb-1 pt-1", children: [
27474
- /* @__PURE__ */ jsx17("div", { className: "px-1 pb-1 text-[10px] font-semibold uppercase tracking-[0.08em] text-[hsl(var(--muted-foreground))]", children: "\u547D\u4EE4" }),
27475
- commandItems.map((item, index) => /* @__PURE__ */ jsxs8(
27269
+ return /* @__PURE__ */ jsx18("div", { className: "max-h-64 overflow-y-auto rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] py-1 shadow-[var(--swf-shadow-overlay)]", children: items.length === 0 ? /* @__PURE__ */ jsx18("div", { className: "px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6CA1\u6709\u5339\u914D\u7684\u547D\u4EE4\u6216\u6280\u80FD" }) : /* @__PURE__ */ jsxs9("div", { children: [
27270
+ commandItems.length > 0 ? /* @__PURE__ */ jsxs9("div", { className: "px-2 pb-1 pt-1", children: [
27271
+ /* @__PURE__ */ jsx18("div", { className: "px-1 pb-1 text-[10px] font-semibold uppercase tracking-[0.08em] text-[hsl(var(--muted-foreground))]", children: "\u547D\u4EE4" }),
27272
+ commandItems.map((item, index) => /* @__PURE__ */ jsxs9(
27476
27273
  "button",
27477
27274
  {
27478
27275
  ref: (element) => {
@@ -27487,21 +27284,21 @@ var SkillCompletionMenu = forwardRef3(
27487
27284
  },
27488
27285
  className: `flex w-full items-start gap-2 rounded-lg px-2 py-1.5 text-left transition-colors ${index === selectedIndex ? "bg-[hsl(var(--accent))] text-[hsl(var(--accent-foreground))]" : "text-[hsl(var(--popover-foreground))] hover:bg-[hsl(var(--accent))]"}`,
27489
27286
  children: [
27490
- /* @__PURE__ */ jsx17("span", { className: "pt-0.5 text-sm", children: "\u21BB" }),
27491
- /* @__PURE__ */ jsxs8("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
27492
- /* @__PURE__ */ jsx17("span", { className: "text-sm font-medium", children: item.label }),
27493
- /* @__PURE__ */ jsx17("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: item.description })
27287
+ /* @__PURE__ */ jsx18("span", { className: "pt-0.5 text-sm", children: "\u21BB" }),
27288
+ /* @__PURE__ */ jsxs9("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
27289
+ /* @__PURE__ */ jsx18("span", { className: "text-sm font-medium", children: item.label }),
27290
+ /* @__PURE__ */ jsx18("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: item.description })
27494
27291
  ] })
27495
27292
  ]
27496
27293
  },
27497
27294
  item.id
27498
27295
  ))
27499
27296
  ] }) : null,
27500
- skillItems.length > 0 ? /* @__PURE__ */ jsxs8("div", { className: "px-2 pb-1 pt-1", children: [
27501
- /* @__PURE__ */ jsx17("div", { className: "px-1 pb-1 text-[10px] font-semibold uppercase tracking-[0.08em] text-[hsl(var(--muted-foreground))]", children: "\u6280\u80FD" }),
27297
+ skillItems.length > 0 ? /* @__PURE__ */ jsxs9("div", { className: "px-2 pb-1 pt-1", children: [
27298
+ /* @__PURE__ */ jsx18("div", { className: "px-1 pb-1 text-[10px] font-semibold uppercase tracking-[0.08em] text-[hsl(var(--muted-foreground))]", children: "\u6280\u80FD" }),
27502
27299
  skillItems.map((item, skillIndex) => {
27503
27300
  const index = commandItems.length + skillIndex;
27504
- return /* @__PURE__ */ jsxs8(
27301
+ return /* @__PURE__ */ jsxs9(
27505
27302
  "button",
27506
27303
  {
27507
27304
  ref: (element) => {
@@ -27516,9 +27313,9 @@ var SkillCompletionMenu = forwardRef3(
27516
27313
  },
27517
27314
  className: `flex w-full flex-col gap-0.5 rounded-lg px-2 py-1.5 text-left transition-colors ${index === selectedIndex ? "bg-[hsl(var(--accent))] text-[hsl(var(--accent-foreground))]" : "text-[hsl(var(--popover-foreground))] hover:bg-[hsl(var(--accent))]"}`,
27518
27315
  children: [
27519
- /* @__PURE__ */ jsxs8("span", { className: "flex items-center gap-1.5", children: [
27520
- /* @__PURE__ */ jsx17("span", { className: "text-sm font-medium", children: skillDisplayName(item) }),
27521
- item.hasFlow ? /* @__PURE__ */ jsx17(
27316
+ /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-1.5", children: [
27317
+ /* @__PURE__ */ jsx18("span", { className: "text-sm font-medium", children: skillDisplayName(item) }),
27318
+ item.hasFlow ? /* @__PURE__ */ jsx18(
27522
27319
  "span",
27523
27320
  {
27524
27321
  title: "\u8FD9\u4E2A\u6280\u80FD\u6309\u56FA\u5B9A\u6D41\u7A0B\u6267\u884C:\u6B65\u9AA4\u4E8B\u5148\u7F16\u6392\u597D,\u8FD0\u884C\u4E2D\u4E0D\u4F1A\u5373\u5174\u53D1\u6325,\u4E5F\u4E0D\u4F1A\u4E2D\u9014\u95EE\u4F60",
@@ -27526,9 +27323,9 @@ var SkillCompletionMenu = forwardRef3(
27526
27323
  children: "\u26A1 \u56FA\u5B9A\u6D41\u7A0B"
27527
27324
  }
27528
27325
  ) : null,
27529
- item.installed === false ? /* @__PURE__ */ jsx17("span", { className: "shrink-0 rounded-full bg-[hsl(var(--muted))] px-1.5 py-px text-[10px] text-[hsl(var(--muted-foreground))]", children: "\u672A\u5B89\u88C5" }) : null
27326
+ item.installed === false ? /* @__PURE__ */ jsx18("span", { className: "shrink-0 rounded-full bg-[hsl(var(--muted))] px-1.5 py-px text-[10px] text-[hsl(var(--muted-foreground))]", children: "\u672A\u5B89\u88C5" }) : null
27530
27327
  ] }),
27531
- /* @__PURE__ */ jsx17("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: item.description })
27328
+ /* @__PURE__ */ jsx18("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: item.description })
27532
27329
  ]
27533
27330
  },
27534
27331
  item.skillId
@@ -27540,7 +27337,7 @@ var SkillCompletionMenu = forwardRef3(
27540
27337
  );
27541
27338
 
27542
27339
  // src/rich-input/FileSizeLimitDialog.tsx
27543
- import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
27340
+ import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
27544
27341
  function FileSizeLimitDialog({
27545
27342
  open,
27546
27343
  onOpenChange,
@@ -27551,37 +27348,37 @@ function FileSizeLimitDialog({
27551
27348
  return null;
27552
27349
  }
27553
27350
  const limitText = formatFileSize(limitBytes);
27554
- return /* @__PURE__ */ jsx18(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs9(DialogContent, { showCloseButton: false, className: "w-full max-w-lg gap-0 p-0", children: [
27555
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3", children: [
27556
- /* @__PURE__ */ jsxs9("div", { children: [
27557
- /* @__PURE__ */ jsx18(DialogTitle, { className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u9644\u4EF6\u8D85\u8FC7\u5927\u5C0F\u9650\u5236" }),
27558
- /* @__PURE__ */ jsxs9("p", { className: "mt-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
27351
+ return /* @__PURE__ */ jsx19(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs10(DialogContent, { showCloseButton: false, className: "w-full max-w-lg gap-0 p-0", children: [
27352
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-4 py-3", children: [
27353
+ /* @__PURE__ */ jsxs10("div", { children: [
27354
+ /* @__PURE__ */ jsx19(DialogTitle, { className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u9644\u4EF6\u8D85\u8FC7\u5927\u5C0F\u9650\u5236" }),
27355
+ /* @__PURE__ */ jsxs10("p", { className: "mt-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
27559
27356
  "\u5355\u4E2A\u9644\u4EF6\u6700\u5927\u652F\u6301 ",
27560
27357
  limitText,
27561
27358
  "\u3002\u4EE5\u4E0B\u6587\u4EF6\u672A\u52A0\u5165\u9644\u4EF6\u5217\u8868\u3002"
27562
27359
  ] })
27563
27360
  ] }),
27564
- /* @__PURE__ */ jsx18(
27361
+ /* @__PURE__ */ jsx19(
27565
27362
  DialogClose,
27566
27363
  {
27567
27364
  title: "\u5173\u95ED",
27568
27365
  className: "flex h-7 w-7 items-center justify-center rounded-md text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
27569
- children: /* @__PURE__ */ jsx18(X, { size: 14 })
27366
+ children: /* @__PURE__ */ jsx19(X, { size: 14 })
27570
27367
  }
27571
27368
  )
27572
27369
  ] }),
27573
- /* @__PURE__ */ jsx18("div", { className: "max-h-[min(50vh,24rem)] overflow-auto px-4 py-3", children: /* @__PURE__ */ jsx18("div", { className: "flex flex-col gap-2", children: files.map((file) => /* @__PURE__ */ jsxs9(
27370
+ /* @__PURE__ */ jsx19("div", { className: "max-h-[min(50vh,24rem)] overflow-auto px-4 py-3", children: /* @__PURE__ */ jsx19("div", { className: "flex flex-col gap-2", children: files.map((file) => /* @__PURE__ */ jsxs10(
27574
27371
  "div",
27575
27372
  {
27576
27373
  className: "flex items-center justify-between gap-3 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--accent))] px-3 py-2",
27577
27374
  children: [
27578
- /* @__PURE__ */ jsx18("span", { className: "min-w-0 truncate text-sm text-[hsl(var(--foreground))]", children: file.name }),
27579
- /* @__PURE__ */ jsx18("span", { className: "shrink-0 text-xs text-[hsl(var(--muted-foreground))]", children: formatFileSize(file.size) })
27375
+ /* @__PURE__ */ jsx19("span", { className: "min-w-0 truncate text-sm text-[hsl(var(--foreground))]", children: file.name }),
27376
+ /* @__PURE__ */ jsx19("span", { className: "shrink-0 text-xs text-[hsl(var(--muted-foreground))]", children: formatFileSize(file.size) })
27580
27377
  ]
27581
27378
  },
27582
27379
  `${file.name}:${file.size}`
27583
27380
  )) }) }),
27584
- /* @__PURE__ */ jsx18("div", { className: "flex justify-end border-t border-[hsl(var(--border))] px-4 py-3", children: /* @__PURE__ */ jsx18(
27381
+ /* @__PURE__ */ jsx19("div", { className: "flex justify-end border-t border-[hsl(var(--border))] px-4 py-3", children: /* @__PURE__ */ jsx19(
27585
27382
  "button",
27586
27383
  {
27587
27384
  type: "button",
@@ -27659,7 +27456,7 @@ function reasoningLevelLabel(level) {
27659
27456
  }
27660
27457
 
27661
27458
  // src/rich-input/ReasoningModeSelect.tsx
27662
- import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
27459
+ import { jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
27663
27460
  function ReasoningModeSelect({
27664
27461
  level,
27665
27462
  levels,
@@ -27667,11 +27464,11 @@ function ReasoningModeSelect({
27667
27464
  disabledReason,
27668
27465
  onChange
27669
27466
  }) {
27670
- return /* @__PURE__ */ jsxs10("label", { className: "flex w-full flex-col gap-1 px-3 py-2", children: [
27671
- /* @__PURE__ */ jsxs10("span", { className: "flex w-full items-center gap-2", children: [
27672
- /* @__PURE__ */ jsx19(Brain, { size: 14, className: `shrink-0 ${chatTone("reasoning").text}`, "aria-hidden": "true" }),
27673
- /* @__PURE__ */ jsx19("span", { className: "shrink-0", children: "\u601D\u8003\u6A21\u5F0F" }),
27674
- /* @__PURE__ */ jsx19(
27467
+ return /* @__PURE__ */ jsxs11("label", { className: "flex w-full flex-col gap-1 px-3 py-2", children: [
27468
+ /* @__PURE__ */ jsxs11("span", { className: "flex w-full items-center gap-2", children: [
27469
+ /* @__PURE__ */ jsx20(Brain, { size: 14, className: `shrink-0 ${chatTone("reasoning").text}`, "aria-hidden": "true" }),
27470
+ /* @__PURE__ */ jsx20("span", { className: "shrink-0", children: "\u601D\u8003\u6A21\u5F0F" }),
27471
+ /* @__PURE__ */ jsx20(
27675
27472
  "select",
27676
27473
  {
27677
27474
  value: level,
@@ -27680,18 +27477,18 @@ function ReasoningModeSelect({
27680
27477
  "aria-label": "\u601D\u8003\u6A21\u5F0F",
27681
27478
  title: "\u9009\u62E9\u601D\u8003\u6863\u4F4D\u3002\u6863\u4F4D\u8D8A\u9AD8\uFF0C\u6A21\u578B\u601D\u8003\u8D8A\u6DF1\u5165\uFF0C\u4F46\u54CD\u5E94\u53EF\u80FD\u66F4\u6162",
27682
27479
  className: "ml-auto h-6 min-w-20 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--background))] px-1.5 disabled:cursor-not-allowed disabled:opacity-50",
27683
- children: levels.map((item) => /* @__PURE__ */ jsx19("option", { value: item, children: reasoningLevelLabel(item) }, item))
27480
+ children: levels.map((item) => /* @__PURE__ */ jsx20("option", { value: item, children: reasoningLevelLabel(item) }, item))
27684
27481
  }
27685
27482
  )
27686
27483
  ] }),
27687
- disabled && disabledReason ? /* @__PURE__ */ jsx19("span", { className: "pl-[22px] text-xs text-[hsl(var(--muted-foreground))]", children: disabledReason }) : null
27484
+ disabled && disabledReason ? /* @__PURE__ */ jsx20("span", { className: "pl-[22px] text-xs text-[hsl(var(--muted-foreground))]", children: disabledReason }) : null
27688
27485
  ] });
27689
27486
  }
27690
27487
 
27691
27488
  // src/rich-input/PlanningToggle.tsx
27692
- import { jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
27489
+ import { jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
27693
27490
  function PlanningToggle({ enabled, onChange, disabled }) {
27694
- return /* @__PURE__ */ jsxs11(
27491
+ return /* @__PURE__ */ jsxs12(
27695
27492
  "button",
27696
27493
  {
27697
27494
  type: "button",
@@ -27703,18 +27500,18 @@ function PlanningToggle({ enabled, onChange, disabled }) {
27703
27500
  disabled,
27704
27501
  className: "flex w-full items-center justify-between gap-3 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))] disabled:cursor-not-allowed disabled:opacity-50",
27705
27502
  children: [
27706
- /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-2", children: [
27707
- /* @__PURE__ */ jsx20(Lightbulb, { size: 14, className: "text-[#F97316]", "aria-hidden": "true" }),
27503
+ /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-2", children: [
27504
+ /* @__PURE__ */ jsx21(Lightbulb, { size: 14, className: "text-[#F97316]", "aria-hidden": "true" }),
27708
27505
  "\u89C4\u5212\u6A21\u5F0F"
27709
27506
  ] }),
27710
- /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-2", children: [
27711
- /* @__PURE__ */ jsx20("span", { className: "text-[hsl(var(--muted-foreground))]", children: enabled ? "\u5F00" : "\u5173" }),
27712
- /* @__PURE__ */ jsx20(
27507
+ /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-2", children: [
27508
+ /* @__PURE__ */ jsx21("span", { className: "text-[hsl(var(--muted-foreground))]", children: enabled ? "\u5F00" : "\u5173" }),
27509
+ /* @__PURE__ */ jsx21(
27713
27510
  "span",
27714
27511
  {
27715
27512
  className: `flex h-4 w-7 items-center rounded-full p-0.5 transition-colors ${enabled ? "justify-end bg-[hsl(var(--primary))]" : "justify-start bg-[hsl(var(--muted))]"}`,
27716
27513
  "aria-hidden": "true",
27717
- children: /* @__PURE__ */ jsx20("span", { className: "h-3 w-3 rounded-full bg-[hsl(var(--background))]" })
27514
+ children: /* @__PURE__ */ jsx21("span", { className: "h-3 w-3 rounded-full bg-[hsl(var(--background))]" })
27718
27515
  }
27719
27516
  )
27720
27517
  ] })
@@ -27735,12 +27532,12 @@ function shouldHandleHistoryKey(event, menuOpen) {
27735
27532
  }
27736
27533
 
27737
27534
  // src/rich-input/ComposerAttachmentViewport.tsx
27738
- import { jsx as jsx21 } from "react/jsx-runtime";
27535
+ import { jsx as jsx23 } from "react/jsx-runtime";
27739
27536
  function ComposerAttachmentViewport({
27740
27537
  className,
27741
27538
  ...props
27742
27539
  }) {
27743
- return /* @__PURE__ */ jsx21(
27540
+ return /* @__PURE__ */ jsx23(
27744
27541
  "div",
27745
27542
  {
27746
27543
  className: cn("min-h-0 max-h-40 overflow-y-auto overscroll-contain", className),
@@ -27750,7 +27547,7 @@ function ComposerAttachmentViewport({
27750
27547
  }
27751
27548
 
27752
27549
  // src/rich-input/ChatInput.tsx
27753
- import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
27550
+ import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
27754
27551
  var RECENT_SESSION_LIMIT = 50;
27755
27552
  var DOUBLE_ESCAPE_MS = 450;
27756
27553
  function getEditorText(editor) {
@@ -27921,31 +27718,31 @@ function ComposerFilePill({
27921
27718
  const isFailed = isFile && attachment.status === "failed";
27922
27719
  const isUploading = isFile && attachment.status === "uploading";
27923
27720
  const uploadPercent = isUploading && typeof attachment.uploadProgress === "number" ? Math.max(0, Math.min(100, Math.round(attachment.uploadProgress * 100))) : null;
27924
- return /* @__PURE__ */ jsxs12(
27721
+ return /* @__PURE__ */ jsxs13(
27925
27722
  "div",
27926
27723
  {
27927
27724
  className: `relative flex shrink-0 items-center gap-1.5 overflow-hidden rounded-full border px-2.5 py-1 text-[11px] ${isFailed ? "border-[hsl(var(--swf-danger)/0.3)] bg-[hsl(var(--swf-danger-soft))] text-[hsl(var(--swf-danger))]" : "border-[hsl(var(--border))] bg-[hsl(var(--card))] text-[hsl(var(--foreground))]"}`,
27928
27725
  children: [
27929
- uploadPercent !== null ? /* @__PURE__ */ jsx23(
27726
+ uploadPercent !== null ? /* @__PURE__ */ jsx24(
27930
27727
  "span",
27931
27728
  {
27932
27729
  className: "absolute inset-y-0 left-0 bg-[hsl(var(--primary))]/10 transition-[width]",
27933
27730
  style: { width: `${uploadPercent}%` }
27934
27731
  }
27935
27732
  ) : null,
27936
- isUploading ? /* @__PURE__ */ jsx23(
27733
+ isUploading ? /* @__PURE__ */ jsx24(
27937
27734
  LoaderCircle,
27938
27735
  {
27939
27736
  size: 12,
27940
27737
  className: "relative z-10 shrink-0 animate-spin text-[hsl(var(--muted-foreground))]"
27941
27738
  }
27942
- ) : /* @__PURE__ */ jsx23(Icon, { size: 12, className: "relative z-10 shrink-0 text-[hsl(var(--muted-foreground))]" }),
27943
- /* @__PURE__ */ jsx23("span", { className: "relative z-10 max-w-32 truncate", children: attachment.name }),
27944
- uploadPercent !== null ? /* @__PURE__ */ jsxs12("span", { className: "relative z-10 font-mono text-[10px] tabular-nums text-[hsl(var(--muted-foreground))]", children: [
27739
+ ) : /* @__PURE__ */ jsx24(Icon, { size: 12, className: "relative z-10 shrink-0 text-[hsl(var(--muted-foreground))]" }),
27740
+ /* @__PURE__ */ jsx24("span", { className: "relative z-10 max-w-32 truncate", children: attachment.name }),
27741
+ uploadPercent !== null ? /* @__PURE__ */ jsxs13("span", { className: "relative z-10 font-mono text-[10px] tabular-nums text-[hsl(var(--muted-foreground))]", children: [
27945
27742
  uploadPercent,
27946
27743
  "%"
27947
27744
  ] }) : null,
27948
- /* @__PURE__ */ jsx23(
27745
+ /* @__PURE__ */ jsx24(
27949
27746
  "button",
27950
27747
  {
27951
27748
  type: "button",
@@ -27953,7 +27750,7 @@ function ComposerFilePill({
27953
27750
  "aria-label": `\u79FB\u9664 ${attachment.name}`,
27954
27751
  title: "\u79FB\u9664",
27955
27752
  className: "relative z-10 ml-0.5 inline-flex shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition hover:text-[hsl(var(--swf-danger))]",
27956
- children: /* @__PURE__ */ jsx23(X, { size: 10 })
27753
+ children: /* @__PURE__ */ jsx24(X, { size: 10 })
27957
27754
  }
27958
27755
  )
27959
27756
  ]
@@ -28076,7 +27873,7 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
28076
27873
  setImportingId(null);
28077
27874
  }
28078
27875
  };
28079
- return /* @__PURE__ */ jsx23(
27876
+ return /* @__PURE__ */ jsx24(
28080
27877
  "div",
28081
27878
  {
28082
27879
  className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/55 p-4",
@@ -28084,44 +27881,44 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
28084
27881
  onKeyDown: (e) => {
28085
27882
  if (e.key === "Escape") onClose();
28086
27883
  },
28087
- children: /* @__PURE__ */ jsxs12(
27884
+ children: /* @__PURE__ */ jsxs13(
28088
27885
  "div",
28089
27886
  {
28090
27887
  className: "w-full max-w-lg flex flex-col rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-[var(--swf-shadow-overlay)]",
28091
27888
  onClick: (e) => e.stopPropagation(),
28092
27889
  onKeyDown: (e) => e.stopPropagation(),
28093
27890
  children: [
28094
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-5 py-3", children: [
28095
- /* @__PURE__ */ jsx23("h4", { className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u6DFB\u52A0\u4E0A\u4E0B\u6587" }),
28096
- /* @__PURE__ */ jsx23(
27891
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-5 py-3", children: [
27892
+ /* @__PURE__ */ jsx24("h4", { className: "text-sm font-semibold text-[hsl(var(--foreground))]", children: "\u6DFB\u52A0\u4E0A\u4E0B\u6587" }),
27893
+ /* @__PURE__ */ jsx24(
28097
27894
  "button",
28098
27895
  {
28099
27896
  type: "button",
28100
27897
  onClick: onClose,
28101
27898
  className: "rounded-md p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
28102
- children: /* @__PURE__ */ jsx23(X, { size: 14 })
27899
+ children: /* @__PURE__ */ jsx24(X, { size: 14 })
28103
27900
  }
28104
27901
  )
28105
27902
  ] }),
28106
- /* @__PURE__ */ jsxs12("div", { className: "px-5 py-4 space-y-3", children: [
28107
- /* @__PURE__ */ jsxs12("div", { className: "relative", children: [
28108
- /* @__PURE__ */ jsxs12(
27903
+ /* @__PURE__ */ jsxs13("div", { className: "px-5 py-4 space-y-3", children: [
27904
+ /* @__PURE__ */ jsxs13("div", { className: "relative", children: [
27905
+ /* @__PURE__ */ jsxs13(
28109
27906
  "button",
28110
27907
  {
28111
27908
  type: "button",
28112
27909
  onClick: handleLoadSessions,
28113
27910
  className: "inline-flex items-center gap-1.5 rounded-md border border-[hsl(var(--border))] px-2.5 py-1.5 text-xs text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))]",
28114
27911
  children: [
28115
- /* @__PURE__ */ jsx23(Import, { size: 12 }),
27912
+ /* @__PURE__ */ jsx24(Import, { size: 12 }),
28116
27913
  "\u4ECE\u5176\u4ED6\u4F1A\u8BDD\u5BFC\u5165",
28117
- /* @__PURE__ */ jsx23(ChevronDown, { size: 10, className: `transition-transform ${showSessionPicker ? "rotate-180" : ""}` })
27914
+ /* @__PURE__ */ jsx24(ChevronDown, { size: 10, className: `transition-transform ${showSessionPicker ? "rotate-180" : ""}` })
28118
27915
  ]
28119
27916
  }
28120
27917
  ),
28121
- showSessionPicker && /* @__PURE__ */ jsx23("div", { className: "absolute left-0 top-full z-10 mt-1 max-h-48 w-full overflow-y-auto rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-[var(--swf-shadow-overlay)]", children: loadingSessions ? /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
28122
- /* @__PURE__ */ jsx23(LoaderCircle, { size: 12, className: "animate-spin" }),
27918
+ showSessionPicker && /* @__PURE__ */ jsx24("div", { className: "absolute left-0 top-full z-10 mt-1 max-h-48 w-full overflow-y-auto rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-[var(--swf-shadow-overlay)]", children: loadingSessions ? /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: [
27919
+ /* @__PURE__ */ jsx24(LoaderCircle, { size: 12, className: "animate-spin" }),
28123
27920
  "\u52A0\u8F7D\u4F1A\u8BDD\u5217\u8868\u2026"
28124
- ] }) : sessions.length === 0 ? /* @__PURE__ */ jsx23("div", { className: "px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5176\u4ED6\u4F1A\u8BDD" }) : sessions.map((s) => /* @__PURE__ */ jsxs12(
27921
+ ] }) : sessions.length === 0 ? /* @__PURE__ */ jsx24("div", { className: "px-3 py-2.5 text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u5176\u4ED6\u4F1A\u8BDD" }) : sessions.map((s) => /* @__PURE__ */ jsxs13(
28125
27922
  "button",
28126
27923
  {
28127
27924
  type: "button",
@@ -28129,16 +27926,16 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
28129
27926
  onClick: () => handleImportSession(s.id),
28130
27927
  className: "flex w-full items-center gap-2 px-3 py-2 text-left text-xs text-[hsl(var(--foreground))] transition-colors hover:bg-[hsl(var(--accent))] disabled:opacity-50",
28131
27928
  children: [
28132
- importingId === s.id && /* @__PURE__ */ jsx23(LoaderCircle, { size: 10, className: "shrink-0 animate-spin" }),
28133
- /* @__PURE__ */ jsx23("span", { className: "truncate", children: s.intent })
27929
+ importingId === s.id && /* @__PURE__ */ jsx24(LoaderCircle, { size: 10, className: "shrink-0 animate-spin" }),
27930
+ /* @__PURE__ */ jsx24("span", { className: "truncate", children: s.intent })
28134
27931
  ]
28135
27932
  },
28136
27933
  s.id
28137
27934
  )) })
28138
27935
  ] }),
28139
- /* @__PURE__ */ jsxs12("div", { children: [
28140
- /* @__PURE__ */ jsx23("label", { htmlFor: "ctx-label", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u6807\u7B7E" }),
28141
- /* @__PURE__ */ jsx23(
27936
+ /* @__PURE__ */ jsxs13("div", { children: [
27937
+ /* @__PURE__ */ jsx24("label", { htmlFor: "ctx-label", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u6807\u7B7E" }),
27938
+ /* @__PURE__ */ jsx24(
28142
27939
  "input",
28143
27940
  {
28144
27941
  id: "ctx-label",
@@ -28149,13 +27946,13 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
28149
27946
  }
28150
27947
  )
28151
27948
  ] }),
28152
- /* @__PURE__ */ jsxs12("div", { children: [
28153
- /* @__PURE__ */ jsx23("label", { htmlFor: "ctx-content", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u5185\u5BB9" }),
28154
- isImportProcessing && /* @__PURE__ */ jsxs12("div", { className: "mb-1.5 flex items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
28155
- /* @__PURE__ */ jsx23(LoaderCircle, { size: 12, className: "animate-spin" }),
27949
+ /* @__PURE__ */ jsxs13("div", { children: [
27950
+ /* @__PURE__ */ jsx24("label", { htmlFor: "ctx-content", className: "block text-xs font-medium text-[hsl(var(--foreground))] mb-1", children: "\u5185\u5BB9" }),
27951
+ isImportProcessing && /* @__PURE__ */ jsxs13("div", { className: "mb-1.5 flex items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
27952
+ /* @__PURE__ */ jsx24(LoaderCircle, { size: 12, className: "animate-spin" }),
28156
27953
  "\u6B63\u5728\u5904\u7406\u5BFC\u5165\u5185\u5BB9\u5E76\u5199\u5165 workspace/context\uFF0C\u5B8C\u6210\u540E\u53EF\u70B9\u51FB\u201C\u786E\u5B9A\u201D"
28157
27954
  ] }),
28158
- /* @__PURE__ */ jsx23(
27955
+ /* @__PURE__ */ jsx24(
28159
27956
  "textarea",
28160
27957
  {
28161
27958
  id: "ctx-content",
@@ -28168,8 +27965,8 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
28168
27965
  )
28169
27966
  ] })
28170
27967
  ] }),
28171
- /* @__PURE__ */ jsxs12("div", { className: "flex justify-end gap-2 border-t border-[hsl(var(--border))] px-5 py-3", children: [
28172
- /* @__PURE__ */ jsx23(
27968
+ /* @__PURE__ */ jsxs13("div", { className: "flex justify-end gap-2 border-t border-[hsl(var(--border))] px-5 py-3", children: [
27969
+ /* @__PURE__ */ jsx24(
28173
27970
  "button",
28174
27971
  {
28175
27972
  type: "button",
@@ -28178,7 +27975,7 @@ ${upload.rawResultStr.slice(0, CONTEXT_INLINE_THRESHOLD)}...`
28178
27975
  children: "\u53D6\u6D88"
28179
27976
  }
28180
27977
  ),
28181
- /* @__PURE__ */ jsx23(
27978
+ /* @__PURE__ */ jsx24(
28182
27979
  "button",
28183
27980
  {
28184
27981
  type: "button",
@@ -28209,19 +28006,19 @@ function ComposerContextPill({
28209
28006
  }) {
28210
28007
  const [showDetail, setShowDetail] = useState11(false);
28211
28008
  const tokenK = formatTokenK(content);
28212
- return /* @__PURE__ */ jsxs12(Fragment5, { children: [
28213
- /* @__PURE__ */ jsxs12("div", { className: "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--accent))] px-2.5 py-1 text-[11px] text-[hsl(var(--foreground))]", children: [
28214
- imageUrl ? /* @__PURE__ */ jsx23(
28009
+ return /* @__PURE__ */ jsxs13(Fragment5, { children: [
28010
+ /* @__PURE__ */ jsxs13("div", { className: "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--accent))] px-2.5 py-1 text-[11px] text-[hsl(var(--foreground))]", children: [
28011
+ imageUrl ? /* @__PURE__ */ jsx24(
28215
28012
  "button",
28216
28013
  {
28217
28014
  type: "button",
28218
28015
  onClick: () => setShowDetail(true),
28219
28016
  className: "h-6 w-6 overflow-hidden rounded-md border border-[hsl(var(--border))] bg-white",
28220
28017
  title: "\u67E5\u770B\u9009\u4E2D\u533A\u57DF\u622A\u56FE",
28221
- children: /* @__PURE__ */ jsx23("img", { src: imageUrl, alt: "\u9009\u4E2D\u533A\u57DF\u622A\u56FE", className: "h-full w-full object-cover" })
28018
+ children: /* @__PURE__ */ jsx24("img", { src: imageUrl, alt: "\u9009\u4E2D\u533A\u57DF\u622A\u56FE", className: "h-full w-full object-cover" })
28222
28019
  }
28223
28020
  ) : null,
28224
- /* @__PURE__ */ jsx23(
28021
+ /* @__PURE__ */ jsx24(
28225
28022
  "button",
28226
28023
  {
28227
28024
  type: "button",
@@ -28231,7 +28028,7 @@ function ComposerContextPill({
28231
28028
  children: label
28232
28029
  }
28233
28030
  ),
28234
- /* @__PURE__ */ jsx23(
28031
+ /* @__PURE__ */ jsx24(
28235
28032
  "span",
28236
28033
  {
28237
28034
  className: "shrink-0 rounded bg-[hsl(var(--background))] px-1.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]",
@@ -28239,7 +28036,7 @@ function ComposerContextPill({
28239
28036
  children: tokenK
28240
28037
  }
28241
28038
  ),
28242
- /* @__PURE__ */ jsx23(
28039
+ /* @__PURE__ */ jsx24(
28243
28040
  "button",
28244
28041
  {
28245
28042
  type: "button",
@@ -28247,11 +28044,11 @@ function ComposerContextPill({
28247
28044
  "aria-label": `\u79FB\u9664\u4E0A\u4E0B\u6587 ${label}`,
28248
28045
  title: "\u79FB\u9664",
28249
28046
  className: "ml-0.5 inline-flex shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition hover:text-[hsl(var(--swf-danger))]",
28250
- children: /* @__PURE__ */ jsx23(X, { size: 10 })
28047
+ children: /* @__PURE__ */ jsx24(X, { size: 10 })
28251
28048
  }
28252
28049
  )
28253
28050
  ] }),
28254
- showDetail && /* @__PURE__ */ jsx23(
28051
+ showDetail && /* @__PURE__ */ jsx24(
28255
28052
  "div",
28256
28053
  {
28257
28054
  className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/55 p-6",
@@ -28259,31 +28056,31 @@ function ComposerContextPill({
28259
28056
  onKeyDown: (e) => {
28260
28057
  if (e.key === "Escape") setShowDetail(false);
28261
28058
  },
28262
- children: /* @__PURE__ */ jsxs12(
28059
+ children: /* @__PURE__ */ jsxs13(
28263
28060
  "div",
28264
28061
  {
28265
28062
  className: "w-full max-w-4xl max-h-[85vh] flex flex-col rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] shadow-[var(--swf-shadow-overlay)]",
28266
28063
  onClick: (e) => e.stopPropagation(),
28267
28064
  onKeyDown: (e) => e.stopPropagation(),
28268
28065
  children: [
28269
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-6 py-3", children: [
28270
- /* @__PURE__ */ jsxs12("div", { className: "min-w-0", children: [
28271
- /* @__PURE__ */ jsx23("h4", { className: "truncate text-xs font-semibold text-[hsl(var(--foreground))]", children: label }),
28272
- imageUrl ? /* @__PURE__ */ jsx23("p", { className: "mt-0.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u9644\u52A0\u9009\u4E2D\u533A\u57DF\u622A\u56FE\uFF0C\u975E\u591A\u6A21\u6001\u6A21\u578B\u4F1A\u81EA\u52A8\u5FFD\u7565\u56FE\u7247\u3002" }) : null
28066
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-6 py-3", children: [
28067
+ /* @__PURE__ */ jsxs13("div", { className: "min-w-0", children: [
28068
+ /* @__PURE__ */ jsx24("h4", { className: "truncate text-xs font-semibold text-[hsl(var(--foreground))]", children: label }),
28069
+ imageUrl ? /* @__PURE__ */ jsx24("p", { className: "mt-0.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u9644\u52A0\u9009\u4E2D\u533A\u57DF\u622A\u56FE\uFF0C\u975E\u591A\u6A21\u6001\u6A21\u578B\u4F1A\u81EA\u52A8\u5FFD\u7565\u56FE\u7247\u3002" }) : null
28273
28070
  ] }),
28274
- /* @__PURE__ */ jsx23(
28071
+ /* @__PURE__ */ jsx24(
28275
28072
  "button",
28276
28073
  {
28277
28074
  type: "button",
28278
28075
  onClick: () => setShowDetail(false),
28279
28076
  className: "rounded-md p-1 text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
28280
- children: /* @__PURE__ */ jsx23(X, { size: 14 })
28077
+ children: /* @__PURE__ */ jsx24(X, { size: 14 })
28281
28078
  }
28282
28079
  )
28283
28080
  ] }),
28284
- /* @__PURE__ */ jsxs12("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: [
28285
- imageUrl ? /* @__PURE__ */ jsx23("div", { className: "mb-4 rounded-xl border border-[hsl(var(--border))] bg-white p-2", children: /* @__PURE__ */ jsx23("img", { src: imageUrl, alt: "\u9009\u4E2D\u533A\u57DF\u622A\u56FE", className: "max-h-72 max-w-full rounded-lg object-contain" }) }) : null,
28286
- /* @__PURE__ */ jsx23("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.6] text-[hsl(var(--foreground)/0.85)]", children: content })
28081
+ /* @__PURE__ */ jsxs13("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: [
28082
+ imageUrl ? /* @__PURE__ */ jsx24("div", { className: "mb-4 rounded-xl border border-[hsl(var(--border))] bg-white p-2", children: /* @__PURE__ */ jsx24("img", { src: imageUrl, alt: "\u9009\u4E2D\u533A\u57DF\u622A\u56FE", className: "max-h-72 max-w-full rounded-lg object-contain" }) }) : null,
28083
+ /* @__PURE__ */ jsx24("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.6] text-[hsl(var(--foreground)/0.85)]", children: content })
28287
28084
  ] })
28288
28085
  ]
28289
28086
  }
@@ -28366,11 +28163,11 @@ function ChatInput({
28366
28163
  externalDraft?.setValue(value);
28367
28164
  });
28368
28165
  const externalDraftValue = externalDraft?.value;
28369
- const inputRef = useRef9(input);
28166
+ const inputRef = useRef7(input);
28370
28167
  inputRef.current = input;
28371
- const appliedInitialDraftKeyRef = useRef9(null);
28372
- const appliedInitialDraftRef = useRef9(null);
28373
- useEffect9(() => {
28168
+ const appliedInitialDraftKeyRef = useRef7(null);
28169
+ const appliedInitialDraftRef = useRef7(null);
28170
+ useEffect8(() => {
28374
28171
  if (externalDraftValue == null) return;
28375
28172
  if (inputRef.current === externalDraftValue) return;
28376
28173
  if (editorRef.current) {
@@ -28378,7 +28175,7 @@ function ChatInput({
28378
28175
  }
28379
28176
  setInputInternal(externalDraftValue);
28380
28177
  }, [externalDraftValue]);
28381
- useEffect9(() => {
28178
+ useEffect8(() => {
28382
28179
  const key = initialDraftKey ?? initialDraft ?? "";
28383
28180
  if (!initialDraft || !key || appliedInitialDraftKeyRef.current === key) return;
28384
28181
  if (inputRef.current === initialDraft) appliedInitialDraftRef.current = initialDraft;
@@ -28404,9 +28201,9 @@ function ChatInput({
28404
28201
  }
28405
28202
  );
28406
28203
  const externalAttachmentsValue = externalAttachments?.value;
28407
- const composerAttachmentsRef = useRef9(composerAttachments);
28204
+ const composerAttachmentsRef = useRef7(composerAttachments);
28408
28205
  composerAttachmentsRef.current = composerAttachments;
28409
- useEffect9(() => {
28206
+ useEffect8(() => {
28410
28207
  if (externalAttachmentsValue == null) return;
28411
28208
  if (composerAttachmentsRef.current === externalAttachmentsValue) return;
28412
28209
  setComposerAttachmentsInternal(externalAttachmentsValue);
@@ -28420,16 +28217,16 @@ function ChatInput({
28420
28217
  const invalidation = useSessionDataInvalidation();
28421
28218
  const SkillStatusBarComponent = SkillStatusBarOverride ?? SkillStatusBar;
28422
28219
  const [actionMenuOpen, setActionMenuOpen] = useState11(false);
28423
- const actionMenuOpenRef = useRef9(false);
28424
- useEffect9(() => {
28220
+ const actionMenuOpenRef = useRef7(false);
28221
+ useEffect8(() => {
28425
28222
  actionMenuOpenRef.current = actionMenuOpen;
28426
28223
  }, [actionMenuOpen]);
28427
28224
  const [connectMenuOpen, setConnectMenuOpen] = useState11(false);
28428
- const fileInputRef = useRef9(null);
28429
- const folderInputRef = useRef9(null);
28430
- const editorRef = useRef9(null);
28431
- const lastEscapeAtRef = useRef9(0);
28432
- const localImageUrlsRef = useRef9(/* @__PURE__ */ new Map());
28225
+ const fileInputRef = useRef7(null);
28226
+ const folderInputRef = useRef7(null);
28227
+ const editorRef = useRef7(null);
28228
+ const lastEscapeAtRef = useRef7(0);
28229
+ const localImageUrlsRef = useRef7(/* @__PURE__ */ new Map());
28433
28230
  const currentChatSessionId = useCurrentChatSessionId();
28434
28231
  const activeSessionId = sessionIdProp ?? currentChatSessionId;
28435
28232
  const currentSession = useChatSessionDetail(activeSessionId);
@@ -28464,7 +28261,7 @@ function ChatInput({
28464
28261
  const detail = await client.sessions.getSession(activeSessionId);
28465
28262
  return getTopicAssetSuggestionItems(client, detail.chat_group_id, query);
28466
28263
  } catch {
28467
- return [{ kind: "topicAssetError", message: "\u4E3B\u9898\u8D44\u4EA7\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165 @ \u91CD\u8BD5" }];
28264
+ return [{ kind: "topicAssetError", message: "\u5DE5\u4F5C\u7A7A\u95F4\u8D44\u4EA7\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165 @ \u91CD\u8BD5" }];
28468
28265
  }
28469
28266
  });
28470
28267
  const getSessionId = useEffectEvent(() => activeSessionId);
@@ -28581,7 +28378,7 @@ function ChatInput({
28581
28378
  if (!container || !root) return;
28582
28379
  updateSuggestionPosition(container, props.clientRect);
28583
28380
  root.render(
28584
- /* @__PURE__ */ jsx23(
28381
+ /* @__PURE__ */ jsx24(
28585
28382
  FileCompletionMenu,
28586
28383
  {
28587
28384
  ref: (instance) => {
@@ -28674,7 +28471,7 @@ function ChatInput({
28674
28471
  if (!container || !root) return;
28675
28472
  updateSuggestionPosition(container, props.clientRect);
28676
28473
  root.render(
28677
- /* @__PURE__ */ jsx23(
28474
+ /* @__PURE__ */ jsx24(
28678
28475
  SkillCompletionMenu,
28679
28476
  {
28680
28477
  ref: (instance) => {
@@ -28809,13 +28606,13 @@ function ChatInput({
28809
28606
  }
28810
28607
  });
28811
28608
  useDismissSkillSuggestionsOnModeChange(editor);
28812
- useEffect9(() => {
28609
+ useEffect8(() => {
28813
28610
  const dom = editor?.view.dom;
28814
28611
  if (!dom) return;
28815
28612
  dom.setAttribute("aria-label", resolvedInputLabel);
28816
28613
  dom.setAttribute("data-blade-input-label", resolvedInputLabel);
28817
28614
  }, [editor, resolvedInputLabel]);
28818
- useEffect9(() => {
28615
+ useEffect8(() => {
28819
28616
  if (!editor || !activeSessionId || rewindDraft == null) {
28820
28617
  return;
28821
28618
  }
@@ -28826,9 +28623,9 @@ function ChatInput({
28826
28623
  editor.commands.focus("end");
28827
28624
  composerChannels.setRewindDraft(activeSessionId, null);
28828
28625
  }, [activeSessionId, editor, rewindDraft]);
28829
- const submittingRef = useRef9(false);
28626
+ const submittingRef = useRef7(false);
28830
28627
  const [isSubmitting, setIsSubmitting] = useState11(false);
28831
- useEffect9(() => {
28628
+ useEffect8(() => {
28832
28629
  let changed = false;
28833
28630
  const nextLocalIds = /* @__PURE__ */ new Set();
28834
28631
  for (const attachment of composerAttachments) {
@@ -28853,7 +28650,7 @@ function ChatInput({
28853
28650
  setLocalImageUrls(Object.fromEntries(localImageUrlsRef.current));
28854
28651
  }
28855
28652
  }, [composerAttachments]);
28856
- useEffect9(() => {
28653
+ useEffect8(() => {
28857
28654
  return () => {
28858
28655
  for (const url of localImageUrlsRef.current.values()) {
28859
28656
  URL.revokeObjectURL(url);
@@ -28862,8 +28659,8 @@ function ChatInput({
28862
28659
  };
28863
28660
  }, []);
28864
28661
  const sessionHandle = useSessionHandle(activeSessionId);
28865
- const restoredPluginSelection = useRef9(null);
28866
- useEffect9(() => {
28662
+ const restoredPluginSelection = useRef7(null);
28663
+ useEffect8(() => {
28867
28664
  if (!sessionHandle || !activeSessionId || !editor) return;
28868
28665
  const restore = () => {
28869
28666
  if (restoredPluginSelection.current === activeSessionId) return;
@@ -28878,7 +28675,7 @@ function ChatInput({
28878
28675
  restore();
28879
28676
  return sessionHandle.subscribe(restore);
28880
28677
  }, [sessionHandle, activeSessionId, editor]);
28881
- useEffect9(() => {
28678
+ useEffect8(() => {
28882
28679
  if (!sessionHandle || !activeSessionId) return;
28883
28680
  const offInsert = sessionHandle.on("insertTextRequested", ({ text }) => {
28884
28681
  const separate = /^\n/.test(text);
@@ -28913,7 +28710,7 @@ ${append2.text}` : append2.text;
28913
28710
  editor.chain().focus("end").insertContent(text).run();
28914
28711
  });
28915
28712
  const editorReady = editor != null;
28916
- useEffect9(() => {
28713
+ useEffect8(() => {
28917
28714
  if (!editorReady || !draftAppends?.length) {
28918
28715
  return;
28919
28716
  }
@@ -28929,7 +28726,7 @@ ${append2.text}` : append2.text;
28929
28726
  }
28930
28727
  void stableHandleSubmit();
28931
28728
  });
28932
- useEffect9(() => {
28729
+ useEffect8(() => {
28933
28730
  if (!sendRequests?.length) {
28934
28731
  return;
28935
28732
  }
@@ -28944,10 +28741,10 @@ ${append2.text}` : append2.text;
28944
28741
  });
28945
28742
  const { isRecording, level: voiceLevel } = voice;
28946
28743
  const isVoiceStarting = voice.status === "starting";
28947
- const voiceStopRef = useRef9(voice.stop);
28744
+ const voiceStopRef = useRef7(voice.stop);
28948
28745
  voiceStopRef.current = voice.stop;
28949
- const prevSessionIdRef = useRef9(activeSessionId);
28950
- useEffect9(() => {
28746
+ const prevSessionIdRef = useRef7(activeSessionId);
28747
+ useEffect8(() => {
28951
28748
  if (prevSessionIdRef.current !== activeSessionId) {
28952
28749
  prevSessionIdRef.current = activeSessionId;
28953
28750
  if (isRecording) {
@@ -29012,7 +28809,7 @@ ${append2.text}` : append2.text;
29012
28809
  }
29013
28810
  const topicAssetRefs = collectTopicAssetMentions(json);
29014
28811
  if (topicAssetRefs.length > 20) {
29015
- notifyChat(environment, "error", "\u6BCF\u6761\u6D88\u606F\u6700\u591A\u5F15\u7528 20 \u4E2A\u4E3B\u9898\u8D44\u4EA7");
28812
+ notifyChat(environment, "error", "\u6BCF\u6761\u6D88\u606F\u6700\u591A\u5F15\u7528 20 \u4E2A\u5DE5\u4F5C\u7A7A\u95F4\u8D44\u4EA7");
29016
28813
  return;
29017
28814
  }
29018
28815
  const text = rawText;
@@ -29181,7 +28978,7 @@ ${append2.text}` : append2.text;
29181
28978
  setIsSubmitting(false);
29182
28979
  }
29183
28980
  };
29184
- useEffect9(() => {
28981
+ useEffect8(() => {
29185
28982
  if (!editor || !activeSessionId || !queuedTopicRefs?.length) return;
29186
28983
  const existing = collectTopicAssetMentions(editor.getJSON());
29187
28984
  const refs = composerChannels.consumeTopicAssetReferences(activeSessionId).filter((ref) => !existing.some((item) => item.topic_id === ref.topic_id && item.path === ref.path));
@@ -29201,9 +28998,9 @@ ${append2.text}` : append2.text;
29201
28998
  const reduceMotion = typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
29202
28999
  return reduceMotion ? fullPlaceholder : "";
29203
29000
  });
29204
- const typewriterPlayedRef = useRef9(false);
29205
- const isTypingRef = useRef9(false);
29206
- useEffect9(() => {
29001
+ const typewriterPlayedRef = useRef7(false);
29002
+ const isTypingRef = useRef7(false);
29003
+ useEffect8(() => {
29207
29004
  if (!typewriterPlaceholder || typewriterPlayedRef.current) return;
29208
29005
  typewriterPlayedRef.current = true;
29209
29006
  const reduceMotion = typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
@@ -29224,7 +29021,7 @@ ${append2.text}` : append2.text;
29224
29021
  isTypingRef.current = false;
29225
29022
  };
29226
29023
  }, [typewriterPlaceholder]);
29227
- useEffect9(() => {
29024
+ useEffect8(() => {
29228
29025
  if (isTypingRef.current) return;
29229
29026
  setTypedPlaceholder(fullPlaceholder);
29230
29027
  }, [fullPlaceholder]);
@@ -29245,11 +29042,11 @@ ${append2.text}` : append2.text;
29245
29042
  const hasComposerContent = Boolean(input.trim()) || hasValidAttachments || hasRenderedAttachments || hasPendingContexts;
29246
29043
  const isSendDisabled = connectionStatus !== "connected" || isCompacting || !submitWhileRunning && isModelLoading || !submitWhileRunning && !hasAvailableModel || isSubmitting || hasUploadingFiles || !input.trim() && !hasValidAttachments && !hasRenderedAttachments && !hasPendingContexts;
29247
29044
  const showQueueShortcut = Boolean(input.trim()) && !isSendDisabled && !isStopping && !isRecording && (!isStreaming || queueWhileRunning && !hasRunningSendBlockers());
29248
- return /* @__PURE__ */ jsxs12(Fragment5, { children: [
29249
- /* @__PURE__ */ jsx23("div", { className: `px-5 pb-3 pt-0 ${className ?? ""}`, children: /* @__PURE__ */ jsxs12("div", { className: `mx-auto ${maxWidthClassName} ${innerClassName ?? ""}`, children: [
29250
- statusBarAddon ? /* @__PURE__ */ jsx23("div", { className: "mb-2 flex flex-wrap items-center gap-2", children: statusBarAddon }) : null,
29251
- !isModelLoading && !hasAvailableModel ? /* @__PURE__ */ jsx23("div", { className: "mb-2 rounded-lg border border-[hsl(var(--destructive))]/30 bg-[hsl(var(--destructive))]/8 px-3 py-2 text-xs text-[hsl(var(--destructive))]", children: modelAvailabilityMessage }) : null,
29252
- /* @__PURE__ */ jsx23(
29045
+ return /* @__PURE__ */ jsxs13(Fragment5, { children: [
29046
+ /* @__PURE__ */ jsx24("div", { className: `px-5 pb-3 pt-0 ${className ?? ""}`, children: /* @__PURE__ */ jsxs13("div", { className: `mx-auto ${maxWidthClassName} ${innerClassName ?? ""}`, children: [
29047
+ statusBarAddon ? /* @__PURE__ */ jsx24("div", { className: "mb-2 flex flex-wrap items-center gap-2", children: statusBarAddon }) : null,
29048
+ !isModelLoading && !hasAvailableModel ? /* @__PURE__ */ jsx24("div", { className: "mb-2 rounded-lg border border-[hsl(var(--destructive))]/30 bg-[hsl(var(--destructive))]/8 px-3 py-2 text-xs text-[hsl(var(--destructive))]", children: modelAvailabilityMessage }) : null,
29049
+ /* @__PURE__ */ jsx24(
29253
29050
  "div",
29254
29051
  {
29255
29052
  className: "relative",
@@ -29283,20 +29080,20 @@ ${append2.text}` : append2.text;
29283
29080
  if (files.length > 0) void stableAppendFiles(files);
29284
29081
  });
29285
29082
  },
29286
- children: /* @__PURE__ */ jsxs12(
29083
+ children: /* @__PURE__ */ jsxs13(
29287
29084
  "div",
29288
29085
  {
29289
29086
  className: `overflow-visible border bg-[hsl(var(--card))] transition-[box-shadow,border-color] duration-300 ${mergesWithPanelAbove ? "rounded-b-[22px]" : "rounded-[22px]"} ${isRecording ? "border-[hsl(var(--swf-success))]!" : isPlanning ? dragging || isEditorFocused ? "border-[hsl(var(--swf-warning)/0.6)]" : "border-[hsl(var(--swf-warning)/0.3)]" : dragging || isEditorFocused ? "border-[hsl(213_94%_60%/0.55)] shadow-[0_0_0_3px_hsl(213_94%_60%/0.16),0_8px_24px_-6px_hsl(213_94%_60%/0.3)]" : "border-[hsl(213_94%_60%/0.28)] shadow-[0_0_0_2px_hsl(213_94%_60%/0.08),0_4px_14px_-6px_hsl(213_94%_60%/0.16)]"}`,
29290
29087
  children: [
29291
- dragging && /* @__PURE__ */ jsx23("div", { className: `pointer-events-none absolute inset-0 z-10 flex items-center justify-center bg-[hsl(var(--primary)/0.06)] ${mergesWithPanelAbove ? "rounded-b-[22px]" : "rounded-2xl"}`, children: /* @__PURE__ */ jsx23("span", { className: "rounded-full bg-[hsl(var(--primary)/0.12)] px-4 py-2 text-sm font-medium text-[hsl(var(--primary))]", children: "\u677E\u624B\u5F15\u7528\u6587\u4EF6" }) }),
29088
+ dragging && /* @__PURE__ */ jsx24("div", { className: `pointer-events-none absolute inset-0 z-10 flex items-center justify-center bg-[hsl(var(--primary)/0.06)] ${mergesWithPanelAbove ? "rounded-b-[22px]" : "rounded-2xl"}`, children: /* @__PURE__ */ jsx24("span", { className: "rounded-full bg-[hsl(var(--primary)/0.12)] px-4 py-2 text-sm font-medium text-[hsl(var(--primary))]", children: "\u677E\u624B\u5F15\u7528\u6587\u4EF6" }) }),
29292
29089
  planPanel,
29293
- composerAttachments.length > 0 && /* @__PURE__ */ jsxs12(ComposerAttachmentViewport, { className: "flex flex-col gap-2 border-b border-[hsl(var(--border))] px-4 py-2", children: [
29294
- imageAttachments.length > 0 && /* @__PURE__ */ jsx23("div", { className: "grid grid-cols-3 gap-2", children: imageAttachments.map((attachment) => /* @__PURE__ */ jsxs12(
29090
+ composerAttachments.length > 0 && /* @__PURE__ */ jsxs13(ComposerAttachmentViewport, { className: "flex flex-col gap-2 border-b border-[hsl(var(--border))] px-4 py-2", children: [
29091
+ imageAttachments.length > 0 && /* @__PURE__ */ jsx24("div", { className: "grid grid-cols-3 gap-2", children: imageAttachments.map((attachment) => /* @__PURE__ */ jsxs13(
29295
29092
  "div",
29296
29093
  {
29297
29094
  className: "relative overflow-hidden rounded-xl border border-[hsl(var(--border))]",
29298
29095
  children: [
29299
- /* @__PURE__ */ jsx23(
29096
+ /* @__PURE__ */ jsx24(
29300
29097
  "img",
29301
29098
  {
29302
29099
  src: getImagePreviewUrl(client, attachment, activeSessionId, localImageUrls),
@@ -29304,7 +29101,7 @@ ${append2.text}` : append2.text;
29304
29101
  className: "h-24 w-full object-cover"
29305
29102
  }
29306
29103
  ),
29307
- /* @__PURE__ */ jsx23(
29104
+ /* @__PURE__ */ jsx24(
29308
29105
  "button",
29309
29106
  {
29310
29107
  type: "button",
@@ -29312,14 +29109,14 @@ ${append2.text}` : append2.text;
29312
29109
  "aria-label": `\u79FB\u9664 ${attachment.name || "\u56FE\u7247"}`,
29313
29110
  title: "\u79FB\u9664",
29314
29111
  className: "absolute right-1.5 top-1.5 flex h-6 w-6 items-center justify-center rounded-full bg-[hsl(var(--background)/0.85)] text-[hsl(var(--foreground))]",
29315
- children: /* @__PURE__ */ jsx23(X, { size: 12 })
29112
+ children: /* @__PURE__ */ jsx24(X, { size: 12 })
29316
29113
  }
29317
29114
  )
29318
29115
  ]
29319
29116
  },
29320
29117
  attachment.id
29321
29118
  )) }),
29322
- fileAttachments.length > 0 && /* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-1.5", children: fileAttachments.map((attachment) => /* @__PURE__ */ jsx23(
29119
+ fileAttachments.length > 0 && /* @__PURE__ */ jsx24("div", { className: "flex flex-wrap gap-1.5", children: fileAttachments.map((attachment) => /* @__PURE__ */ jsx24(
29323
29120
  ComposerFilePill,
29324
29121
  {
29325
29122
  attachment,
@@ -29328,8 +29125,8 @@ ${append2.text}` : append2.text;
29328
29125
  attachment.id
29329
29126
  )) })
29330
29127
  ] }),
29331
- hasPendingContexts || isSkillEditor ? /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-1.5 border-b border-[hsl(var(--border))] px-4 py-2", children: [
29332
- pendingContexts?.map((context) => /* @__PURE__ */ jsx23(
29128
+ hasPendingContexts || isSkillEditor ? /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-1.5 border-b border-[hsl(var(--border))] px-4 py-2", children: [
29129
+ pendingContexts?.map((context) => /* @__PURE__ */ jsx24(
29333
29130
  ComposerContextPill,
29334
29131
  {
29335
29132
  id: context.id,
@@ -29345,18 +29142,18 @@ ${append2.text}` : append2.text;
29345
29142
  },
29346
29143
  context.id
29347
29144
  )),
29348
- isSkillEditor && /* @__PURE__ */ jsx23(
29145
+ isSkillEditor && /* @__PURE__ */ jsx24(
29349
29146
  "button",
29350
29147
  {
29351
29148
  type: "button",
29352
29149
  onClick: () => setShowAddContext(true),
29353
29150
  title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
29354
29151
  className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full border border-dashed border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] transition-colors hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))]",
29355
- children: /* @__PURE__ */ jsx23(Plus, { size: 12 })
29152
+ children: /* @__PURE__ */ jsx24(Plus, { size: 12 })
29356
29153
  }
29357
29154
  )
29358
29155
  ] }) : null,
29359
- showAddContext && activeSessionId && /* @__PURE__ */ jsx23(
29156
+ showAddContext && activeSessionId && /* @__PURE__ */ jsx24(
29360
29157
  AddContextDialog,
29361
29158
  {
29362
29159
  sessionId: activeSessionId,
@@ -29368,15 +29165,15 @@ ${append2.text}` : append2.text;
29368
29165
  }
29369
29166
  }
29370
29167
  ),
29371
- attachments ? /* @__PURE__ */ jsx23("div", { className: "border-b border-[hsl(var(--border))] px-4 py-3", children: attachments }) : null,
29372
- slotAboveTextarea ? /* @__PURE__ */ jsx23("div", { className: "border-b border-[hsl(var(--border))] px-4 py-2", children: slotAboveTextarea }) : null,
29373
- /* @__PURE__ */ jsxs12("div", { className: "relative", children: [
29374
- input.length === 0 && /* @__PURE__ */ jsx23("div", { className: "pointer-events-none absolute left-5 top-3 text-sm leading-relaxed text-[hsl(var(--muted-foreground)/0.6)]", children: placeholder }),
29375
- /* @__PURE__ */ jsx23(EditorContent, { editor })
29168
+ attachments ? /* @__PURE__ */ jsx24("div", { className: "border-b border-[hsl(var(--border))] px-4 py-3", children: attachments }) : null,
29169
+ slotAboveTextarea ? /* @__PURE__ */ jsx24("div", { className: "border-b border-[hsl(var(--border))] px-4 py-2", children: slotAboveTextarea }) : null,
29170
+ /* @__PURE__ */ jsxs13("div", { className: "relative", children: [
29171
+ input.length === 0 && /* @__PURE__ */ jsx24("div", { className: "pointer-events-none absolute left-5 top-3 text-sm leading-relaxed text-[hsl(var(--muted-foreground)/0.6)]", children: placeholder }),
29172
+ /* @__PURE__ */ jsx24(EditorContent, { editor })
29376
29173
  ] }),
29377
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between px-4 pb-3 pt-1", children: [
29378
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
29379
- /* @__PURE__ */ jsx23(
29174
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between px-4 pb-3 pt-1", children: [
29175
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
29176
+ /* @__PURE__ */ jsx24(
29380
29177
  "input",
29381
29178
  {
29382
29179
  ref: fileInputRef,
@@ -29392,7 +29189,7 @@ ${append2.text}` : append2.text;
29392
29189
  className: "hidden"
29393
29190
  }
29394
29191
  ),
29395
- /* @__PURE__ */ jsx23(
29192
+ /* @__PURE__ */ jsx24(
29396
29193
  "input",
29397
29194
  {
29398
29195
  ref: folderInputRef,
@@ -29408,7 +29205,7 @@ ${append2.text}` : append2.text;
29408
29205
  ...{ webkitdirectory: "" }
29409
29206
  }
29410
29207
  ),
29411
- /* @__PURE__ */ jsxs12(
29208
+ /* @__PURE__ */ jsxs13(
29412
29209
  dist_exports.Root,
29413
29210
  {
29414
29211
  open: actionMenuOpen,
@@ -29417,17 +29214,17 @@ ${append2.text}` : append2.text;
29417
29214
  if (open) setConnectMenuOpen(false);
29418
29215
  },
29419
29216
  children: [
29420
- /* @__PURE__ */ jsx23(dist_exports.Trigger, { asChild: true, children: /* @__PURE__ */ jsx23(
29217
+ /* @__PURE__ */ jsx24(dist_exports.Trigger, { asChild: true, children: /* @__PURE__ */ jsx24(
29421
29218
  "button",
29422
29219
  {
29423
29220
  type: "button",
29424
29221
  "aria-label": "\u6DFB\u52A0\u5185\u5BB9",
29425
29222
  title: "\u6DFB\u52A0\u5185\u5BB9",
29426
29223
  className: "flex h-9 w-9 shrink-0 cursor-pointer items-center justify-center rounded-full border border-[hsl(var(--border))] text-[hsl(var(--muted-foreground))] transition-colors hover:border-[hsl(var(--ring))] hover:text-[hsl(var(--foreground))]",
29427
- children: /* @__PURE__ */ jsx23(Plus, { size: 14 })
29224
+ children: /* @__PURE__ */ jsx24(Plus, { size: 14 })
29428
29225
  }
29429
29226
  ) }),
29430
- /* @__PURE__ */ jsx23(dist_exports.Portal, { children: /* @__PURE__ */ jsxs12(
29227
+ /* @__PURE__ */ jsx24(dist_exports.Portal, { children: /* @__PURE__ */ jsxs13(
29431
29228
  dist_exports.Content,
29432
29229
  {
29433
29230
  side: "top",
@@ -29435,7 +29232,7 @@ ${append2.text}` : append2.text;
29435
29232
  sideOffset: 8,
29436
29233
  className: "z-30 w-[min(380px,calc(100vw-2rem))] origin-(--radix-popover-content-transform-origin) overflow-visible rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--popover))] py-1 text-[11px] text-[hsl(var(--popover-foreground))] shadow-[var(--swf-shadow-overlay)] outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
29437
29234
  children: [
29438
- /* @__PURE__ */ jsxs12(
29235
+ /* @__PURE__ */ jsxs13(
29439
29236
  "button",
29440
29237
  {
29441
29238
  type: "button",
@@ -29445,12 +29242,12 @@ ${append2.text}` : append2.text;
29445
29242
  },
29446
29243
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
29447
29244
  children: [
29448
- /* @__PURE__ */ jsx23(Paperclip, { size: 14 }),
29245
+ /* @__PURE__ */ jsx24(Paperclip, { size: 14 }),
29449
29246
  "\u4E0A\u4F20\u6587\u4EF6"
29450
29247
  ]
29451
29248
  }
29452
29249
  ),
29453
- /* @__PURE__ */ jsxs12(
29250
+ /* @__PURE__ */ jsxs13(
29454
29251
  "button",
29455
29252
  {
29456
29253
  type: "button",
@@ -29460,12 +29257,12 @@ ${append2.text}` : append2.text;
29460
29257
  },
29461
29258
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
29462
29259
  children: [
29463
- /* @__PURE__ */ jsx23(FolderUp, { size: 14 }),
29260
+ /* @__PURE__ */ jsx24(FolderUp, { size: 14 }),
29464
29261
  "\u4E0A\u4F20\u6587\u4EF6\u5939"
29465
29262
  ]
29466
29263
  }
29467
29264
  ),
29468
- onCommand && canCreateBoardTask && !lite ? /* @__PURE__ */ jsxs12(
29265
+ onCommand && canCreateBoardTask && !lite ? /* @__PURE__ */ jsxs13(
29469
29266
  "button",
29470
29267
  {
29471
29268
  type: "button",
@@ -29475,12 +29272,12 @@ ${append2.text}` : append2.text;
29475
29272
  },
29476
29273
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
29477
29274
  children: [
29478
- /* @__PURE__ */ jsx23(ListPlus, { size: 14 }),
29275
+ /* @__PURE__ */ jsx24(ListPlus, { size: 14 }),
29479
29276
  "\u521B\u5EFA\u540E\u53F0\u4EFB\u52A1"
29480
29277
  ]
29481
29278
  }
29482
29279
  ) : null,
29483
- onDoubleEscape ? /* @__PURE__ */ jsxs12(
29280
+ onDoubleEscape ? /* @__PURE__ */ jsxs13(
29484
29281
  "button",
29485
29282
  {
29486
29283
  type: "button",
@@ -29492,13 +29289,13 @@ ${append2.text}` : append2.text;
29492
29289
  },
29493
29290
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
29494
29291
  children: [
29495
- /* @__PURE__ */ jsx23(RotateCcw, { size: 14 }),
29292
+ /* @__PURE__ */ jsx24(RotateCcw, { size: 14 }),
29496
29293
  "\u56DE\u5230\u4E4B\u524D\u7684\u67D0\u4E00\u6B65"
29497
29294
  ]
29498
29295
  }
29499
29296
  ) : null,
29500
- onCommand && !lite ? /* @__PURE__ */ jsxs12(Fragment5, { children: [
29501
- developer ? /* @__PURE__ */ jsxs12(
29297
+ onCommand && !lite ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
29298
+ developer ? /* @__PURE__ */ jsxs13(
29502
29299
  "button",
29503
29300
  {
29504
29301
  type: "button",
@@ -29509,12 +29306,12 @@ ${append2.text}` : append2.text;
29509
29306
  disabled: isBusy,
29510
29307
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))] disabled:cursor-not-allowed disabled:opacity-50",
29511
29308
  children: [
29512
- isCompacting ? /* @__PURE__ */ jsx23(LoaderCircle, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx23(Scissors, { size: 14 }),
29309
+ isCompacting ? /* @__PURE__ */ jsx24(LoaderCircle, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx24(Scissors, { size: 14 }),
29513
29310
  "\u6574\u7406\u5BF9\u8BDD"
29514
29311
  ]
29515
29312
  }
29516
29313
  ) : null,
29517
- /* @__PURE__ */ jsxs12(
29314
+ /* @__PURE__ */ jsxs13(
29518
29315
  "button",
29519
29316
  {
29520
29317
  type: "button",
@@ -29524,12 +29321,12 @@ ${append2.text}` : append2.text;
29524
29321
  },
29525
29322
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
29526
29323
  children: [
29527
- /* @__PURE__ */ jsx23(Download, { size: 14 }),
29324
+ /* @__PURE__ */ jsx24(Download, { size: 14 }),
29528
29325
  "\u5BFC\u51FA\u4F1A\u8BDD"
29529
29326
  ]
29530
29327
  }
29531
29328
  ),
29532
- /* @__PURE__ */ jsxs12(
29329
+ /* @__PURE__ */ jsxs13(
29533
29330
  "button",
29534
29331
  {
29535
29332
  type: "button",
@@ -29539,12 +29336,12 @@ ${append2.text}` : append2.text;
29539
29336
  },
29540
29337
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
29541
29338
  children: [
29542
- /* @__PURE__ */ jsx23(Play, { size: 14 }),
29339
+ /* @__PURE__ */ jsx24(Play, { size: 14 }),
29543
29340
  "\u56DE\u653E\u8FD9\u4E2A\u5BF9\u8BDD"
29544
29341
  ]
29545
29342
  }
29546
29343
  ),
29547
- canShareSession ? /* @__PURE__ */ jsxs12(
29344
+ canShareSession ? /* @__PURE__ */ jsxs13(
29548
29345
  "button",
29549
29346
  {
29550
29347
  type: "button",
@@ -29554,12 +29351,12 @@ ${append2.text}` : append2.text;
29554
29351
  },
29555
29352
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
29556
29353
  children: [
29557
- /* @__PURE__ */ jsx23(Share2, { size: 14 }),
29354
+ /* @__PURE__ */ jsx24(Share2, { size: 14 }),
29558
29355
  "\u5206\u4EAB\u4F1A\u8BDD"
29559
29356
  ]
29560
29357
  }
29561
29358
  ) : null,
29562
- /* @__PURE__ */ jsxs12(
29359
+ /* @__PURE__ */ jsxs13(
29563
29360
  "button",
29564
29361
  {
29565
29362
  type: "button",
@@ -29569,12 +29366,12 @@ ${append2.text}` : append2.text;
29569
29366
  },
29570
29367
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
29571
29368
  children: [
29572
- /* @__PURE__ */ jsx23(FlaskConical, { size: 14 }),
29369
+ /* @__PURE__ */ jsx24(FlaskConical, { size: 14 }),
29573
29370
  "\u63D0\u53D6\u6280\u80FD"
29574
29371
  ]
29575
29372
  }
29576
29373
  ),
29577
- /* @__PURE__ */ jsxs12(
29374
+ /* @__PURE__ */ jsxs13(
29578
29375
  "button",
29579
29376
  {
29580
29377
  type: "button",
@@ -29584,13 +29381,13 @@ ${append2.text}` : append2.text;
29584
29381
  },
29585
29382
  className: "flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-[hsl(var(--accent))]",
29586
29383
  children: [
29587
- /* @__PURE__ */ jsx23(Rocket, { size: 14 }),
29384
+ /* @__PURE__ */ jsx24(Rocket, { size: 14 }),
29588
29385
  "\u751F\u6210\u5E94\u7528"
29589
29386
  ]
29590
29387
  }
29591
29388
  )
29592
29389
  ] }) : null,
29593
- onToggleMode && !lite ? /* @__PURE__ */ jsx23(
29390
+ onToggleMode && !lite ? /* @__PURE__ */ jsx24(
29594
29391
  PlanningToggle,
29595
29392
  {
29596
29393
  enabled: isPlanning,
@@ -29601,7 +29398,7 @@ ${append2.text}` : append2.text;
29601
29398
  disabled: isBusy
29602
29399
  }
29603
29400
  ) : null,
29604
- !lite && thinkingAvailable && reasoningLevels.length > 0 ? /* @__PURE__ */ jsx23(
29401
+ !lite && thinkingAvailable && reasoningLevels.length > 0 ? /* @__PURE__ */ jsx24(
29605
29402
  ReasoningModeSelect,
29606
29403
  {
29607
29404
  level: selectedReasoningLevel,
@@ -29611,12 +29408,13 @@ ${append2.text}` : append2.text;
29611
29408
  onChange: model.setReasoningLevel
29612
29409
  }
29613
29410
  ) : null,
29614
- !lite ? /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 px-3 py-2", children: [
29615
- /* @__PURE__ */ jsx23(Sparkles, { size: 14, className: "shrink-0", "aria-hidden": "true" }),
29616
- /* @__PURE__ */ jsx23("span", { className: "shrink-0", children: "\u6A21\u578B" }),
29617
- /* @__PURE__ */ jsx23(
29411
+ !lite ? /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 px-3 py-2", children: [
29412
+ /* @__PURE__ */ jsx24(Sparkles, { size: 14, className: "shrink-0", "aria-hidden": "true" }),
29413
+ /* @__PURE__ */ jsx24("span", { className: "shrink-0", children: "\u6A21\u578B" }),
29414
+ /* @__PURE__ */ jsx24(
29618
29415
  ModelSelector,
29619
29416
  {
29417
+ disabled: isModelLoading,
29620
29418
  value: selectedModel,
29621
29419
  onValueChange: model.selectModel,
29622
29420
  compact: true,
@@ -29624,8 +29422,8 @@ ${append2.text}` : append2.text;
29624
29422
  }
29625
29423
  )
29626
29424
  ] }) : null,
29627
- !lite && activeSessionId && actionMenuOpen ? /* @__PURE__ */ jsxs12("div", { className: "border-t border-[hsl(var(--border))] px-3 py-2.5", children: [
29628
- /* @__PURE__ */ jsx23(
29425
+ !lite && activeSessionId && actionMenuOpen ? /* @__PURE__ */ jsxs13("div", { className: "border-t border-[hsl(var(--border))] px-3 py-2.5", children: [
29426
+ /* @__PURE__ */ jsx24(
29629
29427
  SkillStatusBarComponent,
29630
29428
  {
29631
29429
  sessionId: activeSessionId,
@@ -29635,7 +29433,7 @@ ${append2.text}` : append2.text;
29635
29433
  innerClassName: skillStatusBarInnerClassName
29636
29434
  }
29637
29435
  ),
29638
- composerHint ? /* @__PURE__ */ jsx23("div", { className: "mt-2 border-t border-[hsl(var(--border))] pt-2 text-[hsl(var(--muted-foreground))]", children: composerHint }) : null
29436
+ composerHint ? /* @__PURE__ */ jsx24("div", { className: "mt-2 border-t border-[hsl(var(--border))] pt-2 text-[hsl(var(--muted-foreground))]", children: composerHint }) : null
29639
29437
  ] }) : null
29640
29438
  ]
29641
29439
  }
@@ -29643,7 +29441,7 @@ ${append2.text}` : append2.text;
29643
29441
  ]
29644
29442
  }
29645
29443
  ),
29646
- /* @__PURE__ */ jsx23(
29444
+ /* @__PURE__ */ jsx24(
29647
29445
  ConnectButton,
29648
29446
  {
29649
29447
  sessionId: activeSessionId,
@@ -29656,15 +29454,15 @@ ${append2.text}` : append2.text;
29656
29454
  }
29657
29455
  }
29658
29456
  ),
29659
- !lite && activeSessionId ? /* @__PURE__ */ jsx23(BackgroundTasksPill, { sessionId: activeSessionId }) : null
29457
+ !lite && activeSessionId ? /* @__PURE__ */ jsx24(BackgroundTasksPill, { sessionId: activeSessionId }) : null
29660
29458
  ] }),
29661
- /* @__PURE__ */ jsxs12("div", { className: "flex min-h-10 items-center gap-1.5", children: [
29662
- showQueueShortcut && /* @__PURE__ */ jsxs12("span", { className: "mr-1 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
29459
+ /* @__PURE__ */ jsxs13("div", { className: "flex min-h-10 items-center gap-1.5", children: [
29460
+ showQueueShortcut && /* @__PURE__ */ jsxs13("span", { className: "mr-1 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
29663
29461
  queueShortcutLabel(),
29664
29462
  " \xB7 \u6392\u961F\u6D88\u606F"
29665
29463
  ] }),
29666
29464
  slotBeforeSend,
29667
- !isStreaming && !isCompacting && asrEnabled && (isRecording || isVoiceStarting || !hasComposerContent) ? /* @__PURE__ */ jsx23(
29465
+ !isStreaming && !isCompacting && asrEnabled && (isRecording || isVoiceStarting || !hasComposerContent) ? /* @__PURE__ */ jsx24(
29668
29466
  "button",
29669
29467
  {
29670
29468
  type: "button",
@@ -29672,11 +29470,11 @@ ${append2.text}` : append2.text;
29672
29470
  "aria-label": isRecording || isVoiceStarting ? "\u505C\u6B62\u8BED\u97F3\u8F93\u5165" : "\u5F00\u59CB\u8BED\u97F3\u8F93\u5165",
29673
29471
  title: isVoiceStarting ? "\u6B63\u5728\u8FDE\u63A5\u8BED\u97F3\u8F93\u5165\uFF0C\u70B9\u51FB\u53D6\u6D88" : isRecording ? "\u505C\u6B62\u8BED\u97F3\u8F93\u5165" : "\u8BED\u97F3\u8F93\u5165",
29674
29472
  className: `flex items-center justify-center rounded-full transition-[width,height,background-color,color,box-shadow] duration-300 disabled:opacity-40 ${isRecording ? "h-10 w-10 bg-[hsl(var(--swf-success-soft))] text-[hsl(var(--swf-success))]" : "h-10 w-10 bg-[hsl(213_94%_60%/0.10)] text-[hsl(213_94%_45%)] hover:bg-[hsl(213_94%_60%/0.18)]"}`,
29675
- children: isVoiceStarting ? /* @__PURE__ */ jsx23(LoaderCircle, { size: 20, className: "animate-spin" }) : isRecording ? /* @__PURE__ */ jsx23(VoiceWaveform, { level: voiceLevel, size: 20 }) : /* @__PURE__ */ jsx23(Mic, { size: 20 })
29473
+ children: isVoiceStarting ? /* @__PURE__ */ jsx24(LoaderCircle, { size: 20, className: "animate-spin" }) : isRecording ? /* @__PURE__ */ jsx24(VoiceWaveform, { level: voiceLevel, size: 20 }) : /* @__PURE__ */ jsx24(Mic, { size: 20 })
29676
29474
  }
29677
29475
  ) : null,
29678
- isStreaming ? /* @__PURE__ */ jsxs12(Fragment5, { children: [
29679
- submitWhileRunning ? /* @__PURE__ */ jsx23(
29476
+ isStreaming ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
29477
+ submitWhileRunning ? /* @__PURE__ */ jsx24(
29680
29478
  "button",
29681
29479
  {
29682
29480
  type: "button",
@@ -29685,10 +29483,10 @@ ${append2.text}` : append2.text;
29685
29483
  "aria-label": "\u53D1\u9001\u5F15\u5BFC\u6D88\u606F",
29686
29484
  title: "\u53D1\u9001\u5F15\u5BFC\u6D88\u606F",
29687
29485
  className: "flex h-10 w-10 items-center justify-center rounded-full bg-[hsl(213_94%_55%)] text-white disabled:opacity-25",
29688
- children: isSubmitting ? /* @__PURE__ */ jsx23(LoaderCircle, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx23(Send, { size: 16 })
29486
+ children: isSubmitting ? /* @__PURE__ */ jsx24(LoaderCircle, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx24(Send, { size: 16 })
29689
29487
  }
29690
29488
  ) : null,
29691
- /* @__PURE__ */ jsx23(
29489
+ /* @__PURE__ */ jsx24(
29692
29490
  "button",
29693
29491
  {
29694
29492
  type: "button",
@@ -29697,10 +29495,10 @@ ${append2.text}` : append2.text;
29697
29495
  "aria-label": isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u751F\u6210",
29698
29496
  title: isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u751F\u6210",
29699
29497
  className: "flex h-10 w-10 items-center justify-center rounded-full bg-[hsl(var(--destructive))] text-[hsl(var(--destructive-foreground))] transition-opacity hover:opacity-80 disabled:cursor-wait disabled:opacity-70",
29700
- children: isStopping ? /* @__PURE__ */ jsx23(LoaderCircle, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx23(Square, { size: 16 })
29498
+ children: isStopping ? /* @__PURE__ */ jsx24(LoaderCircle, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx24(Square, { size: 16 })
29701
29499
  }
29702
29500
  )
29703
- ] }) : isCompacting ? /* @__PURE__ */ jsx23(
29501
+ ] }) : isCompacting ? /* @__PURE__ */ jsx24(
29704
29502
  "button",
29705
29503
  {
29706
29504
  type: "button",
@@ -29708,9 +29506,9 @@ ${append2.text}` : append2.text;
29708
29506
  "aria-label": developer ? "\u6B63\u5728\u6574\u7406\u5BF9\u8BDD" : "\u6B63\u5728\u5904\u7406",
29709
29507
  title: developer ? "\u6B63\u5728\u6574\u7406\u5BF9\u8BDD" : "\u6B63\u5728\u5904\u7406",
29710
29508
  className: "flex h-10 w-10 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] opacity-50",
29711
- children: /* @__PURE__ */ jsx23(LoaderCircle, { size: 16, className: "animate-spin" })
29509
+ children: /* @__PURE__ */ jsx24(LoaderCircle, { size: 16, className: "animate-spin" })
29712
29510
  }
29713
- ) : !isRecording && hasComposerContent ? /* @__PURE__ */ jsx23(
29511
+ ) : !isRecording && hasComposerContent ? /* @__PURE__ */ jsx24(
29714
29512
  "button",
29715
29513
  {
29716
29514
  type: "button",
@@ -29719,19 +29517,19 @@ ${append2.text}` : append2.text;
29719
29517
  "aria-label": "\u53D1\u9001\u5F15\u5BFC\u6D88\u606F",
29720
29518
  title: isModelLoading ? "\u6B63\u5728\u52A0\u8F7D\u6A21\u578B\u914D\u7F6E" : !hasAvailableModel ? modelAvailabilityMessage : "\u53D1\u9001\u5F15\u5BFC\u6D88\u606F",
29721
29519
  className: "flex h-10 w-10 items-center justify-center rounded-full bg-[hsl(213_94%_55%)] text-white transition-colors duration-[120ms] ease-out hover:bg-[hsl(213_94%_48%)] disabled:opacity-25",
29722
- children: isSubmitting ? /* @__PURE__ */ jsx23(LoaderCircle, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx23(Send, { size: 16 })
29520
+ children: isSubmitting ? /* @__PURE__ */ jsx24(LoaderCircle, { size: 16, className: "animate-spin" }) : /* @__PURE__ */ jsx24(Send, { size: 16 })
29723
29521
  }
29724
29522
  ) : null
29725
29523
  ] })
29726
29524
  ] }),
29727
- slotBelowActions ? /* @__PURE__ */ jsx23("div", { className: "border-t border-[hsl(var(--border))] px-4 py-1.5", children: slotBelowActions }) : null
29525
+ slotBelowActions ? /* @__PURE__ */ jsx24("div", { className: "border-t border-[hsl(var(--border))] px-4 py-1.5", children: slotBelowActions }) : null
29728
29526
  ]
29729
29527
  }
29730
29528
  )
29731
29529
  }
29732
29530
  )
29733
29531
  ] }) }),
29734
- /* @__PURE__ */ jsx23(
29532
+ /* @__PURE__ */ jsx24(
29735
29533
  FileSizeLimitDialog,
29736
29534
  {
29737
29535
  open: oversizedFiles.length > 0,
@@ -29746,6 +29544,42 @@ ${append2.text}` : append2.text;
29746
29544
  )
29747
29545
  ] });
29748
29546
  }
29547
+
29548
+ // src/rich-input/SkillActionMenu.tsx
29549
+ import { useEffect as useEffect9, useState as useState12 } from "react";
29550
+ import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
29551
+ function SkillActionMenu({ open, onOpenChange, renderMode, onSelect, onManage, disabled }) {
29552
+ return /* @__PURE__ */ jsx25(InputActionSubmenu, { label: "\u6280\u80FD", icon: /* @__PURE__ */ jsx25(Sparkles, { size: 16, "aria-hidden": "true" }), open, onOpenChange, disabled, children: /* @__PURE__ */ jsx25(SkillPicker, { renderMode, onSelect, onManage }) });
29553
+ }
29554
+ function SkillPicker({ renderMode, onSelect, onManage }) {
29555
+ const client = useBladeClient();
29556
+ const [query, setQuery] = useState12("");
29557
+ const [skills, setSkills] = useState12(null);
29558
+ useEffect9(() => {
29559
+ let active = true;
29560
+ setSkills(null);
29561
+ getSlashSuggestions(query, { client, sessionId: null, renderMode }).then((items) => {
29562
+ if (active) setSkills(items);
29563
+ }).catch(() => {
29564
+ if (active) setSkills([]);
29565
+ });
29566
+ return () => {
29567
+ active = false;
29568
+ };
29569
+ }, [client, renderMode, query]);
29570
+ return /* @__PURE__ */ jsxs14(Fragment6, { children: [
29571
+ /* @__PURE__ */ jsxs14("label", { className: "m-1 flex items-center gap-2 rounded-lg bg-[hsl(var(--muted))] px-3 py-2", children: [
29572
+ /* @__PURE__ */ jsx25(Search, { size: 14, "aria-hidden": "true" }),
29573
+ /* @__PURE__ */ jsx25("input", { "aria-label": "\u641C\u7D22\u6280\u80FD", placeholder: "\u641C\u7D22\u6280\u80FD", value: query, onChange: (event) => setQuery(event.target.value), className: "min-w-0 flex-1 bg-transparent outline-none" })
29574
+ ] }),
29575
+ /* @__PURE__ */ jsx25("div", { className: "max-h-60 overflow-y-auto", children: skills === null ? /* @__PURE__ */ jsx25("p", { className: "px-3 py-2 text-[hsl(var(--muted-foreground))]", children: "\u52A0\u8F7D\u6280\u80FD\u4E2D\u2026" }) : skills.length ? skills.map((skill) => skill.type === "skill" ? /* @__PURE__ */ jsxs14("button", { type: "button", onClick: () => onSelect(skill), className: "flex w-full flex-col gap-1 rounded-lg px-3 py-2 text-left hover:bg-[hsl(var(--accent))] focus-visible:bg-[hsl(var(--accent))]", children: [
29576
+ /* @__PURE__ */ jsx25("span", { children: skillDisplayName(skill) }),
29577
+ /* @__PURE__ */ jsx25("span", { className: "line-clamp-2 text-[11px] text-[hsl(var(--muted-foreground))]", children: skill.description })
29578
+ ] }, skill.skillId) : null) : /* @__PURE__ */ jsx25("p", { className: "px-3 py-2 text-[hsl(var(--muted-foreground))]", children: "\u6CA1\u6709\u5339\u914D\u7684\u6280\u80FD" }) }),
29579
+ /* @__PURE__ */ jsx25("div", { className: "my-1 border-t border-[hsl(var(--border))]" }),
29580
+ /* @__PURE__ */ jsx25("button", { type: "button", onClick: onManage, className: "w-full rounded-lg px-3 py-2 text-left hover:bg-[hsl(var(--accent))]", children: "\u7BA1\u7406\u6280\u80FD \u2192" })
29581
+ ] });
29582
+ }
29749
29583
  export {
29750
29584
  ATTACHMENT_SIZE_LIMIT_BYTES,
29751
29585
  ATTENTION_STATUSES,
@@ -29757,6 +29591,7 @@ export {
29757
29591
  FileMention,
29758
29592
  FileSizeLimitDialog,
29759
29593
  IMAGE_INPUT_UNSUPPORTED_MESSAGE,
29594
+ InputActionSubmenu,
29760
29595
  LIVE_STATUSES,
29761
29596
  MODEL_LOADING_SEND_HINT,
29762
29597
  MODEL_REASONING_LEVELS_KEY,
@@ -29769,6 +29604,7 @@ export {
29769
29604
  RichInputServicesProvider,
29770
29605
  STATUS_LABELS,
29771
29606
  STOPPABLE_STATUSES,
29607
+ SkillActionMenu,
29772
29608
  SkillCompletionMenu,
29773
29609
  SkillMention,
29774
29610
  SkillStatusBar,