@burdenoff/fe-libs 2026.1029.8 → 2026.1029.9

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 (35) hide show
  1. package/dist/shared/assistant/i18nManifest.d.ts +27 -0
  2. package/dist/shared/assistant/i18nManifest.js +27 -0
  3. package/dist/shared/assistant/index.d.ts +9 -0
  4. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts +11 -0
  5. package/dist/shared/assistant/ui/AIAssistantPanel.js +233 -127
  6. package/dist/shared/assistant/ui/AssistantChatArea.d.ts +13 -1
  7. package/dist/shared/assistant/ui/AssistantChatArea.js +1632 -1605
  8. package/dist/shared/assistant/ui/AssistantConversationList.d.ts +17 -1
  9. package/dist/shared/assistant/ui/AssistantConversationList.js +304 -274
  10. package/dist/shared/assistant/ui/AssistantOverlay.d.ts +11 -0
  11. package/dist/shared/assistant/ui/AssistantOverlay.js +106 -90
  12. package/dist/shared/assistant/ui/closeGuard.d.ts +21 -0
  13. package/dist/shared/assistant/ui/closeGuard.js +8 -0
  14. package/dist/shared/assistant/ui/compact/AssistantCompactHeader.d.ts +38 -0
  15. package/dist/shared/assistant/ui/compact/AssistantCompactHeader.js +89 -0
  16. package/dist/shared/assistant/ui/compact/AssistantConversationMenu.d.ts +29 -0
  17. package/dist/shared/assistant/ui/compact/AssistantConversationMenu.js +87 -0
  18. package/dist/shared/assistant/ui/compact/AssistantDiscardDraftDialog.d.ts +19 -0
  19. package/dist/shared/assistant/ui/compact/AssistantDiscardDraftDialog.js +38 -0
  20. package/dist/shared/assistant/ui/compact/AssistantMenuView.d.ts +42 -0
  21. package/dist/shared/assistant/ui/compact/AssistantMenuView.js +285 -0
  22. package/dist/shared/assistant/ui/compact/AssistantVoiceLanguageSettings.d.ts +24 -0
  23. package/dist/shared/assistant/ui/compact/AssistantVoiceLanguageSettings.js +68 -0
  24. package/dist/shared/assistant/ui/compact/AssistantWaitingChangeRow.d.ts +21 -0
  25. package/dist/shared/assistant/ui/compact/AssistantWaitingChangeRow.js +34 -0
  26. package/dist/shared/assistant/ui/compact/compactChrome.d.ts +75 -0
  27. package/dist/shared/assistant/ui/compact/compactChrome.js +39 -0
  28. package/dist/shared/assistant/ui/compact/waitingChange.d.ts +49 -0
  29. package/dist/shared/assistant/ui/compact/waitingChange.js +12 -0
  30. package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts +19 -18
  31. package/dist/shared/assistant/ui/composer/AssistantComposer.js +261 -224
  32. package/dist/shared/assistant/useAssistantKeyboardShortcuts.d.ts +16 -2
  33. package/dist/shared/assistant/useAssistantKeyboardShortcuts.js +28 -16
  34. package/dist/shared-assistant.js +42 -33
  35. package/package.json +1 -1
@@ -346,6 +346,10 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
346
346
  readonly 'chatArea.placeholderGeneral': "Ask me anything…";
347
347
  readonly 'chatInput.ariaLabel': "Message input";
348
348
  readonly 'chatInput.send': "Send message";
349
+ readonly 'closeConfirm.body': "What you typed or attached has not been sent. If you close the assistant now, it is discarded.";
350
+ readonly 'closeConfirm.discard': "Discard and close";
351
+ readonly 'closeConfirm.keep': "Keep writing";
352
+ readonly 'closeConfirm.title': "Discard your unsent message?";
349
353
  readonly 'composer.attach': "Attach files or photos";
350
354
  readonly 'composer.attachFull': "Attachment limit reached ({{max}})";
351
355
  readonly 'composer.attachSource': "Attach from";
@@ -355,6 +359,7 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
355
359
  readonly 'composer.placeholder': "Ask me anything…";
356
360
  readonly 'composer.stop': "Stop the reply";
357
361
  readonly 'composer.stopped': "Reply stopped.";
