@burdenoff/fe-libs 2026.911.4 → 2026.911.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/dist/shared/assistant/index.d.ts +1 -0
  2. package/dist/shared/assistant/index.d.ts.map +1 -1
  3. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts.map +1 -1
  4. package/dist/shared/assistant/ui/AIAssistantPanel.js +68 -63
  5. package/dist/shared/assistant/ui/AssistantConversationList.d.ts.map +1 -1
  6. package/dist/shared/assistant/ui/AssistantConversationList.js +1 -1
  7. package/dist/shared/assistant/ui/AssistantMoreMenu.d.ts.map +1 -1
  8. package/dist/shared/assistant/ui/AssistantMoreMenu.js +58 -59
  9. package/dist/shared/assistant/ui/composer/AssistantAttachmentButton.d.ts.map +1 -1
  10. package/dist/shared/assistant/ui/composer/AssistantAttachmentButton.js +49 -50
  11. package/dist/shared/assistant/ui/panelOverlays.d.ts +106 -0
  12. package/dist/shared/assistant/ui/panelOverlays.d.ts.map +1 -1
  13. package/dist/shared/assistant/ui/panelOverlays.js +15 -1
  14. package/dist/shared/assistant/ui/useDropdownEscape.d.ts +34 -0
  15. package/dist/shared/assistant/ui/useDropdownEscape.d.ts.map +1 -0
  16. package/dist/shared/assistant/ui/useDropdownEscape.js +23 -0
  17. package/dist/shared/assistant/ui/useOverlayFocus.d.ts.map +1 -1
  18. package/dist/shared/assistant/ui/useOverlayFocus.js +11 -10
  19. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts.map +1 -1
  20. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.js +34 -33
  21. package/dist/shared/assistant/useAssistantKeyboardShortcuts.d.ts.map +1 -1
  22. package/dist/shared/assistant/useAssistantKeyboardShortcuts.js +27 -21
  23. package/dist/shared-assistant.js +44 -43
  24. package/package.json +1 -1
@@ -95,6 +95,7 @@ export * from './preview/types';
95
95
  export * from './preview/context';
96
96
  export * from './preview/previewTransitions';
97
97
  export * from './ui/panelOverlays';
98
+ export * from './ui/useDropdownEscape';
98
99
  export * from './ui/useOverlayFocus';
99
100
  export * from './preview/useAssistantPreviewBridge';
100
101
  export * from './preview/AssistantPreviewOverlay';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AIAssistantPanel.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AIAssistantPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAU,KAAK,EAAE,EAAY,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAIvE,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,6BAA6B,CAAC;AAQrC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAGnE,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG;IAC/C,gEAAgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B;;;;;;;;;OASG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACtC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAyMtD,CAAC"}
1
+ {"version":3,"file":"AIAssistantPanel.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AIAssistantPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAU,KAAK,EAAE,EAAY,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAIvE,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,6BAA6B,CAAC;AAcrC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAGnE,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG;IAC/C,gEAAgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B;;;;;;;;;OASG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACtC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CA0NtD,CAAC"}
@@ -4,84 +4,89 @@ import { AssistantNavigateProvider as n } from "./AssistantMarkdownRenderer.js";
4
4
  import { useAssistantStore as r } from "../store.js";
5
5
  import { AssistantSpeechProvider as i } from "./AssistantSpeechProvider.js";
6
6
  import { AssistantConnectSourceProvider as a } from "./composer/connectSource.js";
7
- import { AssistantPreviewProvider as o } from "../preview/context.js";
8
- import { escapeDismisses as s, nextPanelOverlays as c } from "./panelOverlays.js";
9
- import { useAssistantPreviewBridge as l } from "../preview/useAssistantPreviewBridge.js";
10
- import { AssistantPreviewOverlay as u } from "../preview/AssistantPreviewOverlay.js";
11
- import { AssistantHeader as d } from "./AssistantHeader.js";
12
- import { AssistantConversationList as f } from "./AssistantConversationList.js";
13
- import { useFilesServiceWarmup as p } from "../../../storage/warmFilesService.js";
14
- import { useAssistantHeartbeat as m } from "../useAssistantHeartbeat.js";
15
- import { useAssistantKeyboardShortcuts as h } from "../useAssistantKeyboardShortcuts.js";
16
- import { AssistantChatArea as g } from "./AssistantChatArea.js";
17
- import { useRef as _, useState as v } from "react";
18
- import { jsx as y, jsxs as b } from "react/jsx-runtime";
7
+ import { ASSISTANT_OVERLAY_ATTR as o, ASSISTANT_PANEL_ATTR as s, activePanelOverlay as c, escapeDismisses as l, nextPanelOverlays as u } from "./panelOverlays.js";
8
+ import { AssistantPreviewProvider as d } from "../preview/context.js";
9
+ import { useAssistantPreviewBridge as f } from "../preview/useAssistantPreviewBridge.js";
10
+ import { AssistantPreviewOverlay as p } from "../preview/AssistantPreviewOverlay.js";
11
+ import { AssistantHeader as m } from "./AssistantHeader.js";
12
+ import { AssistantConversationList as h } from "./AssistantConversationList.js";
13
+ import { useFilesServiceWarmup as g } from "../../../storage/warmFilesService.js";
14
+ import { useAssistantHeartbeat as _ } from "../useAssistantHeartbeat.js";
15
+ import { useAssistantKeyboardShortcuts as v } from "../useAssistantKeyboardShortcuts.js";
16
+ import { AssistantChatArea as y } from "./AssistantChatArea.js";
17
+ import { useRef as b, useState as x } from "react";
18
+ import { jsx as S, jsxs as C } from "react/jsx-runtime";
19
19
  //#region src/shared/assistant/ui/AIAssistantPanel.tsx
