@burdenoff/fe-libs 2026.1029.11 → 2026.1030.2

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 (62) hide show
  1. package/dist/connections/ConnectionDetailsTab.d.ts +4 -1
  2. package/dist/connections/ConnectionDetailsTab.js +18 -15
  3. package/dist/connections/ConnectionDialog.d.ts +8 -2
  4. package/dist/connections/ConnectionDialog.js +18 -17
  5. package/dist/connections/ConnectionDialogPanel.d.ts +3 -1
  6. package/dist/connections/ConnectionDialogPanel.js +141 -135
  7. package/dist/connections/ShareConnectionDialog.d.ts +23 -0
  8. package/dist/connections/ShareConnectionDialog.js +146 -0
  9. package/dist/connections/SharePanels.d.ts +32 -0
  10. package/dist/connections/SharePanels.js +158 -0
  11. package/dist/connections/VisibilityChoice.d.ts +12 -0
  12. package/dist/connections/VisibilityChoice.js +60 -0
  13. package/dist/connections/api.d.ts +12 -1
  14. package/dist/connections/api.js +1 -1
  15. package/dist/connections/connectionFlow.d.ts +6 -1
  16. package/dist/connections/connectionFlow.js +1 -1
  17. package/dist/connections/index.d.ts +4 -1
  18. package/dist/connections/sharingApi.d.ts +28 -0
  19. package/dist/connections/sharingApi.js +215 -0
  20. package/dist/connections/types.d.ts +31 -0
  21. package/dist/connections/useConnectionSharingDraft.d.ts +40 -0
  22. package/dist/connections/useConnectionSharingDraft.js +93 -0
  23. package/dist/connections.js +12 -9
  24. package/dist/shared/assistant/i18nManifest.d.ts +18 -0
  25. package/dist/shared/assistant/i18nManifest.js +18 -0
  26. package/dist/shared/assistant/index.d.ts +4 -0
  27. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts +9 -1
  28. package/dist/shared/assistant/ui/AIAssistantPanel.js +194 -174
  29. package/dist/shared/assistant/ui/AssistantChatArea.d.ts +33 -0
  30. package/dist/shared/assistant/ui/AssistantChatArea.js +1463 -1397
  31. package/dist/shared/assistant/ui/AssistantLanguageMenu.d.ts +9 -1
  32. package/dist/shared/assistant/ui/AssistantLanguageMenu.js +22 -22
  33. package/dist/shared/assistant/ui/AssistantOverlay.d.ts +16 -2
  34. package/dist/shared/assistant/ui/AssistantOverlay.js +219 -200
  35. package/dist/shared/assistant/ui/assistantOverlayState.d.ts +16 -2
  36. package/dist/shared/assistant/ui/assistantOverlayState.js +57 -40
  37. package/dist/shared/assistant/ui/compact/AssistantConversationMenu.js +53 -52
  38. package/dist/shared/assistant/ui/compact/AssistantDiscardDraftDialog.js +3 -4
  39. package/dist/shared/assistant/ui/compact/AssistantLanguagePill.d.ts +29 -0
  40. package/dist/shared/assistant/ui/compact/AssistantLanguagePill.js +98 -0
  41. package/dist/shared/assistant/ui/compact/AssistantVoiceReady.d.ts +31 -0
  42. package/dist/shared/assistant/ui/compact/AssistantVoiceReady.js +41 -0
  43. package/dist/shared/assistant/ui/compact/AssistantWaitingChangeRow.d.ts +6 -0
  44. package/dist/shared/assistant/ui/compact/AssistantWaitingChangeRow.js +5 -5
  45. package/dist/shared/assistant/ui/compact/AssistantWindowHeader.d.ts +22 -5
  46. package/dist/shared/assistant/ui/compact/AssistantWindowHeader.js +45 -31
  47. package/dist/shared/assistant/ui/compact/windowView.d.ts +50 -0
  48. package/dist/shared/assistant/ui/compact/windowView.js +31 -0
  49. package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts +6 -0
  50. package/dist/shared/assistant/ui/composer/AssistantComposer.js +90 -89
  51. package/dist/shared/assistant/ui/composer/AssistantModeMenu.d.ts +6 -0
  52. package/dist/shared/assistant/ui/composer/AssistantModeMenu.js +83 -83
  53. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts +31 -0
  54. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +270 -166
  55. package/dist/shared/assistant/ui/voice/VoiceStage.d.ts +8 -0
  56. package/dist/shared/assistant/ui/voice/VoiceStage.js +10 -10
  57. package/dist/shared/assistant/voice/voiceStartedCue.d.ts +11 -0
  58. package/dist/shared/assistant/voice/voiceStartedCue.js +7 -0
  59. package/dist/shared-assistant.js +266 -262
  60. package/dist/ui/modal-shell.d.ts +6 -1
  61. package/dist/ui/modal-shell.js +7 -6
  62. package/package.json +1 -1