362
+ readonly 'composer.stopping': "Stopping the reply…";
358
363
  readonly 'composer.voiceStart': "Dictate a message";
359
364
  readonly 'composer.voiceStarting': "Starting the microphone — tap to cancel";
360
365
  readonly 'composer.voiceStop': "Stop dictation";
@@ -381,6 +386,8 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
381
386
  readonly 'conversationList.spokenCount': "{{count}} spoken";
382
387
  readonly 'conversationList.spokenCountOne': "1 spoken";
383
388
  readonly 'conversationList.voiceOnly': "Spoken conversation";
389
+ readonly 'conversationMenu.empty': "Nothing to export yet";
390
+ readonly 'conversationMenu.voiceTranscript': "Voice transcript";
384
391
  readonly 'conversations.archive': "Archive conversation";
385
392
  readonly 'conversations.collapse': "Collapse history";
386
393
  readonly 'conversations.collapseLabel': "Collapse";
@@ -413,13 +420,18 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
413
420
  readonly 'header.autoSpeakOn': "Read replies aloud automatically";
414
421
  readonly 'header.close': "Close assistant";
415
422
  readonly 'header.context': "Context: {{page}}";
423
+ readonly 'header.conversationOptions': "Conversation options";
416
424
  readonly 'header.dock': "Dock to side panel";
425
+ readonly 'header.expand': "Expand assistant";
426
+ readonly 'header.expandTip': "Expand";
417
427
  readonly 'header.float': "Float chat window";
418
428
  readonly 'header.history': "Conversation history";
429
+ readonly 'header.menu': "Assistant menu";
419
430
  readonly 'header.more': "More options";
420
431
  readonly 'header.newConversation': "New conversation";
421
432
  readonly 'header.preview': "Preview";
422
433
  readonly 'header.ready': "Ready";
434
+ readonly 'header.restoreSize': "Restore size";
423
435
  readonly 'header.title': "AI Assistant";
424
436
  readonly 'history.archivedNotice': "Archived. It stays out of your list until you unarchive it.";
425
437
  readonly 'history.badgeLoading': "Loading…";
@@ -493,6 +505,18 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
493
505
  readonly 'markdown.imageUnavailable': "Image unavailable";
494
506
  readonly 'markdown.showRemoteImage': "Show remote image";
495
507
  readonly 'markdown.showRemoteImageNamed': "Show image from {{host}}";
508
+ readonly 'menuView.avatar': "Avatar";
509
+ readonly 'menuView.back': "Back";
510
+ readonly 'menuView.backToConversation': "Back to conversation";
511
+ readonly 'menuView.layoutDocked': "Docked side panel";
512
+ readonly 'menuView.layoutFloating': "Floating window";
513
+ readonly 'menuView.panelLayout': "Panel layout";
514
+ readonly 'menuView.readAloud': "Read replies aloud";
515
+ readonly 'menuView.recent': "Recent";
516
+ readonly 'menuView.settings': "Settings";
517
+ readonly 'menuView.title': "Assistant menu";
518
+ readonly 'menuView.viewAllHistory': "View all history";
519
+ readonly 'menuView.voiceLanguage': "Voice & language";
496
520
  readonly 'message.copied': "Copied";
497
521
  readonly 'message.copy': "Copy message";
498
522
  readonly 'message.copyShort': "Copy";
@@ -634,6 +658,9 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
634
658
  readonly 'voiceSession.transcriptHint': "Spoken turns in this conversation — kept out of your typed chat.";
635
659
  readonly 'voiceSession.transcriptTitle': "Voice transcript";
636
660
  readonly 'voiceSession.unmute': "Turn the microphone on";
661
+ readonly 'waitingChange.review': "Review";
662
+ readonly 'waitingChange.reviewLabel': "Review the change waiting for your approval";
663
+ readonly 'waitingChange.status': "{{count}} change(s) waiting for your approval";
637
664
  readonly 'writeConsent.body': "In {{mode}} mode the assistant can read AND change your data — creating records, logging activity, updating details, and more, on your behalf.";
638
665
  readonly 'writeConsent.cancel': "Stay in {{mode}}";
639
666
  readonly 'writeConsent.confirm': "Enable {{mode}}";
