@burdenoff/fe-libs 2026.922.2 → 2026.923.1

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.
@@ -35,9 +35,35 @@ export declare function configureSpeechEngine(options: {
35
35
  /**
36
36
  * Read the rollout config.
37
37
  *
38
- * Order matters: explicit runtime configuration, then a global the host can set
39
- * before the bundle loads, and only then the build-time variable — which is
40
- * eliminated in the published package and therefore useful for local dev only.
38
+ * Order matters: explicit runtime configuration, then the build-time variable —
39
+ * which is eliminated in the published package and therefore useful for local
40
+ * dev only.
41
+ *
42
+ * ★★★ `window.__HB_TTS_ENDPOINT__` IS DELIBERATELY NOT READ (BOFF-7730).
43
+ *
44
+ * It used to be honoured here, and `getHeaders` rode along with it, so the
45
+ * config returned `{ endpoint: <whatever that global said>, getHeaders:
46
+ * liveHeaders }` — and `liveHeaders` yields `{ authorization: 'Bearer
47
+ * <accessToken>' }`. Anything able to write one global before this ran got the
48
+ * signed-in user's live token POSTed cross-origin to a URL of its choosing.
49
+ * That needs script execution on the page first, so it was not a hole by
50
+ * itself; it was a clean, low-noise exfiltration channel handed to any
51
+ * injection that found one, shipping in all four products.
52
+ *
53
+ * Two things made removal the right fix rather than a guard:
54
+ *
55
+ * 1. NOTHING SET IT. An org-wide search found six references and not one
56
+ * writer — this module, its test, and four comments describing the old
57
+ * three-source order.
58
+ * 2. THE DOCS SAID IT WAS SAFE. Both
59
+ * `healthybowl-specs/.../13-ai-assistant-integration.md` and
60
+ * microfe-healthybowl's `HealthyBowlContext` told readers the global
61
+ * "carries no headers" and could only enable an anonymous POST. True once;
62
+ * when headers were attached to every source the docs were never updated,
63
+ * so a reader reasoning from them concluded the opposite of what ran.
64
+ *
65
+ * Local development already has a first-precedence, header-carrying path in
66
+ * `configureSpeechEngine()`, which every product calls, so nothing is lost.
41
67
  */
42
68
  export declare function readSpeechEngineConfig(): SpeechEngineConfig;
43
69
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"createSpeechEngine.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/speech/createSpeechEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAqBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C,GAAG,IAAI,CA2BP;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,kBAAkB,CAY3D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,kBAA6C,GAAG;IAC1F,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACnC,CASA;AAiBD,wBAAgB,eAAe,IAAI,YAAY,CAO9C;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAKtE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CASxC"}
1
+ {"version":3,"file":"createSpeechEngine.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/speech/createSpeechEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAqBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C,GAAG,IAAI,CA2BP;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,sBAAsB,IAAI,kBAAkB,CAO3D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,kBAA6C,GAAG;IAC1F,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACnC,CASA;AAiBD,wBAAgB,eAAe,IAAI,YAAY,CAO9C;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAKtE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CASxC"}
@@ -12,18 +12,10 @@ function o(e) {
12
12
  r = t, i = e.getHeaders, _();
13
13
  }
14
14
  function s() {
15
- if (r) return {
15
+ return r ? {
16
16
  endpoint: r,
17
17
  getHeaders: a
18
- };
19
- if (typeof window < "u") {
20
- let e = window.__HB_TTS_ENDPOINT__;
21
- if (e) return {
22
- endpoint: e,
23
- getHeaders: a
24
- };
25
- }
26
- return { endpoint: (void 0)?.trim() || null };
18
+ } : { endpoint: (void 0)?.trim() || null };
27
19
  }
28
20
  function c(n = s()) {
29
21
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantVoiceSession.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/AssistantVoiceSession.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAI1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAgB7D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,UAAU,KAAK;IACb,OAAO,EAAE,oBAAoB,CAAC;IAC9B,iEAAiE;IACjE,KAAK,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC3C,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnC,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4DAA4D;IAC5D,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mFAAmF;IACnF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CAukB3C,CAAC"}
1
+ {"version":3,"file":"AssistantVoiceSession.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/AssistantVoiceSession.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAI1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAgB7D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,UAAU,KAAK;IACb,OAAO,EAAE,oBAAoB,CAAC;IAC9B,iEAAiE;IACjE,KAAK,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC3C,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnC,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4DAA4D;IAC5D,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mFAAmF;IACnF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CAyoB3C,CAAC"}
@@ -1,118 +1,123 @@
1
1
  import { useAssistantTr as e } from "../../i18n.js";
2
2
  import { micIsInterrupt as t, showsAssistantCaption as n, voiceStageState as r } from "../../voice/voiceStageState.js";
3
- import { VOICE_THINKING_LABEL as i, composeVoiceStatus as a, voiceStatusSuffix as o } from "../../voice/voiceStatus.js";
4
- import { spokenSoFar as s } from "../../voice/voiceSession.js";
5
- import { AssistantAttachmentButton as ee } from "../composer/AssistantAttachmentButton.js";
6
- import { AssistantAttachmentChips as te } from "../composer/AssistantAttachmentChips.js";
7
- import { AssistantVoiceOrb as ne } from "./AssistantVoiceOrb.js";
3
+ import { VOICE_THINKING_LABEL as i, composeVoiceStatus as ee, voiceStatusSuffix as te } from "../../voice/voiceStatus.js";
4
+ import { spokenSoFar as a } from "../../voice/voiceSession.js";
5
+ import { AssistantAttachmentButton as o } from "../composer/AssistantAttachmentButton.js";
6
+ import { AssistantAttachmentChips as ne } from "../composer/AssistantAttachmentChips.js";
7
+ import { AssistantVoiceOrb as s } from "./AssistantVoiceOrb.js";
8
8
  import { VoiceMiniController as c } from "./VoiceMiniController.js";
9
9
  import { VoiceStage as l } from "./VoiceStage.js";
10
10
  import { VoiceTranscriptDrawer as u } from "./VoiceTranscriptDrawer.js";
11
11
  import { useCallback as d, useEffect as f, useRef as p, useState as m } from "react";
12
- import { Maximize2 as re, Minimize2 as ie, ScrollText as ae, X as oe } from "lucide-react";
13
- import { jsx as h, jsxs as g } from "react/jsx-runtime";
12
+ import { Maximize2 as re, Minimize2 as h, ScrollText as g, X as _ } from "lucide-react";
13
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
14
14
  //#region src/shared/assistant/ui/voice/AssistantVoiceSession.tsx
15
- var _ = ({ session: _, turns: y = [], onSaveTranscript: b, onContinueInChat: x, notice: S = null, spoken: C, onInterrupt: ce, onToggleMute: w, attachments: T = [], onAttachFiles: E, onRemoveAttachment: D, onRetryAttachment: le, canAttachMore: ue = !0, preparingAttachments: O = 0, spokenChunks: k = null, onEnd: A, capturing: de = !0, interrupting: j = !1, awaitingEndpoint: M = !1 }) => {
16
- let N = e(), { muted: P, error: F } = _, I = p(null), L = p(null), [R, z] = m("mini"), B = R === "full", V = R === "mini", H = R === "mini" ? "panel" : R === "panel" ? "full" : "mini", [U, W] = m(!1), G = p(!1), K = p(w);
17
- K.current = w;
18
- let fe = d(() => {
19
- P || G.current || s(_) || (G.current = !0, K.current());
20
- }, [P, _]);
15
+ var b = ({ session: b, turns: oe = [], onSaveTranscript: se, onContinueInChat: ce, notice: x = null, spoken: S, onInterrupt: C, onToggleMute: w, attachments: T = [], onAttachFiles: E, onRemoveAttachment: le, onRetryAttachment: ue, canAttachMore: de = !0, preparingAttachments: D = 0, spokenChunks: O = null, onEnd: k, capturing: A = !0, interrupting: fe = !1, awaitingEndpoint: pe = !1 }) => {
16
+ let j = e(), { muted: M, error: N } = b, P = p(null), F = p(null), [I, L] = m("mini"), R = I === "full", z = I === "mini", B = I === "mini" ? "panel" : I === "panel" ? "full" : "mini", [V, H] = m(!1), U = p(!1), W = p(w);
17
+ W.current = w;
18
+ let G = d(() => {
19
+ b.phase === "listening" && (M || U.current || a(b) || (U.current = !0, W.current()));
20
+ }, [M, b]), K = d(() => {
21
+ U.current && (U.current = !1, W.current());
22
+ }, []), me = G;
21
23
  f(() => {
22
24
  let e = () => {
23
- G.current && (G.current = !1, K.current());
25
+ document.visibilityState === "hidden" ? G() : K();
24
26
  };
27
+ return document.addEventListener("visibilitychange", e), () => document.removeEventListener("visibilitychange", e);
28
+ }, [G, K]), f(() => {
29
+ let e = K;
25
30
  return window.addEventListener("focus", e), () => {
26
- window.removeEventListener("focus", e), G.current = !1;
31
+ window.removeEventListener("focus", e), U.current = !1;
27
32
  };
28
33
  }, []), f(() => {
29
- I.current?.focus();
34
+ P.current?.focus();
30
35
  }, []), f(() => {
31
36
  let e = (e) => {
32
37
  if (e.key === "Escape") {
33
- if (U) {
34
- W(!1);
38
+ if (V) {
39
+ H(!1);
35
40
  return;
36
41
  }
37
- A();
42
+ k();
38
43
  return;
39
44
  }
40
- if (e.key !== "Tab" || !B) return;
41
- let t = (U ? L.current?.querySelector("[data-testid=\"assistant-voice-transcript\"]") : L.current)?.querySelectorAll("button:not([disabled])");
45
+ if (e.key !== "Tab" || !R) return;
46
+ let t = (V ? F.current?.querySelector("[data-testid=\"assistant-voice-transcript\"]") : F.current)?.querySelectorAll("button:not([disabled])");
42
47
  if (!t || t.length === 0) return;
43
48
  let n = t[0], r = t[t.length - 1];
44
49
  !n || !r || (e.shiftKey && document.activeElement === n ? (e.preventDefault(), r.focus()) : !e.shiftKey && document.activeElement === r && (e.preventDefault(), n.focus()));
45
50
  };
46
51
  return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
47
52
  }, [
48
- A,
49
- B,
50
- U
53
+ k,
54
+ R,
55
+ V
51
56
  ]);
52
- let q = S !== null && F === null, J = s(_), Y = r({
53
- snapshot: _,
54
- capturing: de,
55
- interrupting: j,
56
- awaitingEndpoint: M
57
+ let q = x !== null && N === null, J = a(b), Y = r({
58
+ snapshot: b,
59
+ capturing: A,
60
+ interrupting: fe,
61
+ awaitingEndpoint: pe
57
62
  }), X = (() => {
58
63
  switch (Y) {
59
- case "connecting": return N("voiceSession.connecting", "Starting the microphone…");
60
- case "endpoint-grace": return N("voiceSession.endpointGrace", "Still listening — take your time");
61
- case "interrupting": return N("voiceSession.interrupting", "Stopped — go ahead");
62
- case "thinking": return N(i.key, i.fallback);
63
- case "speaking": return N("voiceSession.speaking", "Speaking — tap to stop");
64
+ case "connecting": return j("voiceSession.connecting", "Starting the microphone…");
65
+ case "endpoint-grace": return j("voiceSession.endpointGrace", "Still listening — take your time");
66
+ case "interrupting": return j("voiceSession.interrupting", "Stopped — go ahead");
67
+ case "thinking": return j(i.key, i.fallback);
68
+ case "speaking": return j("voiceSession.speaking", "Speaking — tap to stop");
64
69
  case "mic-error":
65
70
  case "ended": return "";
66
- case "listening": return P ? N("voiceSession.muted", "Microphone off") : N("voiceSession.listening", "Listening…");
71
+ case "listening": return M ? j("voiceSession.muted", "Microphone off") : j("voiceSession.listening", "Listening…");
67
72
  default: return Y;
68
73
  }
69
- })(), Z = o({
70
- tr: N,
74
+ })(), Z = te({
75
+ tr: j,
71
76
  stage: Y,
72
- muted: P,
77
+ muted: M,
73
78
  label: X
74
- }), Q = a(X, Z), $ = Y === "thinking";
75
- return /* @__PURE__ */ g("div", {
76
- ref: L,
77
- className: `flex flex-col items-center justify-between bg-bg-sunken ${R === "full" ? "fixed inset-x-0 bottom-0 top-14 z-[60] px-6 py-8" : R === "panel" ? "absolute inset-0 z-20 px-4 py-6" : "absolute inset-x-0 bottom-0 z-20 h-[11.25rem] border-t border-border-subtle px-3 py-3 shadow-lg"}`,
79
+ }), Q = ee(X, Z), $ = Y === "thinking";
80
+ return /* @__PURE__ */ y("div", {
81
+ ref: F,
82
+ className: `flex flex-col items-center justify-between bg-bg-sunken ${I === "full" ? "fixed inset-x-0 bottom-0 top-14 z-[60] px-6 py-8" : I === "panel" ? "absolute inset-0 z-20 px-4 py-6" : "absolute inset-x-0 bottom-0 z-20 h-[11.25rem] border-t border-border-subtle px-3 py-3 shadow-lg"}`,
78
83
  role: "dialog",
79
- "aria-modal": B || void 0,
80
- "aria-label": N("voiceSession.title", "Voice conversation"),
84
+ "aria-modal": R || void 0,
85
+ "aria-label": j("voiceSession.title", "Voice conversation"),
81
86
  "data-testid": "assistant-voice-session",
82
87
  children: [
83
- /* @__PURE__ */ g("button", {
84
- ref: I,
88
+ /* @__PURE__ */ y("button", {
89
+ ref: P,
85
90
  type: "button",
86
- onClick: A,
87
- className: `absolute ${B ? "right-6 top-6 h-14 gap-2 px-5 text-base" : V ? "right-12 top-2 h-8 gap-1.5 px-2.5 text-xs" : "right-3 top-3 h-11 gap-2 px-4 text-sm"} flex items-center justify-center rounded-full border border-border-default bg-bg-elevated text-text-secondary hover:bg-bg-sunken transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
88
- title: N("voiceSession.end", "End the voice conversation"),
91
+ onClick: k,
92
+ className: `absolute ${R ? "right-6 top-6 h-14 gap-2 px-5 text-base" : z ? "right-12 top-2 h-8 gap-1.5 px-2.5 text-xs" : "right-3 top-3 h-11 gap-2 px-4 text-sm"} flex items-center justify-center rounded-full border border-border-default bg-bg-elevated text-text-secondary hover:bg-bg-sunken transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
93
+ title: j("voiceSession.end", "End the voice conversation"),
89
94
  "data-testid": "assistant-voice-end",
90
- children: [/* @__PURE__ */ h(oe, {
91
- className: B ? "size-6" : V ? "size-4" : "size-5",
95
+ children: [/* @__PURE__ */ v(_, {
96
+ className: R ? "size-6" : z ? "size-4" : "size-5",
92
97
  "aria-hidden": "true"
93
- }), /* @__PURE__ */ h("span", {
94
- className: `truncate whitespace-nowrap font-medium ${V ? "max-w-[3.5rem] text-xs" : "max-w-[7rem]"}`,
95
- children: N("voiceSession.endShort", "End")
98
+ }), /* @__PURE__ */ v("span", {
99
+ className: `truncate whitespace-nowrap font-medium ${z ? "max-w-[3.5rem] text-xs" : "max-w-[7rem]"}`,
100
+ children: j("voiceSession.endShort", "End")
96
101
  })]
97
102
  }),
98
- /* @__PURE__ */ h("div", {
99
- className: `flex flex-col items-center ${V ? "px-3" : `min-h-[1.5rem] ${q ? B ? "pt-14" : "pt-10" : ""}`}`,
100
- children: q ? /* @__PURE__ */ h("p", {
103
+ /* @__PURE__ */ v("div", {
104
+ className: `flex flex-col items-center ${z ? "px-3" : `min-h-[1.5rem] ${q ? R ? "pt-14" : "pt-10" : ""}`}`,
105
+ children: q ? /* @__PURE__ */ v("p", {
101
106
  className: "max-w-xs text-center text-xs text-status-warning",
102
107
  "data-testid": "assistant-voice-notice",
103
- children: se(S, N)
108
+ children: ie(x, j)
104
109
  }) : null
105
110
  }),
106
111
  (() => {
107
- let e = /* @__PURE__ */ h(ne, {
108
- session: _,
109
- compact: V,
112
+ let e = /* @__PURE__ */ v(s, {
113
+ session: b,
114
+ compact: z,
110
115
  connecting: Y === "connecting",
111
- onPress: t(Y) ? ce : w,
112
- label: t(Y) ? N("voiceSession.interrupt", "Stop the assistant and speak") : P ? N("voiceSession.unmute", "Turn the microphone on") : N("voiceSession.mute", "Turn the microphone off")
113
- }), r = n(Y) ? C : J || null, i = F === null ? null : v(F, N);
114
- return V ? /* @__PURE__ */ h(c, {
115
- spokenChunks: k,
116
+ onPress: t(Y) ? C : w,
117
+ label: t(Y) ? j("voiceSession.interrupt", "Stop the assistant and speak") : M ? j("voiceSession.unmute", "Turn the microphone on") : j("voiceSession.mute", "Turn the microphone off")
118
+ }), r = n(Y) ? S : J || null, i = N === null ? null : ae(N, j);
119
+ return z ? /* @__PURE__ */ v(c, {
120
+ spokenChunks: O,
116
121
  state: Y,
117
122
  caption: r,
118
123
  statusText: Q,
@@ -120,12 +125,12 @@ var _ = ({ session: _, turns: y = [], onSaveTranscript: b, onContinueInChat: x,
120
125
  rotateStatus: $,
121
126
  errorText: i,
122
127
  control: e
123
- }) : /* @__PURE__ */ h(l, {
128
+ }) : /* @__PURE__ */ v(l, {
124
129
  state: Y,
125
130
  userCaption: J || null,
126
- spokenChunks: k,
127
- assistantCaption: C,
128
- expanded: B,
131
+ spokenChunks: O,
132
+ assistantCaption: S,
133
+ expanded: R,
129
134
  statusText: Q,
130
135
  statusSuffix: Z,
131
136
  rotateStatus: $,
@@ -133,54 +138,54 @@ var _ = ({ session: _, turns: y = [], onSaveTranscript: b, onContinueInChat: x,
133
138
  control: e
134
139
  });
135
140
  })(),
136
- U ? /* @__PURE__ */ h(u, {
137
- turns: y,
138
- onClose: () => W(!1),
139
- onSave: b,
140
- onContinueInChat: x
141
+ V ? /* @__PURE__ */ v(u, {
142
+ turns: oe,
143
+ onClose: () => H(!1),
144
+ onSave: se,
145
+ onContinueInChat: ce
141
146
  }) : null,
142
- E ? /* @__PURE__ */ h("div", {
143
- className: `absolute ${B ? "left-6 top-6" : V ? "left-11 top-2" : "left-3 top-3"}`,
144
- children: /* @__PURE__ */ h(ee, {
147
+ E ? /* @__PURE__ */ v("div", {
148
+ className: `absolute ${R ? "left-6 top-6" : z ? "left-11 top-2" : "left-3 top-3"}`,
149
+ children: /* @__PURE__ */ v(o, {
145
150
  onFiles: (e) => {
146
- E(e), z((e) => e === "mini" ? "panel" : e);
151
+ E(e), L((e) => e === "mini" ? "panel" : e);
147
152
  },
148
- onPickerOpen: fe,
153
+ onPickerOpen: me,
149
154
  direction: "down",
150
- canAddMore: ue
155
+ canAddMore: de
151
156
  })
152
157
  }) : null,
153
- (T.length > 0 || O > 0) && !V ? /* @__PURE__ */ h("div", {
154
- className: `absolute ${B ? "bottom-24 left-24 right-24" : "bottom-16 left-16 right-16"}`,
158
+ (T.length > 0 || D > 0) && !z ? /* @__PURE__ */ v("div", {
159
+ className: `absolute ${R ? "bottom-24 left-24 right-24" : "bottom-16 left-16 right-16"}`,
155
160
  "data-testid": "assistant-voice-attachments",
156
- children: /* @__PURE__ */ h(te, {
161
+ children: /* @__PURE__ */ v(ne, {
157
162
  attachments: T,
158
- onRemove: D ?? (() => void 0),
159
- onRetry: le ?? (() => void 0),
160
- preparingCount: O
163
+ onRemove: le ?? (() => void 0),
164
+ onRetry: ue ?? (() => void 0),
165
+ preparingCount: D
161
166
  })
162
167
  }) : null,
163
- /* @__PURE__ */ h("button", {
168
+ /* @__PURE__ */ v("button", {
164
169
  type: "button",
165
- onClick: () => W((e) => !e),
166
- className: `absolute ${B ? "bottom-6 right-6 size-14" : V ? "right-2 top-2 size-8" : "bottom-3 right-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated 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`,
167
- "aria-pressed": U,
168
- "aria-label": N("voiceSession.transcriptTitle", "Voice transcript"),
170
+ onClick: () => H((e) => !e),
171
+ className: `absolute ${R ? "bottom-6 right-6 size-14" : z ? "right-2 top-2 size-8" : "bottom-3 right-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated 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`,
172
+ "aria-pressed": V,
173
+ "aria-label": j("voiceSession.transcriptTitle", "Voice transcript"),
169
174
  "data-testid": "assistant-voice-transcript-toggle",
170
- children: /* @__PURE__ */ h(ae, { className: B ? "size-6" : V ? "size-4" : "size-5" })
175
+ children: /* @__PURE__ */ v(g, { className: R ? "size-6" : z ? "size-4" : "size-5" })
171
176
  }),
172
- /* @__PURE__ */ h("button", {
177
+ /* @__PURE__ */ v("button", {
173
178
  type: "button",
174
- onClick: () => z(H),
175
- className: `absolute ${B ? "bottom-6 left-6 size-14" : V ? "left-2 top-2 size-8" : "bottom-3 left-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated 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`,
176
- "aria-label": H === "panel" ? N("voiceSession.expandPanel", "Show the conversation in the panel") : H === "full" ? N("voiceSession.expand", "Expand the conversation to full screen") : N("voiceSession.collapse", "Shrink to the compact controller"),
179
+ onClick: () => L(B),
180
+ className: `absolute ${R ? "bottom-6 left-6 size-14" : z ? "left-2 top-2 size-8" : "bottom-3 left-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated 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`,
181
+ "aria-label": B === "panel" ? j("voiceSession.expandPanel", "Show the conversation in the panel") : B === "full" ? j("voiceSession.expand", "Expand the conversation to full screen") : j("voiceSession.collapse", "Shrink to the compact controller"),
177
182
  "data-testid": "assistant-voice-expand",
178
- children: B ? /* @__PURE__ */ h(ie, { className: "size-5" }) : /* @__PURE__ */ h(re, { className: V ? "size-4" : "size-5" })
183
+ children: R ? /* @__PURE__ */ v(h, { className: "size-5" }) : /* @__PURE__ */ v(re, { className: z ? "size-4" : "size-5" })
179
184
  })
180
185
  ]
181
186
  });
182
187
  };
183
- function se(e, t) {
188
+ function ie(e, t) {
184
189
  switch (e) {
185
190
  case "network": return t("voiceSession.noticeNetwork", "Speech recognition lost its connection. Check your network — it will retry.");
186
191
  case "not-capturing": return t("voiceSession.noticeNotCapturing", "The microphone did not start. Check that this site is allowed to use it, then try again.");
@@ -189,7 +194,7 @@ function se(e, t) {
189
194
  default: return e;
190
195
  }
191
196
  }
192
- function v(e, t) {
197
+ function ae(e, t) {
193
198
  switch (e) {
194
199
  case "mic-denied": return t("voiceSession.micDenied", "Microphone access is blocked. Allow it in your browser settings to talk.");
195
200
  case "no-speech-support": return t("voiceSession.noSpeechSupport", "This browser cannot listen. Try a different browser, or type instead.");
@@ -198,4 +203,4 @@ function v(e, t) {
198
203
  }
199
204
  }
200
205
  //#endregion
201
- export { _ as AssistantVoiceSession };
206
+ export { b as AssistantVoiceSession };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fe-libs",
3
- "version": "2026.922.2",
3
+ "version": "2026.923.1",
4
4
  "description": "Burdenoff frontend primitives and domain libraries",
5
5
  "type": "module",
6
6
  "bin": {