@burdenoff/fe-libs 2026.1029.8 → 2026.1029.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/shared/assistant/i18nManifest.d.ts +27 -0
  2. package/dist/shared/assistant/i18nManifest.js +27 -0
  3. package/dist/shared/assistant/index.d.ts +9 -0
  4. package/dist/shared/assistant/speech/speechFeed.d.ts +4 -3
  5. package/dist/shared/assistant/speech/speechFeed.js +3 -2
  6. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts +11 -0
  7. package/dist/shared/assistant/ui/AIAssistantPanel.js +233 -127
  8. package/dist/shared/assistant/ui/AssistantChatArea.d.ts +13 -1
  9. package/dist/shared/assistant/ui/AssistantChatArea.js +1632 -1605
  10. package/dist/shared/assistant/ui/AssistantConversationList.d.ts +17 -1
  11. package/dist/shared/assistant/ui/AssistantConversationList.js +304 -274
  12. package/dist/shared/assistant/ui/AssistantOverlay.d.ts +11 -0
  13. package/dist/shared/assistant/ui/AssistantOverlay.js +106 -90
  14. package/dist/shared/assistant/ui/AssistantSpeechProvider.js +140 -137
  15. package/dist/shared/assistant/ui/closeGuard.d.ts +21 -0
  16. package/dist/shared/assistant/ui/closeGuard.js +8 -0
  17. package/dist/shared/assistant/ui/compact/AssistantCompactHeader.d.ts +38 -0
  18. package/dist/shared/assistant/ui/compact/AssistantCompactHeader.js +89 -0
  19. package/dist/shared/assistant/ui/compact/AssistantConversationMenu.d.ts +29 -0
  20. package/dist/shared/assistant/ui/compact/AssistantConversationMenu.js +87 -0
  21. package/dist/shared/assistant/ui/compact/AssistantDiscardDraftDialog.d.ts +19 -0
  22. package/dist/shared/assistant/ui/compact/AssistantDiscardDraftDialog.js +38 -0
  23. package/dist/shared/assistant/ui/compact/AssistantMenuView.d.ts +42 -0
  24. package/dist/shared/assistant/ui/compact/AssistantMenuView.js +285 -0
  25. package/dist/shared/assistant/ui/compact/AssistantVoiceLanguageSettings.d.ts +24 -0
  26. package/dist/shared/assistant/ui/compact/AssistantVoiceLanguageSettings.js +68 -0
  27. package/dist/shared/assistant/ui/compact/AssistantWaitingChangeRow.d.ts +21 -0
  28. package/dist/shared/assistant/ui/compact/AssistantWaitingChangeRow.js +34 -0
  29. package/dist/shared/assistant/ui/compact/compactChrome.d.ts +75 -0
  30. package/dist/shared/assistant/ui/compact/compactChrome.js +39 -0
  31. package/dist/shared/assistant/ui/compact/waitingChange.d.ts +49 -0
  32. package/dist/shared/assistant/ui/compact/waitingChange.js +12 -0
  33. package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts +19 -18
  34. package/dist/shared/assistant/ui/composer/AssistantComposer.js +261 -224
  35. package/dist/shared/assistant/ui/useVoiceSession.js +13 -8
  36. package/dist/shared/assistant/useAssistantKeyboardShortcuts.d.ts +16 -2
  37. package/dist/shared/assistant/useAssistantKeyboardShortcuts.js +28 -16
  38. package/dist/shared-assistant.js +42 -33
  39. package/package.json +1 -1
@@ -2,8 +2,8 @@ import { useI18n as e } from "../../../providers/shell/I18nProvider.js";
2
2
  import { EscapeLayer as t } from "../../../components/EscapeLayer.js";
3
3
  import { useVoiceInput as n } from "../../voice/useVoiceInput.js";
4
4
  import { useAssistantTr as r } from "../../i18n.js";
5
- import { useAssistantStore as i } from "../../store.js";
6
- import { languageDisplayName as ee } from "../../voice/speechVoices.js";
5
+ import { useAssistantStore as ee } from "../../store.js";
6
+ import { languageDisplayName as i } from "../../voice/speechVoices.js";
7
7
  import { resolveAssistantLanguage as te } from "../../voice/languages.js";
8
8
  import { attachmentEditorAccessMessage as ne } from "../../attachmentAccessCopy.js";
9
9
  import { getSendableAttachments as re } from "../../attachments.js";
@@ -12,168 +12,194 @@ import { AssistantAttachmentButton as ie } from "./AssistantAttachmentButton.js"
12
12
  import { AssistantAttachmentChips as ae } from "./AssistantAttachmentChips.js";
13
13
  import { AssistantModeSelector as oe } from "./AssistantModeSelector.js";
14
14
  import { AssistantModeMenu as se } from "./AssistantModeMenu.js";
15
- import { compactEnterSends as ce } from "./imeEnter.js";
16
- import { AssistantVoiceButton as le, ListeningDot as ue } from "./AssistantVoiceButton.js";
17
- import { AssistantVoiceSessionButton as de } from "../voice/AssistantVoiceSessionButton.js";
18
- import { useAssistantAttachments as fe } from "../../useAssistantAttachments.js";
19
- import { useCallback as o, useEffect as s, useLayoutEffect as pe, useMemo as me, useRef as c, useState as l } from "react";
20
- import { ArrowUp as he, Loader2 as u, Square as ge } from "lucide-react";
21
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
15
+ import { compactEnterSends as ce, isImeComposingEnter as le } from "./imeEnter.js";
16
+ import { AssistantVoiceButton as ue, ListeningDot as de } from "./AssistantVoiceButton.js";
17
+ import { AssistantVoiceSessionButton as fe } from "../voice/AssistantVoiceSessionButton.js";
18
+ import { useAssistantAttachments as pe } from "../../useAssistantAttachments.js";
19
+ import { useCallback as o, useEffect as s, useLayoutEffect as c, useMemo as me, useRef as l, useState as u } from "react";
20
+ import { ArrowUp as he, Loader2 as d, Square as ge } from "lucide-react";
21
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
22
22
  //#region src/shared/assistant/ui/composer/AssistantComposer.tsx
