@burdenoff/fe-libs 2026.1029.2 → 2026.1029.4

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 (31) hide show
  1. package/dist/shared/assistant/conversation.d.ts +10 -0
  2. package/dist/shared/assistant/i18nManifest.d.ts +15 -2
  3. package/dist/shared/assistant/i18nManifest.js +12 -0
  4. package/dist/shared/assistant/index.d.ts +4 -0
  5. package/dist/shared/assistant/productCopy.d.ts +8 -0
  6. package/dist/shared/assistant/productCopy.js +8 -5
  7. package/dist/shared/assistant/turnTimeline.js +1 -1
  8. package/dist/shared/assistant/turnTimingReporter.d.ts +11 -0
  9. package/dist/shared/assistant/turnTimingReporter.js +73 -56
  10. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts +9 -0
  11. package/dist/shared/assistant/ui/AIAssistantPanel.js +70 -69
  12. package/dist/shared/assistant/ui/AssistantApiCallsConsentDialog.d.ts +23 -0
  13. package/dist/shared/assistant/ui/AssistantApiCallsConsentDialog.js +72 -18
  14. package/dist/shared/assistant/ui/AssistantChatArea.d.ts +6 -0
  15. package/dist/shared/assistant/ui/AssistantChatArea.js +1206 -1095
  16. package/dist/shared/assistant/ui/AssistantSpeechProvider.js +134 -129
  17. package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts +27 -0
  18. package/dist/shared/assistant/ui/composer/AssistantComposer.js +350 -206
  19. package/dist/shared/assistant/ui/composer/AssistantModeMenu.d.ts +51 -0
  20. package/dist/shared/assistant/ui/composer/AssistantModeMenu.js +188 -0
  21. package/dist/shared/assistant/ui/composer/imeEnter.d.ts +44 -0
  22. package/dist/shared/assistant/ui/composer/imeEnter.js +11 -0
  23. package/dist/shared/assistant/ui/composer/modeMenuKeys.d.ts +76 -0
  24. package/dist/shared/assistant/ui/composer/modeMenuKeys.js +61 -0
  25. package/dist/shared/assistant/ui/composer/modeSwitchPlan.d.ts +73 -0
  26. package/dist/shared/assistant/ui/composer/modeSwitchPlan.js +25 -0
  27. package/dist/shared/assistant/ui/useVoiceSession.js +201 -177
  28. package/dist/shared/assistant/voice/voiceSession.d.ts +7 -0
  29. package/dist/shared/assistant/voice/voiceSession.js +10 -1
  30. package/dist/shared-assistant.js +241 -237
  31. package/package.json +1 -1
@@ -5,47 +5,47 @@ import { useAssistantTr as n } from "../i18n.js";
5
5
  import { useAssistantStore as r } from "../store.js";
6
6
  import { AssistantSpeechProvider as i } from "./AssistantSpeechProvider.js";
7
7
  import { ASSISTANT_OVERLAY_ATTR as a, ASSISTANT_PANEL_ATTR as o, activePanelOverlay as s, escapeDismisses as c, nextPanelOverlays as l } from "./panelOverlays.js";