@@ -239,6 +239,10 @@ var g = {
239
239
  "chatArea.placeholderGeneral": "Ask me anything…",
240
240
  "chatInput.ariaLabel": "Message input",
241
241
  "chatInput.send": "Send message",
242
+ "closeConfirm.body": "What you typed or attached has not been sent. If you close the assistant now, it is discarded.",
243
+ "closeConfirm.discard": "Discard and close",
244
+ "closeConfirm.keep": "Keep writing",
245
+ "closeConfirm.title": "Discard your unsent message?",
242
246
  "composer.attach": "Attach files or photos",
243
247
  "composer.attachFull": "Attachment limit reached ({{max}})",
244
248
  "composer.attachSource": "Attach from",
@@ -248,6 +252,7 @@ var g = {
248
252
  "composer.placeholder": "Ask me anything…",
249
253
  "composer.stop": "Stop the reply",
250
254
  "composer.stopped": "Reply stopped.",
255
+ "composer.stopping": "Stopping the reply…",
251
256
  "composer.voiceStart": "Dictate a message",
252
257
  "composer.voiceStarting": "Starting the microphone — tap to cancel",
253
258
  "composer.voiceStop": "Stop dictation",
@@ -274,6 +279,8 @@ var g = {
274
279
  "conversationList.spokenCount": "{{count}} spoken",
275
280
  "conversationList.spokenCountOne": "1 spoken",
276
281
  "conversationList.voiceOnly": "Spoken conversation",
282
+ "conversationMenu.empty": "Nothing to export yet",
283
+ "conversationMenu.voiceTranscript": "Voice transcript",
277
284
  "conversations.archive": "Archive conversation",
278
285
  "conversations.collapse": "Collapse history",
279
286
  "conversations.collapseLabel": "Collapse",
@@ -306,13 +313,18 @@ var g = {
306
313
  "header.autoSpeakOn": "Read replies aloud automatically",
307
314
  "header.close": "Close assistant",
308
315
  "header.context": "Context: {{page}}",
316
+ "header.conversationOptions": "Conversation options",
309
317
  "header.dock": "Dock to side panel",
318
+ "header.expand": "Expand assistant",
319
+ "header.expandTip": "Expand",
310
320
  "header.float": "Float chat window",
311
321
  "header.history": "Conversation history",
322
+ "header.menu": "Assistant menu",
312
323
  "header.more": "More options",
313
324
  "header.newConversation": "New conversation",
314
325
  "header.preview": "Preview",
315
326
  "header.ready": "Ready",
327
+ "header.restoreSize": "Restore size",
316
328
  "header.title": "AI Assistant",
317
329
  "history.archivedNotice": "Archived. It stays out of your list until you unarchive it.",
318
330
  "history.badgeLoading": "Loading…",
@@ -386,6 +398,18 @@ var g = {
386
398
  "markdown.imageUnavailable": "Image unavailable",
387
399
  "markdown.showRemoteImage": "Show remote image",
388
400
  "markdown.showRemoteImageNamed": "Show image from {{host}}",
401
+ "menuView.avatar": "Avatar",
402
+ "menuView.back": "Back",
403
+ "menuView.backToConversation": "Back to conversation",
404
+ "menuView.layoutDocked": "Docked side panel",
405
+ "menuView.layoutFloating": "Floating window",
406
+ "menuView.panelLayout": "Panel layout",
407
+ "menuView.readAloud": "Read replies aloud",
408
+ "menuView.recent": "Recent",
409
+ "menuView.settings": "Settings",
410
+ "menuView.title": "Assistant menu",
411
+ "menuView.viewAllHistory": "View all history",
412
+ "menuView.voiceLanguage": "Voice & language",
389
413
  "message.copied": "Copied",
390
414
  "message.copy": "Copy message",
391
415
  "message.copyShort": "Copy",
@@ -527,6 +551,9 @@ var g = {
527
551
  "voiceSession.transcriptHint": "Spoken turns in this conversation — kept out of your typed chat.",
528
552
  "voiceSession.transcriptTitle": "Voice transcript",
529
553
  "voiceSession.unmute": "Turn the microphone on",
554
+ "waitingChange.review": "Review",
555
+ "waitingChange.reviewLabel": "Review the change waiting for your approval",
556
+ "waitingChange.status": "{{count}} change(s) waiting for your approval",
530
557
  "writeConsent.body": "In {{mode}} mode the assistant can read AND change your data — creating records, logging activity, updating details, and more, on your behalf.",
531
558
  "writeConsent.cancel": "Stay in {{mode}}",
532
559
  "writeConsent.confirm": "Enable {{mode}}",
@@ -372,3 +372,12 @@ export * from './voice/livePhraseSpeech';
372
372
  export * from './voice/phrasePlayback';
373
373
  export * from './attachmentAccess';
374
374
  export * from './attachmentAccessCopy';
375
+ export * from './ui/closeGuard';
376
+ export * from './ui/compact/compactChrome';
377
+ export * from './ui/compact/AssistantCompactHeader';
378
+ export * from './ui/compact/AssistantConversationMenu';
379
+ export * from './ui/compact/AssistantDiscardDraftDialog';
380
+ export * from './ui/compact/AssistantMenuView';
381
+ export * from './ui/compact/AssistantVoiceLanguageSettings';
382
+ export * from './ui/compact/AssistantWaitingChangeRow';
383
+ export * from './ui/compact/waitingChange';
@@ -113,6 +113,17 @@ export type AIAssistantPanelProps = PanelProps & {
113
113
  * `panelProps`, behind its own flag.
114
114
  */
115
115
  presentation?: AssistantPresentation;
116
+ /**
117
+ * BOFF-10177 (compact only): told when the person presses Expand or Restore,
118
+ * and when the expansion ends under them (the viewport fell under the width
119
+ * that offers it, or the panel unmounted). The panel itself changes no width:
120
+ * that is the host's geometry (N2: a fixed 760 px), which reads this and the
121
+ * root's `data-assistant-expanded`.
122
+ *
123
+ * ★ Expand/Restore is OFFERED only while this is given, and only from 1536 px:
124
+ * without a host that honours it the control would do nothing.
125
+ */
126
+ onExpandedChange?: (expanded: boolean) => void;
116
127
  };
117
128
  /**
118
129
  * The panel.
@@ -1,161 +1,267 @@
1
1
  import { useReturnFocus as e } from "../../hooks/useReturnFocus.js";
2
2
  import { useAssistantControl as t } from "../appControls/useAssistantControl.js";
3
3
  import { useAssistantPageLabel as ee } from "../product.js";
4
- import { useAssistantTr as n } from "../i18n.js";
5
- import { useAssistantStore as r } from "../store.js";
6
- import { AssistantSpeechProvider as i } from "./AssistantSpeechProvider.js";
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 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";
4
+ import { useAssistantTr as te } from "../i18n.js";
5
+ import { useAssistantStore as ne } from "../store.js";
6
+ import { AssistantSpeechProvider as re } from "./AssistantSpeechProvider.js";
7
+ import { ASSISTANT_OVERLAY_ATTR as ie, ASSISTANT_PANEL_ATTR as ae, activePanelOverlay as oe, escapeDismisses as se, nextPanelOverlays as ce } from "./panelOverlays.js";
8
+ import { LiveAvatarSeamProvider as le, LiveAvatarTabContext as ue, useLiveAvatarSpeechEngine as de, useLiveAvatarTabOffered as fe } from "./assistantLiveAvatarSeam.js";
9
+ import { AssistantPreviewProvider as pe } from "../preview/context.js";
10
+ import { useAssistantPreviewBridge as me } from "../preview/useAssistantPreviewBridge.js";
11
+ import { AssistantConnectSourceProvider as he } from "./composer/connectSource.js";
12
+ import { hasAssistantPreviewSurface as ge } from "../preview/types.js";
13
+ import { panelOwnedPreviewBridge as _e, useHostedAssistantPreviewBridge as ve } from "../preview/bridgeHostContext.js";
14
+ import { AssistantPreviewOverlay as ye } from "../preview/AssistantPreviewOverlay.js";
15
+ import { AssistantHeader as be } from "./AssistantHeader.js";
16
+ import { AssistantConversationList as xe } from "./AssistantConversationList.js";
17
+ import { AssistantConversationDeleteDialogProvider as Se } from "./conversationDeleteDialog.js";
18
+ import { AssistantControlConfirmProvider as Ce } from "./controlConfirmDialog.js";
19
+ import { AssistantLeaveConfirmNavigateProvider as we } from "./leaveConfirm.js";
20
+ import { useAssistantServerHistory as Te } from "../history/useAssistantServerHistory.js";
21
+ import { useFilesServiceWarmup as Ee } from "../../../storage/warmFilesService.js";
22
+ import { AssistantAvatarTabs as De } from "./AssistantAvatarTabs.js";
23
+ import { useAssistantHeartbeat as Oe } from "../useAssistantHeartbeat.js";
24
+ import { useAssistantKeyboardShortcuts as ke } from "../useAssistantKeyboardShortcuts.js";
25
+ import { closeRequestAction as Ae, useCompactExpandOffered as je } from "./compact/compactChrome.js";
26
+ import { AssistantChatArea as Me } from "./AssistantChatArea.js";
27
+ import { useAssistantCloseGuardRegistration as Ne } from "./closeGuard.js";
28
+ import { AssistantCompactHeader as Pe } from "./compact/AssistantCompactHeader.js";
29
+ import { AssistantConversationMenu as Fe } from "./compact/AssistantConversationMenu.js";
30
+ import { AssistantDiscardDraftDialog as Ie } from "./compact/AssistantDiscardDraftDialog.js";
31
+ import { AssistantMenuView as Le } from "./compact/AssistantMenuView.js";
32
+ import { useCallback as n, useEffect as r, useId as Re, useMemo as i, useRef as a, useState as o } from "react";
33
+ import { Fragment as ze, jsx as s, jsxs as c } from "react/jsx-runtime";
28
34
  //#region src/shared/assistant/ui/AIAssistantPanel.tsx
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
- P && !I && F(!1);
34
- let L = P && I;
35
- ie(se(O, ce()));
36
- let R = h(null);
37
- e(R);
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
- chatTab: `${K}-chat-tab`,
42
- avatarTab: `${K}-avatar-tab`,
43
- chatPanel: `${K}-chat-panel`,
44
- avatarPanel: `${K}-avatar-panel`,
45
- leaveHint: `${K}-avatar-leave`
46
- } : null, [G, K]), J = f(() => W(!1), []), Y = h(null), X = f((e) => {
47
- Y.current = e;
48
- }, []), Te = m(() => ({
49
- open: U,
50
- close: J,
51
- ids: q,
52
- covered: V,
53
- setReplyEscape: X
35
+ var l = ({ onClose: l, visible: u, docked: d, onToggleDock: f, writeAccess: Be, onNavigate: Ve, isShellLessTarget: He, connectSourceHref: Ue, onConnectSource: We, preview: p, liveAvatar: m, presentation: h, onExpandedChange: g, serverHistory: Ge = !1 }) => {
36
+ let Ke = te(), qe = de(m);
37
+ Te(Ge);
38
+ let [_, v] = o(!1), y = ge(p);
39
+ _ && !y && v(!1);
40
+ let b = _ && y;
41
+ me(_e(p, ve()));
42
+ let x = a(null);
43
+ e(x);
44
+ let { conversations: Je, activeConversationId: Ye, conversationListOpen: S, setConversationListOpen: C, createConversation: w } = ne(), T = h === "compact", [E, D] = o(!1), O = a(!1);
45
+ E && (!T || S || b) && D(!1);
46
+ let k = T && E, [Xe, A] = o(!1), j = je(T && g !== void 0), [M, N] = o(!1), P = j && M;
47
+ r(() => {
48
+ M && !j && (N(!1), g?.(!1));
49
+ }, [
50
+ M,
51
+ j,
52
+ g
53
+ ]);
54
+ let Ze = () => {
55
+ let e = !P;
56
+ N(e), g?.(e);
57
+ }, F = a(!1), I = a(g);
58
+ r(() => {
59
+ F.current = P, I.current = g;
60
+ }), r(() => () => {
61
+ F.current && I.current?.(!1);
62
+ }, []);
63
+ let L = S || b || k, R = m?.tab, Qe = fe(R), [z, B] = o(!1);
64
+ z && (!R || u === !1) && B(!1);
65
+ let V = R !== void 0 && (Qe || z), H = Re(), $e = Re(), U = i(() => V ? {
66
+ chatTab: `${H}-chat-tab`,
67
+ avatarTab: `${H}-avatar-tab`,
68
+ chatPanel: `${H}-chat-panel`,
69
+ avatarPanel: `${H}-avatar-panel`,
70
+ leaveHint: `${H}-avatar-leave`
71
+ } : null, [V, H]), et = n(() => B(!1), []), W = a(null), tt = n((e) => {
72
+ W.current = e;
73
+ }, []), nt = i(() => ({
74
+ open: z,
75
+ close: et,
76
+ ids: U,
77
+ covered: L,
78
+ setReplyEscape: tt
54
79
  }), [
80
+ z,
81
+ et,
55
82
  U,
56
- J,
57
- q,
58
- V,
59
- X
60
- ]), Ee = (e) => W(e === "avatar"), Z = s({
61
- historyOpen: z,
62
- previewOpen: L,
63
- avatarOpen: U
64
- }), Q = (e) => {
65
- let t = l({
66
- historyOpen: z,
67
- previewOpen: L
83
+ L,
84
+ tt
85
+ ]), rt = (e) => B(e === "avatar"), it = () => {
86
+ D(!1), rt("avatar"), O.current = !0;
87
+ }, at = oe({
88
+ historyOpen: S,
89
+ previewOpen: b,
90
+ avatarOpen: z
91
+ }) ?? (k ? "menu" : null), G = (e) => {
92
+ let t = ce({
93
+ historyOpen: S,
94
+ previewOpen: b
68
95
  }, e);
69
- B(t.historyOpen), F(t.previewOpen);
96
+ C(t.historyOpen), v(t.previewOpen);
70
97
  };
71
- t("assistant.history", m(() => ({ run: () => z ? { status: "already" } : (B(!0), F(!1), { status: "done" }) }), [z, B])), t("assistant.preview", m(() => I ? {
98
+ t("assistant.history", i(() => ({ run: () => S ? { status: "already" } : (C(!0), v(!1), { status: "done" }) }), [S, C])), t("assistant.preview", i(() => y ? {
72
99
  surface: "panel",
73
- run: () => L ? { status: "already" } : (B(!1), F(!0), { status: "done" }),
74
- close: () => L ? (F(!1), { status: "done" }) : { status: "already" }
100
+ run: () => b ? { status: "already" } : (C(!1), v(!0), { status: "done" }),
101
+ close: () => b ? (v(!1), { status: "done" }) : { status: "already" }
75
102
  } : null, [
76
- I,
77
- L,
78
- B
103
+ y,
104
+ b,
105
+ C
79
106
  ]));
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
- panelRef: R,
107
+ let ot = Je.find((e) => e.id === Ye);
108
+ Oe(ot?.backendSessionId ?? null, ot?.mode ?? null, u ?? !0), Ee(u ?? !0);
109
+ let st = ee(u !== !1), K = Ne(), q = a(!1), ct = n((e) => {
110
+ q.current = e;
111
+ }, []), J = a(!1), [lt, Y] = o(!1), X = n(() => Ae({
112
+ compact: T,
113
+ unsent: q.current,
114
+ confirmed: J.current
115
+ }) === "close" ? !1 : (Y(!0), !0), [T]);
116
+ r(() => {
117
+ if (!(!T || !K)) return K(X);
118
+ }, [
119
+ T,
120
+ K,
121
+ X
122
+ ]);
123
+ let Z = n(() => {
124
+ X() || l();
125
+ }, [X, l]), ut = () => {
126
+ J.current = !0, q.current = !1, Y(!1);
127
+ try {
128
+ l();
129
+ } finally {
130
+ J.current = !1;
131
+ }
132
+ }, Q = a(null), dt = a(null), ft = a(null), pt = n(() => D(!1), []), [mt, ht] = o(0), gt = n(() => {
133
+ w(), D(!1), C(!1), ht((e) => e + 1);
134
+ }, [w, C]), _t = n(() => {
135
+ D(!1), A(!0);
136
+ }, []), $ = a(!1);
137
+ return r(() => {
138
+ if ($.current && !k) {
139
+ let e = document.activeElement;
140
+ (!e || e === document.body || e === x.current) && dt.current?.focus({ preventScroll: !0 });
141
+ }
142
+ $.current = k;
143
+ }, [k]), r(() => {
144
+ mt > 0 && Q.current?.focus({ preventScroll: !0 });
145
+ }, [mt]), r(() => {
146
+ !O.current || !z || !U || (O.current = !1, document.getElementById(U.avatarTab)?.focus({ preventScroll: !0 }));
147
+ }, [z, U]), ke({
148
+ panelRef: x,
149
+ inputRef: T ? Q : void 0,
150
+ onNewConversation: T ? gt : void 0,
151
+ onOpenConversationMenu: T ? _t : void 0,
85
152
  onClose: () => {
86
- let e = c({
87
- historyOpen: z,
88
- previewOpen: L,
89
- avatarOpen: U,
90
- tabReplySpeaking: Y.current !== null
153
+ let e = se({
154
+ historyOpen: S,
155
+ previewOpen: b,
156
+ avatarOpen: z,
157
+ tabReplySpeaking: W.current !== null
91
158
  });
92
159
  if (e === "overlay") {
93
- B(!1), F(!1);
160
+ C(!1), v(!1);
94
161
  return;
95
162
  }
96
163
  if (e === "tab-reply") {
97
- Y.current?.();
164
+ W.current?.();
98
165
  return;
99
166
  }
100
167
  if (e === "tab") {
101
- W(!1), q && document.getElementById(q.chatTab)?.focus();
168
+ B(!1), U && document.getElementById(U.chatTab)?.focus();
169
+ return;
170
+ }
171
+ if (k) {
172
+ D(!1);
102
173
  return;
103
174
  }
104
- y();
175
+ Z();
105
176
  }
106
- }), /* @__PURE__ */ _(i, {
107
- visible: b ?? !0,
108
- engine: N,
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
- ref: R,
177
+ }), /* @__PURE__ */ s(re, {
178
+ visible: u ?? !0,
179
+ engine: qe,
180
+ children: /* @__PURE__ */ s(le, {
181
+ value: m,
182
+ children: /* @__PURE__ */ s(ue.Provider, {
183
+ value: nt,
184
+ children: /* @__PURE__ */ s(pe, {
185
+ value: p,
186
+ children: /* @__PURE__ */ s(we, {
187
+ navigate: Ve,
188
+ isShellLessTarget: He,
189
+ children: /* @__PURE__ */ s(he, {
190
+ value: Ue,
191
+ onOpen: We,
192
+ children: /* @__PURE__ */ s(Se, { children: /* @__PURE__ */ s(Ce, { children: /* @__PURE__ */ c("div", {
193
+ ref: x,
123
194
  className: "relative flex h-full w-full flex-col bg-bg-surface",
124
195
  role: "complementary",
125
- "aria-label": M("panel.ariaLabel", "AI Assistant"),
196
+ "aria-label": Ke("panel.ariaLabel", "AI Assistant"),
126
197
  "data-testid": "ai-assistant-panel",
127
- [o]: "",
128
- ...Z ? { [a]: Z } : {},
198
+ [ae]: "",
199
+ ...at ? { [ie]: at } : {},
200
+ ...T ? {
201
+ "data-presentation": "compact",
202
+ ...P ? { "data-assistant-expanded": "" } : {}
203
+ } : {},
129
204
  tabIndex: -1,
130
205
  children: [
131
- /* @__PURE__ */ v("div", {
206
+ /* @__PURE__ */ c("div", {
132
207
  className: "contents",
133
- inert: V || void 0,
134
- children: [/* @__PURE__ */ _(ue, {
135
- contextLabel: De,
136
- onNewConversation: () => Ce(),
137
- onOpenHistory: () => Q("history"),
138
- historyOpen: z,
139
- onTogglePreview: () => Q("preview"),
140
- previewOpen: L,
141
- onClose: y,
142
- docked: x,
143
- onToggleDock: S
144
- }), q ? /* @__PURE__ */ _(_e, {
145
- selected: U ? "avatar" : "chat",
146
- onSelect: Ee,
147
- ids: q
208
+ inert: L || void 0,
209
+ children: [T ? /* @__PURE__ */ c(ze, { children: [/* @__PURE__ */ s(Pe, {
210
+ contextLabel: st,
211
+ menuOpen: k,
212
+ menuViewId: $e,
213
+ onOpenMenu: () => D(!0),
214
+ menuButtonRef: dt,
215
+ conversationMenu: /* @__PURE__ */ s(Fe, {
216
+ open: Xe,
217
+ onOpenChange: A,
218
+ triggerRef: ft
219
+ }),
220
+ expandOffered: j,
221
+ expanded: P,
222
+ onToggleExpanded: Ze,
223
+ onTogglePreview: () => G("preview"),
224
+ previewOpen: b,
225
+ onClose: Z
226
+ }), /* @__PURE__ */ s(Ie, {
227
+ open: lt,
228
+ onKeep: () => Y(!1),
229
+ onDiscard: ut
230
+ })] }) : /* @__PURE__ */ s(be, {
231
+ contextLabel: st,
232
+ onNewConversation: () => w(),
233
+ onOpenHistory: () => G("history"),
234
+ historyOpen: S,
235
+ onTogglePreview: () => G("preview"),
236
+ previewOpen: b,
237
+ onClose: l,
238
+ docked: d,
239
+ onToggleDock: f
240
+ }), U ? /* @__PURE__ */ s(De, {
241
+ selected: z ? "avatar" : "chat",
242
+ onSelect: rt,
243
+ ids: U
148
244
  }) : null]
149
245
  }),
150
- z && /* @__PURE__ */ _(de, {}),
151
- L && /* @__PURE__ */ _(le, { onClose: () => F(!1) }),
152
- /* @__PURE__ */ _("div", {
246
+ S ? /* @__PURE__ */ s(xe, { presentation: h }) : k ? /* @__PURE__ */ s(Le, {
247
+ id: $e,
248
+ onClose: pt,
249
+ onRequestClosePanel: Z,
250
+ onNewConversation: gt,
251
+ onOpenAvatar: V ? it : void 0,
252
+ docked: d,
253
+ onToggleDock: f
254
+ }) : null,
255
+ b && /* @__PURE__ */ s(ye, { onClose: () => v(!1) }),
256
+ /* @__PURE__ */ s("div", {
153
257
  className: "contents",
154
- inert: V || void 0,
155
- children: /* @__PURE__ */ _(be, {
156
- visible: b ?? !0,
157
- writeAccess: C,
158
- presentation: A
258
+ inert: L || void 0,
259
+ children: /* @__PURE__ */ s(Me, {
260
+ visible: u ?? !0,
261
+ writeAccess: Be,
262
+ presentation: h,
263
+ inputRef: T ? Q : void 0,
264
+ onDraftDirtyChange: T ? ct : void 0
159
265
  })
160
266
  })
161
267
  ]
@@ -168,4 +274,4 @@ var y = ({ onClose: y, visible: b, docked: x, onToggleDock: S, writeAccess: C, o
168
274
  });
169
275
  };
170
276
  //#endregion
171
- export { y as AIAssistantPanel };
277
+ export { l as AIAssistantPanel };
@@ -1,4 +1,4 @@
1
- import { FC } from 'react';
1
+ import { FC, Ref } from 'react';
2
2
  import { AssistantPresentation } from './composer/AssistantComposer';
3
3
  import { WorkspaceWriteAccess } from '../useWorkspaceWriteAccess';
4
4
  /**
@@ -28,5 +28,17 @@ export interface AssistantChatAreaProps {
28
28
  * and the mode-switch confirmation. Absent or `classic`: as before.
29
29
  */
30
30
  presentation?: AssistantPresentation;
31
+ /**
32
+ * BOFF-10177 (compact only): the message box, for the panel's `/` shortcut.
33
+ * Read by the compact composer alone.
34
+ */
35
+ inputRef?: Ref<HTMLTextAreaElement>;
36
+ /**
37
+ * BOFF-10177 (N1, compact only): told whenever the composer's draft becomes
38
+ * unsent text or attachments, or stops being so. The draft is composer-local
39
+ * state, so this is the panel's only way to ask Close's question without
40
+ * lifting it. Absent: nothing is reported.
41
+ */
42
+ onDraftDirtyChange?: (dirty: boolean) => void;
31
43
  }
32
44
  export declare const AssistantChatArea: FC<AssistantChatAreaProps>;