23
- var _e = 200, p = ({ writeAccessDenied: p = !1, onSend: m, disabled: h = !1, readOnly: ve = !1, placeholder: ye, mode: be, availableModes: g, attachmentCharsPerFile: xe, onModeChange: Se, auto: Ce, onStartVoiceSession: _, onDraftStart: we, onDraftChange: Te, suspendDictation: Ee = !1, onVoiceStateChange: De, presentation: Oe = "classic", turnInFlight: v = !1, onStop: y, modeDisabledReason: ke = null }) => {
24
- let b = r(), { locale: x } = e(), S = h || ve, Ae = Oe === "compact", C = c(null), [w, T] = l(""), [E, D] = l(!1), [O, je] = l(!1), k = c(!1), [Me, A] = l(null), [Ne, j] = l(null), [Pe, Fe] = l(v);
25
- Pe !== v && (Fe(v), v && j(null));
26
- let M = c(!1), N = c(null), P = c(!1), F = c(0), { attachments: I, isBusy: Ie, preparingCount: Le, sendBlocker: Re, rejection: ze, addFiles: L, remove: Be, retry: Ve, clear: R, clearRejection: He, canAddMore: Ue, commit: We, cancelCommit: Ge } = fe({ perFileChars: xe }), z = w.trim() !== "" || I.length > 0, B = c(!1), V = c(!1);
23
+ var _e = 200;
24
+ function ve(e) {
25
+ if (!e) return !1;
26
+ let t = e.ownerDocument.activeElement;
27
+ return !t || t === e.ownerDocument.body ? !1 : e.contains(t) ? !0 : e.closest("[data-assistant-panel]")?.contains(t) ?? !1;
28
+ }
29
+ var m = ({ writeAccessDenied: m = !1, onSend: ye, disabled: h = !1, readOnly: be = !1, placeholder: xe, mode: Se, availableModes: g, attachmentCharsPerFile: Ce, onModeChange: we, auto: Te, onStartVoiceSession: _, onDraftStart: Ee, onDraftChange: De, suspendDictation: Oe = !1, onVoiceStateChange: ke, presentation: Ae = "classic", turnInFlight: v = !1, onStop: je, turnId: Me, modeDisabledReason: Ne = null, inputRef: y, aboveCard: Pe }) => {
30
+ let b = r(), { locale: x } = e(), S = h || be, C = Ae === "compact", w = l(null), Fe = o((e) => {
31
+ w.current = e, typeof y == "function" ? y(e) : y && (y.current = e);
32
+ }, [y]), [T, E] = u(""), [D, Ie] = u(!1), [O, Le] = u(!1), k = l(!1), [Re, A] = u(null), [ze, j] = u(null), [M, N] = u(null), [Be, Ve] = u(v);
33
+ Be === v ? M !== null && v && Me != null && Me !== M && N(null) : (Ve(v), v ? (j(null), N(null)) : M !== null && (j(M), N(null)));
34
+ let He = l(!1), P = l(null), Ue = l(!1), We = l(!1), Ge = l(null), F = l(!1), I = l(0), { attachments: L, isBusy: Ke, preparingCount: qe, sendBlocker: Je, rejection: Ye, addFiles: R, remove: Xe, retry: Ze, clear: z, clearRejection: Qe, canAddMore: $e, commit: et, cancelCommit: tt } = pe({ perFileChars: Ce }), B = T.trim() !== "" || L.length > 0, V = l(!1), H = l(!1);
27
35
  s(() => {
28
- z && !B.current ? (B.current = !0, we?.()) : z || (B.current = !1);
29
- }, [z, we]), s(() => {
30
- z || (V.current = !1), Te?.({
31
- text: w,
32
- hasAttachments: I.length > 0,
33
- dictated: V.current
36
+ B && !V.current ? (V.current = !0, Ee?.()) : B || (V.current = !1);
37
+ }, [B, Ee]), s(() => {
38
+ B || (H.current = !1), De?.({
39
+ text: T,
40
+ hasAttachments: L.length > 0,
41
+ dictated: H.current
34
42
  });
35
43
  }, [
36
- w,
37
- I.length,
38
- z,
39
- Te
44
+ T,
45
+ L.length,
46
+ B,
47
+ De
40
48
  ]);
41
- let H = o((e) => {
42
- V.current = !0, T((t) => t ? `${t.replace(/\s+$/, "")} ${e}` : e);
43
- }, []), Ke = i((e) => e.assistantLanguage), U = n({
44
- onFinalize: H,
45
- language: me(() => te(Ke, x), [Ke, x]).tag
46
- }), W = U.isActive, G = U.interim, qe = U.stop;
49
+ let U = o((e) => {
50
+ H.current = !0, E((t) => t ? `${t.replace(/\s+$/, "")} ${e}` : e);
51
+ }, []), nt = ee((e) => e.assistantLanguage), W = n({
52
+ onFinalize: U,
53
+ language: me(() => te(nt, x), [nt, x]).tag
54
+ }), G = W.isActive, K = W.interim, rt = W.stop;
47
55
  s(() => {
48
- !Ee || !W || (G.trim() !== "" && H(G.trim()), qe());
56
+ !Oe || !G || (K.trim() !== "" && U(K.trim()), rt());
49
57
  }, [
50
- Ee,
51
- W,
58
+ Oe,
52
59
  G,
53
- qe,
54
- H
60
+ K,
61
+ rt,
62
+ U
55
63
  ]), s(() => {
56
- De?.({
64
+ ke?.({
57
65
  committing: O,
58
- dictating: W
66
+ dictating: G
59
67
  });
60
68
  }, [
61
- De,
69
+ ke,
62
70
  O,
63
- W
71
+ G
64
72
  ]);
65
- let Je = ye ?? b("composer.placeholder", "Ask me anything…"), K = w.trim(), q = re(I), J = I.filter((e) => e.status === "error"), Y = (K.length > 0 || q.length > 0) && !S && !O && Re === null, Ye = q.some((e) => !(e.fileId && e.downloadUrl) && !e.inlineOnly), X = c(S);
66
- X.current = S;
67
- let Z = c(!0);
68
- s(() => (Z.current = !0, () => {
69
- Z.current = !1;
70
- }), []), pe(() => {
71
- let e = C.current;
73
+ let it = xe ?? b("composer.placeholder", "Ask me anything…"), q = T.trim(), J = re(L), at = L.filter((e) => e.status === "error"), Y = (q.length > 0 || J.length > 0) && !S && !O && Je === null, ot = J.some((e) => !(e.fileId && e.downloadUrl) && !e.inlineOnly), st = l(S);
74
+ st.current = S;
75
+ let X = l(!0);
76
+ s(() => (X.current = !0, () => {
77
+ X.current = !1;
78
+ }), []), c(() => {
79
+ let e = w.current;
72
80
  e && (e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, _e)}px`);
73
- }, [w]);
74
- let Q = o(async () => {
81
+ }, [T]);
82
+ let Z = o(async () => {
75
83
  if (!Y || k.current) return;
76
- U.isActive && U.stop();
77
- let e = w.trim();
78
- if (A(null), !Ye) {
79
- m(e, q), T(""), R();
84
+ W.isActive && W.stop();
85
+ let e = T.trim();
86
+ A(null);
87
+ let t = C && ve(Ge.current);
88
+ if (!ot) {
89
+ F.current = t, ye(e, J), E(""), z();
80
90
  return;
81
91
  }
82
- let t = i.getState().activeConversationId;
83
- k.current = !0, je(!0);
92
+ let n = ee.getState().activeConversationId;
93
+ k.current = !0, Le(!0);
84
94
  try {
85
- let n = await We();
86
- if (!Z.current) {
87
- n.ok && await n.rollback();
95
+ let r = await et();
96
+ if (!X.current) {
97
+ r.ok && await r.rollback();
88
98
  return;
89
99
  }
90
- if (!n.ok) {
91
- n.cancelled || A({
100
+ if (!r.ok) {
101
+ r.cancelled || A({
92
102
  kind: "failed",
93
- failures: n.failures
103
+ failures: r.failures
94
104
  });
95
105
  return;
96
106
  }
97
- if (X.current) {
98
- await n.rollback(), Z.current && A({
107
+ if (st.current) {
108
+ await r.rollback(), X.current && A({
99
109
  kind: "busy",
100
110
  failures: []
101
111
  });
102
112
  return;
103
113
  }
104
- let r = i.getState();
105
- if (!(r.activeConversationId === t && (t === null || r.conversations.some((e) => e.id === t)))) {
106
- await n.rollback(), Z.current && A({
114
+ let i = ee.getState();
115
+ if (!(i.activeConversationId === n && (n === null || i.conversations.some((e) => e.id === n)))) {
116
+ await r.rollback(), X.current && A({
107
117
  kind: "moved",
108
118
  failures: []
109
119
  });
110
120
  return;
111
121
  }
112
- m(e, re(n.attachments)), n.handedOver(), T(""), R();
122
+ F.current = t, ye(e, re(r.attachments)), r.handedOver(), E(""), z();
113
123
  } finally {
114
- k.current = !1, Z.current && je(!1);
124
+ k.current = !1, X.current && Le(!1);
115
125
  }
116
126
  }, [
117
127
  Y,
118
- Ye,
119
- We,
120
- m,
121
- w,
122
- q,
123
- R,
124
- U
125
- ]), Xe = o(() => {
126
- Ge(), C.current?.focus();
127
- }, [Ge]), $ = o(() => {
128
- X.current ? M.current = !0 : C.current?.focus();
129
- }, []), Ze = o(() => {
130
- let e = y?.() ?? null;
131
- e !== null && j(e), $();
132
- }, [y, $]);
128
+ ot,
129
+ et,
130
+ ye,
131
+ T,
132
+ J,
133
+ z,
134
+ W,
135
+ C
136
+ ]), ct = o(() => {
137
+ tt(), w.current?.focus();
138
+ }, [tt]), Q = o(() => {
139
+ st.current ? He.current = !0 : w.current?.focus();
140
+ }, []), lt = o(() => {
141
+ if (We.current) return;
142
+ let e = je?.() ?? null;
143
+ e !== null && (We.current = !0, N(e)), Q();
144
+ }, [je, Q]);
133
145
  s(() => {
134
- S || !M.current || (M.current = !1, C.current?.focus());
146
+ S || !He.current || (He.current = !1, w.current?.focus());
135
147
  }, [S]);
136
- let Qe = o((e) => {
148
+ let ut = o((e) => {
137
149
  if (e !== null) {
138
- N.current = e;
150
+ P.current = e;
139
151
  return;
140
152
  }
141
- let t = N.current;
142
- N.current = null, t !== null && t.ownerDocument.activeElement === t && (P.current = !0);
143
- }, []), $e = Ae && v && y !== void 0;
144
- pe(() => {
145
- $e || !P.current || (P.current = !1, $());
146
- }, [$e, $]);
147
- let et = o((e) => {
148
- T(e), j(null);
153
+ let t = P.current;
154
+ P.current = null, t !== null && t.ownerDocument.activeElement === t && (Ue.current = !0);
155
+ }, []), $ = C && v && je !== void 0;
156
+ c(() => {
157
+ $ || !Ue.current || (Ue.current = !1, Q());
158
+ }, [$, Q]), s(() => {
159
+ M === null && (We.current = !1);
160
+ }, [M]), c(() => {
161
+ if (!$) return;
162
+ let e = F.current;
163
+ if (F.current = !1, !e) return;
164
+ let t = P.current;
165
+ if (t === null) return;
166
+ let n = t.ownerDocument, r = n.activeElement;
167
+ (r === null || r === n.body || r === w.current) && t.focus({ preventScroll: !0 });
168
+ }, [$]);
169
+ let dt = o((e) => {
170
+ E(e), j(null);
149
171
  }, []);
150
172
  s(() => {
151
173
  A(null);
152
- }, [I.length]);
153
- let tt = (e) => {
174
+ }, [L.length]);
175
+ let ft = (e) => {
154
176
  if (e.kind === "busy") return b("attachments.saveBusy", "The assistant started another reply, so nothing was sent. Your message and files are still here.");
155
177
  if (e.kind === "moved") return b("attachments.saveMoved", "You switched conversations while the files were being saved, so nothing was sent. Your message and files are still here.");
156
178
  let { failures: t } = e;
157
179
  if (t.some((e) => e.code === a.editorAccessRequired)) return ne(b, x);
158
180
  if (t.some((e) => e.code === a.quotaExceeded || e.code === a.quotaNotProvisioned)) return `${b("attachments.quotaFull", "File storage is full or not set up for this workspace, so the attachments couldn't be saved. Nothing was sent.")} ${b("attachments.retrySend", "Press Send to try again, or remove the file.")}`;
159
- let n = t[0], r = I.find((e) => e.id === n?.id)?.filename ?? "";
181
+ let n = t[0], r = L.find((e) => e.id === n?.id)?.filename ?? "";
160
182
  return `${t.length <= 1 ? b("attachments.saveFailedOne", "{{name}} couldn't be saved, so nothing was sent.", { name: r }) : b("attachments.saveFailedMany", "{{count}} attachments couldn't be saved, so nothing was sent.", { count: t.length })} ${b("attachments.retrySend", "Press Send to try again, or remove the file.")}`;
161
- }, nt = o((e) => {
162
- e.key === "Enter" && !e.shiftKey && (e.preventDefault(), Q());
163
- }, [Q]), rt = o((e) => {
164
- ce(e) && (e.preventDefault(), j(null), Q());
165
- }, [Q]), it = o((e) => {
183
+ }, pt = o((e) => {
184
+ e.key === "Enter" && !e.shiftKey && (e.preventDefault(), Z());
185
+ }, [Z]), mt = o((e) => {
186
+ if (e.key === "Escape") {
187
+ le(e) && e.stopPropagation();
188
+ return;
189
+ }
190
+ ce(e) && (e.preventDefault(), j(null), Z());
191
+ }, [Z]), ht = o((e) => {
166
192
  let t = Array.from(e.clipboardData?.files ?? []);
167
- t.length !== 0 && (e.preventDefault(), L(t));
168
- }, [L]), at = o((e) => {
169
- Array.from(e.dataTransfer?.types ?? []).includes("Files") && (F.current += 1, D(!0));
170
- }, []), ot = o(() => {
171
- F.current = Math.max(0, F.current - 1), F.current === 0 && D(!1);
172
- }, []), st = o((e) => {
193
+ t.length !== 0 && (e.preventDefault(), R(t));
194
+ }, [R]), gt = o((e) => {
195
+ Array.from(e.dataTransfer?.types ?? []).includes("Files") && (I.current += 1, Ie(!0));
196
+ }, []), _t = o(() => {
197
+ I.current = Math.max(0, I.current - 1), I.current === 0 && Ie(!1);
198
+ }, []), vt = o((e) => {
173
199
  Array.from(e.dataTransfer?.types ?? []).includes("Files") && e.preventDefault();
174
- }, []), ct = o((e) => {
175
- e.preventDefault(), F.current = 0, D(!1), L(e.dataTransfer?.files ?? null);
176
- }, [L]), lt = (e) => {
200
+ }, []), yt = o((e) => {
201
+ e.preventDefault(), I.current = 0, Ie(!1), R(e.dataTransfer?.files ?? null);
202
+ }, [R]), bt = (e) => {
177
203
  switch (e) {
178
204
  case "too-many": return b("attachments.tooMany", "You can attach up to {{max}} files per message.", { max: 5 });
179
205
  case "too-large": return b("attachments.tooLarge", "That file is larger than 10 MB.");
@@ -182,161 +208,172 @@ var _e = 200, p = ({ writeAccessDenied: p = !1, onSend: m, disabled: h = !1, rea
182
208
  case "unsupported-image": return b("attachments.unsupportedImage", "This device can't read that image format, so it can't be resized to send. Save it as JPEG and try again.");
183
209
  case "too-large-to-save": return b("attachments.tooLargeToSave", "That file is over 5 MB, so it can't be saved to Files, and no text could be read from it.");
184
210
  }
185
- }, ut = (() => {
186
- switch (U.error) {
211
+ }, xt = (() => {
212
+ switch (W.error) {
187
213
  case "not-allowed": return b("voice.denied", "Microphone access is blocked. Allow it in your browser settings to dictate.");
188
214
  case "audio-capture": return b("voice.noMic", "No microphone was found.");
189
215
  case "network": return b("voice.network", "Speech recognition is offline right now.");
190
- case "language-not-supported": return b("voice.languageNotSupported", "This browser cannot recognise spoken {{language}}. Try a different browser, or type instead.", { language: ee(U.language, x) });
216
+ case "language-not-supported": return b("voice.languageNotSupported", "This browser cannot recognise spoken {{language}}. Try a different browser, or type instead.", { language: i(W.language, x) });
191
217
  case "unknown": return b("voice.failed", "Dictation stopped unexpectedly.");
192
218
  default: return null;
193
219
  }
194
- })(), dt = (e) => O ? /* @__PURE__ */ d(t, {
195
- onDismiss: Xe,
196
- children: /* @__PURE__ */ f("p", {
220
+ })(), St = (e, n) => O ? /* @__PURE__ */ f(t, {
221
+ onDismiss: ct,
222
+ children: /* @__PURE__ */ p("p", {
197
223
  className: "flex items-center justify-center gap-2 text-text-muted",
198
224
  "data-testid": "assistant-commit-status",
199
225
  children: [
200
- /* @__PURE__ */ d(u, {
226
+ /* @__PURE__ */ f(d, {
201
227
  className: "size-3 motion-safe:animate-spin",
202
228
  "aria-hidden": "true"
203
229
  }),
204
- /* @__PURE__ */ d("span", { children: b("attachments.saving", "Saving your attachments…") }),
205
- /* @__PURE__ */ d("button", {
230
+ /* @__PURE__ */ f("span", { children: b("attachments.saving", "Saving your attachments…") }),
231
+ /* @__PURE__ */ f("button", {
206
232
  type: "button",
207
- onClick: Xe,
233
+ onClick: ct,
208
234
  className: "rounded text-text-primary underline underline-offset-2 hover:text-action-primary-bg focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
209
235
  "data-testid": "assistant-commit-cancel",
210
236
  children: b("attachments.cancelSaving", "Cancel")
211
237
  })
212
238
  ]
213
239
  })
214
- }) : Me ? /* @__PURE__ */ d("p", {
240
+ }) : Re ? /* @__PURE__ */ f("p", {
215
241
  className: "text-status-error-text",
216
242
  role: "alert",
217
243
  "data-testid": "assistant-commit-failed",
218
- children: tt(Me)
219
- }) : U.isStarting && !U.isListening ? /* @__PURE__ */ d("p", {
244
+ children: ft(Re)
245
+ }) : W.isStarting && !W.isListening ? /* @__PURE__ */ f("p", {
220
246
  className: "text-text-muted",
221
247
  "data-testid": "assistant-voice-starting",
222
248
  children: b("voice.starting", "Starting the microphone…")
223
- }) : U.isListening ? /* @__PURE__ */ f("p", {
249
+ }) : W.isListening ? /* @__PURE__ */ p("p", {
224
250
  className: "text-status-error-text",
225
251
  "data-testid": "assistant-voice-status",
226
- children: [/* @__PURE__ */ d(ue, {}), U.interim || b("voice.listening", "Listening… speak now, tap the square to stop")]
227
- }) : ut ? /* @__PURE__ */ d("p", {
252
+ children: [/* @__PURE__ */ f(de, {}), W.interim || b("voice.listening", "Listening… speak now, tap the square to stop")]
253
+ }) : xt ? /* @__PURE__ */ f("p", {
228
254
  className: "text-status-error-text",
229
255
  "data-testid": "assistant-voice-error",
230
- children: ut
231
- }) : ze ? /* @__PURE__ */ d("button", {
256
+ children: xt
257
+ }) : Ye ? /* @__PURE__ */ f("button", {
232
258
  type: "button",
233
- onClick: He,
259
+ onClick: Qe,
234
260
  className: "text-status-error-text underline-offset-2 hover:underline",
235
261
  "data-testid": "assistant-attachment-rejection",
236
- children: lt(ze)
237
- }) : Re === "failed" ? /* @__PURE__ */ d("p", {
262
+ children: bt(Ye)
263
+ }) : Je === "failed" ? /* @__PURE__ */ f("p", {
238
264
  className: "text-status-error-text",
239
265
  "data-testid": "assistant-attachment-blocked",
240
- children: J.length === 1 ? b("attachments.blockedOne", "{{name}} didn't upload. Retry or remove it before sending.", { name: J[0].filename }) : b("attachments.blockedMany", "{{count}} attachments didn't upload. Retry or remove them before sending.", { count: J.length })
241
- }) : e ? /* @__PURE__ */ d("p", {
266
+ children: at.length === 1 ? b("attachments.blockedOne", "{{name}} didn't upload. Retry or remove it before sending.", { name: at[0].filename }) : b("attachments.blockedMany", "{{count}} attachments didn't upload. Retry or remove them before sending.", { count: at.length })
267
+ }) : n ? /* @__PURE__ */ f("p", {
268
+ className: "text-text-muted",
269
+ "data-testid": "assistant-stopping-status",
270
+ children: b("composer.stopping", "Stopping the reply…")
271
+ }) : e ? /* @__PURE__ */ f("p", {
242
272
  className: "text-text-muted",
243
273
  "data-testid": "assistant-stop-status",
244
274
  children: b("composer.stopped", "Reply stopped.")
245
- }) : /* @__PURE__ */ d("p", {
275
+ }) : /* @__PURE__ */ f("p", {
246
276
  className: "text-text-muted",
247
277
  children: b("composer.hint", "Enter to send · Shift+Enter for newline · drag or paste files to attach")
248
278
  });
249
- if (Ae) {
250
- let e = _ !== void 0 && K.length === 0 && I.length === 0 && !U.isActive, t = "focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-bg-elevated)]";
251
- return /* @__PURE__ */ f("div", {
279
+ if (C) {
280
+ let e = _ !== void 0 && q.length === 0 && L.length === 0 && !W.isActive, t = "focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-bg-elevated)]";
281
+ return /* @__PURE__ */ p("div", {
282
+ ref: Ge,
252
283
  className: "flex-shrink-0 px-3 pb-3 pt-1.5",
253
284
  children: [
254
- /* @__PURE__ */ f("div", {
255
- onDragEnter: at,
256
- onDragLeave: ot,
257
- onDragOver: st,
258
- onDrop: ct,
259
- className: `flex flex-col rounded-3xl border bg-bg-elevated shadow-[var(--shadow-elevation-2)] transition-colors focus-within:border-[var(--color-focus-ring)] focus-within:ring-1 focus-within:ring-[var(--color-focus-ring)] ${E ? "border-dashed border-[var(--color-focus-ring)]" : "border-[var(--color-text-muted)]"}`,
285
+ Pe,
286
+ /* @__PURE__ */ p("div", {
287
+ onDragEnter: gt,
288
+ onDragLeave: _t,
289
+ onDragOver: vt,
290
+ onDrop: yt,
291
+ className: `flex flex-col rounded-3xl border bg-bg-elevated shadow-[var(--shadow-elevation-2)] transition-colors focus-within:border-[var(--color-focus-ring)] focus-within:ring-1 focus-within:ring-[var(--color-focus-ring)] ${D ? "border-dashed border-[var(--color-focus-ring)]" : "border-[var(--color-text-muted)]"}`,
260
292
  "data-testid": "assistant-composer",
261
293
  "data-presentation": "compact",
262
294
  children: [
263
- /* @__PURE__ */ d("div", {
295
+ /* @__PURE__ */ f("div", {
264
296
  className: "px-3 pt-3 empty:hidden",
265
- children: /* @__PURE__ */ d(ae, {
266
- attachments: I,
267
- onRemove: Be,
268
- onRetry: Ve,
297
+ children: /* @__PURE__ */ f(ae, {
298
+ attachments: L,
299
+ onRemove: Xe,
300
+ onRetry: Ze,
269
301
  disabled: S || O,
270
- preparingCount: Le
302
+ preparingCount: qe
271
303
  })
272
304
  }),
273
- /* @__PURE__ */ d("textarea", {
274
- ref: C,
275
- value: w,
276
- onChange: (e) => et(e.target.value),
277
- onKeyDown: rt,
278
- onPaste: it,
305
+ /* @__PURE__ */ f("textarea", {
306
+ ref: Fe,
307
+ value: T,
308
+ onChange: (e) => dt(e.target.value),
309
+ onKeyDown: mt,
310
+ onPaste: ht,
279
311
  disabled: S,
280
312
  readOnly: O,
281
313
  "aria-busy": O || void 0,
282
- placeholder: E ? b("composer.dropHere", "Drop files to attach") : Je,
314
+ placeholder: D ? b("composer.dropHere", "Drop files to attach") : it,
283
315
  rows: 1,
284
316
  className: "min-h-14 w-full resize-none bg-transparent px-5 pb-2 pt-4 text-base leading-6 text-text-primary placeholder:text-text-muted focus:outline-none disabled:opacity-50",
285
317
  "aria-label": b("chatInput.ariaLabel", "Message input"),
286
318
  "data-testid": "assistant-input"
287
319
  }),
288
- /* @__PURE__ */ f("div", {
320
+ /* @__PURE__ */ p("div", {
289
321
  className: "flex items-center gap-1 px-2 pb-2 pt-1",
290
322
  children: [
291
- /* @__PURE__ */ d(ie, {
292
- onFiles: L,
293
- canAddMore: Ue,
323
+ /* @__PURE__ */ f(ie, {
324
+ onFiles: R,
325
+ canAddMore: $e,
294
326
  disabled: S || O,
295
327
  showLabel: !0
296
328
  }),
297
- /* @__PURE__ */ d(se, {
298
- mode: be,
329
+ /* @__PURE__ */ f(se, {
330
+ mode: Se,
299
331
  availableModes: g,
300
- onModeChange: Se,
301
- auto: Ce,
332
+ onModeChange: we,
333
+ auto: Te,
302
334
  disabled: S || O,
303
- disabledReason: v ? "replying" : ke ?? "busy"
335
+ disabledReason: M === null ? v ? "replying" : Ne ?? "busy" : "busy"
304
336
  }),
305
- /* @__PURE__ */ d("div", { className: "min-w-0 flex-1" }),
306
- U.isSupported && /* @__PURE__ */ d(le, {
307
- isListening: U.isListening,
308
- isStarting: U.isStarting,
309
- onToggle: U.toggle,
337
+ /* @__PURE__ */ f("div", { className: "min-w-0 flex-1" }),
338
+ W.isSupported && /* @__PURE__ */ f(ue, {
339
+ isListening: W.isListening,
340
+ isStarting: W.isStarting,
341
+ onToggle: W.toggle,
310
342
  disabled: S || O
311
343
  }),
312
- $e ? /* @__PURE__ */ d("button", {
313
- ref: Qe,
344
+ $ ? /* @__PURE__ */ f("button", {
345
+ ref: ut,
314
346
  type: "button",
315
- onClick: Ze,
316
- className: `flex size-10 flex-shrink-0 items-center justify-center rounded-full bg-action-primary-bg text-action-primary-text transition-colors hover:bg-action-primary-bg-hover ${t}`,
317
- "aria-label": b("composer.stop", "Stop the reply"),
318
- title: b("composer.stop", "Stop the reply"),
347
+ onClick: lt,
348
+ className: `flex size-10 flex-shrink-0 items-center justify-center rounded-full bg-action-primary-bg text-action-primary-text transition-colors hover:bg-action-primary-bg-hover ${t} ${M === null ? "" : "cursor-default opacity-60"}`,
349
+ "aria-label": M === null ? b("composer.stop", "Stop the reply") : b("composer.stopping", "Stopping the reply…"),
350
+ title: M === null ? b("composer.stop", "Stop the reply") : b("composer.stopping", "Stopping the reply…"),
351
+ "aria-disabled": M === null ? void 0 : "true",
352
+ "aria-busy": M === null ? void 0 : "true",
319
353
  "data-testid": "assistant-stop",
320
- children: /* @__PURE__ */ d(ge, {
354
+ children: M === null ? /* @__PURE__ */ f(ge, {
321
355
  className: "size-4 fill-current",
322
356
  "aria-hidden": "true"
357
+ }) : /* @__PURE__ */ f(d, {
358
+ className: "size-4 motion-safe:animate-spin",
359
+ "aria-hidden": "true"
323
360
  })
324
- }) : e ? /* @__PURE__ */ d(de, {
361
+ }) : e ? /* @__PURE__ */ f(fe, {
325
362
  onStart: _,
326
363
  disabled: S || O
327
- }) : /* @__PURE__ */ d("button", {
364
+ }) : /* @__PURE__ */ f("button", {
328
365
  type: "button",
329
366
  onClick: () => {
330
- j(null), Q();
367
+ j(null), Z();
331
368
  },
332
369
  disabled: !Y,
333
370
  className: `flex size-10 flex-shrink-0 items-center justify-center rounded-full transition-colors ${t} ${Y ? "bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover" : "bg-[var(--color-bg-disabled)] text-[var(--color-text-disabled)]"}`,
334
371
  "aria-label": b("chatInput.send", "Send message"),
335
372
  "data-testid": "assistant-send",
336
- children: h || Ie || O ? /* @__PURE__ */ d(u, {
373
+ children: h || Ke || O ? /* @__PURE__ */ f(d, {
337
374
  className: "size-5 motion-safe:animate-spin",
338
375
  "aria-hidden": "true"
339
- }) : /* @__PURE__ */ d(he, {
376
+ }) : /* @__PURE__ */ f(he, {
340
377
  className: "size-5",
341
378
  "aria-hidden": "true"
342
379
  })
@@ -345,105 +382,105 @@ var _e = 200, p = ({ writeAccessDenied: p = !1, onSend: m, disabled: h = !1, rea
345
382
  })
346
383
  ]
347
384
  }),
348
- p ? /* @__PURE__ */ d("p", {
385
+ m ? /* @__PURE__ */ f("p", {
349
386
  className: "mt-1.5 px-1 text-center text-xs text-status-warning",
350
387
  "data-testid": "assistant-write-access-warning",
351
388
  children: b("composer.writeAccessDenied", "Changes may not save — your role in this workspace does not currently allow edits. You can still plan and review an action.")
352
389
  }) : null,
353
- /* @__PURE__ */ d("div", {
390
+ /* @__PURE__ */ f("div", {
354
391
  className: "mt-1.5 px-1 text-center text-xs",
355
392
  "aria-live": "polite",
356
- children: dt(Ne !== null)
393
+ children: St(ze !== null, M !== null)
357
394
  })
358
395
  ]
359
396
  });
360
397
  }
361
- return /* @__PURE__ */ f("div", {
398
+ return /* @__PURE__ */ p("div", {
362
399
  className: "flex-shrink-0 px-3 pb-3 pt-1.5",
363
400
  children: [
364
- /* @__PURE__ */ f("div", {
365
- onDragEnter: at,
366
- onDragLeave: ot,
367
- onDragOver: st,
368
- onDrop: ct,
369
- className: `rounded-2xl border p-2 shadow-sm transition-colors focus-within:border-action-primary-bg focus-within:ring-2 focus-within:ring-action-primary-bg/15 ${E ? "border-action-primary-bg border-dashed bg-action-primary-bg/5" : "border-border-default bg-bg-sunken"}`,
401
+ /* @__PURE__ */ p("div", {
402
+ onDragEnter: gt,
403
+ onDragLeave: _t,
404
+ onDragOver: vt,
405
+ onDrop: yt,
406
+ className: `rounded-2xl border p-2 shadow-sm transition-colors focus-within:border-action-primary-bg focus-within:ring-2 focus-within:ring-action-primary-bg/15 ${D ? "border-action-primary-bg border-dashed bg-action-primary-bg/5" : "border-border-default bg-bg-sunken"}`,
370
407
  "data-testid": "assistant-composer",
371
408
  children: [
372
- /* @__PURE__ */ d(ae, {
373
- attachments: I,
374
- onRemove: Be,
375
- onRetry: Ve,
409
+ /* @__PURE__ */ f(ae, {
410
+ attachments: L,
411
+ onRemove: Xe,
412
+ onRetry: Ze,
376
413
  disabled: S || O,
377
- preparingCount: Le
414
+ preparingCount: qe
378
415
  }),
379
- /* @__PURE__ */ f("div", {
416
+ /* @__PURE__ */ p("div", {
380
417
  className: "flex items-end gap-2",
381
418
  children: [
382
- /* @__PURE__ */ d(ie, {
383
- onFiles: L,
384
- canAddMore: Ue,
419
+ /* @__PURE__ */ f(ie, {
420
+ onFiles: R,
421
+ canAddMore: $e,
385
422
  disabled: S || O,
386
423
  showLabel: !0
387
424
  }),
388
- /* @__PURE__ */ d("textarea", {
389
- ref: C,
390
- value: w,
391
- onChange: (e) => T(e.target.value),
392
- onKeyDown: nt,
393
- onPaste: it,
425
+ /* @__PURE__ */ f("textarea", {
426
+ ref: w,
427
+ value: T,
428
+ onChange: (e) => E(e.target.value),
429
+ onKeyDown: pt,
430
+ onPaste: ht,
394
431
  disabled: S,
395
432
  readOnly: O,
396
433
  "aria-busy": O || void 0,
397
- placeholder: E ? b("composer.dropHere", "Drop files to attach") : Je,
434
+ placeholder: D ? b("composer.dropHere", "Drop files to attach") : it,
398
435
  rows: 1,
399
436
  className: "min-h-[36px] flex-1 resize-none self-center bg-transparent px-1 py-2 text-[15px] leading-relaxed text-text-primary placeholder:text-text-muted focus:outline-none disabled:opacity-50",
400
437
  "aria-label": b("chatInput.ariaLabel", "Message input"),
401
438
  "data-testid": "assistant-input"
402
439
  }),
403
- U.isSupported && /* @__PURE__ */ d(le, {
404
- isListening: U.isListening,
405
- isStarting: U.isStarting,
406
- onToggle: U.toggle,
440
+ W.isSupported && /* @__PURE__ */ f(ue, {
441
+ isListening: W.isListening,
442
+ isStarting: W.isStarting,
443
+ onToggle: W.toggle,
407
444
  disabled: S || O
408
445
  }),
409
- _ && K.length === 0 && I.length === 0 && !U.isActive ? /* @__PURE__ */ d(de, {
446
+ _ && q.length === 0 && L.length === 0 && !W.isActive ? /* @__PURE__ */ f(fe, {
410
447
  onStart: _,
411
448
  disabled: S || O
412
- }) : /* @__PURE__ */ d("button", {
449
+ }) : /* @__PURE__ */ f("button", {
413
450
  type: "button",
414
- onClick: () => void Q(),
451
+ onClick: () => void Z(),
415
452
  disabled: !Y,
416
453
  className: `flex size-9 flex-shrink-0 items-center justify-center rounded-full shadow-sm transition-all focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong ${Y ? "bg-action-primary-bg text-action-primary-text hover:scale-105 hover:bg-action-primary-bg-hover" : "bg-bg-elevated text-text-muted"}`,
417
454
  "aria-label": b("chatInput.send", "Send message"),
418
455
  "data-testid": "assistant-send",
419
- children: h || Ie || O ? /* @__PURE__ */ d(u, { className: "size-4 motion-safe:animate-spin" }) : /* @__PURE__ */ d(he, { className: "size-4" })
456
+ children: h || Ke || O ? /* @__PURE__ */ f(d, { className: "size-4 motion-safe:animate-spin" }) : /* @__PURE__ */ f(he, { className: "size-4" })
420
457
  })
421
458
  ]
422
459
  }),
423
- g.length > 1 && /* @__PURE__ */ d("div", {
460
+ g.length > 1 && /* @__PURE__ */ f("div", {
424
461
  className: "mt-2 px-0.5",
425
- children: /* @__PURE__ */ d(oe, {
426
- mode: be,
462
+ children: /* @__PURE__ */ f(oe, {
463
+ mode: Se,
427
464
  availableModes: g,
428
- onModeChange: Se,
465
+ onModeChange: we,
429
466
  disabled: S || O,
430
- auto: Ce
467
+ auto: Te
431
468
  })
432
469
  })
433
470
  ]
434
471
  }),
435
- p ? /* @__PURE__ */ d("p", {
472
+ m ? /* @__PURE__ */ f("p", {
436
473
  className: "mt-1.5 px-1 text-center text-[11px] text-status-warning",
437
474
  "data-testid": "assistant-write-access-warning",
438
475
  children: b("composer.writeAccessDenied", "Changes may not save — your role in this workspace does not currently allow edits. You can still plan and review an action.")
439
476
  }) : null,
440
- /* @__PURE__ */ d("div", {
477
+ /* @__PURE__ */ f("div", {
441
478
  className: "mt-1.5 px-1 text-center text-[11px]",
442
479
  "aria-live": "polite",
443
- children: dt(!1)
480
+ children: St(!1, !1)
444
481
  })
445
482
  ]
446
483
  });
447
484
  };
448
485
  //#endregion
449
- export { p as AssistantComposer };
486
+ export { m as AssistantComposer };