@burdenoff/fe-libs 2026.1001.1 → 2026.1001.3

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 (54) hide show
  1. package/dist/connections/api.d.ts.map +1 -1
  2. package/dist/connections/api.js +4 -3
  3. package/dist/connections/oauthPopup.d.ts.map +1 -1
  4. package/dist/connections/oauthPopup.js +8 -9
  5. package/dist/shared/assistant/conversationDeleteCommand.d.ts +31 -0
  6. package/dist/shared/assistant/conversationDeleteCommand.d.ts.map +1 -0
  7. package/dist/shared/assistant/conversationDeleteCommand.js +14 -0
  8. package/dist/shared/assistant/history/historyControls.d.ts +9 -0
  9. package/dist/shared/assistant/history/historyControls.d.ts.map +1 -1
  10. package/dist/shared/assistant/history/historyControls.js +7 -1
  11. package/dist/shared/assistant/history/historyList.d.ts +10 -0
  12. package/dist/shared/assistant/history/historyList.d.ts.map +1 -1
  13. package/dist/shared/assistant/history/historyList.js +33 -28
  14. package/dist/shared/assistant/history/useHistoryRowControls.d.ts +13 -0
  15. package/dist/shared/assistant/history/useHistoryRowControls.d.ts.map +1 -0
  16. package/dist/shared/assistant/history/useHistoryRowControls.js +24 -0
  17. package/dist/shared/assistant/i18nManifest.d.ts +36 -0
  18. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  19. package/dist/shared/assistant/i18nManifest.js +36 -0
  20. package/dist/shared/assistant/index.d.ts +6 -0
  21. package/dist/shared/assistant/index.d.ts.map +1 -1
  22. package/dist/shared/assistant/localUiCommands.d.ts +8 -0
  23. package/dist/shared/assistant/localUiCommands.d.ts.map +1 -1
  24. package/dist/shared/assistant/localUiCommands.js +20 -19
  25. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts.map +1 -1
  26. package/dist/shared/assistant/ui/AIAssistantPanel.js +67 -66
  27. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  28. package/dist/shared/assistant/ui/AssistantChatArea.js +854 -809
  29. package/dist/shared/assistant/ui/AssistantConversationFilters.d.ts +12 -0
  30. package/dist/shared/assistant/ui/AssistantConversationFilters.d.ts.map +1 -0
  31. package/dist/shared/assistant/ui/AssistantConversationFilters.js +92 -0
  32. package/dist/shared/assistant/ui/AssistantConversationList.d.ts +9 -0
  33. package/dist/shared/assistant/ui/AssistantConversationList.d.ts.map +1 -1
  34. package/dist/shared/assistant/ui/AssistantConversationList.js +314 -214
  35. package/dist/shared/assistant/ui/AssistantDeleteConversationDialog.d.ts +59 -0
  36. package/dist/shared/assistant/ui/AssistantDeleteConversationDialog.d.ts.map +1 -0
  37. package/dist/shared/assistant/ui/AssistantDeleteConversationDialog.js +84 -0
  38. package/dist/shared/assistant/ui/AssistantHistoryNotices.d.ts +18 -0
  39. package/dist/shared/assistant/ui/AssistantHistoryNotices.d.ts.map +1 -1
  40. package/dist/shared/assistant/ui/AssistantHistoryNotices.js +76 -29
  41. package/dist/shared/assistant/ui/conversationDelete.d.ts +18 -0
  42. package/dist/shared/assistant/ui/conversationDelete.d.ts.map +1 -0
  43. package/dist/shared/assistant/ui/conversationDelete.js +16 -0
  44. package/dist/shared/assistant/ui/conversationDeleteDialog.d.ts +32 -0
  45. package/dist/shared/assistant/ui/conversationDeleteDialog.d.ts.map +1 -0
  46. package/dist/shared/assistant/ui/conversationDeleteDialog.js +54 -0
  47. package/dist/shared/assistant/ui/useVoiceSession.d.ts +5 -0
  48. package/dist/shared/assistant/ui/useVoiceSession.d.ts.map +1 -1
  49. package/dist/shared/assistant/ui/useVoiceSession.js +129 -121
  50. package/dist/shared/assistant/voice/voiceSession.d.ts +10 -0
  51. package/dist/shared/assistant/voice/voiceSession.d.ts.map +1 -1
  52. package/dist/shared/assistant/voice/voiceSession.js +6 -0
  53. package/dist/shared-assistant.js +170 -164
  54. package/package.json +1 -1
