@burdenoff/fe-libs 2026.904.23 → 2026.904.24

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 (34) hide show
  1. package/dist/shared/assistant/env.d.ts +10 -0
  2. package/dist/shared/assistant/env.d.ts.map +1 -0
  3. package/dist/shared/assistant/env.js +6 -0
  4. package/dist/shared/assistant/index.d.ts +6 -0
  5. package/dist/shared/assistant/index.d.ts.map +1 -1
  6. package/dist/shared/assistant/product.d.ts +38 -1
  7. package/dist/shared/assistant/product.d.ts.map +1 -1
  8. package/dist/shared/assistant/product.js +12 -6
  9. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts +26 -0
  10. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts.map +1 -0
  11. package/dist/shared/assistant/ui/AIAssistantPanel.js +61 -0
  12. package/dist/shared/assistant/ui/AssistantApiCallsConsentDialog.d.ts +25 -0
  13. package/dist/shared/assistant/ui/AssistantApiCallsConsentDialog.d.ts.map +1 -0
  14. package/dist/shared/assistant/ui/AssistantApiCallsConsentDialog.js +31 -0
  15. package/dist/shared/assistant/ui/AssistantChatArea.d.ts +27 -0
  16. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -0
  17. package/dist/shared/assistant/ui/AssistantChatArea.js +461 -0
  18. package/dist/shared/assistant/ui/AssistantHeader.d.ts +9 -1
  19. package/dist/shared/assistant/ui/AssistantHeader.d.ts.map +1 -1
  20. package/dist/shared/assistant/ui/AssistantHeader.js +37 -41
  21. package/dist/shared/assistant/useAssistantHeartbeat.d.ts +14 -0
  22. package/dist/shared/assistant/useAssistantHeartbeat.d.ts.map +1 -0
  23. package/dist/shared/assistant/useAssistantHeartbeat.js +38 -0
  24. package/dist/shared/assistant/useAssistantKeyboardShortcuts.d.ts +24 -0
  25. package/dist/shared/assistant/useAssistantKeyboardShortcuts.d.ts.map +1 -0
  26. package/dist/shared/assistant/useAssistantKeyboardShortcuts.js +35 -0
  27. package/dist/shared-assistant.js +7 -1
  28. package/dist/ui/index.d.ts +1 -0
  29. package/dist/ui/index.d.ts.map +1 -1
  30. package/dist/ui/modal-shell.d.ts +22 -0
  31. package/dist/ui/modal-shell.d.ts.map +1 -0
  32. package/dist/ui/modal-shell.js +30 -0
  33. package/dist/ui.js +2 -1
  34. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Which environment the app is running in, as the sandbox image tag needs it.
3
+ *
4
+ * ★ Generic, not a product answer: every consumer's Vite build defines
5
+ * `VITE_APP_ENV`. `images.ts` deliberately takes `isProd` as an argument so a
6
+ * product CAN pin it; this is the default for the common case, so the panel
7
+ * needs no seam field for something the environment already knows.
8
+ */
9
+ export declare function isProdRuntime(): boolean;
10
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/env.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC"}
@@ -0,0 +1,6 @@
1
+ //#region src/shared/assistant/env.ts
2
+ function e() {
3
+ return !1;
4
+ }
5
+ //#endregion
6
+ export { e as isProdRuntime };
@@ -116,4 +116,10 @@ export * from './useWorkspaceWriteAccess';
116
116
  export * from './documentExtract';
117
117
  export * from './useAssistantAttachments';
118
118
  export * from './ui/composer/AssistantComposer';
119
+ export * from './env';
120
+ export * from './useAssistantHeartbeat';
121
+ export * from './useAssistantKeyboardShortcuts';
122
+ export * from './ui/AssistantApiCallsConsentDialog';
123
+ export * from './ui/AssistantChatArea';
124
+ export * from './ui/AIAssistantPanel';
119
125
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { AssistantModeConfig } from './conversation';
3
+ import { AssistantMode, PageContext } from './types';
3
4
  /**
4
5
  * What a product tells the shared assistant about ITSELF.
5
6
  *
@@ -39,6 +40,42 @@ export interface AssistantProductCapabilities {
39
40
  * a wrong answer is worse than none.
40
41
  */
41
42
  describeCurrentPage?: () => string | null;
43
+ /**
44
+ * Where the user is, as the AGENT's context — structured, not a label.
45
+ *
46
+ * Resolving a route to an entity is deep product knowledge and a wrong entity
47
+ * is worse than none, so a product with no route model omits this and the turn
48
+ * simply carries no page context. The same field already exists on
49
+ * `SandboxAssistantConfig` for the transport; this is the panel's half.
50
+ */
51
+ gatherPageContext?: () => PageContext;
52
+ /**
53
+ * The product's system preamble, wrapped around what the user typed.
54
+ *
55
+ * Irreducible: HealthyBowl tells the agent it is an agronomy assistant;
56
+ * another product would say something else entirely. Any shared default is
57
+ * one product's voice imposed on the rest, so when absent the user's text is
58
+ * sent unwrapped.
59
+ */
60
+ buildPrompt?: (mode: AssistantMode, content: string, languageName?: string, isExplicitChoice?: boolean, dictated?: boolean) => string;
61
+ /**
62
+ * Record what a turn cost, against the product's own billing.
63
+ *
64
+ * ★ Irreducible because the MUTATION differs — `reportHealthyBowlAiTokenUsage`
65
+ * against the transport's `reportAiTokenUsage`. Different backend paths
66
+ * writing different rows, so defaulting to either silently bills the wrong
67
+ * ledger. Absent means the product does not meter, which is a real choice.
68
+ */
69
+ reportTokenUsage?: (usage: {
70
+ workspaceId: string;
71
+ sessionId: string;
72
+ messageId?: string;
73
+ model?: string;
74
+ tokens: {
75
+ input: number;
76
+ output: number;
77
+ };
78
+ }) => Promise<void>;
42
79
  }