8
- import { LiveAvatarSeamProvider as u, LiveAvatarTabContext as d, useLiveAvatarSpeechEngine as f, useLiveAvatarTabOffered as te } from "./assistantLiveAvatarSeam.js";
9
- import { AssistantPreviewProvider as ne } from "../preview/context.js";
10
- import { useAssistantPreviewBridge as re } from "../preview/useAssistantPreviewBridge.js";
11
- import { AssistantConnectSourceProvider as ie } from "./composer/connectSource.js";
12
- import { hasAssistantPreviewSurface as ae } from "../preview/types.js";
13
- import { panelOwnedPreviewBridge as oe, useHostedAssistantPreviewBridge as se } from "../preview/bridgeHostContext.js";
14
- import { AssistantPreviewOverlay as ce } from "../preview/AssistantPreviewOverlay.js";
15
- import { AssistantHeader as le } from "./AssistantHeader.js";
16
- import { AssistantConversationList as ue } from "./AssistantConversationList.js";
17
- import { AssistantConversationDeleteDialogProvider as de } from "./conversationDeleteDialog.js";
18
- import { AssistantControlConfirmProvider as fe } from "./controlConfirmDialog.js";
19
- import { AssistantLeaveConfirmNavigateProvider as pe } from "./leaveConfirm.js";
20
- import { useAssistantServerHistory as me } from "../history/useAssistantServerHistory.js";
21
- import { useFilesServiceWarmup as he } from "../../../storage/warmFilesService.js";
22
- import { AssistantAvatarTabs as ge } from "./AssistantAvatarTabs.js";
23
- import { useAssistantHeartbeat as _e } from "../useAssistantHeartbeat.js";
24
- import { useAssistantKeyboardShortcuts as ve } from "../useAssistantKeyboardShortcuts.js";
25
- import { AssistantChatArea as ye } from "./AssistantChatArea.js";
26
- import { useCallback as p, useId as m, useMemo as h, useRef as g, useState as _ } from "react";
27
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
8
+ import { LiveAvatarSeamProvider as u, LiveAvatarTabContext as d, useLiveAvatarSpeechEngine as te, useLiveAvatarTabOffered as ne } from "./assistantLiveAvatarSeam.js";
9
+ import { AssistantPreviewProvider as re } from "../preview/context.js";
10
+ import { useAssistantPreviewBridge as ie } from "../preview/useAssistantPreviewBridge.js";
11
+ import { AssistantConnectSourceProvider as ae } from "./composer/connectSource.js";
12
+ import { hasAssistantPreviewSurface as oe } from "../preview/types.js";
13
+ import { panelOwnedPreviewBridge as se, useHostedAssistantPreviewBridge as ce } from "../preview/bridgeHostContext.js";
14
+ import { AssistantPreviewOverlay as le } from "../preview/AssistantPreviewOverlay.js";
15
+ import { AssistantHeader as ue } from "./AssistantHeader.js";
16
+ import { AssistantConversationList as de } from "./AssistantConversationList.js";
17
+ import { AssistantConversationDeleteDialogProvider as fe } from "./conversationDeleteDialog.js";
18
+ import { AssistantControlConfirmProvider as pe } from "./controlConfirmDialog.js";
19
+ import { AssistantLeaveConfirmNavigateProvider as me } from "./leaveConfirm.js";
20
+ import { useAssistantServerHistory as he } from "../history/useAssistantServerHistory.js";
21
+ import { useFilesServiceWarmup as ge } from "../../../storage/warmFilesService.js";
22
+ import { AssistantAvatarTabs as _e } from "./AssistantAvatarTabs.js";
23
+ import { useAssistantHeartbeat as ve } from "../useAssistantHeartbeat.js";
24
+ import { useAssistantKeyboardShortcuts as ye } from "../useAssistantKeyboardShortcuts.js";
25
+ import { AssistantChatArea as be } from "./AssistantChatArea.js";
26
+ import { useCallback as f, useId as p, useMemo as m, useRef as h, useState as g } from "react";
27
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
28
28
  //#region src/shared/assistant/ui/AIAssistantPanel.tsx