@@ -267,6 +267,10 @@ export declare function assistantOverlayClassName(input: {
267
267
  export type AssistantSurface = 'window' | 'panel';
268
268
  /** Narrow a stored value to a surface. */
269
269
  export declare function isAssistantSurface(value: unknown): value is AssistantSurface;
270
+ /** The Quick assistant window's two views (BOFF-10180): the conversation, or the voice stage. */
271
+ export type AssistantWindowView = 'chat' | 'voice';
272
+ /** Narrow a stored value to a window view. */
273
+ export declare function isAssistantWindowView(value: unknown): value is AssistantWindowView;
270
274
  /** The storage keys only the compact presentation uses. */
271
275
  export interface AssistantCompactOverlayKeys {
272
276
  /** localStorage: the person's EXPLICIT Dock/Float pick (D1-A), `docked` or `floating`. */
@@ -275,10 +279,16 @@ export interface AssistantCompactOverlayKeys {
275
279
  surfaceStorageKey: string;
276
280
  /** sessionStorage: the Quick assistant window is minimized (`1`/`0`). */
277
281
  minimizedStorageKey: string;
282
+ /**
283
+ * localStorage: the Quick assistant window's LAST USED view (CW-V), `chat` or
284
+ * `voice`. Profile-scoped, like the Dock/Float pick: a preference that outlives
285
+ * a tab, not a moment of this one.
286
+ */
287
+ windowViewStorageKey: string;
278
288
  }
279
289
  /**
280
- * The compact keys for a product prefix: `<prefix>:ai-panel:layout`, `:surface`
281
- * and `:minimized`. Separate from `assistantOverlayKeys` so the classic keys
290
+ * The compact keys for a product prefix: `<prefix>:ai-panel:layout`, `:surface`,
291
+ * `:minimized` and `:window-view`. Separate from `assistantOverlayKeys` so the classic keys
282
292
  * (and what a host reads of them) cannot change.
283
293
  */
284
294
  export declare function assistantCompactOverlayKeys(prefix: string): AssistantCompactOverlayKeys;
@@ -286,6 +296,10 @@ export declare function assistantCompactOverlayKeys(prefix: string): AssistantCo
286
296
  export type AssistantLayoutChoice = 'docked' | 'floating';
287
297
  /** The explicit Dock/Float pick (D1-A), or null when none was made or storage fails. */
288
298
  export declare function readAssistantLayoutChoice(storage: () => Pick<Storage, 'getItem'> | undefined, key: string): AssistantLayoutChoice | null;
299
+ /** The window's last-used view (CW-V), or null when none was ever chosen or storage fails. */
300
+ export declare function readAssistantWindowView(storage: () => Pick<Storage, 'getItem'> | undefined, key: string): AssistantWindowView | null;
301
+ /** Persist the window's last-used view. An unavailable store keeps it in memory only. */
302
+ export declare function writeAssistantWindowView(storage: () => Pick<Storage, 'setItem'> | undefined, key: string, view: AssistantWindowView): void;
289
303
  /** Persist an explicit Dock/Float pick. An unavailable store keeps it in memory only. */
290
304
  export declare function writeAssistantLayoutChoice(storage: () => Pick<Storage, 'setItem'> | undefined, key: string, choice: AssistantLayoutChoice): void;
291
305
  /**
@@ -20,13 +20,13 @@ function ee(e) {
20
20
  return (e.ctrlKey || e.metaKey) && e.shiftKey && typeof e.key == "string" && e.key.toLowerCase() === "a";
21
21
  }
22
22
  var te = "[role=\"dialog\"],[role=\"alertdialog\"],dialog[open]";
23
- function a(e, t) {
24
- return o(e) ? e.closest(t) : null;
23
+ function ne(e, t) {
24
+ return a(e) ? e.closest(t) : null;
25
25
  }
26
- function o(e) {
26
+ function a(e) {
27
27
  return typeof e == "object" && !!e && "closest" in e && typeof e.closest == "function";
28
28
  }
29
- function ne(e) {
29
+ function o(e) {
30
30
  return e.key !== "Escape" || !e.isOpen || e.alreadyHandled || e.dialogOpen || e.pressedInsideDialog || e.panelOwnsEscape ? "ignore" : "close";
31
31
  }
32
32
  var s = "max(var(--mobile-tabbar-height, 0px), var(--safe-bottom, 0px), env(safe-area-inset-bottom, 0px))";
@@ -38,36 +38,40 @@ function u(e) {
38
38
  return `calc(var(${l}, 0px) + ${c(e)})`;
39
39
  }
40
40
  var d = "1.5rem";
41
- function re(e) {
41
+ function f(e) {
42
42
  return e > 0 ? `calc(${d} + ${e}px)` : d;
43
43
  }
44
- var f = 440, p = "--assistant-dock-width", m = "--assistant-sheet-bottom", h = "--assistant-overlay-top", g = 56, _ = "(min-width: 640px)";
45
- function v(e) {
44
+ var p = 440, re = "--assistant-dock-width", m = "--assistant-sheet-bottom", ie = "--assistant-overlay-top", ae = 56, oe = "(min-width: 640px)";
45
+ function se(e) {
46
46
  return e.isOpen && e.docked && e.isDesktop ? 440 : 0;
47
47
  }
48
- var y = 520, ie = 24, ae = "--assistant-panel-inset";
49
- function oe(e) {
48
+ var ce = 520, le = 24, ue = "--assistant-panel-inset";
49
+ function de(e) {
50
50
  return !e.isOpen || !e.isDesktop ? 0 : e.docked ? 440 : 544;
51
51
  }
52
- var b = "fixed z-50 flex flex-col overflow-hidden border border-border-default bg-bg-surface shadow-2xl inset-x-0 bottom-[var(--assistant-sheet-bottom,0px)] top-auto rounded-t-2xl animate-in slide-in-from-bottom-4 fade-in duration-200", x = "h-[60vh] max-h-[60vh]", S = "h-[88vh] max-h-[88vh]", C = "sm:inset-auto sm:top-auto sm:bottom-24 sm:right-6 sm:rounded-2xl sm:h-[680px] sm:max-h-[calc(100vh-6rem-var(--assistant-overlay-top,56px)-0.5rem)] sm:w-[520px] sm:max-w-[calc(100vw-2rem)]", w = "sm:left-auto sm:right-0 sm:top-[var(--assistant-overlay-top)] sm:bottom-0 sm:rounded-none sm:h-auto sm:max-h-none sm:w-[440px] sm:max-w-[calc(100vw-2rem)]";
53
- function T(e) {
52
+ var h = "fixed z-50 flex flex-col overflow-hidden border border-border-default bg-bg-surface shadow-2xl inset-x-0 bottom-[var(--assistant-sheet-bottom,0px)] top-auto rounded-t-2xl animate-in slide-in-from-bottom-4 fade-in duration-200", g = "h-[60vh] max-h-[60vh]", _ = "h-[88vh] max-h-[88vh]", v = "sm:inset-auto sm:top-auto sm:bottom-24 sm:right-6 sm:rounded-2xl sm:h-[680px] sm:max-h-[calc(100vh-6rem-var(--assistant-overlay-top,56px)-0.5rem)] sm:w-[520px] sm:max-w-[calc(100vw-2rem)]", y = "sm:left-auto sm:right-0 sm:top-[var(--assistant-overlay-top)] sm:bottom-0 sm:rounded-none sm:h-auto sm:max-h-none sm:w-[440px] sm:max-w-[calc(100vw-2rem)]";
53
+ function b(e) {
54
54
  return [
55
- b,
56
- e.expanded ? S : x,
57
- e.docked ? w : C
55
+ h,
56
+ e.expanded ? _ : g,
57
+ e.docked ? y : v
58
58
  ].join(" ");
59
59
  }
60
- function E(e) {
60
+ function x(e) {
61
61
  return e === "window" || e === "panel";
62
62
  }
63
- function D(e) {
63
+ function S(e) {
64
+ return e === "chat" || e === "voice";
65
+ }
66
+ function C(e) {
64
67
  return {
65
68
  layoutStorageKey: `${e}:ai-panel:layout`,
66
69
  surfaceStorageKey: `${e}:ai-panel:surface`,
67
- minimizedStorageKey: `${e}:ai-panel:minimized`
70
+ minimizedStorageKey: `${e}:ai-panel:minimized`,
71
+ windowViewStorageKey: `${e}:ai-panel:window-view`
68
72
  };
69
73
  }
70
- function O(e, t) {
74
+ function w(e, t) {
71
75
  try {
72
76
  let n = e()?.getItem(t);
73
77
  return n === "docked" || n === "floating" ? n : null;
@@ -75,12 +79,25 @@ function O(e, t) {
75
79
  return null;
76
80
  }
77
81
  }
78
- function k(e, t, n) {
82
+ function T(e, t) {
83
+ try {
84
+ let n = e()?.getItem(t);
85
+ return S(n) ? n : null;
86
+ } catch {
87
+ return null;
88
+ }
89
+ }
90
+ function E(e, t, n) {
91
+ try {
92
+ e()?.setItem(t, n);
93
+ } catch {}
94
+ }
95
+ function D(e, t, n) {
79
96
  try {
80
97
  e()?.setItem(t, n);
81
98
  } catch {}
82
99
  }
83
- function A(e, t) {
100
+ function O(e, t) {
84
101
  try {
85
102
  let n = e()?.getItem(t);
86
103
  return n === "1" ? "docked" : n === "0" ? "floating" : null;
@@ -88,46 +105,46 @@ function A(e, t) {
88
105
  return null;
89
106
  }
90
107
  }
91
- var j = 1280, M = `(min-width: ${j}px)`;
92
- function N(e) {
108
+ var k = 1280, A = `(min-width: ${k}px)`;
109
+ function j(e) {
93
110
  let t = e.explicit ?? e.legacy;
94
111
  return t === null ? e.wideViewport : t === "docked";
95
112
  }
96
- var P = 360, F = 600, I = 760;
97
- function L(e) {
113
+ var M = 360, N = 600, P = 760;
114
+ function F(e) {
98
115
  return !e.isOpen || !e.isDesktop || e.surface !== "panel" || !e.docked ? 0 : e.expanded ? 760 : 440;
99
116
  }
100
- function R(e) {
117
+ function I(e) {
101
118
  if (!e.isOpen || !e.isDesktop || e.surface !== "panel") return 0;
102
119
  let t = e.expanded ? 760 : e.docked ? 440 : 520;
103
120
  return e.docked ? t : t + 24;
104
121
  }
105
- var z = "--assistant-window-bottom", B = "4.5rem";
106
- function V(e) {
107
- return `calc(${u(e)} + ${B})`;
122
+ var L = "--assistant-window-bottom", R = "4.5rem";
123
+ function z(e) {
124
+ return `calc(${u(e)} + ${R})`;
108
125
  }
109
- var se = "--assistant-viewport-height", H = "--assistant-keyboard-inset", U = "fixed z-50 flex flex-col overflow-hidden border border-border-default inset-x-0 bottom-[max(var(--assistant-sheet-bottom,0px),var(--assistant-keyboard-inset,0px))] top-auto rounded-t-2xl animate-in slide-in-from-bottom-4 fade-in duration-200", W = "bg-bg-surface shadow-2xl", G = "bg-bg-elevated shadow-[var(--shadow-elevation-4)]", K = "h-[62dvh] max-h-[min(62dvh,var(--assistant-viewport-height,100dvh))]", q = "h-[60dvh] max-h-[min(60dvh,var(--assistant-viewport-height,100dvh))]", J = "h-[88dvh] max-h-[min(88dvh,var(--assistant-viewport-height,100dvh))]", Y = "sm:inset-auto sm:top-auto sm:bottom-[var(--assistant-window-bottom,6rem)] sm:right-6 sm:rounded-3xl sm:h-[min(600px,calc(100dvh-var(--assistant-window-bottom,6rem)-var(--assistant-overlay-top,56px)-0.5rem))] sm:max-h-none sm:w-[360px] sm:max-w-[calc(100vw-2rem)]", X = "sm:left-auto sm:right-0 sm:top-[var(--assistant-overlay-top)] sm:bottom-0 sm:rounded-none sm:h-auto sm:max-h-none sm:w-[440px] sm:max-w-[calc(100vw-2rem)]", Z = "sm:left-auto sm:right-0 sm:top-[var(--assistant-overlay-top)] sm:bottom-0 sm:rounded-none sm:h-auto sm:max-h-none sm:w-[760px] sm:max-w-[calc(100vw-2rem)]", Q = "sm:inset-auto sm:top-auto sm:bottom-24 sm:right-6 sm:rounded-2xl sm:h-[680px] sm:max-h-[calc(100dvh-6rem-var(--assistant-overlay-top,56px)-0.5rem)] sm:w-[520px] sm:max-w-[calc(100vw-2rem)]", $ = "sm:inset-auto sm:top-auto sm:bottom-6 sm:right-6 sm:rounded-2xl sm:h-[calc(100dvh-var(--assistant-overlay-top,56px)-3rem)] sm:max-h-none sm:w-[760px] sm:max-w-[calc(100vw-2rem)]";
110
- function ce(e) {
126
+ var B = "--assistant-viewport-height", V = "--assistant-keyboard-inset", H = "fixed z-50 flex flex-col overflow-hidden border border-border-default inset-x-0 bottom-[max(var(--assistant-sheet-bottom,0px),var(--assistant-keyboard-inset,0px))] top-auto rounded-t-2xl animate-in slide-in-from-bottom-4 fade-in duration-200", U = "bg-bg-surface shadow-2xl", W = "bg-bg-elevated shadow-[var(--shadow-elevation-4)]", G = "h-[62dvh] max-h-[min(62dvh,var(--assistant-viewport-height,100dvh))]", K = "h-[60dvh] max-h-[min(60dvh,var(--assistant-viewport-height,100dvh))]", q = "h-[88dvh] max-h-[min(88dvh,var(--assistant-viewport-height,100dvh))]", J = "sm:inset-auto sm:top-auto sm:bottom-[var(--assistant-window-bottom,6rem)] sm:right-6 sm:rounded-3xl sm:h-[min(600px,calc(100dvh-var(--assistant-window-bottom,6rem)-var(--assistant-overlay-top,56px)-0.5rem))] sm:max-h-none sm:w-[360px] sm:max-w-[calc(100vw-2rem)]", Y = "sm:left-auto sm:right-0 sm:top-[var(--assistant-overlay-top)] sm:bottom-0 sm:rounded-none sm:h-auto sm:max-h-none sm:w-[440px] sm:max-w-[calc(100vw-2rem)]", X = "sm:left-auto sm:right-0 sm:top-[var(--assistant-overlay-top)] sm:bottom-0 sm:rounded-none sm:h-auto sm:max-h-none sm:w-[760px] sm:max-w-[calc(100vw-2rem)]", Z = "sm:inset-auto sm:top-auto sm:bottom-24 sm:right-6 sm:rounded-2xl sm:h-[680px] sm:max-h-[calc(100dvh-6rem-var(--assistant-overlay-top,56px)-0.5rem)] sm:w-[520px] sm:max-w-[calc(100vw-2rem)]", Q = "sm:inset-auto sm:top-auto sm:bottom-6 sm:right-6 sm:rounded-2xl sm:h-[calc(100dvh-var(--assistant-overlay-top,56px)-3rem)] sm:max-h-none sm:w-[760px] sm:max-w-[calc(100vw-2rem)]";
127
+ function fe(e) {
111
128
  if (e.minimized) return "hidden";
112
- let t = e.surface === "window", n = e.sheetExpanded ? J : t ? K : q, r = t ? Y : e.docked ? e.expanded ? Z : X : e.expanded ? $ : Q;
129
+ let t = e.surface === "window", n = e.sheetExpanded ? q : t ? G : K, r = t ? J : e.docked ? e.expanded ? X : Y : e.expanded ? Q : Z;
113
130
  return [
114
- U,
115
- t ? G : W,
131
+ H,
132
+ t ? W : U,
116
133
  n,
117
134
  r
118
135
  ].join(" ");
119
136
  }
120
- function le(e) {
137
+ function pe(e) {
121
138
  return !e.isOpen || e.minimized ? "always" : e.surface === "panel" ? "hidden" : "desktop-only";
122
139
  }
123
- function ue(e) {
140
+ function me(e) {
124
141
  let t = e.scale > 1.01, n = e.layoutHeight - e.viewportHeight - e.viewportOffsetTop, r = t ? 0 : Math.max(0, Math.round(n));
125
142
  return {
126
143
  heightPx: Math.max(0, Math.round(t ? e.layoutHeight : e.viewportHeight)),
127
144
  keyboardInsetPx: r
128
145
  };
129
146
  }
130
- function de(t) {
147
+ function he(t) {
131
148
  return (n, r) => {
132
149
  if (t.isShellLessTarget?.(n)) return t.openInNewTab(n), { kind: "new-tab" };
133
150
  let i = e(r);
@@ -138,22 +155,22 @@ function de(t) {
138
155
  } : (t.navigate(n), t.isDesktop() || t.collapseSheet(), { kind: "routed" });
139
156
  };
140
157
  }
141
- function fe(e) {
158
+ function ge(e) {
142
159
  if (typeof CustomEvent > "u" || !(e instanceof CustomEvent)) return "generic";
143
160
  let t = e.detail;
144
161
  return typeof t != "object" || !t || !("kind" in t) ? "generic" : t.kind === "sandbox" || t.kind === "ai-credits" ? t.kind : "generic";
145
162
  }
146
- function pe(e, t) {
163
+ function $(e, t) {
147
164
  try {
148
165
  return e()?.getItem(t) === "1";
149
166
  } catch {
150
167
  return !1;
151
168
  }
152
169
  }
153
- function me(e, t, n) {
170
+ function _e(e, t, n) {
154
171
  try {
155
172
  e()?.setItem(t, n ? "1" : "0");
156
173
  } catch {}
157
174
  }
158
175
  //#endregion
159
- export { s as ASSISTANT_BOTTOM_CHROME_CLEARANCE, M as ASSISTANT_COMPACT_DOCKED_DEFAULT_QUERY, X as ASSISTANT_COMPACT_DOCKED_DESKTOP_CLASS, Z as ASSISTANT_COMPACT_DOCKED_EXPANDED_DESKTOP_CLASS, j as ASSISTANT_COMPACT_DOCKED_MIN_VIEWPORT_PX, I as ASSISTANT_COMPACT_EXPANDED_WIDTH_PX, Q as ASSISTANT_COMPACT_FLOATING_DESKTOP_CLASS, $ as ASSISTANT_COMPACT_FLOATING_EXPANDED_DESKTOP_CLASS, W as ASSISTANT_COMPACT_PANEL_SURFACE_CLASS, U as ASSISTANT_COMPACT_SHEET_BASE_CLASS, J as ASSISTANT_COMPACT_SHEET_EXPANDED_CLASS, q as ASSISTANT_COMPACT_SHEET_PANEL_CLASS, K as ASSISTANT_COMPACT_SHEET_WINDOW_CLASS, Y as ASSISTANT_COMPACT_WINDOW_DESKTOP_CLASS, F as ASSISTANT_COMPACT_WINDOW_HEIGHT_PX, G as ASSISTANT_COMPACT_WINDOW_SURFACE_CLASS, P as ASSISTANT_COMPACT_WINDOW_WIDTH_PX, te as ASSISTANT_DIALOG_SELECTOR, w as ASSISTANT_DOCKED_DESKTOP_CLASS, f as ASSISTANT_DOCK_WIDTH_PX, p as ASSISTANT_DOCK_WIDTH_VAR, C as ASSISTANT_FLOATING_DESKTOP_CLASS, ie as ASSISTANT_FLOATING_RIGHT_PX, y as ASSISTANT_FLOATING_WIDTH_PX, H as ASSISTANT_KEYBOARD_INSET_VAR, l as ASSISTANT_LAUNCHER_LIFT_VAR, d as ASSISTANT_LAUNCHER_RIGHT_INSET, g as ASSISTANT_OVERLAY_DEFAULT_TOP_PX, _ as ASSISTANT_OVERLAY_DESKTOP_QUERY, h as ASSISTANT_OVERLAY_TOP_VAR, ae as ASSISTANT_PANEL_INSET_VAR, b as ASSISTANT_SHEET_BASE_CLASS, m as ASSISTANT_SHEET_BOTTOM_VAR, x as ASSISTANT_SHEET_COMPACT_CLASS, S as ASSISTANT_SHEET_EXPANDED_CLASS, i as ASSISTANT_TOGGLE_SHORTCUT_LABEL, se as ASSISTANT_VIEWPORT_HEIGHT_VAR, z as ASSISTANT_WINDOW_BOTTOM_VAR, B as ASSISTANT_WINDOW_LAUNCHER_CLEARANCE, c as aboveAssistantBottomChrome, le as assistantCompactLauncherVisibility, ce as assistantCompactOverlayClassName, D as assistantCompactOverlayKeys, u as assistantLauncherBottom, re as assistantLauncherRight, T as assistantOverlayClassName, ne as assistantOverlayEscapeAction, t as assistantOverlayKeys, fe as assistantQuotaKindOf, ue as assistantVisualViewportMetrics, V as assistantWindowBottom, a as closestAround, de as createAssistantNavigate, E as isAssistantSurface, ee as isAssistantToggleShortcut, r as nextAssistantOpenState, v as publishedAssistantDockWidth, oe as publishedAssistantPanelInset, L as publishedCompactDockWidth, R as publishedCompactPanelInset, O as readAssistantLayoutChoice, A as readAssistantLegacyDockChoice, pe as readAssistantOverlayFlag, n as requestedAssistantOpenState, N as resolveCompactDocked, k as writeAssistantLayoutChoice, me as writeAssistantOverlayFlag };
176
+ export { s as ASSISTANT_BOTTOM_CHROME_CLEARANCE, A as ASSISTANT_COMPACT_DOCKED_DEFAULT_QUERY, Y as ASSISTANT_COMPACT_DOCKED_DESKTOP_CLASS, X as ASSISTANT_COMPACT_DOCKED_EXPANDED_DESKTOP_CLASS, k as ASSISTANT_COMPACT_DOCKED_MIN_VIEWPORT_PX, P as ASSISTANT_COMPACT_EXPANDED_WIDTH_PX, Z as ASSISTANT_COMPACT_FLOATING_DESKTOP_CLASS, Q as ASSISTANT_COMPACT_FLOATING_EXPANDED_DESKTOP_CLASS, U as ASSISTANT_COMPACT_PANEL_SURFACE_CLASS, H as ASSISTANT_COMPACT_SHEET_BASE_CLASS, q as ASSISTANT_COMPACT_SHEET_EXPANDED_CLASS, K as ASSISTANT_COMPACT_SHEET_PANEL_CLASS, G as ASSISTANT_COMPACT_SHEET_WINDOW_CLASS, J as ASSISTANT_COMPACT_WINDOW_DESKTOP_CLASS, N as ASSISTANT_COMPACT_WINDOW_HEIGHT_PX, W as ASSISTANT_COMPACT_WINDOW_SURFACE_CLASS, M as ASSISTANT_COMPACT_WINDOW_WIDTH_PX, te as ASSISTANT_DIALOG_SELECTOR, y as ASSISTANT_DOCKED_DESKTOP_CLASS, p as ASSISTANT_DOCK_WIDTH_PX, re as ASSISTANT_DOCK_WIDTH_VAR, v as ASSISTANT_FLOATING_DESKTOP_CLASS, le as ASSISTANT_FLOATING_RIGHT_PX, ce as ASSISTANT_FLOATING_WIDTH_PX, V as ASSISTANT_KEYBOARD_INSET_VAR, l as ASSISTANT_LAUNCHER_LIFT_VAR, d as ASSISTANT_LAUNCHER_RIGHT_INSET, ae as ASSISTANT_OVERLAY_DEFAULT_TOP_PX, oe as ASSISTANT_OVERLAY_DESKTOP_QUERY, ie as ASSISTANT_OVERLAY_TOP_VAR, ue as ASSISTANT_PANEL_INSET_VAR, h as ASSISTANT_SHEET_BASE_CLASS, m as ASSISTANT_SHEET_BOTTOM_VAR, g as ASSISTANT_SHEET_COMPACT_CLASS, _ as ASSISTANT_SHEET_EXPANDED_CLASS, i as ASSISTANT_TOGGLE_SHORTCUT_LABEL, B as ASSISTANT_VIEWPORT_HEIGHT_VAR, L as ASSISTANT_WINDOW_BOTTOM_VAR, R as ASSISTANT_WINDOW_LAUNCHER_CLEARANCE, c as aboveAssistantBottomChrome, pe as assistantCompactLauncherVisibility, fe as assistantCompactOverlayClassName, C as assistantCompactOverlayKeys, u as assistantLauncherBottom, f as assistantLauncherRight, b as assistantOverlayClassName, o as assistantOverlayEscapeAction, t as assistantOverlayKeys, ge as assistantQuotaKindOf, me as assistantVisualViewportMetrics, z as assistantWindowBottom, ne as closestAround, he as createAssistantNavigate, x as isAssistantSurface, ee as isAssistantToggleShortcut, S as isAssistantWindowView, r as nextAssistantOpenState, se as publishedAssistantDockWidth, de as publishedAssistantPanelInset, F as publishedCompactDockWidth, I as publishedCompactPanelInset, w as readAssistantLayoutChoice, O as readAssistantLegacyDockChoice, $ as readAssistantOverlayFlag, T as readAssistantWindowView, n as requestedAssistantOpenState, j as resolveCompactDocked, D as writeAssistantLayoutChoice, _e as writeAssistantOverlayFlag, E as writeAssistantWindowView };
@@ -1,87 +1,88 @@
1
- import { DropdownMenu as e, DropdownMenuContent as t, DropdownMenuItem as n, DropdownMenuLabel as r, DropdownMenuTrigger as i } from "../../../../ui/dropdown-menu.js";
2
- import { focusWasDropped as a } from "../../../hooks/useReturnFocus.js";
3
- import { getAssistantControl as o, hasAssistantControl as s, subscribeAssistantControls as c } from "../../appControls/registry.js";
4
- import { useAssistantTr as l } from "../../i18n.js";
5
- import { useAssistantStore as u } from "../../store.js";
6
- import { voiceTurnsOnly as d } from "../../voice/turnVisibility.js";
7
- import { downloadFile as f, exportConversation as p } from "../../exportConversation.js";
8
- import { useCallback as m, useSyncExternalStore as h } from "react";
9
- import { FileJson as g, FileText as _, Mic as v, MoreHorizontal as y } from "lucide-react";
10
- import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
1
+ import { DropdownMenu as e, DropdownMenuContent as t, DropdownMenuItem as n, DropdownMenuTrigger as r } from "../../../../ui/dropdown-menu.js";
2
+ import { focusWasDropped as i } from "../../../hooks/useReturnFocus.js";
3
+ import { getAssistantControl as a, hasAssistantControl as o, subscribeAssistantControls as s } from "../../appControls/registry.js";
4
+ import { useAssistantTr as c } from "../../i18n.js";
5
+ import { useAssistantStore as l } from "../../store.js";
6
+ import { voiceTurnsOnly as u } from "../../voice/turnVisibility.js";
7
+ import { downloadFile as d, exportConversation as f } from "../../exportConversation.js";
8
+ import { useCallback as p, useSyncExternalStore as m } from "react";
9
+ import { FileJson as h, FileText as g, Mic as _, MoreHorizontal as v } from "lucide-react";
10
+ import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
11
11
  //#region src/shared/assistant/ui/compact/AssistantConversationMenu.tsx
12
- var C = "min-h-11 gap-2.5 px-3", w = ({ open: w, onOpenChange: T, triggerRef: E }) => {
13
- let D = l(), { conversations: O, activeConversationId: k, processingByConversationId: A } = u(), j = O.find((e) => e.id === k), M = !!(j && j.messages.length > 0), N = !!(h(c, () => s("assistant.transcript"), () => !1) && j && d(j.messages).length > 0), P = (e) => {
14
- if (!j) return;
15
- let { content: t, filename: n, mimeType: r } = p(j, e, {
16
- processing: A[j.id],
17
- tr: D
12
+ var S = "min-h-11 gap-2.5 px-3", C = ({ open: C, onOpenChange: w, triggerRef: T }) => {
13
+ let E = c(), { conversations: D, activeConversationId: O, processingByConversationId: k } = l(), A = D.find((e) => e.id === O), j = !!(A && A.messages.length > 0), M = !!(m(s, () => o("assistant.transcript"), () => !1) && A && u(A.messages).length > 0), N = (e) => {
14
+ if (!A) return;
15
+ let { content: t, filename: n, mimeType: r } = f(A, e, {
16
+ processing: k[A.id],
17
+ tr: E
18
18
  });
19
- f(t, n, r);
20
- }, F = () => {
21
- o("assistant.transcript")?.run();
22
- }, I = m((e) => {
23
- a(document) || e.preventDefault();
24
- }, []), L = D("header.conversationOptions", "Conversation options");
25
- return /* @__PURE__ */ S(e, {
26
- open: w,
27
- onOpenChange: T,
19
+ d(t, n, r);
20
+ }, P = () => {
21
+ a("assistant.transcript")?.run();
22
+ }, F = p((e) => {
23
+ i(document) || e.preventDefault();
24
+ }, []), I = E("header.conversationOptions", "Conversation options");
25
+ return /* @__PURE__ */ x(e, {
26
+ open: C,
27
+ onOpenChange: w,
28
28
  modal: !1,
29
- children: [/* @__PURE__ */ x(i, {
29
+ children: [/* @__PURE__ */ b(r, {
30
30
  asChild: !0,
31
- children: /* @__PURE__ */ x("button", {
32
- ref: E,
31
+ children: /* @__PURE__ */ b("button", {
32
+ ref: T,
33
33
  type: "button",
34
- "aria-label": L,
35
- title: L,
34
+ "aria-label": I,
35
+ title: I,
36
36
  className: "flex size-10 shrink-0 items-center justify-center rounded-button text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]",
37
37
  "data-testid": "assistant-more",
38
- children: /* @__PURE__ */ x(y, {
38
+ children: /* @__PURE__ */ b(v, {
39
39
  className: "size-5",
40
40
  "aria-hidden": "true"
41
41
  })
42
42
  })
43
- }), /* @__PURE__ */ S(t, {
43
+ }), /* @__PURE__ */ x(t, {
44
44
  align: "end",
45
45
  sideOffset: 4,
46
46
  collisionPadding: 8,
47
- onCloseAutoFocus: I,
47
+ onCloseAutoFocus: F,
48
48
  className: "min-w-56 max-w-[calc(100vw-2rem)] max-h-[var(--radix-dropdown-menu-content-available-height)] overflow-y-auto",
49
49
  "data-testid": "assistant-more-menu",
50
50
  children: [
51
- M ? /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ S(n, {
52
- className: C,
53
- onSelect: () => P("markdown"),
51
+ j ? /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ x(n, {
52
+ className: S,
53
+ onSelect: () => N("markdown"),
54
54
  "data-testid": "export-markdown",
55
- children: [/* @__PURE__ */ x(_, {
55
+ children: [/* @__PURE__ */ b(g, {
56
56
  className: "size-4 shrink-0 text-text-secondary",
57
57
  "aria-hidden": "true"
58
- }), D("export.markdown", "Export as Markdown")]
59
- }), /* @__PURE__ */ S(n, {
60
- className: C,
61
- onSelect: () => P("json"),
58
+ }), E("export.markdown", "Export as Markdown")]
59
+ }), /* @__PURE__ */ x(n, {
60
+ className: S,
61
+ onSelect: () => N("json"),
62
62
  "data-testid": "export-json",
63
- children: [/* @__PURE__ */ x(g, {
63
+ children: [/* @__PURE__ */ b(h, {
64
64
  className: "size-4 shrink-0 text-text-secondary",
65
65
  "aria-hidden": "true"
66
- }), D("export.json", "Export as JSON")]
66
+ }), E("export.json", "Export as JSON")]
67
67
  })] }) : null,
68
- N ? /* @__PURE__ */ S(n, {
69
- className: C,
70
- onSelect: F,
68
+ M ? /* @__PURE__ */ x(n, {
69
+ className: S,
70
+ onSelect: P,
71
71
  "data-testid": "assistant-more-voice-transcript",
72
- children: [/* @__PURE__ */ x(v, {
72
+ children: [/* @__PURE__ */ b(_, {
73
73
  className: "size-4 shrink-0 text-text-secondary",
74
74
  "aria-hidden": "true"
75
- }), D("conversationMenu.voiceTranscript", "Voice transcript")]
75
+ }), E("conversationMenu.voiceTranscript", "Voice transcript")]
76
76
  }) : null,
77
- !M && !N ? /* @__PURE__ */ x(r, {
78
- className: "px-3 py-2 text-sm font-normal text-text-secondary",
77
+ !j && !M ? /* @__PURE__ */ b(n, {
78
+ disabled: !0,
79
+ className: `${S} text-text-secondary`,
79
80
  "data-testid": "assistant-more-empty",
80
- children: D("conversationMenu.empty", "Nothing to export yet")
81
+ children: E("conversationMenu.empty", "Nothing to export yet")
81
82
  }) : null
82
83
  ]
83
84
  })]
84
85
  });
85
86
  };
86
87
  //#endregion
87
- export { w as AssistantConversationMenu };
88
+ export { C as AssistantConversationMenu };
@@ -16,6 +16,8 @@ var s = ({ open: s, onKeep: c, onDiscard: l }) => {
16
16
  e.preventDefault(), d.current?.focus();
17
17
  },
18
18
  title: u("closeConfirm.title", "Discard your unsent message?"),
19
+ description: u("closeConfirm.body", "What you typed or attached has not been sent. If you close the assistant now, it is discarded."),
20
+ ariaModal: !0,
19
21
  footer: /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a(e, {
20
22
  ref: d,
21
23
  variant: "outline",
@@ -28,10 +30,7 @@ var s = ({ open: s, onKeep: c, onDiscard: l }) => {
28
30
  "data-testid": "assistant-discard-draft-confirm",
29
31
  children: u("closeConfirm.discard", "Discard and close")
30
32
  })] }),
31
- children: /* @__PURE__ */ a("p", {
32
- className: "text-sm text-text-secondary",
33
- children: u("closeConfirm.body", "What you typed or attached has not been sent. If you close the assistant now, it is discarded.")
34
- })
33
+ children: null
35
34
  });
36
35
  };
37
36
  //#endregion
@@ -0,0 +1,29 @@
1
+ import { FC } from 'react';
2
+ export interface AssistantLanguagePillProps {
3
+ /**
4
+ * A voice conversation is live. Changing the language stops a running
5
+ * recogniser (`useVoiceInput`), so the pill waits for the end of the
6
+ * conversation and says why.
7
+ */
8
+ voiceLive: boolean;
9
+ }
10
+ /**
11
+ * The Quick assistant window's language pill (BOFF-10180, CW-L, DESIGN §7
12
+ * "Language semantics").
13
+ *
14
+ * ★ It sets the INPUT language (`assistantLanguage`) and nothing else. That
15
+ * language also drives the reply and its voice while "Assistant replies in" is
16
+ * "Match my language", which is the default. A reply language pinned to something
17
+ * else stays in the full assistant: here it is only SAID ("Replies in {{language}}
18
+ * — change in full assistant"), never offered. It never changes the interface
19
+ * language.
20
+ *
21
+ * ★ The menu is the existing `AssistantLanguageMenu`, input row only, so the
22
+ * choice, the list and the stored value are the ones the ⋯ menu and Settings
23
+ * already use. It stays a native `<select>`: a phone opens its own picker.
24
+ *
25
+ * ★ While voice is live the pill is `aria-disabled`, not `disabled`: it stays in
26
+ * the Tab order, so a keyboard or screen-reader user reaches it and hears why
27
+ * (`aria-describedby`), and it cannot open.
28
+ */
29
+ export declare const AssistantLanguagePill: FC<AssistantLanguagePillProps>;
@@ -0,0 +1,98 @@
1
+ import { useI18n as e } from "../../../providers/shell/I18nProvider.js";
2
+ import { EscapeLayer as t } from "../../../components/EscapeLayer.js";
3
+ import { useAssistantTr as n } from "../../i18n.js";
4
+ import { useAssistantStore as r } from "../../store.js";
5
+ import { replyFollowsInput as i, resolveLanguagePair as a } from "../../voice/languagePair.js";
6
+ import { AssistantLanguageMenu as o } from "../AssistantLanguageMenu.js";
7
+ import { useEffect as s, useId as c, useMemo as l, useRef as u, useState as d } from "react";
8
+ import { ChevronDown as f, Languages as p } from "lucide-react";
9
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
10
+ //#region src/shared/assistant/ui/compact/AssistantLanguagePill.tsx
11
+ var g = ({ voiceLive: g }) => {
12
+ let _ = n(), { locale: v } = e(), y = r((e) => e.assistantLanguage), b = r((e) => e.replyLanguage), x = l(() => a(y, b, v), [
13
+ y,
14
+ b,
15
+ v
16
+ ]), [S, C] = d(!1), w = u(null), T = u(null), E = c(), D = c();
17
+ S && g && C(!1);
18
+ let O = u(S);
19
+ s(() => {
20
+ O.current = S;
21
+ });
22
+ let k = u(y);
23
+ s(() => {
24
+ k.current !== y && (k.current = y, O.current && (C(!1), T.current?.focus({ preventScroll: !0 })));
25
+ }, [y]), s(() => {
26
+ if (!S) return;
27
+ let e = (e) => {
28
+ let t = e.target;
29
+ t instanceof Node && w.current?.contains(t) || C(!1);
30
+ };
31
+ return document.addEventListener("pointerdown", e), () => document.removeEventListener("pointerdown", e);
32
+ }, [S]);
33
+ let A = _("window.language", "Language"), j = _("window.languageLocked", "Change the language after you end voice"), M = !i(b) && x.reply.code !== x.input.code ? x.reply.label : null, N = (e) => {
34
+ C(!1), e && T.current?.focus({ preventScroll: !0 });
35
+ };
36
+ return /* @__PURE__ */ h("div", {
37
+ ref: w,
38
+ className: "relative min-w-0 flex-1",
39
+ "data-testid": "assistant-window-language-root",
40
+ children: [
41
+ /* @__PURE__ */ h("button", {
42
+ ref: T,
43
+ type: "button",
44
+ onClick: () => {
45
+ g || C((e) => !e);
46
+ },
47
+ className: `flex h-10 min-w-0 max-w-full items-center gap-1.5 rounded-full border border-border-default px-3 text-sm transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] ${g ? "cursor-default text-text-muted" : "text-text-primary hover:bg-bg-sunken"}`,
48
+ "aria-expanded": S,
49
+ "aria-controls": S ? E : void 0,
50
+ "aria-disabled": g ? "true" : void 0,
51
+ "aria-describedby": g ? D : void 0,
52
+ "aria-label": `${A}: ${x.input.label}`,
53
+ title: g ? j : `${A}: ${x.input.label}`,
54
+ "data-testid": "assistant-window-language",
55
+ children: [
56
+ /* @__PURE__ */ m(p, {
57
+ className: "size-4 shrink-0",
58
+ "aria-hidden": "true"
59
+ }),
60
+ /* @__PURE__ */ m("span", {
61
+ className: "min-w-0 truncate",
62
+ "data-testid": "assistant-window-language-name",
63
+ children: x.input.label
64
+ }),
65
+ /* @__PURE__ */ m(f, {
66
+ className: "size-4 shrink-0",
67
+ "aria-hidden": "true"
68
+ })
69
+ ]
70
+ }),
71
+ g ? /* @__PURE__ */ m("span", {
72
+ id: D,
73
+ className: "sr-only",
74
+ "data-testid": "assistant-window-language-reason",
75
+ children: j
76
+ }) : null,
77
+ S ? /* @__PURE__ */ m(t, {
78
+ onDismiss: () => {
79
+ N(!0);
80
+ },
81
+ children: /* @__PURE__ */ h("div", {
82
+ id: E,
83
+ role: "group",
84
+ "aria-label": A,
85
+ className: "absolute start-0 top-full z-30 mt-1 w-72 max-w-[calc(100vw-2rem)] overflow-hidden rounded-card border border-border-default bg-bg-elevated py-1 shadow-[var(--shadow-overlay)]",
86
+ "data-testid": "assistant-window-language-menu",
87
+ children: [/* @__PURE__ */ m(o, { inputOnly: !0 }), M === null ? null : /* @__PURE__ */ m("p", {
88
+ className: "px-3 py-2 text-xs text-text-muted",
89
+ "data-testid": "assistant-window-language-pinned",
90
+ children: _("window.languagePinned", "Replies in {{language}} — change in full assistant", { language: M })
91
+ })]
92
+ })
93
+ }) : null
94
+ ]
95
+ });
96
+ };
97
+ //#endregion
98
+ export { g as AssistantLanguagePill };
@@ -0,0 +1,31 @@
1
+ import { FC } from 'react';
2
+ export interface AssistantVoiceReadyProps {
3
+ /**
4
+ * Why a voice conversation cannot start here and now (`voiceStartBlocker`),
5
+ * already worded. Null: it can, and Start voice is offered.
6
+ */
7
+ blockedReason: string | null;
8
+ /** Start the voice conversation: the chat area's own `startVoiceWithPrewarm`. */
9
+ onStart: () => void;
10
+ }
11
+ /**
12
+ * The Quick assistant window's Voice view, ready: not started (BOFF-10180, C2).
13
+ *
14
+ * ★ Nothing here listens. The brand orb is a still picture, with no ring, halo or
15
+ * motion, so it cannot read as "the microphone is open"; the status line says
16
+ * when it opens ("only when you press Start voice"); opening the window, or
17
+ * switching to this view, starts neither the microphone nor an avatar. The one
18
+ * thing that does is the person's press on Start voice, which is the composer's
19
+ * own start (`startVoiceWithPrewarm`).
20
+ *
21
+ * ★ Start voice is never auto-focused. Focus lands in the message box when the
22
+ * window opens, so a stray Enter cannot open the microphone.
23
+ *
24
+ * ★ Where voice cannot start (the mode takes none, the browser has no speech,
25
+ * the conversation is read-only, or it is busy) the reason takes the button's
26
+ * place, as a polite status, and there is no Start voice to press.
27
+ *
28
+ * ★ The orb is the brand's. Face stills belong to the avatar seam, which offers
29
+ * no accessor for the chosen face, and the window never starts an avatar.
30
+ */
31
+ export declare const AssistantVoiceReady: FC<AssistantVoiceReadyProps>;
@@ -0,0 +1,41 @@
1
+ import { useAssistantTr as e } from "../../i18n.js";
2
+ import { Mic as t } from "lucide-react";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
+ //#region src/shared/assistant/ui/compact/AssistantVoiceReady.tsx
5
+ var i = ({ blockedReason: i, onStart: a }) => {
6
+ let o = e();
7
+ return /* @__PURE__ */ r("div", {
8
+ className: "flex min-h-0 flex-1 flex-col items-center justify-center gap-4 overflow-y-auto px-6 py-4 text-center",
9
+ "data-testid": "assistant-window-voice-ready",
10
+ children: [
11
+ /* @__PURE__ */ n("span", {
12
+ className: "size-28 shrink-0 rounded-full bg-gradient-to-br from-action-primary-bg/80 to-action-primary-bg/20 shadow-[var(--shadow-elevation-3)]",
13
+ "aria-hidden": "true",
14
+ "data-testid": "assistant-window-orb"
15
+ }),
16
+ /* @__PURE__ */ n("h2", {
17
+ className: "text-lg font-semibold text-text-primary",
18
+ children: o("window.voiceReadyTitle", "Talk to the assistant")
19
+ }),
20
+ /* @__PURE__ */ n("p", {
21
+ role: "status",
22
+ "aria-live": "polite",
23
+ className: "max-w-[16rem] text-sm text-text-secondary",
24
+ "data-testid": "assistant-window-voice-status",
25
+ children: i ?? o("window.voiceReadyStatus", "The microphone starts only when you press Start voice.")
26
+ }),
27
+ i === null ? /* @__PURE__ */ r("button", {
28
+ type: "button",
29
+ onClick: a,
30
+ className: "flex h-12 items-center gap-2 rounded-full bg-action-primary-bg px-6 text-base font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover 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)]",
31
+ "data-testid": "assistant-window-start-voice",
32
+ children: [/* @__PURE__ */ n(t, {
33
+ className: "size-5",
34
+ "aria-hidden": "true"
35
+ }), o("window.startVoice", "Start voice")]
36
+ }) : null
37
+ ]
38
+ });
39
+ };
40
+ //#endregion
41
+ export { i as AssistantVoiceReady };
@@ -4,6 +4,12 @@ export interface AssistantWaitingChangeRowProps {
4
4
  count: number;
5
5
  /** Scroll to the first waiting change's card and focus it. */
6
6
  onReview: () => void;
7
+ /**
8
+ * BOFF-10180 (the Quick assistant window): the card is in the full assistant,
9
+ * so the row's one button says so ("Review in full assistant") and `onReview`
10
+ * opens the full assistant. Still a pointer, never a second way to approve.
11
+ */
12
+ opensFull?: boolean;
7
13
  }
8
14
  /**
9
15
  * The pinned "change waiting" row above the composer (N6, 2026-10-29), in the