@@ -0,0 +1,59 @@
1
+ import { FC } from 'react';
2
+ import { AssistantTr } from '../i18n';
3
+ /**
4
+ * "Delete this conversation?" (BOFF-8159, R5a) — the confirmation the typed or
5
+ * spoken "delete this conversation" opens.
6
+ *
7
+ * ★★ The command only OPENS this. Its Delete button is the one thing that
8
+ * deletes, and the same rules as the 5a confirmation make it so
9
+ * (`AssistantWriteConfirmDialog`):
10
+ * - focus starts on Cancel, never on Delete;
11
+ * - Enter decides nothing: on either button it is swallowed, so a key held or
12
+ * repeated from the composer can neither delete nor cancel;
13
+ * - Delete is armed only `DELETE_CONFIRM_ARM_MS` after the dialog opens, and
14
+ * counts a trusted press only (`event.isTrusted`): a click a script
15
+ * dispatched is ignored, however late;
16
+ * - Esc, the overlay and the close button only CLOSE it. Nothing is deleted.
17
+ * A spoken "yes" cannot reach it either: while it is open the voice session's
18
+ * listening is held, so nothing said is heard, let alone sent.
19
+ *
20
+ * ★ Portalled. `ModalShell` renders into `document.body`, outside the panel and
21
+ * outside the `inert` wrapper a live voice session puts over the chat, so it
22
+ * stays operable during the session. Its `alertdialog` role is one of the
23
+ * layers the voice session's Escape stands aside for (BOFF-8065), and the shell
24
+ * hands focus back to what opened it on close (the composer, for a typed
25
+ * command).
26
+ *
27
+ * ★ Presentational: it says what Delete will do and reports the press. Which
28
+ * conversation, and the delete itself, are the caller's
29
+ * (`AssistantConversationDeleteDialogProvider`).
30
+ */
31
+ /** How long after opening before Delete counts a press. */
32
+ export declare const DELETE_CONFIRM_ARM_MS = 600;
33
+ export interface AssistantDeleteConversationDialogProps {
34
+ open: boolean;
35
+ /** The conversation's title; empty when it has none (it is named "Untitled"). */
36
+ title: string;
37
+ /**
38
+ * Kept in server history: removed from every device now, erased after 30
39
+ * days. False: deleted from this device, which is the only place it is.
40
+ */
41
+ synced: boolean;
42
+ tr: AssistantTr;
43
+ /** Delete was pressed: armed, trusted, not by Enter. Once per opening. */
44
+ onConfirm: () => void;
45
+ /** Cancel, Esc, the overlay or the close button: nothing is deleted. */
46
+ onDismiss: () => void;
47
+ }
48
+ export declare const AssistantDeleteConversationDialog: FC<AssistantDeleteConversationDialogProps>;
49
+ /**
50
+ * A TYPED "delete this conversation" with no conversation to delete — none is
51
+ * open, or the open one is an empty draft (BOFF-8159). Said once, beside the
52
+ * composer, and recorded nowhere: there is no conversation to record it in.
53
+ * (Spoken, the voice session says the same line instead.)
54
+ */
55
+ export declare const AssistantNothingToDeleteNotice: FC<{
56
+ tr: AssistantTr;
57
+ onDismiss: () => void;
58
+ }>;
59
+ //# sourceMappingURL=AssistantDeleteConversationDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssistantDeleteConversationDialog.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantDeleteConversationDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,EAAE,EAGR,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,MAAM,WAAW,sCAAsC;IACrD,IAAI,EAAE,OAAO,CAAC;IACd,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB,EAAE,EAAE,WAAW,CAAC;IAChB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,wEAAwE;IACxE,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,eAAO,MAAM,iCAAiC,EAAE,EAAE,CAChD,sCAAsC,CAqHvC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,EAAE,EAAE,CAAC;IAC9C,EAAE,EAAE,WAAW,CAAC;IAChB,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,CAmBA,CAAC"}
@@ -0,0 +1,84 @@
1
+ import { Button as e } from "../../../ui/button.js";
2
+ import { ModalShell as t } from "../../../ui/modal-shell.js";
3
+ import { useEffect as n, useRef as r, useState as i } from "react";
4
+ import { X as a } from "lucide-react";
5
+ import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
6
+ //#region src/shared/assistant/ui/AssistantDeleteConversationDialog.tsx
7
+ var l = 600, u = ({ open: a, title: l, synced: u, tr: d, onConfirm: f, onDismiss: p }) => {
8
+ let m = r(null), h = r(null), [g, _] = i(!1), v = r(!1);
9
+ n(() => {
10
+ if (!a) {
11
+ h.current = null, _(!1);
12
+ return;
13
+ }
14
+ h.current = Date.now(), v.current = !1, _(!1);
15
+ let e = setTimeout(() => _(!0), 600);
16
+ return () => clearTimeout(e);
17
+ }, [a]);
18
+ let y = r(!1), b = (e) => {
19
+ e.key === "Enter" && (e.preventDefault(), y.current = !0);
20
+ }, x = (e) => {
21
+ e.key === "Enter" && (y.current = !1);
22
+ }, S = () => {
23
+ y.current = !1;
24
+ }, C = (e) => {
25
+ if (!e.isTrusted || y.current) return;
26
+ let t = h.current;
27
+ !g || t === null || Date.now() - t < 600 || v.current || (v.current = !0, f());
28
+ }, w = () => {
29
+ y.current || p();
30
+ }, T = (e) => {
31
+ let t = m.current;
32
+ t && (e.preventDefault(), t.focus());
33
+ }, E = l.trim() || d("history.untitled", "Untitled conversation"), D = u ? d("deleteConversation.body", "“{{title}}” is removed from all your devices now and permanently erased after 30 days. To hide it without deleting, archive it instead.", { title: E }) : d("deleteConversation.bodyDevice", "“{{title}}” is deleted from this device. This can't be undone.", { title: E });
34
+ return /* @__PURE__ */ s(t, {
35
+ open: a,
36
+ onClose: p,
37
+ role: "alertdialog",
38
+ onOpenAutoFocus: T,
39
+ testId: "assistant-delete-conversation-dialog",
40
+ size: "sm",
41
+ title: d("deleteConversation.title", "Delete this conversation?"),
42
+ description: D,
43
+ footer: /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(e, {
44
+ ref: m,
45
+ variant: "outline",
46
+ onClick: w,
47
+ onKeyDown: b,
48
+ onKeyUp: x,
49
+ onBlur: S,
50
+ "data-testid": "assistant-delete-conversation-cancel",
51
+ children: d("deleteConversation.cancel", "Cancel")
52
+ }), /* @__PURE__ */ s(e, {
53
+ variant: "destructive",
54
+ onClick: C,
55
+ onKeyDown: b,
56
+ onKeyUp: x,
57
+ onBlur: S,
58
+ disabled: !g,
59
+ "data-testid": "assistant-delete-conversation-confirm",
60
+ children: d("deleteConversation.confirm", "Delete")
61
+ })] }),
62
+ children: null
63
+ });
64
+ }, d = ({ tr: e, onDismiss: t }) => /* @__PURE__ */ c("div", {
65
+ role: "status",
66
+ className: "mx-3 mb-2 flex items-center gap-2 rounded-lg border border-border-default bg-bg-sunken px-3 py-2 text-xs text-text-secondary",
67
+ "data-testid": "assistant-nothing-to-delete",
68
+ children: [/* @__PURE__ */ s("span", {
69
+ className: "min-w-0 flex-1",
70
+ children: e("deleteConversation.nothing", "There is no conversation to delete.")
71
+ }), /* @__PURE__ */ s("button", {
72
+ type: "button",
73
+ onClick: t,
74
+ className: "flex-shrink-0 rounded-md p-1 transition-colors hover:bg-bg-elevated focus:outline-none focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-[var(--color-focus-ring)]",
75
+ "aria-label": e("history.dismiss", "Dismiss"),
76
+ "data-testid": "assistant-nothing-to-delete-dismiss",
77
+ children: /* @__PURE__ */ s(a, {
78
+ className: "size-3.5",
79
+ "aria-hidden": "true"
80
+ })
81
+ })]
82
+ });
83
+ //#endregion
84
+ export { u as AssistantDeleteConversationDialog, d as AssistantNothingToDeleteNotice, l as DELETE_CONFIRM_ARM_MS };
@@ -33,4 +33,22 @@ export declare const AssistantHistoryDeletedNotice: FC<{
33
33
  * happens — it is not dismissible, because it is not over until then.
34
34
  */
35
35
  export declare const AssistantHistoryUnsavedDeleteNotice: FC;
36
+ /**
37
+ * The conversation open here is archived (BOFF-8159). Archive is not delete: it
38
+ * stays readable and can be continued — a new turn does NOT unarchive it — and
39
+ * it is left out of the list until it is unarchived, here or in the list's
40
+ * Archived view.
41
+ */
42
+ export declare const AssistantHistoryArchivedNotice: FC<{
43
+ onUnarchive: () => void;
44
+ }>;
45
+ /**
46
+ * The server refused a pin: this person already has the most pinned
47
+ * conversations it keeps in this workspace (BOFF-8159). The pin was undone,
48
+ * so the list already shows the truth; this says why.
49
+ */
50
+ export declare const AssistantHistoryPinLimitBanner: FC<{
51
+ limit: number;
52
+ onDismiss: () => void;
53
+ }>;
36
54
  //# sourceMappingURL=AssistantHistoryNotices.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantHistoryNotices.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantHistoryNotices.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAKhC;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC;IACzC,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAkCA,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,2BAA2B,EAAE,EAAE,CAAC;IAC3C,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAcA,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAE,EAAE,CAAC;IAAE,UAAU,EAAE,MAAM,IAAI,CAAA;CAAE,CA4BzE,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,6BAA6B,EAAE,EAAE,CAAC;IAAE,SAAS,EAAE,MAAM,IAAI,CAAA;CAAE,CA4BvE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,EAAE,EAiBjD,CAAC"}
1
+ {"version":3,"file":"AssistantHistoryNotices.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantHistoryNotices.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAchC;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC;IACzC,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAkCA,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,2BAA2B,EAAE,EAAE,CAAC;IAC3C,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAcA,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAE,EAAE,CAAC;IAAE,UAAU,EAAE,MAAM,IAAI,CAAA;CAAE,CA4BzE,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,6BAA6B,EAAE,EAAE,CAAC;IAAE,SAAS,EAAE,MAAM,IAAI,CAAA;CAAE,CA4BvE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,mCAAmC,EAAE,EAiBjD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,EAAE,EAAE,CAAC;IAAE,WAAW,EAAE,MAAM,IAAI,CAAA;CAAE,CA4B1E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAE,EAAE,CAAC;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,CA2BA,CAAC"}
@@ -1,22 +1,22 @@
1
1
  import { useAssistantTr as e } from "../i18n.js";
2
- import { AlertTriangle as t, History as n, Loader2 as r, Lock as i, Trash2 as a, X as o } from "lucide-react";
3
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
2
+ import { AlertTriangle as t, Archive as n, History as r, Loader2 as i, Lock as a, Pin as o, Trash2 as s, X as c } from "lucide-react";
3
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
4
4
  //#region src/shared/assistant/ui/AssistantHistoryNotices.tsx
5
- var l = ({ state: t, onRetry: n, compact: i = !1 }) => {
6
- let a = e(), o = i ? "mx-3 mb-2 flex items-center justify-center gap-2 text-xs" : "flex flex-1 flex-col items-center justify-center gap-2 px-4 text-center text-xs";
7
- return t === "loading" ? /* @__PURE__ */ c("div", {
5
+ var d = ({ state: t, onRetry: n, compact: r = !1 }) => {
6
+ let a = e(), o = r ? "mx-3 mb-2 flex items-center justify-center gap-2 text-xs" : "flex flex-1 flex-col items-center justify-center gap-2 px-4 text-center text-xs";
7
+ return t === "loading" ? /* @__PURE__ */ u("div", {
8
8
  role: "status",
9
9
  className: `${o} text-text-muted`,
10
10
  "data-testid": "assistant-history-loading",
11
- children: [/* @__PURE__ */ s(r, {
11
+ children: [/* @__PURE__ */ l(i, {
12
12
  className: "size-4 motion-safe:animate-spin",
13
13
  "aria-hidden": "true"
14
- }), /* @__PURE__ */ s("span", { children: a("history.loading", "Loading conversation…") })]
15
- }) : /* @__PURE__ */ c("div", {
14
+ }), /* @__PURE__ */ l("span", { children: a("history.loading", "Loading conversation…") })]
15
+ }) : /* @__PURE__ */ u("div", {
16
16
  role: "alert",
17
17
  className: `${o} text-text-secondary`,
18
18
  "data-testid": "assistant-history-load-failed",
19
- children: [/* @__PURE__ */ s("span", { children: a("history.loadFailed", "Couldn't load this conversation.") }), /* @__PURE__ */ s("button", {
19
+ children: [/* @__PURE__ */ l("span", { children: a("history.loadFailed", "Couldn't load this conversation.") }), /* @__PURE__ */ l("button", {
20
20
  type: "button",
21
21
  onClick: n,
22
22
  className: "rounded-md px-2 py-1 font-medium text-action-primary-bg transition-colors hover:bg-bg-elevated focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
@@ -24,30 +24,30 @@ var l = ({ state: t, onRetry: n, compact: i = !1 }) => {
24
24
  children: a("history.tryAgain", "Try again")
25
25
  })]
26
26
  });
27
- }, u = ({ onShowEarlier: t, disabled: r = !1 }) => {
27
+ }, f = ({ onShowEarlier: t, disabled: n = !1 }) => {
28
28
  let i = e();
29
- return /* @__PURE__ */ c("button", {
29
+ return /* @__PURE__ */ u("button", {
30
30
  type: "button",
31
31
  onClick: t,
32
- disabled: r,
32
+ disabled: n,
33
33
  className: "mx-auto mt-2 flex items-center gap-1.5 rounded-md px-2 py-1 text-xs font-medium text-action-primary-bg transition-colors hover:bg-bg-elevated focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong disabled:opacity-50",
34
34
  "data-testid": "assistant-history-show-earlier",
35
- children: [/* @__PURE__ */ s(n, {
35
+ children: [/* @__PURE__ */ l(r, {
36
36
  className: "size-3.5",
37
37
  "aria-hidden": "true"
38
38
  }), i("history.showEarlier", "Show earlier messages")]
39
39
  });
40
- }, d = ({ onStartNew: t }) => {
40
+ }, p = ({ onStartNew: t }) => {
41
41
  let n = e();
42
- return /* @__PURE__ */ c("div", {
42
+ return /* @__PURE__ */ u("div", {
43
43
  className: "mx-3 mb-2 flex items-start gap-2 rounded-lg border border-border-default bg-bg-sunken px-3 py-2 text-xs text-text-secondary",
44
44
  "data-testid": "assistant-history-read-only",
45
- children: [/* @__PURE__ */ s(i, {
45
+ children: [/* @__PURE__ */ l(a, {
46
46
  className: "mt-0.5 size-3.5 flex-shrink-0",
47
47
  "aria-hidden": "true"
48
- }), /* @__PURE__ */ c("div", {
48
+ }), /* @__PURE__ */ u("div", {
49
49
  className: "min-w-0 flex-1",
50
- children: [/* @__PURE__ */ s("p", { children: n("history.legacyReadOnly", "This conversation was saved by an earlier version of the assistant. You can read it, but it can't be continued.") }), /* @__PURE__ */ s("button", {
50
+ children: [/* @__PURE__ */ l("p", { children: n("history.legacyReadOnly", "This conversation was saved by an earlier version of the assistant. You can read it, but it can't be continued.") }), /* @__PURE__ */ l("button", {
51
51
  type: "button",
52
52
  onClick: t,
53
53
  className: "mt-1 font-medium text-action-primary-bg hover:underline focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
@@ -56,48 +56,95 @@ var l = ({ state: t, onRetry: n, compact: i = !1 }) => {
56
56
  })]
57
57
  })]
58
58
  });
59
- }, f = ({ onDismiss: t }) => {
59
+ }, m = ({ onDismiss: t }) => {
60
60
  let n = e();
61
- return /* @__PURE__ */ c("div", {
61
+ return /* @__PURE__ */ u("div", {
62
62
  role: "status",
63
63
  className: "flex items-center gap-2 border-b border-border-subtle bg-bg-sunken/60 px-3 py-2 text-xs text-text-secondary",
64
64
  "data-testid": "assistant-history-deleted-elsewhere",
65
65
  children: [
66
- /* @__PURE__ */ s(a, {
66
+ /* @__PURE__ */ l(s, {
67
67
  className: "size-3.5 flex-shrink-0",
68
68
  "aria-hidden": "true"
69
69
  }),
70
- /* @__PURE__ */ s("span", {
70
+ /* @__PURE__ */ l("span", {
71
71
  className: "min-w-0 flex-1",
72
72
  children: n("history.deletedElsewhere", "The conversation you had open was deleted on another device.")
73
73
  }),
74
- /* @__PURE__ */ s("button", {
74
+ /* @__PURE__ */ l("button", {
75
75
  type: "button",
76
76
  onClick: t,
77
77
  className: "flex-shrink-0 rounded-md p-1 transition-colors hover:bg-bg-elevated focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
78
78
  "aria-label": n("history.dismiss", "Dismiss"),
79
79
  "data-testid": "assistant-history-dismiss-deleted",
80
- children: /* @__PURE__ */ s(o, {
80
+ children: /* @__PURE__ */ l(c, {
81
81
  className: "size-3.5",
82
82
  "aria-hidden": "true"
83
83
  })
84
84
  })
85
85
  ]
86
86
  });
87
- }, p = () => {
87
+ }, h = () => {
88
88
  let n = e();
89
- return /* @__PURE__ */ c("div", {
89
+ return /* @__PURE__ */ u("div", {
90
90
  role: "alert",
91
91
  className: "flex items-start gap-2 border-b border-border-subtle bg-bg-sunken/60 px-3 py-2 text-xs text-text-secondary",
92
92
  "data-testid": "assistant-history-delete-not-saved",
93
- children: [/* @__PURE__ */ s(t, {
93
+ children: [/* @__PURE__ */ l(t, {
94
94
  className: "mt-0.5 size-3.5 flex-shrink-0",
95
95
  "aria-hidden": "true"
96
- }), /* @__PURE__ */ s("span", {
96
+ }), /* @__PURE__ */ l("span", {
97
97
  className: "min-w-0 flex-1",
98
98
  children: n("history.deleteNotSaved", "This device's storage is full, so that delete isn't saved here yet. Keep this page open until it reaches the server.")
99
99
  })]
100
100
  });
101
+ }, g = ({ onUnarchive: t }) => {
102
+ let r = e();
103
+ return /* @__PURE__ */ u("div", {
104
+ className: "mx-3 mb-2 flex items-start gap-2 rounded-lg border border-border-default bg-bg-sunken px-3 py-2 text-xs text-text-secondary",
105
+ "data-testid": "assistant-history-archived",
106
+ children: [/* @__PURE__ */ l(n, {
107
+ className: "mt-0.5 size-3.5 flex-shrink-0",
108
+ "aria-hidden": "true"
109
+ }), /* @__PURE__ */ u("div", {
110
+ className: "min-w-0 flex-1",
111
+ children: [/* @__PURE__ */ l("p", { children: r("history.archivedNotice", "Archived. It stays out of your list until you unarchive it.") }), /* @__PURE__ */ l("button", {
112
+ type: "button",
113
+ onClick: t,
114
+ className: "mt-1 font-medium text-action-primary-bg hover:underline focus:outline-none focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-[var(--color-focus-ring)]",
115
+ "data-testid": "assistant-history-unarchive",
116
+ children: r("history.unarchive", "Unarchive")
117
+ })]
118
+ })]
119
+ });
120
+ }, _ = ({ limit: t, onDismiss: n }) => {
121
+ let r = e();
122
+ return /* @__PURE__ */ u("div", {
123
+ role: "status",
124
+ className: "flex items-center gap-2 border-b border-border-subtle bg-bg-sunken/60 px-3 py-2 text-xs text-text-secondary",
125
+ "data-testid": "assistant-history-pin-limit",
126
+ children: [
127
+ /* @__PURE__ */ l(o, {
128
+ className: "size-3.5 flex-shrink-0",
129
+ "aria-hidden": "true"
130
+ }),
131
+ /* @__PURE__ */ l("span", {
132
+ className: "min-w-0 flex-1",
133
+ children: r("history.pinLimit", "You can pin up to {{limit}} conversations. Unpin one first.", { limit: t })
134
+ }),
135
+ /* @__PURE__ */ l("button", {
136
+ type: "button",
137
+ onClick: n,
138
+ className: "flex-shrink-0 rounded-md p-1 transition-colors hover:bg-bg-elevated focus:outline-none focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-[var(--color-focus-ring)]",
139
+ "aria-label": r("history.dismiss", "Dismiss"),
140
+ "data-testid": "assistant-history-dismiss-pin-limit",
141
+ children: /* @__PURE__ */ l(c, {
142
+ className: "size-3.5",
143
+ "aria-hidden": "true"
144
+ })
145
+ })
146
+ ]
147
+ });
101
148
  };
102
149
  //#endregion
103
- export { f as AssistantHistoryDeletedNotice, l as AssistantHistoryLoadState, d as AssistantHistoryReadOnlyBanner, u as AssistantHistoryShowEarlier, p as AssistantHistoryUnsavedDeleteNotice };
150
+ export { g as AssistantHistoryArchivedNotice, m as AssistantHistoryDeletedNotice, d as AssistantHistoryLoadState, _ as AssistantHistoryPinLimitBanner, p as AssistantHistoryReadOnlyBanner, f as AssistantHistoryShowEarlier, h as AssistantHistoryUnsavedDeleteNotice };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Deleting a conversation outside the history list (BOFF-8159): the rule the
3
+ * list applies, for the Delete confirmation. Kept out of the component files so
4
+ * they export components only (Fast Refresh).
5
+ */
6
+ /** A panel has opted this product into server history (BOFF-7335). */
7
+ export declare function assistantHistoryIsOn(): boolean;
8
+ /**
9
+ * Delete a conversation the way the history list does (BOFF-7335): with server
10
+ * history on, through history — a tombstone first, so it is gone from every
11
+ * flow here at once, then deleted on the server, and nothing arriving later
12
+ * brings it back; with it off, from this device's store.
13
+ *
14
+ * ★ The list's Delete applies the same rule in place, so the two can never
15
+ * delete differently.
16
+ */
17
+ export declare function deleteAssistantConversation(conversationId: string): void;
18
+ //# sourceMappingURL=conversationDelete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversationDelete.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/conversationDelete.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,sEAAsE;AACtE,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAMxE"}
@@ -0,0 +1,16 @@
1
+ import { useAssistantStore as e } from "../store.js";
2
+ import { useAssistantHistoryStatus as t } from "../history/historyStatus.js";
3
+ import { assistantHistory as n } from "../history/historyEngine.js";
4
+ //#region src/shared/assistant/ui/conversationDelete.ts
5
+ function r() {
6
+ return t.getState().product !== null;
7
+ }
8
+ function i(t) {
9
+ if (r()) {
10
+ n.deleteConversation(t);
11
+ return;
12
+ }
13
+ e.getState().deleteConversation(t);
14
+ }
15
+ //#endregion
16
+ export { r as assistantHistoryIsOn, i as deleteAssistantConversation };
@@ -0,0 +1,32 @@
1
+ import { FC, ReactNode } from 'react';
2
+ import { ConversationDeleteTarget } from '../conversationDeleteCommand';
3
+ /** The panel's one Delete confirmation (BOFF-8159). */
4
+ export interface ConversationDeleteDialogController {
5
+ /** Open the confirmation for `target`. Nothing is deleted until its Delete is pressed. */
6
+ request: (target: ConversationDeleteTarget) => void;
7
+ /**
8
+ * The confirmation is open. A live voice session holds its listening
9
+ * meanwhile, so nothing said is heard or sent.
10
+ */
11
+ asking: boolean;
12
+ }
13
+ /**
14
+ * The panel's Delete confirmation, or null outside a panel that provides one
15
+ * (`AIAssistantPanel` does). With none, "delete this conversation" is not a
16
+ * command here: the text goes to the model, as it did before the command.
17
+ */
18
+ export declare function useConversationDeleteDialog(): ConversationDeleteDialogController | null;
19
+ /**
20
+ * Holds the ONE Delete confirmation for the panel (BOFF-8159): opened by the
21
+ * typed or spoken "delete this conversation" (and by the list's Delete, were
22
+ * the operator to choose that — today the list deletes at once). It works with
23
+ * server history on or off.
24
+ *
25
+ * ★ A target that goes while it is open — deleted on another device, in
26
+ * another tab, or here by the list — closes it: there is nothing left to
27
+ * confirm, and a confirm must never delete whatever took its place.
28
+ */
29
+ export declare const AssistantConversationDeleteDialogProvider: FC<{
30
+ children: ReactNode;
31
+ }>;
32
+ //# sourceMappingURL=conversationDeleteDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversationDeleteDialog.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/conversationDeleteDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,EAAE,EACP,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAM7E,uDAAuD;AACvD,MAAM,WAAW,kCAAkC;IACjD,0FAA0F;IAC1F,OAAO,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,CAAC;IACpD;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;CACjB;AAKD;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,kCAAkC,GAAG,IAAI,CAEvF;AASD;;;;;;;;;GASG;AACH,eAAO,MAAM,yCAAyC,EAAE,EAAE,CAAC;IACzD,QAAQ,EAAE,SAAS,CAAC;CACrB,CAiEA,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { useAssistantTr as e } from "../i18n.js";
2
+ import { useAssistantStore as t } from "../store.js";
3
+ import { AssistantDeleteConversationDialog as n } from "./AssistantDeleteConversationDialog.js";
4
+ import { deleteAssistantConversation as r } from "./conversationDelete.js";
5
+ import { createContext as i, useCallback as a, useContext as o, useEffect as s, useMemo as c, useState as l } from "react";
6
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
7
+ //#region src/shared/assistant/ui/conversationDeleteDialog.tsx
8
+ var f = i(null);
9
+ function p() {
10
+ return o(f);
11
+ }
12
+ var m = ({ children: i }) => {
13
+ let o = e(), [p, m] = l({
14
+ target: null,
15
+ open: !1,
16
+ opening: 0
17
+ }), h = a((e) => {
18
+ m((t) => ({
19
+ target: e,
20
+ open: !0,
21
+ opening: t.opening + 1
22
+ }));
23
+ }, []), g = a(() => {
24
+ m((e) => e.open ? {
25
+ ...e,
26
+ open: !1
27
+ } : e);
28
+ }, []), _ = p.open ? p.target?.conversationId : void 0, v = t((e) => _ === void 0 || e.conversations.some((e) => e.id === _));
29
+ s(() => {
30
+ v || g();
31
+ }, [v, g]);
32
+ let y = a(() => {
33
+ let { target: e, open: n } = p;
34
+ if (!n || !e) return;
35
+ let i = t.getState().conversations.some((t) => t.id === e.conversationId);
36
+ g(), i && r(e.conversationId);
37
+ }, [p, g]), b = p.open && v, x = c(() => ({
38
+ request: h,
39
+ asking: b
40
+ }), [h, b]);
41
+ return /* @__PURE__ */ d(f.Provider, {
42
+ value: x,
43
+ children: [i, p.target ? /* @__PURE__ */ u(n, {
44
+ open: b,
45
+ title: p.target.title,
46
+ synced: p.target.synced,
47
+ tr: o,
48
+ onConfirm: y,
49
+ onDismiss: g
50
+ }, p.opening) : null]
51
+ });
52
+ };
53
+ //#endregion
54
+ export { m as AssistantConversationDeleteDialogProvider, p as useConversationDeleteDialog };
@@ -118,6 +118,11 @@ export declare function useVoiceSession({ onSubmit, latestReply, language }: Opt
118
118
  * change confirmation dialog — and resume it (false). BOFF-7803 FE9.
119
119
  */
120
120
  holdListening: (requested: boolean) => void;
121
+ /**
122
+ * Say a line in place of a reply the panel answered itself
123
+ * (`answerLocally`). BOFF-8159.
124
+ */
125
+ answerLocally: (item: VoiceAnnouncement) => void;
121
126
  };
122
127
  export {};
123
128
  //# sourceMappingURL=useVoiceSession.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useVoiceSession.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/useVoiceSession.ts"],"names":[],"mappings":"AAUA,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEpE,OAAO,EAgBL,KAAK,oBAAoB,EAE1B,MAAM,uBAAuB,CAAC;AAsC/B;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAC5B,SAAS,GAAG,eAAe,GAAG,eAAe,GAAG,oBAAoB,CAAC;AAEvE;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;CAC7B;AAMD,UAAU,OAAO;IACf,+EAA+E;IAC/E;;;;;;;OAOG;IACH,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM;IACtB;;;OAGG;IACH,MAAM,EAAE,eAAe,KACpB,IAAI,CAAC;IACV;;;;OAIG;IACH,WAAW,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,OAAO;;IA4sBtE,qEAAqE;;IAErE;;;;;;;OAOG;;;;;IAEH,+DAA+D;;IAE/D;;;;;;;OAOG;;IAIH,0EAA0E;;IAE1E,6DAA6D;;IAE7D,sDAAsD;;;;uCAzDvC,MAAM;;;IAgErB,0EAA0E;qBA7nB1C,iBAAiB;IA+nBjD;;;OAGG;+BA7oBuC,OAAO;EAwqBtD"}
1
+ {"version":3,"file":"useVoiceSession.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/useVoiceSession.ts"],"names":[],"mappings":"AAUA,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEpE,OAAO,EAgBL,KAAK,oBAAoB,EAE1B,MAAM,uBAAuB,CAAC;AAsC/B;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAC5B,SAAS,GAAG,eAAe,GAAG,eAAe,GAAG,oBAAoB,CAAC;AAEvE;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;CAC7B;AAMD,UAAU,OAAO;IACf,+EAA+E;IAC/E;;;;;;;OAOG;IACH,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM;IACtB;;;OAGG;IACH,MAAM,EAAE,eAAe,KACpB,IAAI,CAAC;IACV;;;;OAIG;IACH,WAAW,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,OAAO;;IAouBtE,qEAAqE;;IAErE;;;;;;;OAOG;;;;;IAEH,+DAA+D;;IAE/D;;;;;;;OAOG;;IAIH,0EAA0E;;IAE1E,6DAA6D;;IAE7D,sDAAsD;;;;uCAzDvC,MAAM;;;IAgErB,0EAA0E;qBArpB1C,iBAAiB;IAupBjD;;;OAGG;+BArqBuC,OAAO;IAuqBjD;;;OAGG;0BApoBE,iBAAiB;EAgqB3B"}