29
- var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, onNavigate: T, isShellLessTarget: E, connectSourceHref: D, onConnectSource: O, preview: k, liveAvatar: A, serverHistory: j = !1 }) => {
30
- let M = n(), N = f(A);
31
- me(j);
32
- let [P, F] = _(!1), I = ae(k);
29
+ var y = ({ onClose: y, visible: b, docked: x, onToggleDock: S, writeAccess: C, onNavigate: w, isShellLessTarget: T, connectSourceHref: E, onConnectSource: D, preview: O, liveAvatar: k, presentation: A, serverHistory: j = !1 }) => {
30
+ let M = n(), N = te(k);
31
+ he(j);
32
+ let [P, F] = g(!1), I = oe(O);
33
33
  P && !I && F(!1);
34
34
  let L = P && I;
35
- re(oe(k, se()));
36
- let R = g(null);
35
+ ie(se(O, ce()));
36
+ let R = h(null);
37
37
  e(R);
38
- let { conversations: be, activeConversationId: xe, conversationListOpen: z, setConversationListOpen: B, createConversation: Se } = r(), V = z || L, H = A?.tab, Ce = te(H), [U, W] = _(!1);
39
- U && (!H || x === !1) && W(!1);
40
- let G = H !== void 0 && (Ce || U), K = m(), q = h(() => G ? {
38
+ let { conversations: xe, activeConversationId: Se, conversationListOpen: z, setConversationListOpen: B, createConversation: Ce } = r(), V = z || L, H = k?.tab, we = ne(H), [U, W] = g(!1);
39
+ U && (!H || b === !1) && W(!1);
40
+ let G = H !== void 0 && (we || U), K = p(), q = m(() => G ? {
41
41
  chatTab: `${K}-chat-tab`,
42
42
  avatarTab: `${K}-avatar-tab`,
43
43
  chatPanel: `${K}-chat-panel`,
44
44
  avatarPanel: `${K}-avatar-panel`,
45
45
  leaveHint: `${K}-avatar-leave`
46
- } : null, [G, K]), J = p(() => W(!1), []), Y = g(null), X = p((e) => {
46
+ } : null, [G, K]), J = f(() => W(!1), []), Y = h(null), X = f((e) => {
47
47
  Y.current = e;
48
- }, []), we = h(() => ({
48
+ }, []), Te = m(() => ({
49
49
  open: U,
50
50
  close: J,
51
51
  ids: q,
@@ -57,7 +57,7 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
57
57
  q,
58
58
  V,
59
59
  X
60
- ]), Te = (e) => W(e === "avatar"), Z = s({
60
+ ]), Ee = (e) => W(e === "avatar"), Z = s({
61
61
  historyOpen: z,
62
62
  previewOpen: L,
63
63
  avatarOpen: U
@@ -68,7 +68,7 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
68
68
  }, e);
69
69
  B(t.historyOpen), F(t.previewOpen);
70
70
  };
71
- t("assistant.history", h(() => ({ run: () => z ? { status: "already" } : (B(!0), F(!1), { status: "done" }) }), [z, B])), t("assistant.preview", h(() => I ? {
71
+ t("assistant.history", m(() => ({ run: () => z ? { status: "already" } : (B(!0), F(!1), { status: "done" }) }), [z, B])), t("assistant.preview", m(() => I ? {
72
72
  surface: "panel",
73
73
  run: () => L ? { status: "already" } : (B(!1), F(!0), { status: "done" }),
74
74
  close: () => L ? (F(!1), { status: "done" }) : { status: "already" }
@@ -77,10 +77,10 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
77
77
  L,
78
78
  B
79
79
  ]));
80
- let $ = be.find((e) => e.id === xe);
81
- _e($?.backendSessionId ?? null, $?.mode ?? null, x ?? !0), he(x ?? !0);
82
- let Ee = ee(x !== !1);
83
- return ve({
80
+ let $ = xe.find((e) => e.id === Se);
81
+ ve($?.backendSessionId ?? null, $?.mode ?? null, b ?? !0), ge(b ?? !0);
82
+ let De = ee(b !== !1);
83
+ return ye({
84
84
  panelRef: R,
85
85
  onClose: () => {
86
86
  let e = c({
@@ -101,24 +101,24 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
101
101
  W(!1), q && document.getElementById(q.chatTab)?.focus();
102
102
  return;
103
103
  }
104
- b();
104
+ y();
105
105
  }
106
- }), /* @__PURE__ */ v(i, {
107
- visible: x ?? !0,
106
+ }), /* @__PURE__ */ _(i, {
107
+ visible: b ?? !0,
108
108
  engine: N,
109
- children: /* @__PURE__ */ v(u, {
110
- value: A,
111
- children: /* @__PURE__ */ v(d.Provider, {
112
- value: we,
113
- children: /* @__PURE__ */ v(ne, {
114
- value: k,
115
- children: /* @__PURE__ */ v(pe, {
116
- navigate: T,
117
- isShellLessTarget: E,
118
- children: /* @__PURE__ */ v(ie, {
119
- value: D,
120
- onOpen: O,
121
- children: /* @__PURE__ */ v(de, { children: /* @__PURE__ */ v(fe, { children: /* @__PURE__ */ y("div", {
109
+ children: /* @__PURE__ */ _(u, {
110
+ value: k,
111
+ children: /* @__PURE__ */ _(d.Provider, {
112
+ value: Te,
113
+ children: /* @__PURE__ */ _(re, {
114
+ value: O,
115
+ children: /* @__PURE__ */ _(me, {
116
+ navigate: w,
117
+ isShellLessTarget: T,
118
+ children: /* @__PURE__ */ _(ae, {
119
+ value: E,
120
+ onOpen: D,
121
+ children: /* @__PURE__ */ _(fe, { children: /* @__PURE__ */ _(pe, { children: /* @__PURE__ */ v("div", {
122
122
  ref: R,
123
123
  className: "relative flex h-full w-full flex-col bg-bg-surface",
124
124
  role: "complementary",
@@ -128,33 +128,34 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
128
128
  ...Z ? { [a]: Z } : {},
129
129
  tabIndex: -1,
130
130
  children: [
131
- /* @__PURE__ */ y("div", {
131
+ /* @__PURE__ */ v("div", {
132
132
  className: "contents",
133
133
  inert: V || void 0,
134
- children: [/* @__PURE__ */ v(le, {
135
- contextLabel: Ee,
136
- onNewConversation: () => Se(),
134
+ children: [/* @__PURE__ */ _(ue, {
135
+ contextLabel: De,
136
+ onNewConversation: () => Ce(),
137
137
  onOpenHistory: () => Q("history"),
138
138
  historyOpen: z,
139
139
  onTogglePreview: () => Q("preview"),
140
140
  previewOpen: L,
141
- onClose: b,
142
- docked: S,
143
- onToggleDock: C
144
- }), q ? /* @__PURE__ */ v(ge, {
141
+ onClose: y,
142
+ docked: x,
143
+ onToggleDock: S
144
+ }), q ? /* @__PURE__ */ _(_e, {
145
145
  selected: U ? "avatar" : "chat",
146
- onSelect: Te,
146
+ onSelect: Ee,
147
147
  ids: q
148
148
  }) : null]
149
149
  }),
150
- z && /* @__PURE__ */ v(ue, {}),
151
- L && /* @__PURE__ */ v(ce, { onClose: () => F(!1) }),
152
- /* @__PURE__ */ v("div", {
150
+ z && /* @__PURE__ */ _(de, {}),
151
+ L && /* @__PURE__ */ _(le, { onClose: () => F(!1) }),
152
+ /* @__PURE__ */ _("div", {
153
153
  className: "contents",
154
154
  inert: V || void 0,
155
- children: /* @__PURE__ */ v(ye, {
156
- visible: x ?? !0,
157
- writeAccess: w
155
+ children: /* @__PURE__ */ _(be, {
156
+ visible: b ?? !0,
157
+ writeAccess: C,
158
+ presentation: A
158
159
  })
159
160
  })
160
161
  ]
@@ -167,4 +168,4 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
167
168
  });
168
169
  };
169
170
  //#endregion
170
- export { b as AIAssistantPanel };
171
+ export { y as AIAssistantPanel };
@@ -14,6 +14,29 @@ export interface AssistantApiCallsConsentDialogProps {
14
14
  mode?: WriteConsentMode;
15
15
  /** The mode being left, which names the cancel button. Absent: Ask. */
16
16
  currentMode?: WriteConsentMode | null;
17
+ /**
18
+ * The COMPACT presentation's mode switch (BOFF-10055, D7 merged with the
19
+ * consent): what this switch costs, said in the same dialog as the consent,
20
+ * so one decision never needs two dialogs.
21
+ *
22
+ * Absent: the consent dialog exactly as before, byte for byte.
23
+ */
24
+ switchPlan?: AssistantModeSwitchDialogPlan;
25
+ }
26
+ /** What the dialog says about one switch. From `planModeSwitch`, plus the names. */
27
+ export interface AssistantModeSwitchDialogPlan {
28
+ /** First-time write consent applies: the consent's title, body and buttons lead. */
29
+ consent: boolean;
30
+ withdrawnCount: number;
31
+ movesToNewConversation: boolean;
32
+ draftKept: boolean;
33
+ /** The option switched to, named as its menu item names it ("Workflow", "Auto"). */
34
+ targetName: string;
35
+ /**
36
+ * The option being left, when `currentMode` cannot name it (Auto is not a
37
+ * mode). Names the "Stay in …" button.
38
+ */
39
+ currentName?: string;
17
40
  }
18
41
  /**
19
42
  * One-time consent shown the first time a user switches the assistant into a
@@ -3,35 +3,89 @@ import { ModalShell as t } from "../../../ui/modal-shell.js";
3
3
  import { useAssistantTr as n } from "../i18n.js";
4
4
  import { writeModeConsentCopy as r } from "../writeModeConsent.js";
5
5
  import { modeRequiresConfirmWrites as i } from "../api.js";
6
- import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
6
+ import { useRef as a } from "react";
7
+ import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
7
8
  //#region src/shared/assistant/ui/AssistantApiCallsConsentDialog.tsx
8
- var c = { id: "api-calls" }, l = ({ open: l, onConfirm: u, onCancel: d, mode: f = c, currentMode: p }) => {
9
- let m = r(n(), {
10
- target: f,
11
- current: p,
12
- confirmsWrites: i(f.id)
9
+ var l = { id: "api-calls" }, u = ({ open: a, onConfirm: u, onCancel: f, mode: p = l, currentMode: m, switchPlan: h }) => {
10
+ let g = r(n(), {
11
+ target: p,
12
+ current: m,
13
+ confirmsWrites: i(p.id)
13
14
  });
14
- return /* @__PURE__ */ o(t, {
15
- open: l,
16
- onClose: d,
15
+ return h ? /* @__PURE__ */ s(d, {
16
+ open: a,
17
+ onConfirm: u,
18
+ onCancel: f,
19
+ plan: h,
20
+ consentCopy: g
21
+ }) : /* @__PURE__ */ s(t, {
22
+ open: a,
23
+ onClose: f,
17
24
  size: "sm",
18
- title: m.title,
19
- footer: /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o(e, {
25
+ title: g.title,
26
+ footer: /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(e, {
20
27
  variant: "outline",
21
- onClick: d,
28
+ onClick: f,
22
29
  "data-testid": "assistant-api-calls-consent-cancel",
23
- children: m.cancel
24
- }), /* @__PURE__ */ o(e, {
30
+ children: g.cancel
31
+ }), /* @__PURE__ */ s(e, {
25
32
  variant: "default",
26
33
  onClick: u,
27
34
  "data-testid": "assistant-api-calls-consent-confirm",
28
- children: m.confirm
35
+ children: g.confirm
29
36
  })] }),
30
- children: /* @__PURE__ */ s("div", {
37
+ children: /* @__PURE__ */ c("div", {
31
38
  className: "space-y-2 text-sm text-text-secondary",
32
- children: [/* @__PURE__ */ o("p", { children: m.body }), /* @__PURE__ */ o("p", { children: m.safeguard })]
39
+ children: [/* @__PURE__ */ s("p", { children: g.body }), /* @__PURE__ */ s("p", { children: g.safeguard })]
40
+ })
41
+ });
42
+ }, d = ({ open: r, onConfirm: i, onCancel: l, plan: u, consentCopy: d }) => {
43
+ let f = n(), p = a(null), m = [];
44
+ u.withdrawnCount > 0 && m.push({
45
+ key: "withdrawn",
46
+ text: f("modeSwitch.withdrawn", "{{count}} change(s) waiting for your approval will be withdrawn.", { count: u.withdrawnCount })
47
+ }), u.movesToNewConversation && m.push({
48
+ key: "newConversation",
49
+ text: f("modeSwitch.newConversation", "{{mode}} continues in a new conversation. This one stays in History.", { mode: u.targetName })
50
+ }), u.draftKept && m.length > 0 && m.push({
51
+ key: "draftKept",
52
+ text: f("modeSwitch.draftKept", "What you typed stays in the message box.")
53
+ });
54
+ let h = u.currentName === void 0 ? d.cancel : f("writeConsent.cancel", "Stay in {{mode}}", { mode: u.currentName });
55
+ return /* @__PURE__ */ s(t, {
56
+ open: r,
57
+ onClose: l,
58
+ size: "sm",
59
+ role: "alertdialog",
60
+ testId: "assistant-mode-switch-dialog",
61
+ onOpenAutoFocus: (e) => {
62
+ e.preventDefault(), p.current?.focus();
63
+ },
64
+ title: u.consent ? d.title : f("modeSwitch.title", "Switch to {{mode}}?", { mode: u.targetName }),
65
+ footer: /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(e, {
66
+ ref: p,
67
+ variant: "outline",
68
+ onClick: l,
69
+ "data-testid": "assistant-mode-switch-cancel",
70
+ children: h
71
+ }), /* @__PURE__ */ s(e, {
72
+ variant: "default",
73
+ onClick: i,
74
+ "data-testid": "assistant-mode-switch-confirm",
75
+ children: u.consent ? d.confirm : f("modeSwitch.confirm", "Switch to {{mode}}", { mode: u.targetName })
76
+ })] }),
77
+ children: /* @__PURE__ */ c("div", {
78
+ className: "space-y-2 text-sm text-text-secondary",
79
+ children: [u.consent ? /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("p", { children: d.body }), /* @__PURE__ */ s("p", { children: d.safeguard })] }) : null, m.length > 0 ? /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("p", { children: f("modeSwitch.intro", "If you switch now:") }), /* @__PURE__ */ s("ul", {
80
+ className: "list-disc space-y-1 pl-5",
81
+ "data-testid": "assistant-mode-switch-lines",
82
+ children: m.map((e) => /* @__PURE__ */ s("li", {
83
+ "data-testid": `assistant-mode-switch-${e.key}`,
84
+ children: e.text
85
+ }, e.key))
86
+ })] }) : null]
33
87
  })
34
88
  });
35
89
  };
36
90
  //#endregion
37
- export { l as AssistantApiCallsConsentDialog };
91
+ export { u as AssistantApiCallsConsentDialog };
@@ -1,4 +1,5 @@
1
1
  import { FC } from 'react';
2
+ import { AssistantPresentation } from './composer/AssistantComposer';
2
3
  import { WorkspaceWriteAccess } from '../useWorkspaceWriteAccess';
3
4
  /**
4
5
  * `visible` is false when the host HIDES the panel without unmounting it, which
@@ -22,5 +23,10 @@ export interface AssistantChatAreaProps {
22
23
  * false claim in either direction.
23
24
  */
24
25
  writeAccess?: WorkspaceWriteAccess;
26
+ /**
27
+ * BOFF-10055: `compact` turns on the compact presentation's composer, Stop,
28
+ * and the mode-switch confirmation. Absent or `classic`: as before.
29
+ */
30
+ presentation?: AssistantPresentation;
25
31
  }
26
32
  export declare const AssistantChatArea: FC<AssistantChatAreaProps>;