20
- var x = ({ onClose: x, visible: S, docked: C, onToggleDock: w, writeAccess: T, onNavigate: E, connectSourceHref: D, preview: O }) => {
21
- let k = t(), [A, j] = v(!1);
22
- A && !O && j(!1);
23
- let M = A && !!O;
24
- l(O ?? null);
25
- let N = _(null), { conversations: P, activeConversationId: F, conversationListOpen: I, setConversationListOpen: L, createConversation: R } = r(), z = I || M, B = (e) => {
26
- let t = c({
27
- historyOpen: I,
28
- previewOpen: M
20
+ var w = ({ onClose: w, visible: T, docked: E, onToggleDock: D, writeAccess: O, onNavigate: k, connectSourceHref: A, preview: j }) => {
21
+ let M = t(), [N, P] = x(!1);
22
+ N && !j && P(!1);
23
+ let F = N && !!j;
24
+ f(j ?? null);
25
+ let I = b(null), { conversations: L, activeConversationId: R, conversationListOpen: z, setConversationListOpen: B, createConversation: V } = r(), H = z || F, U = c({
26
+ historyOpen: z,
27
+ previewOpen: F
28
+ }), W = (e) => {
29
+ let t = u({
30
+ historyOpen: z,
31
+ previewOpen: F
29
32
  }, e);
30
- L(t.historyOpen), j(t.previewOpen);
31
- }, V = P.find((e) => e.id === F);
32
- m(V?.backendSessionId ?? null, V?.mode ?? null, S ?? !0), p(S ?? !0);
33
- let H = e(S !== !1);
34
- return h({
35
- panelRef: N,
33
+ B(t.historyOpen), P(t.previewOpen);
34
+ }, G = L.find((e) => e.id === R);
35
+ _(G?.backendSessionId ?? null, G?.mode ?? null, T ?? !0), g(T ?? !0);
36
+ let K = e(T !== !1);
37
+ return v({
38
+ panelRef: I,
36
39
  onClose: () => {
37
- if (s({
38
- historyOpen: I,
39
- previewOpen: M
40
+ if (l({
41
+ historyOpen: z,
42
+ previewOpen: F
40
43
  }) === "overlay") {
41
- L(!1), j(!1);
44
+ B(!1), P(!1);
42
45
  return;
43
46
  }
44
- x();
47
+ w();
45
48
  }
46
- }), /* @__PURE__ */ y(i, {
47
- visible: S ?? !0,
48
- children: /* @__PURE__ */ y(o, {
49
- value: O,
50
- children: /* @__PURE__ */ y(n, {
51
- value: E,
52
- children: /* @__PURE__ */ y(a, {
53
- value: D,
54
- children: /* @__PURE__ */ b("div", {
55
- ref: N,
49
+ }), /* @__PURE__ */ S(i, {
50
+ visible: T ?? !0,
51
+ children: /* @__PURE__ */ S(d, {
52
+ value: j,
53
+ children: /* @__PURE__ */ S(n, {
54
+ value: k,
55
+ children: /* @__PURE__ */ S(a, {
56
+ value: A,
57
+ children: /* @__PURE__ */ C("div", {
58
+ ref: I,
56
59
  className: "relative flex h-full w-full flex-col bg-bg-surface",
57
60
  role: "complementary",
58
- "aria-label": k("panel.ariaLabel", "AI Assistant"),
61
+ "aria-label": M("panel.ariaLabel", "AI Assistant"),
59
62
  "data-testid": "ai-assistant-panel",
63
+ [s]: "",
64
+ ...U ? { [o]: U } : {},
60
65
  tabIndex: -1,
61
66
  children: [
62
- /* @__PURE__ */ y("div", {
67
+ /* @__PURE__ */ S("div", {
63
68
  className: "contents",
64
- inert: z || void 0,
65
- children: /* @__PURE__ */ y(d, {
66
- contextLabel: H,
67
- onNewConversation: () => R(),
68
- onOpenHistory: () => B("history"),
69
- historyOpen: I,
70
- onTogglePreview: () => B("preview"),
71
- previewOpen: M,
72
- onClose: x,
73
- docked: C,
74
- onToggleDock: w
69
+ inert: H || void 0,
70
+ children: /* @__PURE__ */ S(m, {
71
+ contextLabel: K,
72
+ onNewConversation: () => V(),
73
+ onOpenHistory: () => W("history"),
74
+ historyOpen: z,
75
+ onTogglePreview: () => W("preview"),
76
+ previewOpen: F,
77
+ onClose: w,
78
+ docked: E,
79
+ onToggleDock: D
75
80
  })
76
81
  }),
77
- I && /* @__PURE__ */ y(f, {}),
78
- M && /* @__PURE__ */ y(u, { onClose: () => j(!1) }),
79
- /* @__PURE__ */ y("div", {
82
+ z && /* @__PURE__ */ S(h, {}),
83
+ F && /* @__PURE__ */ S(p, { onClose: () => P(!1) }),
84
+ /* @__PURE__ */ S("div", {
80
85
  className: "contents",
81
- inert: z || void 0,
82
- children: /* @__PURE__ */ y(g, {
83
- visible: S ?? !0,
84
- writeAccess: T
86
+ inert: H || void 0,
87
+ children: /* @__PURE__ */ S(y, {
88
+ visible: T ?? !0,
89
+ writeAccess: O
85
90
  })
86
91
  })
87
92
  ]
@@ -92,4 +97,4 @@ var x = ({ onClose: x, visible: S, docked: C, onToggleDock: w, writeAccess: T, o
92
97
  });
93
98
  };
94
99
  //#endregion
95
- export { x as AIAssistantPanel };
100
+ export { w as AIAssistantPanel };
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantConversationList.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantConversationList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAgB1C,eAAO,MAAM,yBAAyB,EAAE,EA8PvC,CAAC"}
1
+ {"version":3,"file":"AssistantConversationList.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantConversationList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAgB1C,eAAO,MAAM,yBAAyB,EAAE,EAuQvC,CAAC"}
@@ -89,7 +89,7 @@ var h = () => {
89
89
  value: O,
90
90
  onChange: (e) => k(e.target.value),
91
91
  onKeyDown: (e) => {
92
- e.key === "Enter" && N(), e.key === "Escape" && D(null);
92
+ e.key === "Enter" && N(), e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), D(null));
93
93
  },
94
94
  className: "flex-1 text-xs bg-bg-sunken border border-border-default rounded px-2 py-1 text-text-primary focus:outline-none focus:border-action-primary-bg",
95
95
  onClick: (e) => e.stopPropagation()
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantMoreMenu.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMoreMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAgB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAoM/B,CAAC"}
1
+ {"version":3,"file":"AssistantMoreMenu.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMoreMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAiB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAgM/B,CAAC"}
@@ -2,115 +2,114 @@ import { useAssistantTr as e } from "../i18n.js";
2
2
  import { useAssistantStore as t } from "../store.js";
3
3
  import { useAssistantSpeech as n } from "./AssistantSpeechProvider.js";
4
4
  import { AssistantLanguageMenu as r } from "./AssistantLanguageMenu.js";
5
- import { AssistantVoiceSelector as i } from "./composer/AssistantVoiceSelector.js";
6
- import { downloadFile as a, exportConversation as o } from "../exportConversation.js";
7
- import { useEffect as s, useRef as c, useState as l } from "react";
8
- import { Check as u, FileJson as d, FileText as f, MoreHorizontal as p, Play as m, Volume2 as h } from "lucide-react";
9
- import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
5
+ import { useDropdownEscape as i } from "./useDropdownEscape.js";
6
+ import { AssistantVoiceSelector as a } from "./composer/AssistantVoiceSelector.js";
7
+ import { downloadFile as o, exportConversation as s } from "../exportConversation.js";
8
+ import { useEffect as c, useRef as l, useState as u } from "react";
9
+ import { Check as d, FileJson as f, FileText as p, MoreHorizontal as m, Play as h, Volume2 as g } from "lucide-react";
10
+ import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
10
11
  //#region src/shared/assistant/ui/AssistantMoreMenu.tsx
11
- var y = () => {
12
- let y = e(), [b, x] = l(!1), S = c(null), C = c(null), { conversations: w, activeConversationId: T } = t(), E = w.find((e) => e.id === T), D = !!(E && E.messages.length > 0), { isSupported: O, isBlocked: k, disabledReason: A, autoSpeakEnabled: j, setAutoSpeak: M, stop: N, previewVoice: P, activeVoiceName: F } = n(), I = k && !j;
13
- s(() => {
14
- if (!b) return;
12
+ var b = () => {
13
+ let b = e(), [x, S] = u(!1), C = l(null), w = l(null), { conversations: T, activeConversationId: E } = t(), D = T.find((e) => e.id === E), O = !!(D && D.messages.length > 0), { isSupported: k, isBlocked: A, disabledReason: j, autoSpeakEnabled: M, setAutoSpeak: N, stop: P, previewVoice: F, activeVoiceName: I } = n(), L = A && !M;
14
+ i(x, C, w, () => S(!1)), c(() => {
15
+ if (!x) return;
15
16
  let e = (e) => {
16
- e.key === "Escape" && (x(!1), C.current?.focus());
17
- }, t = (e) => {
18
17
  let t = e.target;
19
- S.current?.contains(t) || C.current?.contains(t) || x(!1);
18
+ C.current?.contains(t) || w.current?.contains(t) || S(!1);
20
19
  };
21
- return window.addEventListener("keydown", e), document.addEventListener("mousedown", t), () => {
22
- window.removeEventListener("keydown", e), document.removeEventListener("mousedown", t);
20
+ return document.addEventListener("mousedown", e), () => {
21
+ document.removeEventListener("mousedown", e);
23
22
  };
24
- }, [b]);
25
- let L = (e) => {
26
- if (!E) return;
27
- let { content: t, filename: n, mimeType: r } = o(E, e);
28
- a(t, n, r), x(!1);
29
- }, R = () => {
30
- j && N(), M(!j);
31
- }, z = y("header.more", "More options");
32
- return /* @__PURE__ */ v("div", {
23
+ }, [x]);
24
+ let R = (e) => {
25
+ if (!D) return;
26
+ let { content: t, filename: n, mimeType: r } = s(D, e);
27
+ o(t, n, r), S(!1);
28
+ }, z = () => {
29
+ M && P(), N(!M);
30
+ }, B = b("header.more", "More options");
31
+ return /* @__PURE__ */ y("div", {
33
32
  className: "relative",
34
- children: [/* @__PURE__ */ _("button", {
35
- ref: C,
33
+ children: [/* @__PURE__ */ v("button", {
34
+ ref: w,
36
35
  type: "button",
37
- onClick: () => x((e) => !e),
36
+ onClick: () => S((e) => !e),
38
37
  className: "rounded p-1 transition-colors hover:bg-bg-elevated",
39
- "aria-label": z,
38
+ "aria-label": B,
40
39
  "aria-haspopup": "menu",
41
- "aria-expanded": b,
40
+ "aria-expanded": x,
42
41
  "data-testid": "assistant-more",
43
- children: /* @__PURE__ */ _(p, { className: "size-4 text-text-secondary" })
44
- }), b ? /* @__PURE__ */ v("div", {
45
- ref: S,
42
+ children: /* @__PURE__ */ v(m, { className: "size-4 text-text-secondary" })
43
+ }), x ? /* @__PURE__ */ y("div", {
44
+ ref: C,
46
45
  role: "menu",
47
- "aria-label": z,
46
+ "aria-label": B,
48
47
  className: "absolute right-0 top-full z-50 mt-1 min-w-56 overflow-hidden rounded-xl border border-border-default bg-bg-surface py-1 shadow-lg",
49
48
  "data-testid": "assistant-more-menu",
50
49
  children: [
51
- O ? /* @__PURE__ */ v("button", {
50
+ k ? /* @__PURE__ */ y("button", {
52
51
  type: "button",
53
52
  role: "menuitemcheckbox",
54
- "aria-checked": j,
55
- onClick: R,
56
- disabled: I,
57
- title: I ? A ?? void 0 : void 0,
53
+ "aria-checked": M,
54
+ onClick: z,
55
+ disabled: L,
56
+ title: L ? j ?? void 0 : void 0,
58
57
  className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-xs text-text-primary transition-colors hover:bg-bg-elevated disabled:cursor-not-allowed disabled:text-text-muted disabled:hover:bg-transparent",
59
58
  "data-testid": "assistant-auto-speak",
60
59
  children: [
61
- /* @__PURE__ */ _(h, {
60
+ /* @__PURE__ */ v(g, {
62
61
  className: "size-3.5 flex-shrink-0 text-text-secondary",
63
62
  "aria-hidden": "true"
64
63
  }),
65
- /* @__PURE__ */ _("span", {
64
+ /* @__PURE__ */ v("span", {
66
65
  className: "flex-1",
67
- children: y("header.autoRead", "Auto-read replies")
66
+ children: b("header.autoRead", "Auto-read replies")
68
67
  }),
69
- j ? /* @__PURE__ */ _(u, { className: "size-3.5 flex-shrink-0 text-action-primary-bg" }) : null
68
+ M ? /* @__PURE__ */ v(d, { className: "size-3.5 flex-shrink-0 text-action-primary-bg" }) : null
70
69
  ]
71
70
  }) : null,
72
- /* @__PURE__ */ _(r, {}),
73
- /* @__PURE__ */ v("div", {
71
+ /* @__PURE__ */ v(r, {}),
72
+ /* @__PURE__ */ y("div", {
74
73
  className: "flex items-center gap-1 px-3 py-1.5",
75
74
  "data-testid": "assistant-more-voice",
76
- children: [/* @__PURE__ */ _(i, {}), F ? /* @__PURE__ */ v("button", {
75
+ children: [/* @__PURE__ */ v(a, {}), I ? /* @__PURE__ */ y("button", {
77
76
  type: "button",
78
- onClick: () => P(F),
77
+ onClick: () => F(I),
79
78
  className: "flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] text-text-muted transition-colors hover:bg-bg-elevated hover:text-text-secondary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
80
- "aria-label": y("voice.preview", "Hear this voice"),
79
+ "aria-label": b("voice.preview", "Hear this voice"),
81
80
  "data-testid": "assistant-voice-preview",
82
- children: [/* @__PURE__ */ _(m, {
81
+ children: [/* @__PURE__ */ v(h, {
83
82
  className: "size-3",
84
83
  "aria-hidden": "true"
85
- }), y("voice.previewShort", "Preview")]
84
+ }), b("voice.previewShort", "Preview")]
86
85
  }) : null]
87
86
  }),
88
- D ? /* @__PURE__ */ v(g, { children: [
89
- /* @__PURE__ */ _("div", {
87
+ O ? /* @__PURE__ */ y(_, { children: [
88
+ /* @__PURE__ */ v("div", {
90
89
  className: "my-1 border-t border-border-subtle",
91
90
  role: "separator"
92
91
  }),
93
- /* @__PURE__ */ v("button", {
92
+ /* @__PURE__ */ y("button", {
94
93
  type: "button",
95
94
  role: "menuitem",
96
- onClick: () => L("json"),
95
+ onClick: () => R("json"),
97
96
  className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-xs text-text-primary transition-colors hover:bg-bg-elevated",
98
97
  "data-testid": "export-json",
99
- children: [/* @__PURE__ */ _(d, {
98
+ children: [/* @__PURE__ */ v(f, {
100
99
  className: "size-3.5 flex-shrink-0 text-text-secondary",
101
100
  "aria-hidden": "true"
102
- }), y("export.json", "Export as JSON")]
101
+ }), b("export.json", "Export as JSON")]
103
102
  }),
104
- /* @__PURE__ */ v("button", {
103
+ /* @__PURE__ */ y("button", {
105
104
  type: "button",
106
105
  role: "menuitem",
107
- onClick: () => L("markdown"),
106
+ onClick: () => R("markdown"),
108
107
  className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-xs text-text-primary transition-colors hover:bg-bg-elevated",
109
108
  "data-testid": "export-markdown",
110
- children: [/* @__PURE__ */ _(f, {
109
+ children: [/* @__PURE__ */ v(p, {
111
110
  className: "size-3.5 flex-shrink-0 text-text-secondary",
112
111
  "aria-hidden": "true"
113
- }), y("export.markdown", "Export as Markdown")]
112
+ }), b("export.markdown", "Export as Markdown")]
114
113
  })
115
114
  ] }) : null
116
115
  ]
@@ -118,4 +117,4 @@ var y = () => {
118
117
  });
119
118
  };
120
119
  //#endregion
121
- export { y as AssistantMoreMenu };
120
+ export { b as AssistantMoreMenu };
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantAttachmentButton.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/composer/AssistantAttachmentButton.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,EAAE,EACR,MAAM,OAAO,CAAC;AAaf,UAAU,KAAK;IACb,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC1B,wEAAwE;IACxE,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AASD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC,KAAK,CA4J/C,CAAC"}
1
+ {"version":3,"file":"AssistantAttachmentButton.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/composer/AssistantAttachmentButton.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,EAAE,EACR,MAAM,OAAO,CAAC;AAcf,UAAU,KAAK;IACb,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC1B,wEAAwE;IACxE,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AASD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC,KAAK,CAwJ/C,CAAC"}
@@ -3,87 +3,86 @@ import "../../attachments.js";
3
3
  import { availableAttachmentSources as t, deviceHasCamera as n } from "../../attachmentSources.js";
4
4
  import { useAssistantConnectSource as r } from "./connectSource.js";
5
5
  import { AssistantConnectSourceItem as i } from "./AssistantConnectSourceItem.js";
6
- import { useCallback as a, useEffect as o, useMemo as s, useRef as c, useState as l } from "react";
7
- import { Camera as u, FileText as d, FolderOpen as f, ImageIcon as p, Plus as m } from "lucide-react";
8
- import { jsx as h, jsxs as g } from "react/jsx-runtime";
6
+ import { useDropdownEscape as a } from "../useDropdownEscape.js";
7
+ import { useCallback as o, useEffect as s, useMemo as c, useRef as l, useState as u } from "react";
8
+ import { Camera as d, FileText as f, FolderOpen as p, ImageIcon as m, Plus as h } from "lucide-react";
9
+ import { jsx as g, jsxs as _ } from "react/jsx-runtime";
9
10
  //#region src/shared/assistant/ui/composer/AssistantAttachmentButton.tsx
10
- var _ = {
11
- camera: u,
12
- gallery: p,
13
- documents: d,
14
- files: f
15
- }, v = ({ onFiles: u, onPickerOpen: d, direction: f = "up", canAddMore: p, disabled: v = !1 }) => {
16
- let y = e(), b = c(null), x = c(null), S = c(null), [C, w] = l(!1), T = c(d);
17
- T.current = d;
18
- let E = s(() => t(n()), []), D = r(), O = p || !!D, k = p ? y("composer.attach", "Attach files or photos") : y("composer.attachFull", "Attachment limit reached ({{max}})", { max: 5 });
19
- o(() => {
20
- if (!C) return;
11
+ var v = {
12
+ camera: d,
13
+ gallery: m,
14
+ documents: f,
15
+ files: p
16
+ }, y = ({ onFiles: d, onPickerOpen: f, direction: p = "up", canAddMore: m, disabled: y = !1 }) => {
17
+ let b = e(), x = l(null), S = l(null), C = l(null), [w, T] = u(!1), E = l(f);
18
+ E.current = f;
19
+ let D = c(() => t(n()), []), O = r(), k = m || !!O, A = m ? b("composer.attach", "Attach files or photos") : b("composer.attachFull", "Attachment limit reached ({{max}})", { max: 5 });
20
+ a(w, S, C, () => T(!1)), s(() => {
21
+ if (!w) return;
21
22
  let e = (e) => {
22
- e.key === "Escape" && (w(!1), S.current?.focus());
23
- }, t = (e) => {
24
23
  let t = e.target;
25
- x.current?.contains(t) || S.current?.contains(t) || w(!1);
24
+ S.current?.contains(t) || C.current?.contains(t) || T(!1);
26
25
  };
27
- return window.addEventListener("keydown", e), window.addEventListener("mousedown", t), () => {
28
- window.removeEventListener("keydown", e), window.removeEventListener("mousedown", t);
26
+ return window.addEventListener("mousedown", e), () => {
27
+ window.removeEventListener("mousedown", e);
29
28
  };
30
- }, [C]);
31
- let A = a((e) => {
32
- u(e.target.files), e.target.value = "";
33
- }, [u]), j = a((e) => {
34
- let t = b.current;
35
- t && (t.accept = e.accept, t.multiple = e.multiple, e.capture ? t.setAttribute("capture", e.capture) : t.removeAttribute("capture"), w(!1), T.current?.(), t.click());
29
+ }, [w]);
30
+ let j = o((e) => {
31
+ d(e.target.files), e.target.value = "";
32
+ }, [d]), M = o((e) => {
33
+ let t = x.current;
34
+ t && (t.accept = e.accept, t.multiple = e.multiple, e.capture ? t.setAttribute("capture", e.capture) : t.removeAttribute("capture"), T(!1), E.current?.(), t.click());
36
35
  }, []);
37
- return /* @__PURE__ */ g("div", {
36
+ return /* @__PURE__ */ _("div", {
38
37
  className: "relative flex-shrink-0",
39
38
  children: [
40
- /* @__PURE__ */ h("input", {
41
- ref: b,
39
+ /* @__PURE__ */ g("input", {
40
+ ref: x,
42
41
  type: "file",
43
42
  multiple: !0,
44
43
  className: "hidden",
45
- onChange: A,
44
+ onChange: j,
46
45
  tabIndex: -1,
47
46
  "aria-hidden": "true",
48
47
  "data-testid": "assistant-attach-input"
49
48
  }),
50
- /* @__PURE__ */ h("button", {
51
- ref: S,
49
+ /* @__PURE__ */ g("button", {
50
+ ref: C,
52
51
  type: "button",
53
- onClick: () => w((e) => !e),
54
- disabled: v || !O,
55
- title: k,
56
- "aria-label": k,
52
+ onClick: () => T((e) => !e),
53
+ disabled: y || !k,
54
+ title: A,
55
+ "aria-label": A,
57
56
  "aria-haspopup": "menu",
58
- "aria-expanded": C,
57
+ "aria-expanded": w,
59
58
  className: "flex size-9 items-center justify-center rounded-full border border-border-subtle bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong disabled:cursor-not-allowed disabled:text-text-muted disabled:hover:bg-bg-elevated",
60
59
  "data-testid": "assistant-attach",
61
- children: /* @__PURE__ */ h(m, { className: "size-4" })
60
+ children: /* @__PURE__ */ g(h, { className: "size-4" })
62
61
  }),
63
- C ? /* @__PURE__ */ g("div", {
64
- ref: x,
62
+ w ? /* @__PURE__ */ _("div", {
63
+ ref: S,
65
64
  role: "menu",
66
- "aria-label": y("composer.attachSource", "Attach from"),
67
- className: `absolute ${f === "up" ? "bottom-full mb-2" : "top-full mt-2"} left-0 z-30 min-w-44 overflow-hidden rounded-xl border border-border-default bg-bg-elevated py-1 shadow-lg`,
65
+ "aria-label": b("composer.attachSource", "Attach from"),
66
+ className: `absolute ${p === "up" ? "bottom-full mb-2" : "top-full mt-2"} left-0 z-30 min-w-44 overflow-hidden rounded-xl border border-border-default bg-bg-elevated py-1 shadow-lg`,
68
67
  "data-testid": "assistant-attach-menu",
69
- children: [E.map((e) => {
70
- let t = _[e.id];
71
- return /* @__PURE__ */ g("button", {
68
+ children: [D.map((e) => {
69
+ let t = v[e.id];
70
+ return /* @__PURE__ */ _("button", {
72
71
  type: "button",
73
72
  role: "menuitem",
74
- disabled: !p,
75
- onClick: () => j(e),
73
+ disabled: !m,
74
+ onClick: () => M(e),
76
75
  className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm text-text-primary transition-colors hover:bg-bg-sunken focus:outline-none focus-visible:bg-bg-sunken disabled:cursor-not-allowed disabled:text-text-muted disabled:hover:bg-transparent",
77
76
  "data-testid": `assistant-attach-source-${e.id}`,
78
- children: [/* @__PURE__ */ h(t, {
77
+ children: [/* @__PURE__ */ g(t, {
79
78
  className: "size-4 flex-shrink-0 text-text-secondary",
80
79
  "aria-hidden": "true"
81
- }), y(e.labelKey, e.labelFallback)]
80
+ }), b(e.labelKey, e.labelFallback)]
82
81
  }, e.id);
83
- }), /* @__PURE__ */ h(i, { onActivate: () => w(!1) })]
82
+ }), /* @__PURE__ */ g(i, { onActivate: () => T(!1) })]
84
83
  }) : null
85
84
  ]
86
85
  });
87
86
  };
88
87
  //#endregion
89
- export { v as AssistantAttachmentButton };
88
+ export { y as AssistantAttachmentButton };
@@ -45,4 +45,110 @@ export declare function nextPanelOverlays(current: PanelOverlayState, toggled: "
45
45
  * conversation instead.
46
46
  */
47
47
  export declare function escapeDismisses(current: PanelOverlayState): "overlay" | "panel";
48
+ /**
49
+ * Attribute marking the assistant panel's root element.
50
+ *
51
+ * ★★ A CROSS-PACKAGE CONTRACT, not a styling hook. Each host app's own Escape
52
+ * handler reads it through `assistantPanelOwnsEscape` to decide whether the
53
+ * panel is about to handle the key itself. Renaming it silently reintroduces
54
+ * the double-close below, in a different repo, with every test still green.
55
+ *
56
+ * Deliberately NOT the `data-testid` — that is a test handle, free to change.
57
+ * This one is load-bearing at runtime.
58
+ */
59
+ export declare const ASSISTANT_PANEL_ATTR = "data-assistant-panel";
60
+ /**
61
+ * Attribute naming the full-surface overlay the panel is currently showing.
62
+ *
63
+ * ★★ Present only while one is open, and read by `assistantPanelOwnsEscape` —
64
+ * see the "focus fell to `<body>`" case there. Absent means no overlay.
65
+ */
66
+ export declare const ASSISTANT_OVERLAY_ATTR = "data-assistant-overlay";
67
+ /** Which overlay is showing, as the attribute value — `null` when none is. */
68
+ export declare function activePanelOverlay(current: PanelOverlayState): "history" | "preview" | null;
69
+ /**
70
+ * Is `active` the panel itself, or inside it?
71
+ *
72
+ * Extracted so `useAssistantKeyboardShortcuts` (`:32`) and
73
+ * `assistantPanelOwnsEscape` cannot drift apart. The host has to decline
74
+ * exactly the key presses the panel takes — no more, or Escape stops working
75
+ * altogether; no fewer, or it fires twice — and "exactly" is only checkable if
76
+ * both sides ask one question.
77
+ */
78
+ export declare function focusIsInsidePanel(panel: {
79
+ contains(node: Node | null): boolean;
80
+ } | null, active: Node | null): boolean;
81
+ /**
82
+ * Will the assistant panel handle this Escape itself?
83
+ *
84
+ * ★★★ HOSTS MUST CALL THIS BEFORE CLOSING THE PANEL ON ESCAPE. Both host apps
85
+ * register a `document` keydown listener so Escape closes the panel even when
86
+ * focus is elsewhere on the page (healthybowl-app and vibecontrols-app,
87
+ * `src/components/chrome/AIAssistantOverlay.tsx`). The panel registers one too
88
+ * (`useAssistantKeyboardShortcuts.ts:80`), routed through `escapeDismisses` so
89
+ * an open overlay is backed out of rather than the whole assistant.
90
+ *
91
+ * Both listeners are on `document`, so ONE key press ran BOTH: the overlay
92
+ * closed AND the panel unmounted, taking the in-flight turn with it — the exact
93
+ * defect `escapeDismisses` exists to prevent, reintroduced one layer up where
94
+ * this package could not see it. Measured on alpha 2026-09-11: preview open,
95
+ * focus on the overlay, one Escape, and the panel was gone.
96
+ *
97
+ * ★★ `stopPropagation()` CANNOT FIX IT. The two listeners sit on the SAME node,
98
+ * and propagation stops travel BETWEEN nodes; only `stopImmediatePropagation()`
99
+ * reaches a sibling listener, and only one registered later. The panel's is not
100
+ * reliably earlier: `AIAssistantPanel.tsx:207` passes a fresh inline arrow as
101
+ * `onClose`, which is in the hook's dependency array (`:82`), so the panel's
102
+ * effect re-subscribes on EVERY render and keeps moving to the back of the
103
+ * queue. Neither side can depend on order.
104
+ *
105
+ * So ownership is decided by STATE, not by event order — whoever holds focus
106
+ * owns the key:
107
+ * - focus inside the panel -> the panel decides (overlay first, then close)
108
+ * - focus anywhere else -> the host closes the panel, exactly as before
109
+ *
110
+ * That partition is total and disjoint BETWEEN THESE TWO LISTENERS, whichever
111
+ * runs first. It says nothing about any other Escape handler on the page, and
112
+ * the qualifier matters — the first draft of this comment claimed Escape was
113
+ * "neither dropped nor double-handled" full stop, which is not true:
114
+ *
115
+ * - SUB-LAYERS INSIDE THE PANEL still need their own answer. The More menu
116
+ * and the attachment menu each own Escape while open; they take it in the
117
+ * CAPTURE phase and stop it, so it never reaches either listener here.
118
+ * Before that, the panel's hook saw focus inside the panel, found no
119
+ * full-surface overlay open, and closed the whole assistant — one press
120
+ * dismissed a dropdown and destroyed the in-flight turn.
121
+ * - ESCAPE CAN STILL BE DROPPED when focus is OUTSIDE the panel and a
122
+ * `role="dialog"` descendant is mounted inside it (the read-only voice
123
+ * transcript drawer): the host defers to the dialog, the dialog and this
124
+ * package both require focus inside the panel, and nothing acts. Pre-dates
125
+ * this contract and is not fixed by it.
126
+ * - A FULL-SURFACE OVERLAY OPEN WITH FOCUS ON A REAL ELEMENT OUTSIDE the
127
+ * panel still closes the whole assistant rather than backing out of the
128
+ * overlay. Pre-existing. Note this no longer covers focus of "nothing"
129
+ * (`<body>` or null), which is the common way to get here and is handled
130
+ * above — a control unmounting itself on click drops focus to `<body>`
131
+ * without the user going anywhere.
132
+ *
133
+ * This list is kept current deliberately. Earlier drafts described gaps that
134
+ * had been closed and missed one that was reachable in three clicks, which is
135
+ * worse than no list at all: the next reader trusts it.
136
+ */
137
+ export declare function assistantPanelOwnsEscape(doc?: Pick<Document, "querySelectorAll" | "activeElement" | "body">): boolean;
138
+ /**
139
+ * Does THIS panel claim Escape, given what is focused?
140
+ *
141
+ * ★★★ ONE definition, used by both sides. `assistantPanelOwnsEscape` maps it
142
+ * over every mounted panel for the hosts; `useAssistantKeyboardShortcuts` asks
143
+ * it about its own panel. They MUST agree: the host declines exactly what the
144
+ * panel accepts. When they drifted — the predicate widened to cover focus of
145
+ * "nothing" and the hook's guard was left asking only "is focus inside?" — the
146
+ * host deferred and the panel declined the same key, and Escape did nothing at
147
+ * all with the history drawer still open. A zero-handler case is quieter than
148
+ * the double-handler it replaced and no better.
149
+ */
150
+ export declare function panelOwnsEscape(panel: {
151
+ contains(node: Node | null): boolean;
152
+ hasAttribute(name: string): boolean;
153
+ } | null, active: Node | null, body: Node | null): boolean;
48
154
  //# sourceMappingURL=panelOverlays.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"panelOverlays.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/panelOverlays.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,EAAE,iBAG9B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,SAAS,GAAG,SAAS,GAC7B,iBAAiB,CAOnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,iBAAiB,GACzB,SAAS,GAAG,OAAO,CAErB"}
1
+ {"version":3,"file":"panelOverlays.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/panelOverlays.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,EAAE,iBAG9B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,SAAS,GAAG,SAAS,GAC7B,iBAAiB,CAOnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,iBAAiB,GACzB,SAAS,GAAG,OAAO,CAErB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAE/D,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,iBAAiB,GACzB,SAAS,GAAG,SAAS,GAAG,IAAI,CAI9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAA;CAAE,GAAG,IAAI,EACtD,MAAM,EAAE,IAAI,GAAG,IAAI,GAClB,OAAO,CAGT;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,GAAE,IAAI,CAAC,QAAQ,EAAE,kBAAkB,GAAG,eAAe,GAAG,MAAM,CAAY,GAC5E,OAAO,CAqBT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE;IACL,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC;IACrC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACrC,GAAG,IAAI,EACR,MAAM,EAAE,IAAI,GAAG,IAAI,EACnB,IAAI,EAAE,IAAI,GAAG,IAAI,GAChB,OAAO,CAKT"}
@@ -12,5 +12,19 @@ function t(t, n) {
12
12
  function n(e) {
13
13
  return e.historyOpen || e.previewOpen ? "overlay" : "panel";
14
14
  }
15
+ var r = "data-assistant-panel", i = "data-assistant-overlay";
16
+ function a(e) {
17
+ return e.historyOpen ? "history" : e.previewOpen ? "preview" : null;
18
+ }
19
+ function o(e, t) {
20
+ return !e || !t ? !1 : e === t || e.contains(t);
21
+ }
22
+ function s(e = document) {
23
+ let t = e.activeElement;
24
+ return Array.from(e.querySelectorAll(`[${r}]`)).some((n) => c(n, t, e.body));
25
+ }
26
+ function c(e, t, n) {
27
+ return e ? o(e, t) ? !0 : (t === null || t === n) && e.hasAttribute("data-assistant-overlay") : !1;
28
+ }
15
29
  //#endregion
16
- export { e as NO_PANEL_OVERLAY, n as escapeDismisses, t as nextPanelOverlays };
30
+ export { i as ASSISTANT_OVERLAY_ATTR, r as ASSISTANT_PANEL_ATTR, e as NO_PANEL_OVERLAY, a as activePanelOverlay, s as assistantPanelOwnsEscape, n as escapeDismisses, o as focusIsInsidePanel, t as nextPanelOverlays, c as panelOwnsEscape };
@@ -0,0 +1,34 @@
1
+ import { RefObject } from 'react';
2
+ /**
3
+ * Escape closes a dropdown inside the assistant panel — and closes ONLY it.
4
+ *
5
+ * ★★★ WHY CAPTURE. Both dropdowns used to listen on `window` in the bubble
6
+ * phase. `window` is the LAST node an event reaches, so the panel's own
7
+ * shortcut hook — on `document`, also bubbling — always ran first, saw focus
8
+ * inside the panel, found no full-surface overlay open, and closed the WHOLE
9
+ * assistant. One press dismissed a dropdown and destroyed the streaming turn,
10
+ * the draft and the attachments; this handler then ran on an unmounted
11
+ * component. Capture on `document` reaches this node ahead of every bubble
12
+ * listener on it, whatever order they registered in — the only placement that
13
+ * reliably wins.
14
+ *
15
+ * ★★★ WHY IT IS STILL SCOPED TO FOCUS. Consuming Escape unconditionally while
16
+ * open is the same mistake pointing the other way: the dropdown stays mounted
17
+ * when focus leaves it without a click (open it from the keyboard, Tab to the
18
+ * transcript toggle, press Enter), and it would then swallow an Escape meant
19
+ * for the layer the user actually opened last, closing a menu they cannot even
20
+ * see. So the key is taken only while focus is still inside the menu or on its
21
+ * trigger — the same containment question `focusIsInsidePanel` answers for the
22
+ * panel, and the same one this component's outside-click handler already asks.
23
+ *
24
+ * ★ `stopPropagation`, NOT `stopImmediatePropagation`: stopping in the capture
25
+ * phase already prevents every bubble listener from seeing the key. The
26
+ * immediate variant would additionally kill unrelated capture listeners on
27
+ * `document`, which are none of a dropdown's business.
28
+ *
29
+ * Shared by `AssistantMoreMenu` and `AssistantAttachmentButton` so the rule
30
+ * lives in one place — the two copies had drifted into being identical
31
+ * comment-for-comment, which is a third copy waiting to happen.
32
+ */
33
+ export declare function useDropdownEscape(open: boolean, menuRef: RefObject<HTMLElement | null>, buttonRef: RefObject<HTMLElement | null>, close: () => void): void;
34
+ //# sourceMappingURL=useDropdownEscape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDropdownEscape.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/useDropdownEscape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACtC,SAAS,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACxC,KAAK,EAAE,MAAM,IAAI,GAChB,IAAI,CAiCN"}
@@ -0,0 +1,23 @@
1
+ import { focusIsInsidePanel as e } from "./panelOverlays.js";
2
+ import { useEffect as t, useRef as n } from "react";
3
+ //#region src/shared/assistant/ui/useDropdownEscape.ts
4
+ function r(r, i, a, o) {
5
+ let s = n(o);
6
+ t(() => {
7
+ s.current = o;
8
+ }, [o]), t(() => {
9
+ if (!r) return;
10
+ let t = (t) => {
11
+ if (t.key !== "Escape") return;
12
+ let n = document.activeElement;
13
+ (e(i.current, n) || e(a.current, n)) && (t.preventDefault(), t.stopPropagation(), s.current(), a.current?.focus());
14
+ };
15
+ return document.addEventListener("keydown", t, !0), () => document.removeEventListener("keydown", t, !0);
16
+ }, [
17
+ r,
18
+ i,
19
+ a
20
+ ]);
21
+ }
22
+ //#endregion
23
+ export { r as useDropdownEscape };
@@ -1 +1 @@
1
- {"version":3,"file":"useOverlayFocus.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/useOverlayFocus.ts"],"names":[],"mappings":"AAmDA,wBAAgB,eAAe,CAAC,CAAC,SAAS,WAAW;AACnD,8EAA8E;AAC9E,iBAAiB,CAAC,EAAE,MAAM,uCAgE3B"}
1
+ {"version":3,"file":"useOverlayFocus.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/useOverlayFocus.ts"],"names":[],"mappings":"AAkEA,wBAAgB,eAAe,CAAC,CAAC,SAAS,WAAW;AACnD,8EAA8E;AAC9E,iBAAiB,CAAC,EAAE,MAAM,uCAgE3B"}
@@ -1,19 +1,20 @@
1
- import { useEffect as e, useLayoutEffect as t, useRef as n } from "react";
1
+ import { ASSISTANT_PANEL_ATTR as e } from "./panelOverlays.js";
2
+ import { useEffect as t, useLayoutEffect as n, useRef as r } from "react";
2
3
  //#region src/shared/assistant/ui/useOverlayFocus.ts
3
- var r = "[data-testid=\"ai-assistant-panel\"]", i = typeof document > "u" ? e : t;
4
- function a(e) {
5
- let t = n(null);
6
- return i(() => {
7
- let n = t.current, i = n?.closest(r) ?? null;
4
+ var i = `[${e}]`, a = typeof document > "u" ? t : n;
5
+ function o(e) {
6
+ let t = r(null);
7
+ return a(() => {
8
+ let n = t.current, r = n?.closest(i) ?? null;
8
9
  return n?.focus({ preventScroll: !0 }), () => {
9
10
  let t = document.activeElement;
10
11
  if (!(n && (n === t || n.contains(t)))) return;
11
- let r = e ? i?.querySelector(`[data-testid="${e}"]`) : null;
12
- (r?.isConnected ? r : i)?.focus({ preventScroll: !0 });
12
+ let i = e ? r?.querySelector(`[data-testid="${e}"]`) : null;
13
+ (i?.isConnected ? i : r)?.focus({ preventScroll: !0 });
13
14
  let a = document.activeElement;
14
- i && a !== n && !n?.contains(a) && (i === a || i.contains(a)) || i?.focus({ preventScroll: !0 });
15
+ r && a !== n && !n?.contains(a) && (r === a || r.contains(a)) || r?.focus({ preventScroll: !0 });
15
16
  };
16
17
  }, [e]), t;
17
18
  }
18
19
  //#endregion
19
- export { a as useOverlayFocus };
20
+ export { o as useOverlayFocus };
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceTranscriptDrawer.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAInD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;;;;;;;;;;;;;;;;;GAkBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CAqI3C,CAAC"}
1
+ {"version":3,"file":"VoiceTranscriptDrawer.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAKnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;;;;;;;;;;;;;;;;;GAkBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CAsI3C,CAAC"}
@@ -1,64 +1,65 @@
1
1
  import { useAssistantTr as e } from "../../i18n.js";
2
- import { VoiceConversationView as t } from "./VoiceConversationView.js";
3
- import { useEffect as n, useRef as r } from "react";
4
- import { ArrowRight as i, Download as a, X as o } from "lucide-react";
5
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
2
+ import { ASSISTANT_PANEL_ATTR as t, focusIsInsidePanel as n } from "../panelOverlays.js";
3
+ import { VoiceConversationView as r } from "./VoiceConversationView.js";
4
+ import { useEffect as i, useRef as a } from "react";
5
+ import { ArrowRight as o, Download as s, X as c } from "lucide-react";
6
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
6
7
  //#region src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx
7
- var l = ({ turns: l, onClose: u, onSave: d, onContinueInChat: f, closeOnEscape: p = !1 }) => {
8
- let m = e(), h = r(null);
9
- return n(() => {
10
- if (!p) return;
8
+ var d = ({ turns: d, onClose: f, onSave: p, onContinueInChat: m, closeOnEscape: h = !1 }) => {
9
+ let g = e(), _ = a(null);
10
+ return i(() => {
11
+ if (!h) return;
11
12
  let e = (e) => {
12
13
  if (e.key !== "Escape" || document.querySelector("[role=\"alertdialog\"]")) return;
13
- let t = h.current?.closest("[data-testid=\"ai-assistant-panel\"]"), n = document.activeElement;
14
- !t || !n || !t.contains(n) || (e.preventDefault(), e.stopPropagation(), u());
14
+ let r = _.current?.closest(`[${t}]`), i = document.activeElement;
15
+ n(r ?? null, i) && (e.preventDefault(), e.stopPropagation(), f());
15
16
  };
16
17
  return document.addEventListener("keydown", e, !0), () => document.removeEventListener("keydown", e, !0);
17
- }, [p, u]), /* @__PURE__ */ c("div", {
18
- ref: h,
18
+ }, [h, f]), /* @__PURE__ */ u("div", {
19
+ ref: _,
19
20
  className: "absolute inset-0 z-30 flex flex-col bg-bg-sunken/95 backdrop-blur-sm",
20
21
  role: "dialog",
21
- "aria-label": m("voiceSession.transcriptTitle", "Voice transcript"),
22
+ "aria-label": g("voiceSession.transcriptTitle", "Voice transcript"),
22
23
  "data-testid": "assistant-voice-transcript",
23
24
  children: [
24
- /* @__PURE__ */ c("div", {
25
+ /* @__PURE__ */ u("div", {
25
26
  className: "flex items-center justify-between border-b border-border-subtle px-4 py-3",
26
- children: [/* @__PURE__ */ c("div", {
27
+ children: [/* @__PURE__ */ u("div", {
27
28
  className: "min-w-0",
28
- children: [/* @__PURE__ */ s("h2", {
29
+ children: [/* @__PURE__ */ l("h2", {
29
30
  className: "text-sm font-semibold text-text-primary",
30
- children: m("voiceSession.transcript", "Voice conversation")
31
- }), /* @__PURE__ */ s("p", {
31
+ children: g("voiceSession.transcript", "Voice conversation")
32
+ }), /* @__PURE__ */ l("p", {
32
33
  className: "truncate text-xs text-text-muted",
33
- children: m("voiceSession.transcriptHint", "Spoken turns in this conversation — kept out of your typed chat.")
34
+ children: g("voiceSession.transcriptHint", "Spoken turns in this conversation — kept out of your typed chat.")
34
35
  })]
35
- }), /* @__PURE__ */ s("button", {
36
+ }), /* @__PURE__ */ l("button", {
36
37
  type: "button",
37
- onClick: u,
38
+ onClick: f,
38
39
  className: "flex size-8 items-center justify-center rounded-full text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
39
- "aria-label": m("voiceSession.transcriptClose", "Close the transcript"),
40
+ "aria-label": g("voiceSession.transcriptClose", "Close the transcript"),
40
41
  "data-testid": "assistant-voice-transcript-close",
41
- children: /* @__PURE__ */ s(o, { className: "size-4" })
42
+ children: /* @__PURE__ */ l(c, { className: "size-4" })
42
43
  })]
43
44
  }),
44
- /* @__PURE__ */ s(t, { turns: l }),
45
- (d || f) && l.length > 0 ? /* @__PURE__ */ c("div", {
45
+ /* @__PURE__ */ l(r, { turns: d }),
46
+ (p || m) && d.length > 0 ? /* @__PURE__ */ u("div", {
46
47
  className: "flex items-center justify-end gap-2 border-t border-border-subtle px-4 py-3",
47
- children: [d ? /* @__PURE__ */ c("button", {
48
+ children: [p ? /* @__PURE__ */ u("button", {
48
49
  type: "button",
49
- onClick: d,
50
+ onClick: p,
50
51
  className: "flex items-center gap-1.5 rounded-lg border border-border-default px-3 py-1.5 text-xs text-text-secondary transition-colors hover:bg-bg-elevated hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
51
52
  "data-testid": "assistant-voice-save-transcript",
52
- children: [/* @__PURE__ */ s(a, {
53
+ children: [/* @__PURE__ */ l(s, {
53
54
  className: "size-3.5",
54
55
  "aria-hidden": "true"
55
- }), m("voiceSession.save", "Save transcript")]
56
- }) : null, f ? /* @__PURE__ */ c("button", {
56
+ }), g("voiceSession.save", "Save transcript")]
57
+ }) : null, m ? /* @__PURE__ */ u("button", {
57
58
  type: "button",
58
- onClick: f,
59
+ onClick: m,
59
60
  className: "flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-fg transition-opacity hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
60
61
  "data-testid": "assistant-voice-continue-in-chat",
61
- children: [m("voiceSession.continueInChat", "Continue in chat"), /* @__PURE__ */ s(i, {
62
+ children: [g("voiceSession.continueInChat", "Continue in chat"), /* @__PURE__ */ l(o, {
62
63
  className: "size-3.5",
63
64
  "aria-hidden": "true"
64
65
  })]
@@ -68,4 +69,4 @@ var l = ({ turns: l, onClose: u, onSave: d, onContinueInChat: f, closeOnEscape:
68
69
  });
69
70
  };
70
71
  //#endregion
71
- export { l as VoiceTranscriptDrawer };
72
+ export { d as VoiceTranscriptDrawer };
@@ -1 +1 @@
1
- {"version":3,"file":"useAssistantKeyboardShortcuts.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useAssistantKeyboardShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGlD,UAAU,OAAO;IACf,QAAQ,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,QA0DrF"}
1
+ {"version":3,"file":"useAssistantKeyboardShortcuts.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useAssistantKeyboardShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlD,UAAU,OAAO;IACf,QAAQ,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,QA+ErF"}
@@ -1,35 +1,41 @@
1
1
  import { useAssistantStore as e } from "./store.js";
2
- import { useEffect as t } from "react";
2
+ import { focusIsInsidePanel as t, panelOwnsEscape as n } from "./ui/panelOverlays.js";
3
+ import { useEffect as r } from "react";
3
4
  //#region src/shared/assistant/useAssistantKeyboardShortcuts.ts
4
- function n({ panelRef: n, inputRef: r, onClose: i }) {
5
- t(() => {
6
- let t = (t) => {
7
- let a = n.current;
8
- if (!a || !a.contains(document.activeElement) && document.activeElement !== a) return;
9
- let o = t.ctrlKey || t.metaKey;
10
- if (t.key === "Escape") {
11
- t.preventDefault(), i();
5
+ function i({ panelRef: i, inputRef: a, onClose: o }) {
6
+ r(() => {
7
+ let r = (r) => {
8
+ let s = i.current;
9
+ if (!s) return;
10
+ let c = document.activeElement;
11
+ if (r.key === "Escape") {
12
+ if (!n(s, c, document.body)) return;
13
+ r.preventDefault(), o();
12
14
  return;
13
15
  }
14
- if (o && t.shiftKey && (t.key === "N" || t.key === "n")) {
15
- t.preventDefault(), e.getState().createConversation();
16
+ if (!t(s, c)) return;
17
+ let l = r.ctrlKey || r.metaKey;
18
+ if (l && r.shiftKey && (r.key === "N" || r.key === "n")) {
19
+ r.preventDefault(), e.getState().createConversation();
16
20
  return;
17
21
  }
18
- if (o && t.shiftKey && (t.key === "E" || t.key === "e")) {
19
- t.preventDefault(), a.querySelector("[data-testid=\"assistant-more\"]")?.click();
22
+ if (l && r.shiftKey && (r.key === "E" || r.key === "e")) {
23
+ r.preventDefault();
24
+ let e = s.querySelector("[data-testid=\"assistant-more\"]");
25
+ e?.focus(), e?.click();
20
26
  return;
21
27
  }
22
- if (t.key === "/" && !o && !t.shiftKey) {
23
- let e = document.activeElement?.tagName;
24
- e !== "INPUT" && e !== "TEXTAREA" && (t.preventDefault(), r?.current?.focus());
28
+ if (r.key === "/" && !l && !r.shiftKey) {
29
+ let e = c?.tagName;
30
+ e !== "INPUT" && e !== "TEXTAREA" && (r.preventDefault(), a?.current?.focus());
25
31
  }
26
32
  };
27
- return document.addEventListener("keydown", t), () => document.removeEventListener("keydown", t);
33
+ return document.addEventListener("keydown", r), () => document.removeEventListener("keydown", r);
28
34
  }, [
29
- n,
30
- r,
31
- i
35
+ i,
36
+ a,
37
+ o
32
38
  ]);
33
39
  }
34
40
  //#endregion
35
- export { n as useAssistantKeyboardShortcuts };
41
+ export { i as useAssistantKeyboardShortcuts };
@@ -57,46 +57,47 @@ import { AssistantSpeakButton as $r } from "./shared/assistant/ui/AssistantSpeak
57
57
  import { AssistantSpokenTurnsNotice as ei } from "./shared/assistant/ui/AssistantSpokenTurnsNotice.js";
58
58
  import { AssistantConnectSourceProvider as ti, useAssistantConnectSource as ni } from "./shared/assistant/ui/composer/connectSource.js";
59
59
  import { AssistantConnectSourceItem as ri } from "./shared/assistant/ui/composer/AssistantConnectSourceItem.js";
60
- import { AssistantAttachmentButton as ii } from "./shared/assistant/ui/composer/AssistantAttachmentButton.js";
61
- import { AssistantAttachmentChips as ai } from "./shared/assistant/ui/composer/AssistantAttachmentChips.js";
62
- import { AssistantPreviewProvider as oi, useAssistantPreview as si } from "./shared/assistant/preview/context.js";
63
- import { IDLE_PREVIEW_STATE as ci, nextPreviewEvents as li } from "./shared/assistant/preview/previewTransitions.js";
64
- import { NO_PANEL_OVERLAY as ui, escapeDismisses as di, nextPanelOverlays as fi } from "./shared/assistant/ui/panelOverlays.js";
65
- import { useOverlayFocus as pi } from "./shared/assistant/ui/useOverlayFocus.js";
66
- import { useAssistantPreviewBridge as mi } from "./shared/assistant/preview/useAssistantPreviewBridge.js";
67
- import { AssistantPreviewOverlay as hi } from "./shared/assistant/preview/AssistantPreviewOverlay.js";
68
- import { AssistantLanguageSelector as gi, FOLLOW_APP_LOCALE as _i } from "./shared/assistant/ui/composer/AssistantLanguageSelector.js";
69
- import { ASSISTANT_MODE_META as vi, AssistantModeSelector as yi, nextModeIndex as bi } from "./shared/assistant/ui/composer/AssistantModeSelector.js";
70
- import { AssistantVoiceButton as xi } from "./shared/assistant/ui/composer/AssistantVoiceButton.js";
71
- import { AUTO_VOICE as Si, AssistantVoiceSelector as Ci } from "./shared/assistant/ui/composer/AssistantVoiceSelector.js";
72
- import { AssistantVoiceOrb as wi } from "./shared/assistant/ui/voice/AssistantVoiceOrb.js";
73
- import { AssistantVoiceSessionButton as Ti } from "./shared/assistant/ui/voice/AssistantVoiceSessionButton.js";
74
- import { CAPTION_SCROLL_ATTR as Ei, VoiceCaption as Di } from "./shared/assistant/ui/voice/VoiceCaption.js";
75
- import { VoiceConversationView as Oi } from "./shared/assistant/ui/voice/VoiceConversationView.js";
76
- import { VoiceWaveform as ki } from "./shared/assistant/ui/voice/VoiceWaveform.js";
77
- import { VoiceMiniController as Ai } from "./shared/assistant/ui/voice/VoiceMiniController.js";
78
- import { VoiceStage as ji } from "./shared/assistant/ui/voice/VoiceStage.js";
79
- import { VoiceTranscriptDrawer as Mi } from "./shared/assistant/ui/voice/VoiceTranscriptDrawer.js";
80
- import { downloadFile as Ni, exportConversation as Pi } from "./shared/assistant/exportConversation.js";
81
- import { AssistantMoreMenu as Fi } from "./shared/assistant/ui/AssistantMoreMenu.js";
82
- import { AssistantHeader as Ii } from "./shared/assistant/ui/AssistantHeader.js";
83
- import { AssistantConversationList as Li } from "./shared/assistant/ui/AssistantConversationList.js";
84
- import { AssistantEmptyState as Ri } from "./shared/assistant/ui/AssistantEmptyState.js";
85
- import { AssistantMessageItem as zi } from "./shared/assistant/ui/AssistantMessageItem.js";
86
- import { AssistantMessageList as Bi } from "./shared/assistant/ui/AssistantMessageList.js";
87
- import { AssistantVoiceSession as Vi } from "./shared/assistant/ui/voice/AssistantVoiceSession.js";
88
- import { useAssistantApiAccess as Hi } from "./shared/assistant/useAssistantApiAccess.js";
89
- import { useConversationTurns as Ui } from "./shared/assistant/useConversationTurns.js";
90
- import { isMultimodalBodyRejection as Wi, isRecoverableAssistantError as Gi } from "./shared/assistant/transportErrors.js";
91
- import { aiCreditsUpdatedEventName as Ki, dispatchAssistantQuotaExhausted as qi, notifyAiCreditsUpdated as Ji } from "./shared/assistant/aiCredits.js";
92
- import { useWorkspaceWriteAccess as Yi } from "./shared/assistant/useWorkspaceWriteAccess.js";
93
- import { extractDocumentText as Xi } from "./shared/assistant/documentExtract.js";
94
- import { useAssistantAttachments as Zi } from "./shared/assistant/useAssistantAttachments.js";
95
- import { AssistantComposer as Qi } from "./shared/assistant/ui/composer/AssistantComposer.js";
96
- import { isProdRuntime as $i } from "./shared/assistant/env.js";
97
- import { useAssistantHeartbeat as ea } from "./shared/assistant/useAssistantHeartbeat.js";
98
- import { useAssistantKeyboardShortcuts as ta } from "./shared/assistant/useAssistantKeyboardShortcuts.js";
99
- import { AssistantApiCallsConsentDialog as na } from "./shared/assistant/ui/AssistantApiCallsConsentDialog.js";
100
- import { AssistantChatArea as ra } from "./shared/assistant/ui/AssistantChatArea.js";
101
- import { AIAssistantPanel as ia } from "./shared/assistant/ui/AIAssistantPanel.js";
102
- export { ia as AIAssistantPanel, L as ASSISTANT_API_AUTH_STRATEGY, sn as ASSISTANT_LANGUAGES, vi as ASSISTANT_MODE_META, Kn as ATTACHMENT_ACCEPT, Hr as ATTACHMENT_SOURCES, Si as AUTO_VOICE, na as AssistantApiCallsConsentDialog, ii as AssistantAttachmentButton, ai as AssistantAttachmentChips, Jr as AssistantAutoSpeakToggle, ra as AssistantChatArea, Qi as AssistantComposer, ri as AssistantConnectSourceItem, ti as AssistantConnectSourceProvider, Li as AssistantConversationList, Ri as AssistantEmptyState, Ii as AssistantHeader, s as AssistantI18nProvider, Zr as AssistantLanguageMenu, gi as AssistantLanguageSelector, f as AssistantMarkdownImage, h as AssistantMarkdownRenderer, Yr as AssistantMessageAttachments, zi as AssistantMessageItem, Bi as AssistantMessageList, yi as AssistantModeSelector, Fi as AssistantMoreMenu, g as AssistantNavigateProvider, Xr as AssistantPendingWriteCard, hi as AssistantPreviewOverlay, oi as AssistantPreviewProvider, t as AssistantProductProvider, Qr as AssistantReplyLanguageSelector, _e as AssistantRuntimeManager, $r as AssistantSpeakButton, Ir as AssistantSpeechProvider, ei as AssistantSpokenTurnsNotice, Pr as AssistantToolActivity, xi as AssistantVoiceButton, wi as AssistantVoiceOrb, Ci as AssistantVoiceSelector, Vi as AssistantVoiceSession, Ti as AssistantVoiceSessionButton, qn as AttachmentRejectedError, En as BOILERPLATE_PAGE_SHARE, Ei as CAPTION_SCROLL_ATTR, O as CHECK_AI_CREDITS, k as CREATE_SANDBOX, zt as DEFAULT_SPEAKABLE_LABELS, cn as DEFAULT_SPEECH_RATE, ft as ENDPOINT_GRACE_MS, A as EXTEND_SANDBOX_TTL, _i as FOLLOW_APP_LOCALE, j as GET_ACTIVE_SANDBOXES, M as GET_SANDBOX, He as HOSTED_TTS_MAX_CHARS, Re as HOSTED_TTS_TIER, ze as HOSTED_VOICES, yn as IDLE_PLAYBACK, ci as IDLE_PREVIEW_STATE, pt as INITIAL_SESSION, Jn as INLINE_IMAGE_MAX_DIM, Yn as INLINE_IMAGE_QUALITY, mt as INTERRUPT_MAX_MS, ht as INTERRUPT_MIN_MS, Xn as MAX_ATTACHMENTS, Dn as MAX_BOILERPLATE_LINE_CHARS, On as MAX_EXTRACTED_CHARS, Zn as MAX_FILE_BYTES, Qn as MAX_INLINE_CHARS_PER_FILE, $n as MAX_INLINE_CHARS_TOTAL, wn as MAX_INLINE_IMAGE_BASE64_BYTES, er as MAX_INLINE_IMAGE_BASE64_CHARS, tr as MAX_INLINE_IMAGE_PARTS, nr as MAX_INLINE_TURN_BODY_BYTES, kn as MAX_PDF_PAGES_SCANNED, Tn as MAX_REQUEST_BODY_BYTES, Bt as MAX_SPEAKABLE_CHARS, Vt as MAX_SPOKEN_TABLE_ROWS, rr as MAX_TURN_BODY_BYTES, Zt as MINI_CAPTION_BUDGET, An as MIN_PAGE_TEXT_CHARS, jn as MIN_TEXT_PAGE_SHARE, ui as NO_PANEL_OVERLAY, Dr as PHRASE_ROTATE_MS, $t as POLL_FAST_MS, en as POLL_FAST_UNTIL_MS, tn as POLL_SLOW_MS, nn as POLL_STEADY_MS, rn as POLL_STEADY_UNTIL_MS, Yt as PREVIEW_LANGUAGES, ir as PROMPT_ENVELOPE_RESERVE_BYTES, N as PROXY_SANDBOX_REQUEST, P as REPORT_AI_TOKEN_USAGE, Gr as SANDBOX_READY_TTL_MS, gt as SILENCE_SUBMIT_MS, Ue as SPEAKING_RATE_MAX, We as SPEAKING_RATE_MAX_STREAMING, Ge as SPEAKING_RATE_MAX_SYNC, Ke as SPEAKING_RATE_MIN, Ht as SPEECH_CHUNK_CHARS, Ut as SPEECH_CHUNK_CJK_CHARS, wt as SPEECH_LANG, hn as SPOKEN_LABEL_LANGUAGES, Or as STAGE_COPY, F as STOP_ASSISTANT_SANDBOX, kr as THINKING_PHRASES, ar as TURN_BODY_HEADROOM_BYTES, Tt as VOICE_LIST_TIMEOUT_MS, Di as VoiceCaption, Oi as VoiceConversationView, Ai as VoiceMiniController, ji as VoiceStage, Mi as VoiceTranscriptDrawer, ki as VoiceWaveform, I as WAIT_FOR_SANDBOX_RUNNING, q as abortAssistantTurn, Ki as aiCreditsUpdatedEventName, J as approvePendingWrite, _ as assistantRoutePath, c as assistantTranslationKey, v as assistantUrlTransform, Ur as availableAttachmentSources, qe as base64ToBytes, y as browserShouldHandle, Le as browserSpeechEngine, Y as buildAssistantSandboxEnv, or as buildAttachmentPromptBlock, It as buildContinuedFromVoiceNote, ve as buildProgress, sr as buildPromptParts, X as buildPromptRequestBody, cr as buildPromptWithAttachments, Je as buildRequest, E as buildSandboxContextInput, Lt as buildVoiceTranscriptMarkdown, Ae as chatTurns, Z as checkAssistantAiCredits, Wt as chunkForSpeech, b as classifyAssistantHref, lr as classifyAttachment, Ye as classifyHttpFailure, S as classifyQuotaError, Mn as columnLetterToIndex, tt as configureSpeechEngine, Gt as containsCjk, d as copyToClipboard, ur as countInlineImageCandidates, dr as countInlinedImageParts, Q as createAssistantSandbox, $ as createAssistantSession, $e as createHostedTtsEngine, Kr as createReadinessTracker, et as createRoutingSpeechEngine, Oe as createSandboxAssistantTransport, nt as createSpeechEngines, Xe as decodeAudioResponse, Nn as decodeXmlEntities, C as describeQuotaError, fr as detectDocumentFormat, _n as detectScriptLocale, Wr as deviceHasCamera, qi as dispatchAssistantQuotaExhausted, Pn as docxXmlToText, ee as downloadAssistantArtifact, Ni as downloadFile, di as escapeDismisses, pr as estimateTurnBodyBytes, D as executeSandboxGraphQL, Pi as exportConversation, te as extendAssistantSandboxTTL, Xi as extractDocumentText, ln as findAssistantLanguage, ne as findExistingSandbox, pn as findPendingWrite, Fn as fitPdfPages, mr as formatBytes, In as formatPageRanges, zr as getActorId, re as getAssistantArtifacts, ye as getAssistantMedia, ie as getAssistantMessages, ae as getAssistantSession, oe as getAssistantStreamAccess, be as getAssistantText, hr as getAttachmentSendBlocker, U as getCapability, gr as getExtension, R as getImageForMode, z as getImageTagForMode, Br as getOrganizationId, xe as getRawMessageCreatedAt, B as getResourcesForMode, V as getSandboxImageRegistry, _r as getSendableAttachments, rt as getSpeechEngine, Se as getToolProgress, Vr as getWorkspaceId, je as groupBySession, Me as groupConsecutiveBySession, vr as hasAttachmentWorkInFlight, Be as hostedLocaleFor, Ve as hostedSupportsLanguage, p as imageHostLabel, _t as isCapturing, vt as isEcho, Ln as isMostlyImagePages, Wi as isMultimodalBodyRejection, $i as isProdRuntime, w as isQuotaExhaustedError, Ce as isReapedSandboxConnectionError, qr as isRecentlyVerified, we as isRecoverable, Gi as isRecoverableAssistantError, m as isRemoteImageSrc, bn as isSpeakingMessage, Et as isSpeechBlocked, Ar as isStageCopy, yt as isSubmittable, wr as isTurnInFlight, W as isUnknownFieldError, Ne as isVoiceTurn, Rn as joinSheets, Dt as languageDisplayName, Te as mapSessionToHistory, G as markSupported, K as markUnsupported, Ee as mergeMessagesById, ot as micIsInterrupt, se as modeRequiresConfirmWrites, bi as nextModeIndex, fi as nextPanelOverlays, li as nextPreviewEvents, Ot as normalizeLangTag, Ji as notifyAiCreditsUpdated, bt as orbMode, zn as pageMarker, mn as parseConfirmationRefusal, yr as parseDataUrl, Bn as parseSharedStrings, Fr as parseToolActivity, Vn as parseWorkbookSheets, Hn as pdfTextItemsToPage, Tr as planAbandonedTurn, xt as planReplyConsumption, Er as planTurnAbort, an as pollDelayMs, kt as primaryLanguageSubtag, xn as publishedChunks, T as quotaExhaustedEventName, it as readSpeechEngineConfig, ce as releaseSupersededAssistantSandboxes, dn as replyFollowsInput, le as reportAssistantAiTokenUsage, Sn as requiresCancel, at as resetSpeechEngine, un as resolveAssistantLanguage, fn as resolveLanguagePair, n as resolveModeConfig, H as resolveSandboxAssistantMode, vn as resolveSpeechLocale, De as sanitize, ue as selectExistingAssistantSandbox, de as selectSupersededAssistantSandboxes, At as selectVoiceForLocale, fe as sendAssistantPromptAsync, pe as sendHeartbeat, Un as sheetXmlToRows, Ze as shouldDisableEngine, Qt as showPreviousChunk, st as showsAssistantCaption, ct as showsUserCaption, Kt as speakableEmail, jt as speechGate, gn as speechLabelsFor, Mt as speechLangForLocale, Cn as speechPlaybackReducer, Qe as splitForVendor, qt as splitTableRow, St as spokenSoFar, jr as stageText, Mr as statusStageCopy, me as stopReapedAssistantSandbox, Wn as summarisePageText, Nr as thinkingPhrase, on as toCaptionText, br as toMessageAttachment, Jt as toSpeakableText, xr as truncateForInline, Gn as truncatePagesForInline, Hi as useAssistantApiAccess, Zi as useAssistantAttachments, ni as useAssistantConnectSource, ea as useAssistantHeartbeat, l as useAssistantI18nNamespace, ta as useAssistantKeyboardShortcuts, x as useAssistantNavigate, r as useAssistantPageLabel, si as useAssistantPreview, mi as useAssistantPreviewBridge, i as useAssistantProduct, a as useAssistantProductOrNull, Lr as useAssistantSpeech, o as useAssistantStorageFolders, Cr as useAssistantStore, u as useAssistantTr, Ui as useConversationTurns, pi as useOverlayFocus, ke as useSandboxAssistantTransport, e as useVoiceInput, Rr as useVoiceSession, Yi as useWorkspaceWriteAccess, Sr as validateFile, Nt as voiceAvailability, Pe as voiceMarker, Xt as voicePreviewText, Pt as voiceQualityRank, Fe as voiceSessionIdOf, Ct as voiceSessionReducer, lt as voiceStageState, Rt as voiceTranscriptFilename, Ie as voiceTurnsOnly, Ft as voicesForLocale, he as waitForAssistantServiceReady, ge as waitForSandboxRunning, ut as waveformIsActive, dt as waveformIsSettled };
60
+ import { ASSISTANT_OVERLAY_ATTR as ii, ASSISTANT_PANEL_ATTR as ai, NO_PANEL_OVERLAY as oi, activePanelOverlay as si, assistantPanelOwnsEscape as ci, escapeDismisses as li, focusIsInsidePanel as ui, nextPanelOverlays as di, panelOwnsEscape as fi } from "./shared/assistant/ui/panelOverlays.js";
61
+ import { useDropdownEscape as pi } from "./shared/assistant/ui/useDropdownEscape.js";
62
+ import { AssistantAttachmentButton as mi } from "./shared/assistant/ui/composer/AssistantAttachmentButton.js";
63
+ import { AssistantAttachmentChips as hi } from "./shared/assistant/ui/composer/AssistantAttachmentChips.js";
64
+ import { AssistantPreviewProvider as gi, useAssistantPreview as _i } from "./shared/assistant/preview/context.js";
65
+ import { IDLE_PREVIEW_STATE as vi, nextPreviewEvents as yi } from "./shared/assistant/preview/previewTransitions.js";
66
+ import { useOverlayFocus as bi } from "./shared/assistant/ui/useOverlayFocus.js";
67
+ import { useAssistantPreviewBridge as xi } from "./shared/assistant/preview/useAssistantPreviewBridge.js";
68
+ import { AssistantPreviewOverlay as Si } from "./shared/assistant/preview/AssistantPreviewOverlay.js";
69
+ import { AssistantLanguageSelector as Ci, FOLLOW_APP_LOCALE as wi } from "./shared/assistant/ui/composer/AssistantLanguageSelector.js";
70
+ import { ASSISTANT_MODE_META as Ti, AssistantModeSelector as Ei, nextModeIndex as Di } from "./shared/assistant/ui/composer/AssistantModeSelector.js";
71
+ import { AssistantVoiceButton as Oi } from "./shared/assistant/ui/composer/AssistantVoiceButton.js";
72
+ import { AUTO_VOICE as ki, AssistantVoiceSelector as Ai } from "./shared/assistant/ui/composer/AssistantVoiceSelector.js";
73
+ import { AssistantVoiceOrb as ji } from "./shared/assistant/ui/voice/AssistantVoiceOrb.js";
74
+ import { AssistantVoiceSessionButton as Mi } from "./shared/assistant/ui/voice/AssistantVoiceSessionButton.js";
75
+ import { CAPTION_SCROLL_ATTR as Ni, VoiceCaption as Pi } from "./shared/assistant/ui/voice/VoiceCaption.js";
76
+ import { VoiceConversationView as Fi } from "./shared/assistant/ui/voice/VoiceConversationView.js";
77
+ import { VoiceWaveform as Ii } from "./shared/assistant/ui/voice/VoiceWaveform.js";
78
+ import { VoiceMiniController as Li } from "./shared/assistant/ui/voice/VoiceMiniController.js";
79
+ import { VoiceStage as Ri } from "./shared/assistant/ui/voice/VoiceStage.js";
80
+ import { VoiceTranscriptDrawer as zi } from "./shared/assistant/ui/voice/VoiceTranscriptDrawer.js";
81
+ import { downloadFile as Bi, exportConversation as Vi } from "./shared/assistant/exportConversation.js";
82
+ import { AssistantMoreMenu as Hi } from "./shared/assistant/ui/AssistantMoreMenu.js";
83
+ import { AssistantHeader as Ui } from "./shared/assistant/ui/AssistantHeader.js";
84
+ import { AssistantConversationList as Wi } from "./shared/assistant/ui/AssistantConversationList.js";
85
+ import { AssistantEmptyState as Gi } from "./shared/assistant/ui/AssistantEmptyState.js";
86
+ import { AssistantMessageItem as Ki } from "./shared/assistant/ui/AssistantMessageItem.js";
87
+ import { AssistantMessageList as qi } from "./shared/assistant/ui/AssistantMessageList.js";
88
+ import { AssistantVoiceSession as Ji } from "./shared/assistant/ui/voice/AssistantVoiceSession.js";
89
+ import { useAssistantApiAccess as Yi } from "./shared/assistant/useAssistantApiAccess.js";
90
+ import { useConversationTurns as Xi } from "./shared/assistant/useConversationTurns.js";
91
+ import { isMultimodalBodyRejection as Zi, isRecoverableAssistantError as Qi } from "./shared/assistant/transportErrors.js";
92
+ import { aiCreditsUpdatedEventName as $i, dispatchAssistantQuotaExhausted as ea, notifyAiCreditsUpdated as ta } from "./shared/assistant/aiCredits.js";
93
+ import { useWorkspaceWriteAccess as na } from "./shared/assistant/useWorkspaceWriteAccess.js";
94
+ import { extractDocumentText as ra } from "./shared/assistant/documentExtract.js";
95
+ import { useAssistantAttachments as ia } from "./shared/assistant/useAssistantAttachments.js";
96
+ import { AssistantComposer as aa } from "./shared/assistant/ui/composer/AssistantComposer.js";
97
+ import { isProdRuntime as oa } from "./shared/assistant/env.js";
98
+ import { useAssistantHeartbeat as sa } from "./shared/assistant/useAssistantHeartbeat.js";
99
+ import { useAssistantKeyboardShortcuts as ca } from "./shared/assistant/useAssistantKeyboardShortcuts.js";
100
+ import { AssistantApiCallsConsentDialog as la } from "./shared/assistant/ui/AssistantApiCallsConsentDialog.js";
101
+ import { AssistantChatArea as ua } from "./shared/assistant/ui/AssistantChatArea.js";
102
+ import { AIAssistantPanel as da } from "./shared/assistant/ui/AIAssistantPanel.js";
103
+ export { da as AIAssistantPanel, L as ASSISTANT_API_AUTH_STRATEGY, sn as ASSISTANT_LANGUAGES, Ti as ASSISTANT_MODE_META, ii as ASSISTANT_OVERLAY_ATTR, ai as ASSISTANT_PANEL_ATTR, Kn as ATTACHMENT_ACCEPT, Hr as ATTACHMENT_SOURCES, ki as AUTO_VOICE, la as AssistantApiCallsConsentDialog, mi as AssistantAttachmentButton, hi as AssistantAttachmentChips, Jr as AssistantAutoSpeakToggle, ua as AssistantChatArea, aa as AssistantComposer, ri as AssistantConnectSourceItem, ti as AssistantConnectSourceProvider, Wi as AssistantConversationList, Gi as AssistantEmptyState, Ui as AssistantHeader, s as AssistantI18nProvider, Zr as AssistantLanguageMenu, Ci as AssistantLanguageSelector, f as AssistantMarkdownImage, h as AssistantMarkdownRenderer, Yr as AssistantMessageAttachments, Ki as AssistantMessageItem, qi as AssistantMessageList, Ei as AssistantModeSelector, Hi as AssistantMoreMenu, g as AssistantNavigateProvider, Xr as AssistantPendingWriteCard, Si as AssistantPreviewOverlay, gi as AssistantPreviewProvider, t as AssistantProductProvider, Qr as AssistantReplyLanguageSelector, _e as AssistantRuntimeManager, $r as AssistantSpeakButton, Ir as AssistantSpeechProvider, ei as AssistantSpokenTurnsNotice, Pr as AssistantToolActivity, Oi as AssistantVoiceButton, ji as AssistantVoiceOrb, Ai as AssistantVoiceSelector, Ji as AssistantVoiceSession, Mi as AssistantVoiceSessionButton, qn as AttachmentRejectedError, En as BOILERPLATE_PAGE_SHARE, Ni as CAPTION_SCROLL_ATTR, O as CHECK_AI_CREDITS, k as CREATE_SANDBOX, zt as DEFAULT_SPEAKABLE_LABELS, cn as DEFAULT_SPEECH_RATE, ft as ENDPOINT_GRACE_MS, A as EXTEND_SANDBOX_TTL, wi as FOLLOW_APP_LOCALE, j as GET_ACTIVE_SANDBOXES, M as GET_SANDBOX, He as HOSTED_TTS_MAX_CHARS, Re as HOSTED_TTS_TIER, ze as HOSTED_VOICES, yn as IDLE_PLAYBACK, vi as IDLE_PREVIEW_STATE, pt as INITIAL_SESSION, Jn as INLINE_IMAGE_MAX_DIM, Yn as INLINE_IMAGE_QUALITY, mt as INTERRUPT_MAX_MS, ht as INTERRUPT_MIN_MS, Xn as MAX_ATTACHMENTS, Dn as MAX_BOILERPLATE_LINE_CHARS, On as MAX_EXTRACTED_CHARS, Zn as MAX_FILE_BYTES, Qn as MAX_INLINE_CHARS_PER_FILE, $n as MAX_INLINE_CHARS_TOTAL, wn as MAX_INLINE_IMAGE_BASE64_BYTES, er as MAX_INLINE_IMAGE_BASE64_CHARS, tr as MAX_INLINE_IMAGE_PARTS, nr as MAX_INLINE_TURN_BODY_BYTES, kn as MAX_PDF_PAGES_SCANNED, Tn as MAX_REQUEST_BODY_BYTES, Bt as MAX_SPEAKABLE_CHARS, Vt as MAX_SPOKEN_TABLE_ROWS, rr as MAX_TURN_BODY_BYTES, Zt as MINI_CAPTION_BUDGET, An as MIN_PAGE_TEXT_CHARS, jn as MIN_TEXT_PAGE_SHARE, oi as NO_PANEL_OVERLAY, Dr as PHRASE_ROTATE_MS, $t as POLL_FAST_MS, en as POLL_FAST_UNTIL_MS, tn as POLL_SLOW_MS, nn as POLL_STEADY_MS, rn as POLL_STEADY_UNTIL_MS, Yt as PREVIEW_LANGUAGES, ir as PROMPT_ENVELOPE_RESERVE_BYTES, N as PROXY_SANDBOX_REQUEST, P as REPORT_AI_TOKEN_USAGE, Gr as SANDBOX_READY_TTL_MS, gt as SILENCE_SUBMIT_MS, Ue as SPEAKING_RATE_MAX, We as SPEAKING_RATE_MAX_STREAMING, Ge as SPEAKING_RATE_MAX_SYNC, Ke as SPEAKING_RATE_MIN, Ht as SPEECH_CHUNK_CHARS, Ut as SPEECH_CHUNK_CJK_CHARS, wt as SPEECH_LANG, hn as SPOKEN_LABEL_LANGUAGES, Or as STAGE_COPY, F as STOP_ASSISTANT_SANDBOX, kr as THINKING_PHRASES, ar as TURN_BODY_HEADROOM_BYTES, Tt as VOICE_LIST_TIMEOUT_MS, Pi as VoiceCaption, Fi as VoiceConversationView, Li as VoiceMiniController, Ri as VoiceStage, zi as VoiceTranscriptDrawer, Ii as VoiceWaveform, I as WAIT_FOR_SANDBOX_RUNNING, q as abortAssistantTurn, si as activePanelOverlay, $i as aiCreditsUpdatedEventName, J as approvePendingWrite, ci as assistantPanelOwnsEscape, _ as assistantRoutePath, c as assistantTranslationKey, v as assistantUrlTransform, Ur as availableAttachmentSources, qe as base64ToBytes, y as browserShouldHandle, Le as browserSpeechEngine, Y as buildAssistantSandboxEnv, or as buildAttachmentPromptBlock, It as buildContinuedFromVoiceNote, ve as buildProgress, sr as buildPromptParts, X as buildPromptRequestBody, cr as buildPromptWithAttachments, Je as buildRequest, E as buildSandboxContextInput, Lt as buildVoiceTranscriptMarkdown, Ae as chatTurns, Z as checkAssistantAiCredits, Wt as chunkForSpeech, b as classifyAssistantHref, lr as classifyAttachment, Ye as classifyHttpFailure, S as classifyQuotaError, Mn as columnLetterToIndex, tt as configureSpeechEngine, Gt as containsCjk, d as copyToClipboard, ur as countInlineImageCandidates, dr as countInlinedImageParts, Q as createAssistantSandbox, $ as createAssistantSession, $e as createHostedTtsEngine, Kr as createReadinessTracker, et as createRoutingSpeechEngine, Oe as createSandboxAssistantTransport, nt as createSpeechEngines, Xe as decodeAudioResponse, Nn as decodeXmlEntities, C as describeQuotaError, fr as detectDocumentFormat, _n as detectScriptLocale, Wr as deviceHasCamera, ea as dispatchAssistantQuotaExhausted, Pn as docxXmlToText, ee as downloadAssistantArtifact, Bi as downloadFile, li as escapeDismisses, pr as estimateTurnBodyBytes, D as executeSandboxGraphQL, Vi as exportConversation, te as extendAssistantSandboxTTL, ra as extractDocumentText, ln as findAssistantLanguage, ne as findExistingSandbox, pn as findPendingWrite, Fn as fitPdfPages, ui as focusIsInsidePanel, mr as formatBytes, In as formatPageRanges, zr as getActorId, re as getAssistantArtifacts, ye as getAssistantMedia, ie as getAssistantMessages, ae as getAssistantSession, oe as getAssistantStreamAccess, be as getAssistantText, hr as getAttachmentSendBlocker, U as getCapability, gr as getExtension, R as getImageForMode, z as getImageTagForMode, Br as getOrganizationId, xe as getRawMessageCreatedAt, B as getResourcesForMode, V as getSandboxImageRegistry, _r as getSendableAttachments, rt as getSpeechEngine, Se as getToolProgress, Vr as getWorkspaceId, je as groupBySession, Me as groupConsecutiveBySession, vr as hasAttachmentWorkInFlight, Be as hostedLocaleFor, Ve as hostedSupportsLanguage, p as imageHostLabel, _t as isCapturing, vt as isEcho, Ln as isMostlyImagePages, Zi as isMultimodalBodyRejection, oa as isProdRuntime, w as isQuotaExhaustedError, Ce as isReapedSandboxConnectionError, qr as isRecentlyVerified, we as isRecoverable, Qi as isRecoverableAssistantError, m as isRemoteImageSrc, bn as isSpeakingMessage, Et as isSpeechBlocked, Ar as isStageCopy, yt as isSubmittable, wr as isTurnInFlight, W as isUnknownFieldError, Ne as isVoiceTurn, Rn as joinSheets, Dt as languageDisplayName, Te as mapSessionToHistory, G as markSupported, K as markUnsupported, Ee as mergeMessagesById, ot as micIsInterrupt, se as modeRequiresConfirmWrites, Di as nextModeIndex, di as nextPanelOverlays, yi as nextPreviewEvents, Ot as normalizeLangTag, ta as notifyAiCreditsUpdated, bt as orbMode, zn as pageMarker, fi as panelOwnsEscape, mn as parseConfirmationRefusal, yr as parseDataUrl, Bn as parseSharedStrings, Fr as parseToolActivity, Vn as parseWorkbookSheets, Hn as pdfTextItemsToPage, Tr as planAbandonedTurn, xt as planReplyConsumption, Er as planTurnAbort, an as pollDelayMs, kt as primaryLanguageSubtag, xn as publishedChunks, T as quotaExhaustedEventName, it as readSpeechEngineConfig, ce as releaseSupersededAssistantSandboxes, dn as replyFollowsInput, le as reportAssistantAiTokenUsage, Sn as requiresCancel, at as resetSpeechEngine, un as resolveAssistantLanguage, fn as resolveLanguagePair, n as resolveModeConfig, H as resolveSandboxAssistantMode, vn as resolveSpeechLocale, De as sanitize, ue as selectExistingAssistantSandbox, de as selectSupersededAssistantSandboxes, At as selectVoiceForLocale, fe as sendAssistantPromptAsync, pe as sendHeartbeat, Un as sheetXmlToRows, Ze as shouldDisableEngine, Qt as showPreviousChunk, st as showsAssistantCaption, ct as showsUserCaption, Kt as speakableEmail, jt as speechGate, gn as speechLabelsFor, Mt as speechLangForLocale, Cn as speechPlaybackReducer, Qe as splitForVendor, qt as splitTableRow, St as spokenSoFar, jr as stageText, Mr as statusStageCopy, me as stopReapedAssistantSandbox, Wn as summarisePageText, Nr as thinkingPhrase, on as toCaptionText, br as toMessageAttachment, Jt as toSpeakableText, xr as truncateForInline, Gn as truncatePagesForInline, Yi as useAssistantApiAccess, ia as useAssistantAttachments, ni as useAssistantConnectSource, sa as useAssistantHeartbeat, l as useAssistantI18nNamespace, ca as useAssistantKeyboardShortcuts, x as useAssistantNavigate, r as useAssistantPageLabel, _i as useAssistantPreview, xi as useAssistantPreviewBridge, i as useAssistantProduct, a as useAssistantProductOrNull, Lr as useAssistantSpeech, o as useAssistantStorageFolders, Cr as useAssistantStore, u as useAssistantTr, Xi as useConversationTurns, pi as useDropdownEscape, bi as useOverlayFocus, ke as useSandboxAssistantTransport, e as useVoiceInput, Rr as useVoiceSession, na as useWorkspaceWriteAccess, Sr as validateFile, Nt as voiceAvailability, Pe as voiceMarker, Xt as voicePreviewText, Pt as voiceQualityRank, Fe as voiceSessionIdOf, Ct as voiceSessionReducer, lt as voiceStageState, Rt as voiceTranscriptFilename, Ie as voiceTurnsOnly, Ft as voicesForLocale, he as waitForAssistantServiceReady, ge as waitForSandboxRunning, ut as waveformIsActive, dt as waveformIsSettled };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fe-libs",
3
- "version": "2026.911.4",
3
+ "version": "2026.911.6",
4
4
  "description": "Burdenoff frontend primitives and domain libraries",
5
5
  "type": "module",
6
6
  "bin": {