43
80
  export interface AssistantProductValue extends AssistantProductCapabilities {
44
81
  /**
@@ -56,7 +93,7 @@ export interface AssistantProductProviderProps extends AssistantProductCapabilit
56
93
  * Mount once, above the assistant. Everything below can ask what product it is
57
94
  * running inside and what that product offers.
58
95
  */
59
- export declare function AssistantProductProvider({ product, modes, describeCurrentPage, children, }: AssistantProductProviderProps): import("react/jsx-runtime").JSX.Element;
96
+ export declare function AssistantProductProvider({ product, modes, describeCurrentPage, gatherPageContext, buildPrompt, reportTokenUsage, children, }: AssistantProductProviderProps): import("react/jsx-runtime").JSX.Element;
60
97
  /** The product in force, or null when no provider is mounted. */
61
98
  export declare function useAssistantProductOrNull(): AssistantProductValue | null;
62
99
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/product.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;;;OAMG;IACH,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACtC;;;;;;;;OAQG;IACH,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAsB,SAAQ,4BAA4B;IACzE;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,MAAM,WAAW,6BAA8B,SAAQ,4BAA4B;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,KAAK,EACL,mBAAmB,EACnB,QAAQ,GACT,EAAE,6BAA6B,2CAU/B;AAED,iEAAiE;AACjE,wBAAgB,yBAAyB,IAAI,qBAAqB,GAAG,IAAI,CAExE;AAID;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,qBAAqB,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,mBAAmB,EAAE,EACrC,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,mBAAmB,GAAG,SAAS,CAEjC"}
1
+ {"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/product.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;;;OAMG;IACH,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACtC;;;;;;;;OAQG;IACH,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC1C;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,MAAM,WAAW,CAAC;IACtC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,CACZ,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,gBAAgB,CAAC,EAAE,OAAO,EAC1B,QAAQ,CAAC,EAAE,OAAO,KACf,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3C,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,qBAAsB,SAAQ,4BAA4B;IACzE;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,MAAM,WAAW,6BAA8B,SAAQ,4BAA4B;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,KAAK,EACL,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,gBAAgB,EAChB,QAAQ,GACT,EAAE,6BAA6B,2CAe/B;AAED,iEAAiE;AACjE,wBAAgB,yBAAyB,IAAI,qBAAqB,GAAG,IAAI,CAExE;AAID;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,qBAAqB,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,mBAAmB,EAAE,EACrC,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,mBAAmB,GAAG,SAAS,CAEjC"}
@@ -2,19 +2,25 @@ import { createContext as e, useContext as t, useMemo as n } from "react";
2
2
  import { jsx as r } from "react/jsx-runtime";
3
3
  //#region src/shared/assistant/product.tsx
4
4
  var i = e(null);
5
- function a({ product: e, modes: t, describeCurrentPage: a, children: o }) {
6
- let s = n(() => ({
5
+ function a({ product: e, modes: t, describeCurrentPage: a, gatherPageContext: o, buildPrompt: s, reportTokenUsage: c, children: l }) {
6
+ let u = n(() => ({
7
7
  product: e,
8
8
  modes: t,
9
- describeCurrentPage: a
9
+ describeCurrentPage: a,
10
+ gatherPageContext: o,
11
+ buildPrompt: s,
12
+ reportTokenUsage: c
10
13
  }), [
11
14
  e,
12
15
  t,
13
- a
16
+ a,
17
+ o,
18
+ s,
19
+ c
14
20
  ]);
15
21
  return /* @__PURE__ */ r(i.Provider, {
16
- value: s,
17
- children: o
22
+ value: u,
23
+ children: l
18
24
  });
19
25
  }
20
26
  function o() {
@@ -0,0 +1,26 @@
1
+ import { FC } from 'react';
2
+ import { PanelProps } from '../../plugins/types';
3
+ import { WorkspaceWriteAccess } from '../useWorkspaceWriteAccess';
4
+ export type AIAssistantPanelProps = PanelProps & {
5
+ /** When provided, renders a dock/float toggle in the header. */
6
+ docked?: boolean;
7
+ onToggleDock?: () => void;
8
+ /**
9
+ * Whether this actor may write in this workspace — see `AssistantChatArea`.
10
+ *
11
+ * Threaded through rather than resolved here: only the product knows which
12
+ * resource types to probe, so it calls `useWorkspaceWriteAccess` itself. Omit
13
+ * it and the panel simply never claims a write will be refused.
14
+ */
15
+ writeAccess?: WorkspaceWriteAccess;
16
+ };
17
+ /**
18
+ * The panel.
19
+ *
20
+ * ★ Mount it inside an `AssistantProductProvider`. It is exported WITHOUT one
21
+ * wrapped around it, deliberately: a provider baked in here could only carry one
22
+ * product's modes and page vocabulary, which is precisely the coupling this
23
+ * migration removed. The product supplies the provider; this renders inside it.
24
+ */
25
+ export declare const AIAssistantPanel: FC<AIAssistantPanelProps>;
26
+ //# sourceMappingURL=AIAssistantPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AIAssistantPanel.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AIAssistantPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAMtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAgBvE,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG;IAC/C,gEAAgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,oBAAoB,CAAC;CACpC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAgHtD,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { useAssistantProduct as e } from "../product.js";
2
+ import { useAssistantTr as t } from "../i18n.js";
3
+ import { useAssistantStore as n } from "../store.js";
4
+ import { AssistantSpeechProvider as r } from "./AssistantSpeechProvider.js";
5
+ import { AssistantHeader as i } from "./AssistantHeader.js";
6
+ import { AssistantConversationList as a } from "./AssistantConversationList.js";
7
+ import { useFilesServiceWarmup as o } from "../../../storage/warmFilesService.js";
8
+ import { useAssistantHeartbeat as s } from "../useAssistantHeartbeat.js";
9
+ import { useAssistantKeyboardShortcuts as c } from "../useAssistantKeyboardShortcuts.js";
10
+ import { AssistantChatArea as l } from "./AssistantChatArea.js";
11
+ import { useEffect as u, useRef as d, useState as f } from "react";
12
+ import { jsx as p, jsxs as m } from "react/jsx-runtime";
13
+ //#region src/shared/assistant/ui/AIAssistantPanel.tsx
14
+ var h = 1e3, g = ({ onClose: g, visible: _, docked: v, onToggleDock: y, writeAccess: b }) => {
15
+ let x = t(), { describeCurrentPage: S } = e(), C = d(null), { conversations: w, activeConversationId: T, conversationListOpen: E, toggleConversationList: D, createConversation: O } = n(), k = w.find((e) => e.id === T);
16
+ s(k?.backendSessionId ?? null, k?.mode ?? null, _ ?? !0), o(_ ?? !0);
17
+ let [A, j] = f(() => S?.() ?? null);
18
+ return u(() => {
19
+ if (_ === !1) return;
20
+ let e = () => j((e) => {
21
+ let t = S?.() ?? null;
22
+ return t === e ? e : t;
23
+ });
24
+ e(), window.addEventListener("popstate", e);
25
+ let t = window.setInterval(e, h);
26
+ return () => {
27
+ window.removeEventListener("popstate", e), window.clearInterval(t);
28
+ };
29
+ }, [_, S]), c({
30
+ panelRef: C,
31
+ onClose: g
32
+ }), /* @__PURE__ */ p(r, {
33
+ visible: _ ?? !0,
34
+ children: /* @__PURE__ */ m("div", {
35
+ ref: C,
36
+ className: "relative flex h-full w-full flex-col bg-bg-surface",
37
+ role: "complementary",
38
+ "aria-label": x("panel.ariaLabel", "AI Assistant"),
39
+ "data-testid": "ai-assistant-panel",
40
+ tabIndex: -1,
41
+ children: [
42
+ /* @__PURE__ */ p(i, {
43
+ contextLabel: A,
44
+ onNewConversation: () => O(),
45
+ onOpenHistory: D,
46
+ historyOpen: E,
47
+ onClose: g,
48
+ docked: v,
49
+ onToggleDock: y
50
+ }),
51
+ E && /* @__PURE__ */ p(a, {}),
52
+ /* @__PURE__ */ p(l, {
53
+ visible: _ ?? !0,
54
+ writeAccess: b
55
+ })
56
+ ]
57
+ })
58
+ });
59
+ };
60
+ //#endregion
61
+ export { g as AIAssistantPanel };
@@ -0,0 +1,25 @@
1
+ import { FC } from 'react';
2
+ interface Props {
3
+ open: boolean;
4
+ onConfirm: () => void;
5
+ onCancel: () => void;
6
+ }
7
+ /**
8
+ * One-time consent shown the first time a user switches the assistant into the
9
+ * write-capable `api-calls` ("Take action") mode.
10
+ *
11
+ * This is the DEPENDABLE guardrail: the in-sandbox agent executes mutations
12
+ * autonomously, so a host-side acknowledgement (plus the soft
13
+ * describe-and-confirm prompt preamble) is the FE's strongest lever short of an
14
+ * agent-side hard confirm. The ack is persisted per-profile in the assistant
15
+ * store, so this shows once rather than on every switch.
16
+ *
17
+ * ★ The English fallbacks name NO product. They used to say "your HealthyBowl
18
+ * data", which was correct in exactly one product and a lie in every other —
19
+ * and a fallback is what renders wherever the key has not been seeded, which
20
+ * today is most locales. A product wanting its own name here supplies it through
21
+ * `<product>.assistant.apiCalls.*`, which is the mechanism that already exists.
22
+ */
23
+ export declare const AssistantApiCallsConsentDialog: FC<Props>;
24
+ export {};
25
+ //# sourceMappingURL=AssistantApiCallsConsentDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssistantApiCallsConsentDialog.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantApiCallsConsentDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAMhC,UAAU,KAAK;IACb,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,8BAA8B,EAAE,EAAE,CAAC,KAAK,CA4CpD,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { Button as e } from "../../../ui/button.js";
2
+ import { ModalShell as t } from "../../../ui/modal-shell.js";
3
+ import { useAssistantTr as n } from "../i18n.js";
4
+ import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
5
+ //#region src/shared/assistant/ui/AssistantApiCallsConsentDialog.tsx
6
+ var o = ({ open: o, onConfirm: s, onCancel: c }) => {
7
+ let l = n();
8
+ return /* @__PURE__ */ i(t, {
9
+ open: o,
10
+ onClose: c,
11
+ size: "sm",
12
+ title: l("apiCalls.consentTitle", "Switch to Take action mode?"),
13
+ footer: /* @__PURE__ */ a(r, { children: [/* @__PURE__ */ i(e, {
14
+ variant: "outline",
15
+ onClick: c,
16
+ "data-testid": "assistant-api-calls-consent-cancel",
17
+ children: l("apiCalls.consentCancel", "Stay in Ask")
18
+ }), /* @__PURE__ */ i(e, {
19
+ variant: "default",
20
+ onClick: s,
21
+ "data-testid": "assistant-api-calls-consent-confirm",
22
+ children: l("apiCalls.consentConfirm", "Enable Take action")
23
+ })] }),
24
+ children: /* @__PURE__ */ a("div", {
25
+ className: "space-y-2 text-sm text-text-secondary",
26
+ children: [/* @__PURE__ */ i("p", { children: l("apiCalls.consentBody", "In Take action mode the assistant can read AND change your data — creating records, logging activity, updating details, and more, on your behalf.") }), /* @__PURE__ */ i("p", { children: l("apiCalls.consentBody2", "It will describe what it is about to do and ask you to confirm before making a change. Only continue if you want the assistant to take actions for you.") })]
27
+ })
28
+ });
29
+ };
30
+ //#endregion
31
+ export { o as AssistantApiCallsConsentDialog };
@@ -0,0 +1,27 @@
1
+ import { FC } from 'react';
2
+ import { WorkspaceWriteAccess } from '../useWorkspaceWriteAccess';
3
+ /**
4
+ * `visible` is false when the host HIDES the panel without unmounting it, which
5
+ * is what the supported `visible` prop does. That distinction matters here: a
6
+ * live voice session would otherwise keep the microphone open and the silence
7
+ * timer running behind an invisible panel.
8
+ */
9
+ export interface AssistantChatAreaProps {
10
+ visible?: boolean;
11
+ /**
12
+ * Whether this actor may WRITE in this workspace, or `'unknown'`.
13
+ *
14
+ * ★ A prop rather than a sixth field on the product seam. The product can
15
+ * simply call `useWorkspaceWriteAccess(actorId, workspaceId, probeResources)`
16
+ * in its own wrapper — the only thing shared code cannot supply is WHICH
17
+ * resource types to probe, and a capability the product can compute itself
18
+ * does not earn a place in an interface every product must satisfy.
19
+ *
20
+ * Defaults to `'unknown'`, which is exactly the "say nothing" branch: a
21
+ * product that does not pass it gets today's behaviour for a workspace with no
22
+ * roles provisioned, never a false claim in either direction.
23
+ */
24
+ writeAccess?: WorkspaceWriteAccess;
25
+ }
26
+ export declare const AssistantChatArea: FC<AssistantChatAreaProps>;
27
+ //# sourceMappingURL=AssistantChatArea.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssistantChatArea.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantChatArea.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAkDnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAwKvE;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,EAAE,oBAAoB,CAAC;CACpC;AAED,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAw1CxD,CAAC"}
@@ -0,0 +1,461 @@
1
+ import { useI18n as e } from "../../providers/shell/I18nProvider.js";
2
+ import { useAuthToken as t } from "../../providers/shell/AuthTokenProvider.js";
3
+ import "../../../shared-providers-shell.js";
4
+ import { isQuotaExhaustedError as n } from "../quota.js";
5
+ import { createAssistantSandbox as r, createAssistantSession as i, extendAssistantSandboxTTL as a, findExistingSandbox as o, getAssistantArtifacts as s, getAssistantMessages as c, getAssistantSession as l, sendAssistantPromptAsync as u, waitForAssistantServiceReady as d, waitForSandboxRunning as f } from "../api.js";
6
+ import { getAssistantMedia as p, sanitize as ee } from "../progress.js";
7
+ import { isVoiceTurn as m, voiceMarker as h, voiceSessionIdOf as g } from "../voice/turnVisibility.js";
8
+ import { buildContinuedFromVoiceNote as _, buildVoiceTranscriptMarkdown as v, voiceTranscriptFilename as te } from "../voice/voiceTranscript.js";
9
+ import { pollDelayMs as ne } from "../voice/assistantPollSchedule.js";
10
+ import { toCaptionText as y } from "../voice/captionText.js";
11
+ import { resolveAssistantLanguage as b } from "../voice/languages.js";
12
+ import { resolveLanguagePair as re } from "../voice/languagePair.js";
13
+ import { findPendingWrite as x } from "../pendingWrite.js";
14
+ import { useAssistantProduct as ie } from "../product.js";
15
+ import { useAssistantTr as ae } from "../i18n.js";
16
+ import { buildPromptParts as oe, buildPromptWithAttachments as se, countInlineImageCandidates as ce, countInlinedImageParts as le, getSendableAttachments as ue, toMessageAttachment as de } from "../attachments.js";
17
+ import { useAssistantStore as S } from "../store.js";
18
+ import { isTurnInFlight as fe } from "../turnState.js";
19
+ import { parseToolActivity as pe } from "./AssistantToolActivity.js";
20
+ import { useVoiceSession as me } from "./useVoiceSession.js";
21
+ import { getOrganizationId as he, getWorkspaceId as ge } from "../context.js";
22
+ import { createReadinessTracker as _e } from "../sandboxReadiness.js";
23
+ import { AssistantSpokenTurnsNotice as ve } from "./AssistantSpokenTurnsNotice.js";
24
+ import { VoiceTranscriptDrawer as ye } from "./voice/VoiceTranscriptDrawer.js";
25
+ import { downloadFile as be } from "../exportConversation.js";
26
+ import { AssistantEmptyState as xe } from "./AssistantEmptyState.js";
27
+ import { AssistantMessageList as Se } from "./AssistantMessageList.js";
28
+ import { AssistantVoiceSession as Ce } from "./voice/AssistantVoiceSession.js";
29
+ import { useAssistantApiAccess as we } from "../useAssistantApiAccess.js";
30
+ import { useConversationTurns as Te } from "../useConversationTurns.js";
31
+ import { isMultimodalBodyRejection as Ee, isRecoverableAssistantError as De } from "../transportErrors.js";
32
+ import { dispatchAssistantQuotaExhausted as Oe, notifyAiCreditsUpdated as ke } from "../aiCredits.js";
33
+ import { useAssistantAttachments as Ae } from "../useAssistantAttachments.js";
34
+ import { AssistantComposer as je } from "./composer/AssistantComposer.js";
35
+ import { isProdRuntime as Me } from "../env.js";
36
+ import { AssistantApiCallsConsentDialog as Ne } from "./AssistantApiCallsConsentDialog.js";
37
+ import { useCallback as C, useEffect as w, useMemo as T, useRef as E, useState as Pe } from "react";
38
+ import { jsx as D, jsxs as Fe } from "react/jsx-runtime";
39
+ //#region src/shared/assistant/ui/AssistantChatArea.tsx
40
+ var Ie = {
41
+ general: 18e4,
42
+ assistant: 18e4,
43
+ "api-calls": 18e4,
44
+ "vibe-plugins": 6e5
45
+ }, Le = 18e4, Re = 600, ze = 2e4;
46
+ function Be() {
47
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
48
+ }
49
+ function O(e) {
50
+ return e.info?.time?.created ?? 0;
51
+ }
52
+ function k(e) {
53
+ return (e ?? []).filter((e) => e.type === "text" && typeof e.text == "string").map((e) => e.text?.trim() ?? "").filter(Boolean).join("\n");
54
+ }
55
+ function A(e) {
56
+ return (e ?? []).filter((e) => e.type === "tool" && e.tool).map((e) => {
57
+ let t = e.state?.status ?? "running", n = e.tool ?? "tool";
58
+ return t === "completed" ? `Completed: ${n}` : t === "failed" ? `Failed: ${n}` : `Running: ${n}`;
59
+ });
60
+ }
61
+ function Ve(e, t) {
62
+ let n = e.filter((e) => e.info?.role === "assistant" && O(e) > t).sort((e, t) => O(e) - O(t));
63
+ if (n.length === 0) return {
64
+ content: "Thinking...",
65
+ done: !1
66
+ };
67
+ let r = n[n.length - 1], i = k(r.parts), a = p(r.parts), o = A(r.parts), s = x(r.parts), c = [
68
+ i,
69
+ ...a,
70
+ ...o
71
+ ].filter(Boolean).join("\n\n") || "Thinking...", l = r.info?.providerID, u = r.info?.modelID;
72
+ return {
73
+ content: c,
74
+ done: !!r.info?.time?.completed && (!!i || a.length > 0 || o.length > 0),
75
+ tokens: r.info?.tokens,
76
+ messageId: r.info?.id,
77
+ ...l && u ? { model: `${l}/${u}` } : {},
78
+ ...s ? { pendingWrite: s } : {}
79
+ };
80
+ }
81
+ function He(e) {
82
+ switch (e) {
83
+ case "provisioning": return "Starting assistant environment...";
84
+ case "connecting": return "Connecting to assistant...";
85
+ case "streaming": return "Thinking...";
86
+ default: return "";
87
+ }
88
+ }
89
+ var j = ({ visible: p = !0, writeAccess: x = "unknown" }) => {
90
+ let k = ae(), { product: A, modes: j, gatherPageContext: Ue, buildPrompt: We, reportTokenUsage: Ge } = ie(), { getAccessToken: Ke, getWorkspaceToken: qe, userId: Je } = t(), { locale: Ye } = e(), Xe = S((e) => e.assistantLanguage), Ze = S((e) => e.replyLanguage), Qe = T(() => re(Xe, Ze, Ye), [
91
+ Xe,
92
+ Ze,
93
+ Ye
94
+ ]), $e = Qe.reply.english, et = Qe.replyIsExplicit, tt = Qe.reply.code, { conversations: nt, activeConversationId: M, mode: N, processingByConversationId: rt, setMode: P, setConversationMode: it, setActiveConversation: at, createConversation: F, addMessage: I, updateMessage: ot, patchMessage: L, mergeMessageMetadata: st, setConversationProcessing: R, setBackendSessionId: ct, clearBackendSessionId: lt, setSandbox: z, clearSandbox: ut, acknowledgeApiCalls: dt } = S(), B = Te(nt.find((e) => e.id === M)), ft = B.all, V = M ? rt[M] : void 0, H = fe(V?.status), pt = H ? V?.messageId ?? null : null, mt = V?.status === "error" ? V.messageId : null, { canUseApiCalls: U, loading: ht } = we(he()), gt = T(() => j.filter((e) => !e.requiresAdmin || U), [j, U]), [_t, vt] = Pe(null), [yt, bt] = Pe(!1), xt = E({}), W = E(_e()), St = E(/* @__PURE__ */ new Set()), G = T(() => j.find((e) => e.id === N), [j, N]);
95
+ w(() => {
96
+ ht || (!G || G.requiresAdmin && !U) && N !== "assistant" && P("assistant");
97
+ }, [
98
+ N,
99
+ G,
100
+ U,
101
+ ht,
102
+ P
103
+ ]);
104
+ let K = C((e, t, n, r) => {
105
+ R(e, n, t, null), r ? ot(e, t, r) : ot(e, t, He(n));
106
+ }, [R, ot]), Ct = C(async (e, t, n, a, s) => {
107
+ let c = S.getState().sandboxesByMode[n]?.sandboxId ?? null, u = async (e) => {
108
+ if (W.current.isFresh(e)) return !0;
109
+ try {
110
+ return await f(e, a, s, 3e5), await d(e, a, s, 9e4), W.current.markVerified(e), !0;
111
+ } catch {
112
+ return W.current.invalidate(e), !1;
113
+ }
114
+ };
115
+ if (c && (z(n, c, "provisioning"), K(e, t, "provisioning", "Reusing assistant environment..."), await u(c) || (z(n, null, "provisioning"), c = null)), !c) {
116
+ K(e, t, "provisioning", "Looking for existing environment...");
117
+ let r = await o(a, n, Me(), s);
118
+ r && (z(n, r, "provisioning"), K(e, t, "provisioning", "Reusing assistant environment..."), await u(r) ? c = r : z(n, null, "provisioning"));
119
+ }
120
+ if (!c) {
121
+ if (n === "api-calls" && !Ke()) throw Error("API Calls mode requires an authenticated session. Please sign in again.");
122
+ K(e, t, "provisioning", "Starting assistant environment..."), z(n, null, "provisioning"), c = await r(A, n, a, Me(), Re, s), z(n, c, "provisioning"), await f(c, a, s, 3e5), await d(c, a, s, 9e4);
123
+ }
124
+ z(n, c, "running");
125
+ let p = S.getState().conversations.find((t) => t.id === e)?.backendSessionId ?? null;
126
+ if (p) try {
127
+ let e = await l(c, a, p, s);
128
+ if (e.mode !== n) throw Error(`Session mode mismatch: expected ${n}, received ${e.mode}`);
129
+ } catch {
130
+ lt(e), p = null;
131
+ }
132
+ return p || (K(e, t, "connecting", "Preparing session..."), p = (await i(c, a, n, s)).sessionId, ct(e, p)), {
133
+ sandboxId: c,
134
+ sessionId: p
135
+ };
136
+ }, [
137
+ lt,
138
+ Ke,
139
+ A,
140
+ ct,
141
+ z,
142
+ K
143
+ ]), q = C(async (e, t = [], r = {}) => {
144
+ let i = r.voiceSessionId !== void 0, o = S.getState(), l = o.activeConversationId ?? M;
145
+ if (l && (fe(o.processingByConversationId[l]?.status) || St.current.has(l))) return;
146
+ let d = o.mode, f = M, p = f ? S.getState().conversations.find((e) => e.id === f) : void 0;
147
+ if (f ? p && p.mode !== d && (p.messages.length > 0 || p.backendSessionId) ? f = F(void 0, d) : p && p.mode !== d && it(f, d) : f = F(void 0, d), !f) return;
148
+ xt.current[f] = t;
149
+ let m = ge(), g = {
150
+ accessToken: Ke(),
151
+ workspaceToken: qe(),
152
+ userId: Je,
153
+ organizationId: he()
154
+ }, _ = {
155
+ id: Be(),
156
+ role: "user",
157
+ content: e,
158
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
159
+ metadata: {
160
+ ...t.length ? { attachments: t.map(de) } : {},
161
+ ...h(r.voiceSessionId)
162
+ }
163
+ };
164
+ I(f, _);
165
+ let v = Be();
166
+ I(f, {
167
+ id: v,
168
+ role: "assistant",
169
+ content: "",
170
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
171
+ metadata: {
172
+ lang: tt,
173
+ ...h(r.voiceSessionId)
174
+ }
175
+ }), R(f, "provisioning", v, null);
176
+ let te = (e, t, n, i, a = tt) => {
177
+ L(f, v, { content: ee(e) }), st(f, v, {
178
+ lang: a,
179
+ ...t?.length ? { artifacts: t } : {},
180
+ ...t?.length || n || i ? { mode: d } : {},
181
+ ...n ? { sessionId: n } : {},
182
+ ...i ? { sandboxId: i } : {},
183
+ ...h(r.voiceSessionId)
184
+ });
185
+ }, y = async (n = 1) => {
186
+ let r = !1;
187
+ try {
188
+ let { sandboxId: n, sessionId: o } = await Ct(f, v, d, m, g), l = (await c(n, m, o, g, { limit: 50 }).catch(() => [])).reduce((e, t) => Math.max(e, O(t)), 0);
189
+ K(f, v, "streaming", "Thinking...");
190
+ let p = se(e, t), h = We?.(d, p, $e, et, i) ?? p, _ = oe(h, t), y = le(_), b = y > 0, re = Ue?.();
191
+ r = ce(t) > y;
192
+ try {
193
+ await u(n, m, o, h, d, re, g, _?.length ? { parts: _ } : void 0);
194
+ } catch (e) {
195
+ if (!_ || !Ee(e)) throw e;
196
+ await u(n, m, o, h, d, re, g, void 0), r ||= b;
197
+ }
198
+ let x = Ve([], l), ie = Date.now() + (Ie[d] ?? Le), ae = Date.now(), ue = Date.now();
199
+ for (; Date.now() < ie && (x = Ve(await c(n, m, o, g, {
200
+ limit: 50,
201
+ sinceMs: l
202
+ }), l), L(f, v, { content: ee(x.content) }), x.pendingWrite && st(f, v, { pendingWrite: x.pendingWrite }), !x.done);) Date.now() - ae > 3e4 && (await a(n, m, 600, g).catch(() => void 0), ae = Date.now()), await new Promise((e) => setTimeout(e, ne(Date.now() - ue)));
203
+ if (!x.done && d !== "vibe-plugins") throw Error("Assistant response timed out while streaming progress");
204
+ let de = d === "vibe-plugins" ? await s(n, m, o, g).then((e) => e).catch(() => []) : void 0;
205
+ if (x.done || (x = {
206
+ ...x,
207
+ content: `${x.content}\n\n_Still building in the background — any artifacts below will finish shortly. Re-open this conversation to pick up the completed plugin._`
208
+ }), r && (x = {
209
+ ...x,
210
+ content: `${x.content}\n\n${k("attachments.imagesNotSent", "_Your photo was too large to include with this message, so the answer above is from the text and the file link only. Try a smaller or more tightly cropped photo._")}`
211
+ }), te(x.content, de, o, n), x.tokens) {
212
+ L(f, v, { tokens: x.tokens });
213
+ try {
214
+ await Ge?.({
215
+ workspaceId: m,
216
+ sessionId: o,
217
+ messageId: x.messageId,
218
+ model: x.model,
219
+ tokens: x.tokens
220
+ }), ke(A);
221
+ } catch {}
222
+ }
223
+ R(f, "complete", v, null);
224
+ } catch (e) {
225
+ if (n === 1 && De(e)) return lt(f), ut(d), y(2);
226
+ throw e;
227
+ }
228
+ }, b = f;
229
+ St.current.add(b);
230
+ try {
231
+ if (!m) throw Error("Assistant backend is unavailable without an active workspace context.");
232
+ await y();
233
+ } catch (e) {
234
+ if (W.current.invalidate(S.getState().sandboxesByMode[d]?.sandboxId ?? null), n(e)) {
235
+ Oe(A, "sandbox"), te("You've reached your sandbox limit on the current plan. Upgrade to start the AI assistant.", void 0, void 0, void 0, "en"), R(f, "error", v, null);
236
+ return;
237
+ }
238
+ let t = e instanceof Error ? e.message : "Something went wrong";
239
+ R(f, "error", v, t), L(f, v, { content: `Sorry, an error occurred: ${t}. Please try again.` }), st(f, v, {
240
+ lang: "en",
241
+ ...h(r.voiceSessionId)
242
+ });
243
+ } finally {
244
+ St.current.delete(b);
245
+ }
246
+ }, [
247
+ M,
248
+ I,
249
+ We,
250
+ lt,
251
+ ut,
252
+ nt,
253
+ F,
254
+ Ct,
255
+ Ue,
256
+ Ke,
257
+ qe,
258
+ L,
259
+ A,
260
+ Ge,
261
+ et,
262
+ tt,
263
+ $e,
264
+ ct,
265
+ it,
266
+ R,
267
+ k,
268
+ K,
269
+ Je
270
+ ]), wt = C((e) => {
271
+ q(e);
272
+ }, [q]), Tt = C(() => {
273
+ let e = [...B.chat].reverse().find((e) => e.role === "user"), t = M ? xt.current[M] ?? [] : [];
274
+ e && q(e.content, t);
275
+ }, [
276
+ ft,
277
+ q,
278
+ M
279
+ ]), J = E(q);
280
+ w(() => {
281
+ J.current = q;
282
+ }, [q]);
283
+ let Y = T(() => {
284
+ if (H) return null;
285
+ for (let e = ft.length - 1; e >= 0; --e) {
286
+ let t = ft[e];
287
+ if (t?.role !== "assistant" || !m(t)) continue;
288
+ let n = pe(t.content).text.trim();
289
+ return n ? {
290
+ id: t.id,
291
+ text: n
292
+ } : null;
293
+ }
294
+ return null;
295
+ }, [ft, H]), Et = T(() => Y ? y(Y.text) : null, [Y]), Dt = B.chat, X = T(() => B.voice.filter((e) => e.role === "user" || e.role === "assistant").map((e) => ({
296
+ id: e.id,
297
+ role: e.role,
298
+ text: pe(e.content).text.trim(),
299
+ sessionId: g(e),
300
+ timestamp: e.timestamp
301
+ })).filter((e) => e.text.length > 0), [B.voice]), Ot = C(() => {
302
+ if (X.length === 0) return;
303
+ let e = /* @__PURE__ */ new Date();
304
+ be(v(X, {
305
+ title: k("voiceSession.transcript", "Voice conversation"),
306
+ savedAt: k("voiceSession.savedAt", "Saved"),
307
+ session: k("voiceSession.sessionLabel", "Session"),
308
+ earlier: k("voiceSession.earlierLabel", "Earlier"),
309
+ you: k("voiceSession.speakerYou", "You"),
310
+ assistant: k("voiceSession.speakerAssistant", "Assistant")
311
+ }, e), te(e), "text/markdown");
312
+ }, [X, k]), Z = Ae(), Q = E(Z);
313
+ Q.current = Z;
314
+ let $ = me({
315
+ onSubmit: C((e, t) => {
316
+ let n = () => {
317
+ let n = Q.current, r = ue(n.attachments);
318
+ J.current(e, r, { voiceSessionId: t }), n.clear();
319
+ };
320
+ if (!Q.current.isBusy) {
321
+ n();
322
+ return;
323
+ }
324
+ let r = Date.now(), i = window.setInterval(() => {
325
+ Q.current.isBusy && Date.now() - r < ze || (window.clearInterval(i), n());
326
+ }, 200);
327
+ }, []),
328
+ latestReply: Y,
329
+ language: b(Xe, Ye).tag
330
+ }), kt = C(() => {
331
+ let e = S.getState().activeConversationId;
332
+ !e || X.length === 0 || (I(e, {
333
+ id: Be(),
334
+ role: "system",
335
+ content: _(X, {
336
+ intro: k("voiceSession.continuedIntro", "Continued from a voice conversation. You asked about:"),
337
+ nothing: k("voiceSession.continuedNothing", "Continued from a voice conversation."),
338
+ more: (e) => k("voiceSession.continuedMore", "…and {{count}} more", { count: e })
339
+ }),
340
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
341
+ }), bt(!1), $.end());
342
+ }, [
343
+ X,
344
+ I,
345
+ k
346
+ ]);
347
+ w(() => {
348
+ !p && $.active && $.end();
349
+ }, [p, $]), w(() => {
350
+ $.active || Q.current.clear();
351
+ }, [$.active]), w(() => {
352
+ let e = S.getState().consumePendingPrompt();
353
+ return e && J.current(e), S.subscribe((e, t) => {
354
+ if (e.pendingPrompt && e.pendingPrompt !== t.pendingPrompt) {
355
+ let e = S.getState().consumePendingPrompt();
356
+ e && J.current(e);
357
+ }
358
+ });
359
+ }, []);
360
+ let At = C((e) => {
361
+ let t = M ? S.getState().conversations.find((e) => e.id === M) : void 0;
362
+ if (t && (t.messages.length > 0 || t.backendSessionId)) {
363
+ if (t.mode !== e) {
364
+ let t = S.getState().conversations.find((t) => t.mode === e && t.messages.length === 0 && !t.backendSessionId && !S.getState().processingByConversationId[t.id]);
365
+ t ? at(t.id) : F(void 0, e);
366
+ }
367
+ } else M && it(M, e);
368
+ P(e);
369
+ }, [
370
+ M,
371
+ F,
372
+ at,
373
+ it,
374
+ P
375
+ ]), jt = C((e) => {
376
+ if (j.find((t) => t.id === e)?.writeCapable && !S.getState().apiCallsAcknowledged) {
377
+ vt(e);
378
+ return;
379
+ }
380
+ At(e);
381
+ }, [At]), Mt = C(() => {
382
+ let e = _t;
383
+ vt(null), dt(), e && At(e);
384
+ }, [
385
+ _t,
386
+ dt,
387
+ At
388
+ ]), Nt = C(() => {
389
+ vt(null);
390
+ }, []);
391
+ return /* @__PURE__ */ Fe("div", {
392
+ className: "relative flex flex-1 flex-col overflow-hidden",
393
+ children: [
394
+ /* @__PURE__ */ Fe("div", {
395
+ className: "contents",
396
+ inert: $.active || void 0,
397
+ children: [
398
+ X.length > 0 && !$.active ? /* @__PURE__ */ D(ve, {
399
+ count: X.length,
400
+ onOpenTranscript: () => bt(!0)
401
+ }) : null,
402
+ Dt.length === 0 ? /* @__PURE__ */ D(xe, {
403
+ mode: N,
404
+ onSuggestionClick: wt
405
+ }) : /* @__PURE__ */ D("div", {
406
+ className: "flex min-h-0 flex-1 flex-col",
407
+ children: /* @__PURE__ */ D(Se, {
408
+ messages: Dt,
409
+ streamingMessageId: pt,
410
+ failedMessageId: mt,
411
+ onRetry: Tt
412
+ })
413
+ }),
414
+ /* @__PURE__ */ D(je, {
415
+ onStartVoiceSession: $.available && N !== "api-calls" ? $.start : void 0,
416
+ onSend: (e, t) => void q(e, t),
417
+ disabled: H,
418
+ placeholder: N === "api-calls" ? k("chatArea.placeholderActions", "What would you like me to do?") : k("chatArea.placeholderGeneral", "Ask me anything…"),
419
+ mode: N,
420
+ writeAccessDenied: x === "denied" && !!G?.writeCapable,
421
+ availableModes: gt,
422
+ onModeChange: jt
423
+ })
424
+ ]
425
+ }),
426
+ yt && !$.active ? /* @__PURE__ */ D(ye, {
427
+ turns: X,
428
+ onClose: () => bt(!1),
429
+ onSave: Ot
430
+ }) : null,
431
+ $.active && /* @__PURE__ */ D(Ce, {
432
+ session: $.session,
433
+ notice: $.notice,
434
+ capturing: $.capturing,
435
+ interrupting: $.interrupting,
436
+ awaitingEndpoint: $.awaitingEndpoint,
437
+ turns: X,
438
+ spokenChunks: $.spokenChunks,
439
+ attachments: Z.attachments,
440
+ onAttachFiles: Z.addFiles,
441
+ onRemoveAttachment: Z.remove,
442
+ onRetryAttachment: Z.retry,
443
+ canAttachMore: Z.canAddMore,
444
+ preparingAttachments: Z.preparingCount,
445
+ onSaveTranscript: Ot,
446
+ onContinueInChat: kt,
447
+ onInterrupt: $.interrupt,
448
+ spoken: Et,
449
+ onToggleMute: $.toggleMute,
450
+ onEnd: $.end
451
+ }),
452
+ /* @__PURE__ */ D(Ne, {
453
+ open: _t !== null,
454
+ onConfirm: Mt,
455
+ onCancel: Nt
456
+ })
457
+ ]
458
+ });
459
+ };
460
+ //#endregion
461
+ export { j as AssistantChatArea };
@@ -1,7 +1,15 @@
1
1
  import { FC } from 'react';
2
2
  interface Props {
3
3
  /** Friendly label for the page the user is on (e.g. "Inventory"). */
4
- contextLabel: string;
4
+ /**
5
+ * Where the user is, or `null` when the product cannot say.
6
+ *
7
+ * ★ Nullable, and the whole segment is dropped rather than filled with a
8
+ * placeholder. `describeCurrentPage` is optional on the product seam, so a
9
+ * product with no route model reaches here with nothing — and "Context: null"
10
+ * beside a claim to be Ready is worse than saying nothing at all.
11
+ */
12
+ contextLabel: string | null;
5
13
  onNewConversation: () => void;
6
14
  onOpenHistory: () => void;
7
15
  /** True when the history drawer is currently open (drives the toggle state). */
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantHeader.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAYhC,UAAU,KAAK;IACb,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,gFAAgF;IAChF,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,KAAK,CA8FrC,CAAC"}
1
+ {"version":3,"file":"AssistantHeader.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAKhC,UAAU,KAAK;IACb,qEAAqE;IACrE;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,gFAAgF;IAChF,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,KAAK,CAgGrC,CAAC"}
@@ -1,75 +1,71 @@
1
1
  import { useAssistantTr as e } from "../i18n.js";
2
2
  import { AssistantMoreMenu as t } from "./AssistantMoreMenu.js";
3
3
  import { History as n, PanelBottom as r, PanelRight as i, Plus as a, Sparkles as o, X as s } from "lucide-react";
4
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
4
+ import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
5
5
  //#region src/shared/assistant/ui/AssistantHeader.tsx
6
- var u = ({ contextLabel: u, onNewConversation: d, onOpenHistory: f, historyOpen: p, onClose: m, docked: h, onToggleDock: g }) => {
7
- let _ = e();
8
- return /* @__PURE__ */ l("div", {
6
+ var d = ({ contextLabel: d, onNewConversation: f, onOpenHistory: p, historyOpen: m, onClose: h, docked: g, onToggleDock: _ }) => {
7
+ let v = e();
8
+ return /* @__PURE__ */ u("div", {
9
9
  className: "flex items-center gap-2 border-b border-border-default bg-bg-elevated px-3 py-2.5",
10
- children: [/* @__PURE__ */ l("div", {
10
+ children: [/* @__PURE__ */ u("div", {
11
11
  className: "flex min-w-0 flex-1 items-center gap-2",
12
- children: [/* @__PURE__ */ c("span", {
12
+ children: [/* @__PURE__ */ l("span", {
13
13
  className: "flex size-7 flex-shrink-0 items-center justify-center rounded-lg bg-gradient-to-br from-action-primary-bg/25 to-action-primary-bg/5 text-action-primary-bg",
14
- children: /* @__PURE__ */ c(o, { className: "size-4" })
15
- }), /* @__PURE__ */ l("span", {
14
+ children: /* @__PURE__ */ l(o, { className: "size-4" })
15
+ }), /* @__PURE__ */ u("span", {
16
16
  className: "min-w-0 flex-1",
17
- children: [/* @__PURE__ */ c("span", {
17
+ children: [/* @__PURE__ */ l("span", {
18
18
  className: "block truncate text-[14px] font-semibold leading-tight text-text-primary",
19
- children: _("header.title", "HealthyBowl AI")
20
- }), /* @__PURE__ */ l("span", {
19
+ children: v("header.title", "HealthyBowl AI")
20
+ }), /* @__PURE__ */ u("span", {
21
21
  className: "block truncate text-[11px] leading-tight text-text-muted",
22
- children: [
23
- _("header.ready", "Ready"),
24
- /* @__PURE__ */ c("span", {
25
- "aria-hidden": "true",
26
- children: " · "
27
- }),
28
- _("header.context", "Context: {{page}}", { page: u })
29
- ]
22
+ children: [v("header.ready", "Ready"), d && /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ l("span", {
23
+ "aria-hidden": "true",
24
+ children: " · "
25
+ }), v("header.context", "Context: {{page}}", { page: d })] })]
30
26
  })]
31
27
  })]
32
- }), /* @__PURE__ */ l("div", {
28
+ }), /* @__PURE__ */ u("div", {
33
29
  className: "flex flex-shrink-0 items-center gap-0.5",
34
30
  children: [
35
- /* @__PURE__ */ c("button", {
31
+ /* @__PURE__ */ l("button", {
36
32
  type: "button",
37
- onClick: d,
33
+ onClick: f,
38
34
  className: "rounded-lg p-1.5 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary",
39
- "aria-label": _("header.newConversation", "New conversation"),
35
+ "aria-label": v("header.newConversation", "New conversation"),
40
36
  "data-testid": "assistant-new-conversation",
41
- children: /* @__PURE__ */ c(a, { className: "size-4" })
37
+ children: /* @__PURE__ */ l(a, { className: "size-4" })
42
38
  }),
43
- /* @__PURE__ */ c("button", {
39
+ /* @__PURE__ */ l("button", {
44
40
  type: "button",
45
- onClick: f,
46
- className: `rounded-lg p-1.5 transition-colors ${p ? "bg-action-primary-bg/15 text-action-primary-bg" : "text-text-secondary hover:bg-bg-sunken hover:text-text-primary"}`,
47
- "aria-label": _("header.history", "Conversation history"),
48
- "aria-pressed": p,
41
+ onClick: p,
42
+ className: `rounded-lg p-1.5 transition-colors ${m ? "bg-action-primary-bg/15 text-action-primary-bg" : "text-text-secondary hover:bg-bg-sunken hover:text-text-primary"}`,
43
+ "aria-label": v("header.history", "Conversation history"),
44
+ "aria-pressed": m,
49
45
  "data-testid": "assistant-open-history",
50
- children: /* @__PURE__ */ c(n, { className: "size-4" })
46
+ children: /* @__PURE__ */ l(n, { className: "size-4" })
51
47
  }),
52
- /* @__PURE__ */ c(t, {}),
53
- g && /* @__PURE__ */ c("button", {
48
+ /* @__PURE__ */ l(t, {}),
49
+ _ && /* @__PURE__ */ l("button", {
54
50
  type: "button",
55
- onClick: g,
51
+ onClick: _,
56
52
  className: "hidden rounded-lg p-1.5 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary sm:inline-flex",
57
- "aria-label": h ? _("header.float", "Float chat window") : _("header.dock", "Dock to side panel"),
58
- "aria-pressed": h,
53
+ "aria-label": g ? v("header.float", "Float chat window") : v("header.dock", "Dock to side panel"),
54
+ "aria-pressed": g,
59
55
  "data-testid": "assistant-toggle-dock",
60
- children: c(h ? r : i, { className: "size-4" })
56
+ children: l(g ? r : i, { className: "size-4" })
61
57
  }),
62
- /* @__PURE__ */ c("button", {
58
+ /* @__PURE__ */ l("button", {
63
59
  type: "button",
64
- onClick: m,
60
+ onClick: h,
65
61
  className: "rounded-lg p-1.5 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary",
66
- "aria-label": _("header.close", "Close assistant"),
62
+ "aria-label": v("header.close", "Close assistant"),
67
63
  "data-testid": "assistant-close",
68
- children: /* @__PURE__ */ c(s, { className: "size-4" })
64
+ children: /* @__PURE__ */ l(s, { className: "size-4" })
69
65
  })
70
66
  ]
71
67
  })]
72
68
  });
73
69
  };
74
70
  //#endregion
75
- export { u as AssistantHeader };
71
+ export { d as AssistantHeader };
@@ -0,0 +1,14 @@
1
+ import { AssistantMode } from './types';
2
+ /**
3
+ * Keeps the sandbox alive while the panel is open and a session is live.
4
+ *
5
+ * The sandbox is reaped on TTL expiry, so without this a user reading a long
6
+ * answer loses the environment mid-conversation and the next turn pays a full
7
+ * cold provision. Fires immediately on mount as well as on the interval, because
8
+ * the panel may be reopened onto a session whose TTL is already nearly spent.
9
+ *
10
+ * Best-effort by contract: a failed ping is logged, never surfaced. The user has
11
+ * their answer; the worst case is the reprovision this was avoiding.
12
+ */
13
+ export declare function useAssistantHeartbeat(sessionId: string | null, mode: AssistantMode | null, isOpen: boolean): void;
14
+ //# sourceMappingURL=useAssistantHeartbeat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAssistantHeartbeat.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useAssistantHeartbeat.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,IAAI,EAAE,aAAa,GAAG,IAAI,EAC1B,MAAM,EAAE,OAAO,GACd,IAAI,CA+BN"}
@@ -0,0 +1,38 @@
1
+ import { useAuthToken as e } from "../providers/shell/AuthTokenProvider.js";
2
+ import "../../shared-providers-shell.js";
3
+ import { extendAssistantSandboxTTL as t, sendHeartbeat as n } from "./api.js";
4
+ import { useAssistantStore as r } from "./store.js";
5
+ import { getWorkspaceId as i } from "./context.js";
6
+ import { useEffect as a } from "react";
7
+ //#region src/shared/assistant/useAssistantHeartbeat.ts
8
+ var o = 12e4;
9
+ function s(s, c, l) {
10
+ let { getAccessToken: u, getWorkspaceToken: d } = e();
11
+ a(() => {
12
+ if (!s || !c || !l) return;
13
+ let e = r.getState().sandboxesByMode[c]?.sandboxId;
14
+ if (!e) return;
15
+ let a = i();
16
+ if (!a) return;
17
+ let f = () => {
18
+ let r = {
19
+ accessToken: u(),
20
+ workspaceToken: d()
21
+ };
22
+ Promise.all([n(e, a, s, r), t(e, a, 600, r)]).catch((e) => {
23
+ console.warn("[heartbeat] Failed:", e);
24
+ });
25
+ };
26
+ f();
27
+ let p = setInterval(f, o);
28
+ return () => clearInterval(p);
29
+ }, [
30
+ s,
31
+ c,
32
+ l,
33
+ u,
34
+ d
35
+ ]);
36
+ }
37
+ //#endregion
38
+ export { s as useAssistantHeartbeat };
@@ -0,0 +1,24 @@
1
+ import { RefObject } from 'react';
2
+ interface Options {
3
+ panelRef: RefObject<HTMLDivElement | null>;
4
+ inputRef?: RefObject<HTMLTextAreaElement | null>;
5
+ onClose: () => void;
6
+ }
7
+ /**
8
+ * Panel-scoped keyboard shortcuts for the AI assistant.
9
+ *
10
+ * All shortcuts only fire when the assistant panel (or one of its children)
11
+ * has focus, so they never override the host page's own shortcuts. We also
12
+ * deliberately avoid the bare `Ctrl+N`/`Cmd+N`/`Ctrl+E`/`Ctrl+W` set the
13
+ * browser owns at the OS level — those couldn't be cancelled reliably
14
+ * anyway and were just adding visible "shortcut listed, doesn't work"
15
+ * inconsistencies. The shortcuts here match the in-app shortcuts modal.
16
+ *
17
+ * - Escape: Close panel
18
+ * - Ctrl/Cmd+Shift+N: New conversation
19
+ * - Ctrl/Cmd+Shift+E: Export (triggers click on export button)
20
+ * - /: Focus input (only when no input/textarea is already focused)
21
+ */
22
+ export declare function useAssistantKeyboardShortcuts({ panelRef, inputRef, onClose }: Options): void;
23
+ export {};
24
+ //# sourceMappingURL=useAssistantKeyboardShortcuts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAssistantKeyboardShortcuts.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/useAssistantKeyboardShortcuts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGlD,UAAU,OAAO;IACf,QAAQ,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,QA0DrF"}
@@ -0,0 +1,35 @@
1
+ import { useAssistantStore as e } from "./store.js";
2
+ import { useEffect as t } from "react";
3
+ //#region src/shared/assistant/useAssistantKeyboardShortcuts.ts
4
+ function n({ panelRef: n, inputRef: r, onClose: i }) {
5
+ t(() => {
6
+ let t = (t) => {
7
+ let a = n.current;
8
+ if (!a || !a.contains(document.activeElement) && document.activeElement !== a) return;
9
+ let o = t.ctrlKey || t.metaKey;
10
+ if (t.key === "Escape") {
11
+ t.preventDefault(), i();
12
+ return;
13
+ }
14
+ if (o && t.shiftKey && (t.key === "N" || t.key === "n")) {
15
+ t.preventDefault(), e.getState().createConversation();
16
+ return;
17
+ }
18
+ if (o && t.shiftKey && (t.key === "E" || t.key === "e")) {
19
+ t.preventDefault(), a.querySelector("[data-testid=\"assistant-more\"]")?.click();
20
+ return;
21
+ }
22
+ if (t.key === "/" && !o && !t.shiftKey) {
23
+ let e = document.activeElement?.tagName;
24
+ e !== "INPUT" && e !== "TEXTAREA" && (t.preventDefault(), r?.current?.focus());
25
+ }
26
+ };
27
+ return document.addEventListener("keydown", t), () => document.removeEventListener("keydown", t);
28
+ }, [
29
+ n,
30
+ r,
31
+ i
32
+ ]);
33
+ }
34
+ //#endregion
35
+ export { n as useAssistantKeyboardShortcuts };
@@ -82,4 +82,10 @@ import { useWorkspaceWriteAccess as ui } from "./shared/assistant/useWorkspaceWr
82
82
  import { extractDocumentText as di } from "./shared/assistant/documentExtract.js";
83
83
  import { useAssistantAttachments as fi } from "./shared/assistant/useAssistantAttachments.js";
84
84
  import { AssistantComposer as pi } from "./shared/assistant/ui/composer/AssistantComposer.js";
85
- export { h as ASSISTANT_API_AUTH_STRATEGY, Mt as ASSISTANT_LANGUAGES, Pr as ASSISTANT_MODE_META, Tn as ATTACHMENT_ACCEPT, pr as ATTACHMENT_SOURCES, Rr as AUTO_VOICE, Ar as AssistantAttachmentButton, jr as AssistantAttachmentChips, yr as AssistantAutoSpeakToggle, pi as AssistantComposer, Qr as AssistantConversationList, $r as AssistantEmptyState, Zr as AssistantHeader, Wt as AssistantI18nProvider, Mr as AssistantLanguageSelector, br as AssistantMarkdownImage, Cr as AssistantMarkdownRenderer, Tr as AssistantMessageAttachments, ei as AssistantMessageItem, ti as AssistantMessageList, Fr as AssistantModeSelector, Xr as AssistantMoreMenu, Er as AssistantPendingWriteCard, Bt as AssistantProductProvider, Dr as AssistantReplyLanguageSelector, G as AssistantRuntimeManager, Or as AssistantSpeakButton, or as AssistantSpeechProvider, kr as AssistantSpokenTurnsNotice, ir as AssistantToolActivity, Lr as AssistantVoiceButton, Br as AssistantVoiceOrb, zr as AssistantVoiceSelector, ni as AssistantVoiceSession, Vr as AssistantVoiceSessionButton, En as AttachmentRejectedError, an as BOILERPLATE_PAGE_SHARE, o as CHECK_AI_CREDITS, s as CREATE_SANDBOX, pt as DEFAULT_SPEAKABLE_LABELS, Nt as DEFAULT_SPEECH_RATE, Be as ENDPOINT_GRACE_MS, c as EXTEND_SANDBOX_TTL, Nr as FOLLOW_APP_LOCALE, l as GET_ACTIVE_SANDBOXES, u as GET_SANDBOX, ge as HOSTED_TTS_MAX_CHARS, fe as HOSTED_TTS_TIER, pe as HOSTED_VOICES, Qt as IDLE_PLAYBACK, Ve as INITIAL_SESSION, Dn as INLINE_IMAGE_MAX_DIM, On as INLINE_IMAGE_QUALITY, He as INTERRUPT_MAX_MS, Ue as INTERRUPT_MIN_MS, kn as MAX_ATTACHMENTS, on as MAX_BOILERPLATE_LINE_CHARS, sn as MAX_EXTRACTED_CHARS, An as MAX_FILE_BYTES, jn as MAX_INLINE_CHARS_PER_FILE, Mn as MAX_INLINE_CHARS_TOTAL, nn as MAX_INLINE_IMAGE_BASE64_BYTES, Nn as MAX_INLINE_IMAGE_BASE64_CHARS, Pn as MAX_INLINE_IMAGE_PARTS, Fn as MAX_INLINE_TURN_BODY_BYTES, cn as MAX_PDF_PAGES_SCANNED, rn as MAX_REQUEST_BODY_BYTES, mt as MAX_SPEAKABLE_CHARS, ht as MAX_SPOKEN_TABLE_ROWS, In as MAX_TURN_BODY_BYTES, ln as MIN_PAGE_TEXT_CHARS, un as MIN_TEXT_PAGE_SHARE, Tt as POLL_FAST_MS, Et as POLL_FAST_UNTIL_MS, Dt as POLL_SLOW_MS, Ot as POLL_STEADY_MS, kt as POLL_STEADY_UNTIL_MS, Ct as PREVIEW_LANGUAGES, Ln as PROMPT_ENVELOPE_RESERVE_BYTES, d as PROXY_SANDBOX_REQUEST, f as REPORT_AI_TOKEN_USAGE, gr as SANDBOX_READY_TTL_MS, We as SILENCE_SUBMIT_MS, _e as SPEAKING_RATE_MAX, ve as SPEAKING_RATE_MAX_STREAMING, ye as SPEAKING_RATE_MAX_SYNC, be as SPEAKING_RATE_MIN, gt as SPEECH_CHUNK_CHARS, _t as SPEECH_CHUNK_CJK_CHARS, Qe as SPEECH_LANG, Jt as SPOKEN_LABEL_LANGUAGES, p as STOP_ASSISTANT_SANDBOX, Rn as TURN_BODY_HEADROOM_BYTES, $e as VOICE_LIST_TIMEOUT_MS, Hr as VoiceCaption, Ur as VoiceConversationView, Gr as VoiceMiniController, Kr as VoiceStage, qr as VoiceTranscriptDrawer, Wr as VoiceWaveform, m as WAIT_FOR_SANDBOX_RUNNING, si as aiCreditsUpdatedEventName, Gt as assistantTranslationKey, wr as assistantUrlTransform, mr as availableAttachmentSources, xe as base64ToBytes, de as browserSpeechEngine, T as buildAssistantSandboxEnv, zn as buildAttachmentPromptBlock, ut as buildContinuedFromVoiceNote, K as buildProgress, Bn as buildPromptParts, E as buildPromptRequestBody, Vn as buildPromptWithAttachments, Se as buildRequest, i as buildSandboxContextInput, dt as buildVoiceTranscriptMarkdown, ie as chatTurns, D as checkAssistantAiCredits, vt as chunkForSpeech, Hn as classifyAttachment, Ce as classifyHttpFailure, t as classifyQuotaError, dn as columnLetterToIndex, ke as configureSpeechEngine, yt as containsCjk, lr as copyToClipboard, Un as countInlineImageCandidates, Wn as countInlinedImageParts, O as createAssistantSandbox, k as createAssistantSession, De as createHostedTtsEngine, _r as createReadinessTracker, Oe as createRoutingSpeechEngine, ne as createSandboxAssistantTransport, Ae as createSpeechEngines, we as decodeAudioResponse, fn as decodeXmlEntities, Gn as detectDocumentFormat, Xt as detectScriptLocale, hr as deviceHasCamera, ci as dispatchAssistantQuotaExhausted, pn as docxXmlToText, A as downloadAssistantArtifact, Jr as downloadFile, Kn as estimateTurnBodyBytes, a as executeSandboxGraphQL, Yr as exportConversation, j as extendAssistantSandboxTTL, di as extractDocumentText, Pt as findAssistantLanguage, M as findExistingSandbox, Rt as findPendingWrite, mn as fitPdfPages, qn as formatBytes, hn as formatPageRanges, ur as getActorId, N as getAssistantArtifacts, q as getAssistantMedia, P as getAssistantMessages, F as getAssistantSession, I as getAssistantStreamAccess, J as getAssistantText, Jn as getAttachmentSendBlocker, x as getCapability, Yn as getExtension, g as getImageForMode, _ as getImageTagForMode, dr as getOrganizationId, Y as getRawMessageCreatedAt, v as getResourcesForMode, y as getSandboxImageRegistry, Xn as getSendableAttachments, je as getSpeechEngine, X as getToolProgress, fr as getWorkspaceId, ae as groupBySession, oe as groupConsecutiveBySession, Zn as hasAttachmentWorkInFlight, me as hostedLocaleFor, he as hostedSupportsLanguage, xr as imageHostLabel, Ge as isCapturing, Ke as isEcho, gn as isMostlyImagePages, ai as isMultimodalBodyRejection, n as isQuotaExhaustedError, Z as isReapedSandboxConnectionError, vr as isRecentlyVerified, Q as isRecoverable, oi as isRecoverableAssistantError, Sr as isRemoteImageSrc, $t as isSpeakingMessage, et as isSpeechBlocked, qe as isSubmittable, rr as isTurnInFlight, S as isUnknownFieldError, se as isVoiceTurn, _n as joinSheets, tt as languageDisplayName, $ as mapSessionToHistory, C as markSupported, w as markUnsupported, ee as mergeMessagesById, Pe as micIsInterrupt, L as modeRequiresConfirmWrites, Ir as nextModeIndex, nt as normalizeLangTag, li as notifyAiCreditsUpdated, Je as orbMode, vn as pageMarker, zt as parseConfirmationRefusal, Qn as parseDataUrl, yn as parseSharedStrings, ar as parseToolActivity, bn as parseWorkbookSheets, xn as pdfTextItemsToPage, Ye as planReplyConsumption, At as pollDelayMs, rt as primaryLanguageSubtag, r as quotaExhaustedEventName, Me as readSpeechEngineConfig, It as replyFollowsInput, R as reportAssistantAiTokenUsage, en as requiresCancel, Ne as resetSpeechEngine, Ft as resolveAssistantLanguage, Lt as resolveLanguagePair, Vt as resolveModeConfig, b as resolveSandboxAssistantMode, Zt as resolveSpeechLocale, te as sanitize, z as selectExistingAssistantSandbox, it as selectVoiceForLocale, B as sendAssistantPromptAsync, V as sendHeartbeat, Sn as sheetXmlToRows, Te as shouldDisableEngine, Fe as showsAssistantCaption, Ie as showsUserCaption, bt as speakableEmail, at as speechGate, Yt as speechLabelsFor, ot as speechLangForLocale, tn as speechPlaybackReducer, Ee as splitForVendor, xt as splitTableRow, Xe as spokenSoFar, H as stopReapedAssistantSandbox, Cn as summarisePageText, jt as toCaptionText, $n as toMessageAttachment, St as toSpeakableText, er as truncateForInline, wn as truncatePagesForInline, ri as useAssistantApiAccess, fi as useAssistantAttachments, Kt as useAssistantI18nNamespace, Ht as useAssistantProduct, Ut as useAssistantProductOrNull, sr as useAssistantSpeech, nr as useAssistantStore, qt as useAssistantTr, ii as useConversationTurns, re as useSandboxAssistantTransport, e as useVoiceInput, cr as useVoiceSession, ui as useWorkspaceWriteAccess, tr as validateFile, st as voiceAvailability, ce as voiceMarker, wt as voicePreviewText, ct as voiceQualityRank, le as voiceSessionIdOf, Ze as voiceSessionReducer, Le as voiceStageState, ft as voiceTranscriptFilename, ue as voiceTurnsOnly, lt as voicesForLocale, U as waitForAssistantServiceReady, W as waitForSandboxRunning, Re as waveformIsActive, ze as waveformIsSettled };
85
+ import { isProdRuntime as mi } from "./shared/assistant/env.js";
86
+ import { useAssistantHeartbeat as hi } from "./shared/assistant/useAssistantHeartbeat.js";
87
+ import { useAssistantKeyboardShortcuts as gi } from "./shared/assistant/useAssistantKeyboardShortcuts.js";
88
+ import { AssistantApiCallsConsentDialog as _i } from "./shared/assistant/ui/AssistantApiCallsConsentDialog.js";
89
+ import { AssistantChatArea as vi } from "./shared/assistant/ui/AssistantChatArea.js";
90
+ import { AIAssistantPanel as yi } from "./shared/assistant/ui/AIAssistantPanel.js";
91
+ export { yi as AIAssistantPanel, h as ASSISTANT_API_AUTH_STRATEGY, Mt as ASSISTANT_LANGUAGES, Pr as ASSISTANT_MODE_META, Tn as ATTACHMENT_ACCEPT, pr as ATTACHMENT_SOURCES, Rr as AUTO_VOICE, _i as AssistantApiCallsConsentDialog, Ar as AssistantAttachmentButton, jr as AssistantAttachmentChips, yr as AssistantAutoSpeakToggle, vi as AssistantChatArea, pi as AssistantComposer, Qr as AssistantConversationList, $r as AssistantEmptyState, Zr as AssistantHeader, Wt as AssistantI18nProvider, Mr as AssistantLanguageSelector, br as AssistantMarkdownImage, Cr as AssistantMarkdownRenderer, Tr as AssistantMessageAttachments, ei as AssistantMessageItem, ti as AssistantMessageList, Fr as AssistantModeSelector, Xr as AssistantMoreMenu, Er as AssistantPendingWriteCard, Bt as AssistantProductProvider, Dr as AssistantReplyLanguageSelector, G as AssistantRuntimeManager, Or as AssistantSpeakButton, or as AssistantSpeechProvider, kr as AssistantSpokenTurnsNotice, ir as AssistantToolActivity, Lr as AssistantVoiceButton, Br as AssistantVoiceOrb, zr as AssistantVoiceSelector, ni as AssistantVoiceSession, Vr as AssistantVoiceSessionButton, En as AttachmentRejectedError, an as BOILERPLATE_PAGE_SHARE, o as CHECK_AI_CREDITS, s as CREATE_SANDBOX, pt as DEFAULT_SPEAKABLE_LABELS, Nt as DEFAULT_SPEECH_RATE, Be as ENDPOINT_GRACE_MS, c as EXTEND_SANDBOX_TTL, Nr as FOLLOW_APP_LOCALE, l as GET_ACTIVE_SANDBOXES, u as GET_SANDBOX, ge as HOSTED_TTS_MAX_CHARS, fe as HOSTED_TTS_TIER, pe as HOSTED_VOICES, Qt as IDLE_PLAYBACK, Ve as INITIAL_SESSION, Dn as INLINE_IMAGE_MAX_DIM, On as INLINE_IMAGE_QUALITY, He as INTERRUPT_MAX_MS, Ue as INTERRUPT_MIN_MS, kn as MAX_ATTACHMENTS, on as MAX_BOILERPLATE_LINE_CHARS, sn as MAX_EXTRACTED_CHARS, An as MAX_FILE_BYTES, jn as MAX_INLINE_CHARS_PER_FILE, Mn as MAX_INLINE_CHARS_TOTAL, nn as MAX_INLINE_IMAGE_BASE64_BYTES, Nn as MAX_INLINE_IMAGE_BASE64_CHARS, Pn as MAX_INLINE_IMAGE_PARTS, Fn as MAX_INLINE_TURN_BODY_BYTES, cn as MAX_PDF_PAGES_SCANNED, rn as MAX_REQUEST_BODY_BYTES, mt as MAX_SPEAKABLE_CHARS, ht as MAX_SPOKEN_TABLE_ROWS, In as MAX_TURN_BODY_BYTES, ln as MIN_PAGE_TEXT_CHARS, un as MIN_TEXT_PAGE_SHARE, Tt as POLL_FAST_MS, Et as POLL_FAST_UNTIL_MS, Dt as POLL_SLOW_MS, Ot as POLL_STEADY_MS, kt as POLL_STEADY_UNTIL_MS, Ct as PREVIEW_LANGUAGES, Ln as PROMPT_ENVELOPE_RESERVE_BYTES, d as PROXY_SANDBOX_REQUEST, f as REPORT_AI_TOKEN_USAGE, gr as SANDBOX_READY_TTL_MS, We as SILENCE_SUBMIT_MS, _e as SPEAKING_RATE_MAX, ve as SPEAKING_RATE_MAX_STREAMING, ye as SPEAKING_RATE_MAX_SYNC, be as SPEAKING_RATE_MIN, gt as SPEECH_CHUNK_CHARS, _t as SPEECH_CHUNK_CJK_CHARS, Qe as SPEECH_LANG, Jt as SPOKEN_LABEL_LANGUAGES, p as STOP_ASSISTANT_SANDBOX, Rn as TURN_BODY_HEADROOM_BYTES, $e as VOICE_LIST_TIMEOUT_MS, Hr as VoiceCaption, Ur as VoiceConversationView, Gr as VoiceMiniController, Kr as VoiceStage, qr as VoiceTranscriptDrawer, Wr as VoiceWaveform, m as WAIT_FOR_SANDBOX_RUNNING, si as aiCreditsUpdatedEventName, Gt as assistantTranslationKey, wr as assistantUrlTransform, mr as availableAttachmentSources, xe as base64ToBytes, de as browserSpeechEngine, T as buildAssistantSandboxEnv, zn as buildAttachmentPromptBlock, ut as buildContinuedFromVoiceNote, K as buildProgress, Bn as buildPromptParts, E as buildPromptRequestBody, Vn as buildPromptWithAttachments, Se as buildRequest, i as buildSandboxContextInput, dt as buildVoiceTranscriptMarkdown, ie as chatTurns, D as checkAssistantAiCredits, vt as chunkForSpeech, Hn as classifyAttachment, Ce as classifyHttpFailure, t as classifyQuotaError, dn as columnLetterToIndex, ke as configureSpeechEngine, yt as containsCjk, lr as copyToClipboard, Un as countInlineImageCandidates, Wn as countInlinedImageParts, O as createAssistantSandbox, k as createAssistantSession, De as createHostedTtsEngine, _r as createReadinessTracker, Oe as createRoutingSpeechEngine, ne as createSandboxAssistantTransport, Ae as createSpeechEngines, we as decodeAudioResponse, fn as decodeXmlEntities, Gn as detectDocumentFormat, Xt as detectScriptLocale, hr as deviceHasCamera, ci as dispatchAssistantQuotaExhausted, pn as docxXmlToText, A as downloadAssistantArtifact, Jr as downloadFile, Kn as estimateTurnBodyBytes, a as executeSandboxGraphQL, Yr as exportConversation, j as extendAssistantSandboxTTL, di as extractDocumentText, Pt as findAssistantLanguage, M as findExistingSandbox, Rt as findPendingWrite, mn as fitPdfPages, qn as formatBytes, hn as formatPageRanges, ur as getActorId, N as getAssistantArtifacts, q as getAssistantMedia, P as getAssistantMessages, F as getAssistantSession, I as getAssistantStreamAccess, J as getAssistantText, Jn as getAttachmentSendBlocker, x as getCapability, Yn as getExtension, g as getImageForMode, _ as getImageTagForMode, dr as getOrganizationId, Y as getRawMessageCreatedAt, v as getResourcesForMode, y as getSandboxImageRegistry, Xn as getSendableAttachments, je as getSpeechEngine, X as getToolProgress, fr as getWorkspaceId, ae as groupBySession, oe as groupConsecutiveBySession, Zn as hasAttachmentWorkInFlight, me as hostedLocaleFor, he as hostedSupportsLanguage, xr as imageHostLabel, Ge as isCapturing, Ke as isEcho, gn as isMostlyImagePages, ai as isMultimodalBodyRejection, mi as isProdRuntime, n as isQuotaExhaustedError, Z as isReapedSandboxConnectionError, vr as isRecentlyVerified, Q as isRecoverable, oi as isRecoverableAssistantError, Sr as isRemoteImageSrc, $t as isSpeakingMessage, et as isSpeechBlocked, qe as isSubmittable, rr as isTurnInFlight, S as isUnknownFieldError, se as isVoiceTurn, _n as joinSheets, tt as languageDisplayName, $ as mapSessionToHistory, C as markSupported, w as markUnsupported, ee as mergeMessagesById, Pe as micIsInterrupt, L as modeRequiresConfirmWrites, Ir as nextModeIndex, nt as normalizeLangTag, li as notifyAiCreditsUpdated, Je as orbMode, vn as pageMarker, zt as parseConfirmationRefusal, Qn as parseDataUrl, yn as parseSharedStrings, ar as parseToolActivity, bn as parseWorkbookSheets, xn as pdfTextItemsToPage, Ye as planReplyConsumption, At as pollDelayMs, rt as primaryLanguageSubtag, r as quotaExhaustedEventName, Me as readSpeechEngineConfig, It as replyFollowsInput, R as reportAssistantAiTokenUsage, en as requiresCancel, Ne as resetSpeechEngine, Ft as resolveAssistantLanguage, Lt as resolveLanguagePair, Vt as resolveModeConfig, b as resolveSandboxAssistantMode, Zt as resolveSpeechLocale, te as sanitize, z as selectExistingAssistantSandbox, it as selectVoiceForLocale, B as sendAssistantPromptAsync, V as sendHeartbeat, Sn as sheetXmlToRows, Te as shouldDisableEngine, Fe as showsAssistantCaption, Ie as showsUserCaption, bt as speakableEmail, at as speechGate, Yt as speechLabelsFor, ot as speechLangForLocale, tn as speechPlaybackReducer, Ee as splitForVendor, xt as splitTableRow, Xe as spokenSoFar, H as stopReapedAssistantSandbox, Cn as summarisePageText, jt as toCaptionText, $n as toMessageAttachment, St as toSpeakableText, er as truncateForInline, wn as truncatePagesForInline, ri as useAssistantApiAccess, fi as useAssistantAttachments, hi as useAssistantHeartbeat, Kt as useAssistantI18nNamespace, gi as useAssistantKeyboardShortcuts, Ht as useAssistantProduct, Ut as useAssistantProductOrNull, sr as useAssistantSpeech, nr as useAssistantStore, qt as useAssistantTr, ii as useConversationTurns, re as useSandboxAssistantTransport, e as useVoiceInput, cr as useVoiceSession, ui as useWorkspaceWriteAccess, tr as validateFile, st as voiceAvailability, ce as voiceMarker, wt as voicePreviewText, ct as voiceQualityRank, le as voiceSessionIdOf, Ze as voiceSessionReducer, Le as voiceStageState, ft as voiceTranscriptFilename, ue as voiceTurnsOnly, lt as voicesForLocale, U as waitForAssistantServiceReady, W as waitForSandboxRunning, Re as waveformIsActive, ze as waveformIsSettled };
@@ -48,4 +48,5 @@ export { OfflineBanner, type OfflineBannerProps } from './offline-banner';
48
48
  export { PullToRefresh, type PullToRefreshProps } from './pull-to-refresh';
49
49
  export { PWAUpdateToast, type PWAUpdateToastProps } from './pwa-update-toast';
50
50
  export { NativeSelect, type NativeSelectProps, type NativeSelectOption } from './select';
51
+ export { ModalShell, type ModalShellProps } from './modal-shell';
51
52
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { ReactNode } from 'react';
2
+ export interface ModalShellProps {
3
+ open: boolean;
4
+ onClose: () => void;
5
+ title: string;
6
+ description?: string;
7
+ children: ReactNode;
8
+ size?: 'sm' | 'md' | 'lg' | 'xl';
9
+ footer?: ReactNode;
10
+ }
11
+ /**
12
+ * Title / body / footer scaffold over `ResponsiveDialog` — centred on desktop,
13
+ * a bottom sheet on mobile.
14
+ *
15
+ * ★ Named `ModalShell` rather than `Modal` on purpose. Products routinely have
16
+ * their own `Modal`, and a bare `Modal` exported from the design system reads as
17
+ * a replacement for it rather than the thing underneath it. This composes the
18
+ * primitives (which already own the scrim, Escape, focus trap and scroll lock);
19
+ * it does not replace them.
20
+ */
21
+ export declare function ModalShell({ open, onClose, title, description, children, size, footer, }: ModalShellProps): import("react/jsx-runtime").JSX.Element;
22
+ //# sourceMappingURL=modal-shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal-shell.d.ts","sourceRoot":"","sources":["../../src/ui/modal-shell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAWvC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AASD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,OAAO,EACP,KAAK,EACL,WAAW,EACX,QAAQ,EACR,IAAW,EACX,MAAM,GACP,EAAE,eAAe,2CA8BjB"}
@@ -0,0 +1,30 @@
1
+ import { ResponsiveDialog as e, ResponsiveDialogContent as t, ResponsiveDialogDescription as n, ResponsiveDialogFooter as r, ResponsiveDialogHeader as i, ResponsiveDialogTitle as a } from "./responsive-dialog.js";
2
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
3
+ //#region src/ui/modal-shell.tsx
4
+ var c = {
5
+ sm: "sm:max-w-sm",
6
+ md: "sm:max-w-lg",
7
+ lg: "sm:max-w-2xl",
8
+ xl: "sm:max-w-3xl"
9
+ };
10
+ function l({ open: l, onClose: u, title: d, description: f, children: p, size: m = "md", footer: h }) {
11
+ return /* @__PURE__ */ o(e, {
12
+ open: l,
13
+ onOpenChange: (e) => {
14
+ e || u();
15
+ },
16
+ children: /* @__PURE__ */ s(t, {
17
+ className: c[m],
18
+ children: [
19
+ /* @__PURE__ */ s(i, { children: [d && /* @__PURE__ */ o(a, { children: d }), f && /* @__PURE__ */ o(n, { children: f })] }),
20
+ /* @__PURE__ */ o("div", {
21
+ className: "max-h-[60dvh] overflow-y-auto overscroll-contain pr-1",
22
+ children: p
23
+ }),
24
+ h && /* @__PURE__ */ o(r, { children: h })
25
+ ]
26
+ })
27
+ });
28
+ }
29
+ //#endregion
30
+ export { l as ModalShell };
package/dist/ui.js CHANGED
@@ -47,4 +47,5 @@ import { ActionSheet as Bt } from "./ui/action-sheet.js";
47
47
  import { OfflineBanner as Vt } from "./ui/offline-banner.js";
48
48
  import { PullToRefresh as Ht } from "./ui/pull-to-refresh.js";
49
49
  import { PWAUpdateToast as Ut } from "./ui/pwa-update-toast.js";
50
- export { e as Accordion, t as AccordionContent, n as AccordionItem, r as AccordionTrigger, Bt as ActionSheet, oe as AlertDialog, se as AlertDialogAction, ce as AlertDialogCancel, le as AlertDialogContent, ue as AlertDialogDescription, de as AlertDialogFooter, fe as AlertDialogHeader, pe as AlertDialogOverlay, me as AlertDialogPortal, he as AlertDialogTitle, ge as AlertDialogTrigger, Nt as AuroraBackground, _e as Badge, _ as BottomSheet, v as BottomSheetClose, y as BottomSheetContent, b as BottomSheetDescription, x as BottomSheetFooter, S as BottomSheetHeader, C as BottomSheetTitle, w as BottomSheetTrigger, N as BrandedSplash, U as Button, jt as CTAOverflowMenu, ye as Card, be as CardContent, xe as CardDescription, Se as CardFooter, Ce as CardHeader, we as CardTitle, Te as Checkbox, Ee as Command, De as CommandDialog, Oe as CommandEmpty, ke as CommandGroup, Ae as CommandInput, je as CommandItem, Me as CommandList, Ne as CommandSeparator, Pe as CommandShortcut, i as Dialog, a as DialogClose, o as DialogContent, s as DialogDescription, c as DialogFooter, l as DialogHeader, u as DialogOverlay, d as DialogPortal, f as DialogTitle, p as DialogTrigger, Fe as DropdownMenu, Ie as DropdownMenuCheckboxItem, Le as DropdownMenuContent, Re as DropdownMenuGroup, ze as DropdownMenuItem, Be as DropdownMenuLabel, Ve as DropdownMenuPortal, He as DropdownMenuRadioGroup, Ue as DropdownMenuRadioItem, We as DropdownMenuSeparator, Ge as DropdownMenuShortcut, Ke as DropdownMenuSub, qe as DropdownMenuSubContent, Je as DropdownMenuSubTrigger, Ye as DropdownMenuTrigger, kt as EmphasisPanel, ae as EmptyState, m as EntityIdModal, Dt as GlassCard, It as GradientText, Pt as IllustratedEmptyState, Ft as Illustration, Xe as Input, Ze as Label, Mt as ModernLanding, G as NativeSelect, zt as NativeWelcome, Lt as NextSteps, Vt as OfflineBanner, g as OptionalFields, Ut as PWAUpdateToast, Et as PageContainer, Rt as PagePurpose, ne as Pagination, Qe as Popover, $e as PopoverAnchor, et as PopoverContent, tt as PopoverTrigger, Ht as PullToRefresh, T as ResponsiveDialog, E as ResponsiveDialogClose, D as ResponsiveDialogContent, O as ResponsiveDialogDescription, k as ResponsiveDialogFooter, A as ResponsiveDialogHeader, j as ResponsiveDialogTitle, M as ResponsiveDialogTrigger, ie as ResponsiveStack, H as ResponsiveTable, nt as ScrollArea, rt as ScrollBar, K as Select, q as SelectContent, J as SelectGroup, Y as SelectItem, X as SelectLabel, Z as SelectScrollDownButton, Q as SelectScrollUpButton, $ as SelectSeparator, ee as SelectTrigger, te as SelectValue, it as Separator, at as Sheet, ot as SheetClose, st as SheetContent, ct as SheetDescription, lt as SheetFooter, ut as SheetHeader, dt as SheetTitle, ft as SheetTrigger, At as ShowMore, pt as Skeleton, ht as Spinner, re as Stepper, gt as Switch, P as Table, F as TableBody, I as TableCaption, L as TableCell, R as TableFooter, z as TableHead, B as TableHeader, V as TableRow, _t as Tabs, vt as TabsContent, yt as TabsList, bt as TabsTrigger, xt as Textarea, mt as Toaster, St as Tooltip, Ct as TooltipContent, wt as TooltipProvider, Tt as TooltipTrigger, ve as badgeVariants, W as buttonVariants, Ot as glassCardVariants, h as useEntityIdModal };
50
+ import { ModalShell as Wt } from "./ui/modal-shell.js";
51
+ export { e as Accordion, t as AccordionContent, n as AccordionItem, r as AccordionTrigger, Bt as ActionSheet, oe as AlertDialog, se as AlertDialogAction, ce as AlertDialogCancel, le as AlertDialogContent, ue as AlertDialogDescription, de as AlertDialogFooter, fe as AlertDialogHeader, pe as AlertDialogOverlay, me as AlertDialogPortal, he as AlertDialogTitle, ge as AlertDialogTrigger, Nt as AuroraBackground, _e as Badge, _ as BottomSheet, v as BottomSheetClose, y as BottomSheetContent, b as BottomSheetDescription, x as BottomSheetFooter, S as BottomSheetHeader, C as BottomSheetTitle, w as BottomSheetTrigger, N as BrandedSplash, U as Button, jt as CTAOverflowMenu, ye as Card, be as CardContent, xe as CardDescription, Se as CardFooter, Ce as CardHeader, we as CardTitle, Te as Checkbox, Ee as Command, De as CommandDialog, Oe as CommandEmpty, ke as CommandGroup, Ae as CommandInput, je as CommandItem, Me as CommandList, Ne as CommandSeparator, Pe as CommandShortcut, i as Dialog, a as DialogClose, o as DialogContent, s as DialogDescription, c as DialogFooter, l as DialogHeader, u as DialogOverlay, d as DialogPortal, f as DialogTitle, p as DialogTrigger, Fe as DropdownMenu, Ie as DropdownMenuCheckboxItem, Le as DropdownMenuContent, Re as DropdownMenuGroup, ze as DropdownMenuItem, Be as DropdownMenuLabel, Ve as DropdownMenuPortal, He as DropdownMenuRadioGroup, Ue as DropdownMenuRadioItem, We as DropdownMenuSeparator, Ge as DropdownMenuShortcut, Ke as DropdownMenuSub, qe as DropdownMenuSubContent, Je as DropdownMenuSubTrigger, Ye as DropdownMenuTrigger, kt as EmphasisPanel, ae as EmptyState, m as EntityIdModal, Dt as GlassCard, It as GradientText, Pt as IllustratedEmptyState, Ft as Illustration, Xe as Input, Ze as Label, Wt as ModalShell, Mt as ModernLanding, G as NativeSelect, zt as NativeWelcome, Lt as NextSteps, Vt as OfflineBanner, g as OptionalFields, Ut as PWAUpdateToast, Et as PageContainer, Rt as PagePurpose, ne as Pagination, Qe as Popover, $e as PopoverAnchor, et as PopoverContent, tt as PopoverTrigger, Ht as PullToRefresh, T as ResponsiveDialog, E as ResponsiveDialogClose, D as ResponsiveDialogContent, O as ResponsiveDialogDescription, k as ResponsiveDialogFooter, A as ResponsiveDialogHeader, j as ResponsiveDialogTitle, M as ResponsiveDialogTrigger, ie as ResponsiveStack, H as ResponsiveTable, nt as ScrollArea, rt as ScrollBar, K as Select, q as SelectContent, J as SelectGroup, Y as SelectItem, X as SelectLabel, Z as SelectScrollDownButton, Q as SelectScrollUpButton, $ as SelectSeparator, ee as SelectTrigger, te as SelectValue, it as Separator, at as Sheet, ot as SheetClose, st as SheetContent, ct as SheetDescription, lt as SheetFooter, ut as SheetHeader, dt as SheetTitle, ft as SheetTrigger, At as ShowMore, pt as Skeleton, ht as Spinner, re as Stepper, gt as Switch, P as Table, F as TableBody, I as TableCaption, L as TableCell, R as TableFooter, z as TableHead, B as TableHeader, V as TableRow, _t as Tabs, vt as TabsContent, yt as TabsList, bt as TabsTrigger, xt as Textarea, mt as Toaster, St as Tooltip, Ct as TooltipContent, wt as TooltipProvider, Tt as TooltipTrigger, ve as badgeVariants, W as buttonVariants, Ot as glassCardVariants, h as useEntityIdModal };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fe-libs",
3
- "version": "2026.904.23",
3
+ "version": "2026.904.24",
4
4
  "description": "Burdenoff frontend primitives and domain libraries",
5
5
  "type": "module",
6
6
  "bin": {