@burdenoff/fe-libs 2026.713.2 → 2026.713.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,6 +13,22 @@ export interface AssistantWidgetProps {
13
13
  launcherClassName?: string;
14
14
  /** Speech-recognition language tag. */
15
15
  voiceLang?: string;
16
+ /**
17
+ * `floating` (default) — the small bottom-right popover every product uses.
18
+ * `sidebar` — a full-height panel docked to the right edge, for products whose
19
+ * assistant does long multi-step work worth watching (BigConsole).
20
+ *
21
+ * Defaulted, so a product that passes nothing keeps the exact UI it has today.
22
+ */
23
+ layout?: 'floating' | 'sidebar';
24
+ /**
25
+ * Show the conversations rail (New chat / Clear chat / History).
26
+ * Ignored unless the transport actually implements session management —
27
+ * a panel whose buttons do nothing is worse than no panel.
28
+ */
29
+ showSessionPanel?: boolean;
30
+ /** Route in-app links from assistant replies without a full page reload. */
31
+ onNavigate?: (href: string) => void;
16
32
  }
17
33
  /** External toggle hook so command palettes / plugins can open the widget. */
18
34
  export declare const ASSISTANT_WIDGET_TOGGLE_EVENT = "bf:toggle-assistant-widget";
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantWidget.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/AssistantWidget.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAML,KAAK,EAAE,EAER,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,kBAAkB,EAA0B,MAAM,SAAS,CAAC;AAE1E,MAAM,WAAW,oBAAoB;IACnC,oDAAoD;IACpD,SAAS,EAAE,kBAAkB,CAAC;IAC9B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,8EAA8E;AAC9E,eAAO,MAAM,6BAA6B,+BAA+B,CAAC;AAyB1E,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CAkVpD,CAAC"}
1
+ {"version":3,"file":"AssistantWidget.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/AssistantWidget.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAML,KAAK,EAAE,EAER,MAAM,OAAO,CAAC;AAef,OAAO,KAAK,EAA2B,kBAAkB,EAA0B,MAAM,SAAS,CAAC;AAEnG,MAAM,WAAW,oBAAoB;IACnC,oDAAoD;IACpD,SAAS,EAAE,kBAAkB,CAAC;IAC9B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,8EAA8E;AAC9E,eAAO,MAAM,6BAA6B,+BAA+B,CAAC;AAyB1E,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CA+epD,CAAC"}
@@ -1,86 +1,120 @@
1
1
  import { cn as e } from "../../utils/cn.js";
2
2
  import { useVoiceInput as t } from "./useVoiceInput.js";
3
- import { useCallback as n, useEffect as r, useMemo as i, useRef as a, useState as o } from "react";
4
- import { Loader2 as s, MessageCircle as c, Mic as l, Send as u, Sparkles as d, X as f } from "lucide-react";
5
- import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
3
+ import { MessageContent as n } from "./MessageContent.js";
4
+ import { useCallback as r, useEffect as i, useMemo as ee, useRef as a, useState as o } from "react";
5
+ import { History as te, Loader2 as s, MessageCircle as ne, Mic as c, Plus as re, Send as ie, Sparkles as l, Trash2 as u, X as d } from "lucide-react";
6
+ import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
6
7
  //#region src/shared/components/assistantWidget/AssistantWidget.tsx
7
- var g = "bf:toggle-assistant-widget", _ = "bf:assistant-widget:isOpen";
8
- function v() {
8
+ var h = "bf:toggle-assistant-widget", g = "bf:assistant-widget:isOpen";
9
+ function _() {
9
10
  if (typeof window > "u") return !1;
10
11
  try {
11
- return window.sessionStorage.getItem(_) === "1";
12
+ return window.sessionStorage.getItem(g) === "1";
12
13
  } catch {
13
14
  return !1;
14
15
  }
15
16
  }
16
- function y(e) {
17
+ function v(e) {
17
18
  if (!(typeof window > "u")) try {
18
- window.sessionStorage.setItem(_, e ? "1" : "0");
19
+ window.sessionStorage.setItem(g, e ? "1" : "0");
19
20
  } catch {}
20
21
  }
21
- function b() {
22
+ function y() {
22
23
  return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
23
24
  }
24
- var x = ({ transport: _, title: x = "AI Assistant", subtitle: S = "Ask me to do things on this screen — I can run them for you.", placeholder: C = "Ask anything, or describe what to create…", launcherClassName: w, voiceLang: T = "en-US" }) => {
25
- let [E, D] = o(() => v()), [O, k] = o([]), [A, j] = o(""), [M, N] = o(!1), [P, F] = o(!1), I = a(null), L = a(null), R = a(null), z = a(!1), B = t(T), V = n(() => {
26
- y(!0), D(!0);
27
- }, []), H = n(() => {
28
- y(!1), D(!1);
29
- }, []), U = n(() => {
30
- D((e) => {
25
+ var b = ({ transport: g, title: b = "AI Assistant", subtitle: x = "Ask me to do things on this screen — I can run them for you.", placeholder: ae = "Ask anything, or describe what to create…", launcherClassName: S, voiceLang: C = "en-US", layout: w = "floating", showSessionPanel: T = !1, onNavigate: E }) => {
26
+ let [D, O] = o(() => _()), [k, A] = o([]), [j, M] = o(""), [N, P] = o(!1), [F, I] = o(!1), [L, R] = o([]), [z, B] = o(!1), V = a(null), H = a(null), U = a(null), W = a(!1), G = w === "sidebar", K = T && !!(g.newSession && g.clearSession), q = t(C), J = r(() => {
27
+ v(!0), O(!0);
28
+ }, []), Y = r(() => {
29
+ v(!1), O(!1);
30
+ }, []), X = r(() => {
31
+ O((e) => {
31
32
  let t = !e;
32
- return y(t), t;
33
+ return v(t), t;
33
34
  });
34
35
  }, []);
35
- r(() => {
36
+ i(() => {
36
37
  let e = (e) => {
37
38
  let t = e.detail;
38
- t?.open === !0 ? V() : t?.open === !1 ? H() : U();
39
+ t?.open === !0 ? J() : t?.open === !1 ? Y() : X();
39
40
  };
40
- return window.addEventListener(g, e), () => window.removeEventListener(g, e);
41
+ return window.addEventListener(h, e), () => window.removeEventListener(h, e);
41
42
  }, [
42
- V,
43
- H,
44
- U
45
- ]), r(() => {
46
- B.isListening && B.transcript && j(B.transcript);
47
- }, [B.transcript, B.isListening]), r(() => {
48
- if (!E || z.current) return;
49
- let e = _.loadHistory;
43
+ J,
44
+ Y,
45
+ X
46
+ ]), i(() => {
47
+ q.isListening && q.transcript && M(q.transcript);
48
+ }, [q.transcript, q.isListening]), i(() => {
49
+ if (!D || W.current) return;
50
+ let e = g.loadHistory;
50
51
  if (!e) {
51
- z.current = !0;
52
+ W.current = !0;
52
53
  return;
53
54
  }
54
- z.current = !0;
55
+ W.current = !0;
55
56
  let t = !1;
56
- return F(!0), (async () => {
57
+ return I(!0), (async () => {
57
58
  try {
58
59
  let n = await e();
59
- !t && n.length > 0 && k((e) => e.length === 0 ? n : e);
60
+ !t && n.length > 0 && A((e) => e.length === 0 ? n : e);
60
61
  } catch {} finally {
61
- t || F(!1);
62
+ t || I(!1);
62
63
  }
63
64
  })(), () => {
64
65
  t = !0;
65
66
  };
66
- }, [E, _]), r(() => {
67
- E && L.current && (L.current.scrollTop = L.current.scrollHeight);
68
- }, [O, E]);
69
- let W = n((e, t) => {
70
- k((n) => n.map((n) => n.id === e ? {
67
+ }, [D, g]), i(() => {
68
+ D && H.current && (H.current.scrollTop = H.current.scrollHeight);
69
+ }, [k, D]);
70
+ let Z = r((e, t) => {
71
+ A((n) => n.map((n) => n.id === e ? {
71
72
  ...n,
72
73
  ...t
73
74
  } : n));
74
- }, []), G = n(async () => {
75
- let e = A.trim();
76
- if (!e || M) return;
77
- B.isListening && B.stop(), B.reset(), j(""), I.current && (I.current.style.height = "auto");
75
+ }, []), Q = r(async () => {
76
+ if (g.listSessions) try {
77
+ R(await g.listSessions());
78
+ } catch {
79
+ R([]);
80
+ }
81
+ }, [g]), oe = r(async () => {
82
+ !g.newSession || N || (await g.newSession(), A([]), M(""), Q());
83
+ }, [
84
+ g,
85
+ N,
86
+ Q
87
+ ]), se = r(async () => {
88
+ !g.clearSession || N || (await g.clearSession(), A([]), M(""), Q());
89
+ }, [
90
+ g,
91
+ N,
92
+ Q
93
+ ]), ce = r(() => {
94
+ B((e) => (e || Q(), !e));
95
+ }, [Q]), le = r(async (e) => {
96
+ if (!(!g.selectSession || N)) {
97
+ I(!0);
98
+ try {
99
+ A(await g.selectSession(e)), B(!1), Q();
100
+ } catch {} finally {
101
+ I(!1);
102
+ }
103
+ }
104
+ }, [
105
+ g,
106
+ N,
107
+ Q
108
+ ]), $ = r(async () => {
109
+ let e = j.trim();
110
+ if (!e || N) return;
111
+ q.isListening && q.stop(), q.reset(), M(""), V.current && (V.current.style.height = "auto");
78
112
  let t = {
79
- id: b(),
113
+ id: y(),
80
114
  role: "user",
81
115
  content: e
82
- }, n = b();
83
- k((e) => [
116
+ }, n = y();
117
+ A((e) => [
84
118
  ...e,
85
119
  t,
86
120
  {
@@ -89,149 +123,203 @@ var x = ({ transport: _, title: x = "AI Assistant", subtitle: S = "Ask me to do
89
123
  content: "",
90
124
  pending: !0
91
125
  }
92
- ]), N(!0);
126
+ ]), P(!0);
93
127
  let r = new AbortController();
94
- R.current = r;
128
+ U.current = r;
95
129
  try {
96
- let { text: t } = await _.sendPrompt({
130
+ let { text: t } = await g.sendPrompt({
97
131
  prompt: e,
98
132
  signal: r.signal,
99
- onProgress: (e) => W(n, { content: e })
133
+ onProgress: (e) => Z(n, { content: e })
100
134
  });
101
- W(n, {
135
+ Z(n, {
102
136
  content: t,
103
137
  pending: !1
104
138
  });
105
139
  } catch (e) {
106
- W(n, {
140
+ Z(n, {
107
141
  content: `Sorry, I couldn't complete that: ${e instanceof Error ? e.message : "Something went wrong. Please try again."}`,
108
142
  pending: !1,
109
143
  error: !0
110
144
  });
111
145
  } finally {
112
- N(!1), R.current = null;
146
+ P(!1), U.current = null, z && Q();
113
147
  }
114
148
  }, [
115
- A,
116
- M,
117
- W,
118
- _,
119
- B
120
- ]), K = n((e) => {
121
- e.key === "Enter" && !e.shiftKey && (e.preventDefault(), G());
122
- }, [G]), q = n(() => {
123
- let e = I.current;
149
+ j,
150
+ N,
151
+ Z,
152
+ g,
153
+ q,
154
+ z,
155
+ Q
156
+ ]), ue = r((e) => {
157
+ e.key === "Enter" && !e.shiftKey && (e.preventDefault(), $());
158
+ }, [$]), de = r(() => {
159
+ let e = V.current;
124
160
  e && (e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, 120)}px`);
125
- }, []), J = n(() => {
126
- B.isListening ? B.stop() : B.start();
127
- }, [B]);
128
- return /* @__PURE__ */ h(p, { children: [i(() => /* @__PURE__ */ m("button", {
161
+ }, []), fe = r(() => {
162
+ q.isListening ? q.stop() : q.start();
163
+ }, [q]);
164
+ return /* @__PURE__ */ m(f, { children: [ee(() => /* @__PURE__ */ p("button", {
129
165
  type: "button",
130
- onClick: U,
131
- "aria-label": E ? "Close AI assistant" : "Open AI assistant",
132
- "aria-expanded": E,
166
+ onClick: X,
167
+ "aria-label": D ? "Close AI assistant" : "Open AI assistant",
168
+ "aria-expanded": D,
133
169
  "data-testid": "assistant-widget-launcher",
134
- className: e("fixed bottom-6 right-6 z-[100] inline-flex size-14 items-center justify-center rounded-full", "bg-action-primary-bg text-action-primary-text shadow-xl transition-transform duration-200", "hover:scale-105 hover:bg-action-primary-bg-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong cursor-pointer", w),
135
- children: m(E ? f : d, { className: "size-6" })
170
+ className: e("fixed bottom-6 right-6 z-[100] inline-flex size-14 items-center justify-center rounded-full", "bg-action-primary-bg text-action-primary-text shadow-xl transition-transform duration-200", "hover:scale-105 hover:bg-action-primary-bg-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong cursor-pointer", S),
171
+ children: p(D ? d : l, { className: "size-6" })
136
172
  }), [
137
- E,
138
- U,
139
- w
140
- ]), E ? /* @__PURE__ */ h("div", {
173
+ D,
174
+ X,
175
+ S
176
+ ]), D ? /* @__PURE__ */ m("div", {
141
177
  role: "dialog",
142
- "aria-label": x,
178
+ "aria-label": b,
143
179
  "data-testid": "assistant-widget-window",
144
- className: e("fixed z-[100] flex flex-col overflow-hidden rounded-xl border border-border-default bg-bg-surface shadow-2xl", "bottom-24 right-6 h-[560px] max-h-[calc(100vh-7rem)] w-[calc(100vw-3rem)] sm:w-[400px]", "animate-in slide-in-from-bottom-2 fade-in duration-200"),
145
- children: [
146
- /* @__PURE__ */ h("div", {
147
- className: "flex items-center justify-between gap-2 border-b border-border-subtle bg-bg-surface px-4 py-3",
148
- children: [/* @__PURE__ */ h("div", {
149
- className: "flex min-w-0 items-center gap-2",
150
- children: [/* @__PURE__ */ m("span", {
151
- className: "inline-flex size-7 shrink-0 items-center justify-center rounded-full bg-action-primary-bg/10 text-action-primary-bg",
152
- children: /* @__PURE__ */ m(d, { className: "size-4" })
153
- }), /* @__PURE__ */ m("h2", {
154
- className: "truncate text-sm font-semibold text-text-primary",
155
- children: x
156
- })]
157
- }), /* @__PURE__ */ m("button", {
180
+ "data-layout": w,
181
+ className: e("fixed z-[100] flex overflow-hidden border-border-default bg-bg-surface shadow-2xl", G ? "inset-y-0 right-0 h-screen w-full border-l sm:w-[480px] lg:w-[560px] animate-in slide-in-from-right duration-200" : "flex-col rounded-xl border bottom-24 right-6 h-[560px] max-h-[calc(100vh-7rem)] w-[calc(100vw-3rem)] sm:w-[400px] animate-in slide-in-from-bottom-2 fade-in duration-200"),
182
+ children: [G && K ? /* @__PURE__ */ m("aside", {
183
+ "data-testid": "assistant-session-panel",
184
+ className: "flex w-[168px] shrink-0 flex-col gap-1 border-r border-border-subtle bg-bg-sunken p-2",
185
+ children: [
186
+ /* @__PURE__ */ m("button", {
158
187
  type: "button",
159
- onClick: H,
160
- "aria-label": "Close AI assistant",
161
- "data-testid": "assistant-widget-close",
162
- className: "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong cursor-pointer",
163
- children: /* @__PURE__ */ m(f, { className: "size-4" })
164
- })]
165
- }),
166
- /* @__PURE__ */ m("div", {
167
- ref: L,
168
- className: "flex-1 space-y-3 overflow-y-auto px-4 py-4",
169
- "data-testid": "assistant-widget-messages",
170
- children: O.length === 0 && P ? /* @__PURE__ */ h("div", {
171
- "data-testid": "assistant-widget-restoring",
172
- className: "flex h-full flex-col items-center justify-center gap-3 text-center",
173
- children: [/* @__PURE__ */ m(s, { className: "size-5 animate-spin text-text-secondary" }), /* @__PURE__ */ m("p", {
174
- className: "text-xs leading-relaxed text-text-secondary",
175
- children: "Restoring your conversation…"
176
- })]
177
- }) : O.length === 0 ? /* @__PURE__ */ h("div", {
178
- className: "flex h-full flex-col items-center justify-center gap-3 text-center",
179
- children: [/* @__PURE__ */ m("span", {
180
- className: "inline-flex size-12 items-center justify-center rounded-full bg-bg-sunken text-action-primary-bg",
181
- children: /* @__PURE__ */ m(c, { className: "size-6" })
182
- }), /* @__PURE__ */ m("p", {
183
- className: "max-w-[16rem] text-xs leading-relaxed text-text-secondary",
184
- children: S
185
- })]
186
- }) : O.map((t) => /* @__PURE__ */ m("div", {
187
- className: e("flex", t.role === "user" ? "justify-end" : "justify-start"),
188
- children: /* @__PURE__ */ h("div", {
189
- "data-testid": `assistant-widget-message-${t.role}`,
190
- className: e("max-w-[85%] whitespace-pre-wrap break-words rounded-lg px-3 py-2 text-xs leading-relaxed", t.role === "user" ? "bg-action-primary-bg text-action-primary-text" : t.error ? "bg-status-error-bg/10 text-status-error-bg" : "bg-bg-sunken text-text-primary"),
191
- children: [t.content || (t.pending, ""), t.pending ? /* @__PURE__ */ h("span", {
192
- className: "mt-1 inline-flex items-center gap-1 text-text-secondary",
193
- children: [/* @__PURE__ */ m(s, { className: "size-3 animate-spin" }), /* @__PURE__ */ m("span", { children: "Thinking…" })]
194
- }) : null]
195
- })
196
- }, t.id))
197
- }),
198
- /* @__PURE__ */ h("div", {
199
- className: "flex items-end gap-2 border-t border-border-default bg-bg-surface px-3 py-2.5",
200
- children: [
201
- B.isSupported ? /* @__PURE__ */ m("button", {
188
+ onClick: () => void oe(),
189
+ disabled: N,
190
+ "data-testid": "assistant-new-chat",
191
+ className: "flex items-center gap-2 rounded-md px-2 py-2 text-xs font-medium text-text-primary transition-colors hover:bg-bg-surface disabled:opacity-50 cursor-pointer",
192
+ children: [/* @__PURE__ */ p(re, { className: "size-4 shrink-0" }), "New chat"]
193
+ }),
194
+ /* @__PURE__ */ m("button", {
195
+ type: "button",
196
+ onClick: () => void se(),
197
+ disabled: N || k.length === 0,
198
+ "data-testid": "assistant-clear-chat",
199
+ className: "flex items-center gap-2 rounded-md px-2 py-2 text-xs font-medium text-text-primary transition-colors hover:bg-bg-surface disabled:opacity-50 cursor-pointer",
200
+ children: [/* @__PURE__ */ p(u, { className: "size-4 shrink-0" }), "Clear chat"]
201
+ }),
202
+ /* @__PURE__ */ m("button", {
203
+ type: "button",
204
+ onClick: ce,
205
+ "aria-expanded": z,
206
+ "data-testid": "assistant-history-toggle",
207
+ className: "flex items-center gap-2 rounded-md px-2 py-2 text-xs font-medium text-text-primary transition-colors hover:bg-bg-surface cursor-pointer",
208
+ children: [/* @__PURE__ */ p(te, { className: "size-4 shrink-0" }), "History"]
209
+ }),
210
+ z ? /* @__PURE__ */ p("div", {
211
+ "data-testid": "assistant-history-list",
212
+ className: "mt-1 flex-1 space-y-0.5 overflow-y-auto border-t border-border-subtle pt-2",
213
+ children: L.length === 0 ? /* @__PURE__ */ p("p", {
214
+ className: "px-2 py-1 text-[11px] leading-relaxed text-text-muted",
215
+ children: "No past chats yet."
216
+ }) : L.map((t) => /* @__PURE__ */ p("button", {
202
217
  type: "button",
203
- onClick: J,
204
- "aria-label": B.isListening ? "Stop voice input" : "Start voice input",
205
- "aria-pressed": B.isListening,
206
- "data-testid": "assistant-widget-mic",
207
- className: e("flex size-9 shrink-0 items-center justify-center rounded-lg transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong cursor-pointer", B.isListening ? "animate-pulse bg-status-error-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
208
- children: /* @__PURE__ */ m(l, { className: "size-4" })
209
- }) : null,
210
- /* @__PURE__ */ m("textarea", {
211
- ref: I,
212
- value: A,
213
- onChange: (e) => j(e.target.value),
214
- onKeyDown: K,
215
- onInput: q,
216
- rows: 1,
217
- placeholder: C,
218
- "aria-label": "Message the assistant",
219
- "data-testid": "assistant-widget-input",
220
- className: "flex-1 resize-none rounded-lg border border-border-default bg-bg-sunken px-3 py-2 text-xs leading-relaxed text-text-primary placeholder:text-text-muted focus:border-action-primary-bg focus:outline-none"
221
- }),
222
- /* @__PURE__ */ m("button", {
218
+ onClick: () => void le(t.id),
219
+ title: t.title,
220
+ "data-testid": "assistant-history-item",
221
+ className: e("w-full truncate rounded px-2 py-1.5 text-left text-[11px] leading-relaxed transition-colors cursor-pointer", t.active ? "bg-bg-surface font-medium text-text-primary" : "text-text-secondary hover:bg-bg-surface hover:text-text-primary"),
222
+ children: t.title
223
+ }, t.id))
224
+ }) : null
225
+ ]
226
+ }) : null, /* @__PURE__ */ m("div", {
227
+ className: "flex min-w-0 flex-1 flex-col",
228
+ children: [
229
+ /* @__PURE__ */ m("div", {
230
+ className: "flex items-center justify-between gap-2 border-b border-border-subtle bg-bg-surface px-4 py-3",
231
+ children: [/* @__PURE__ */ m("div", {
232
+ className: "flex min-w-0 items-center gap-2",
233
+ children: [/* @__PURE__ */ p("span", {
234
+ className: "inline-flex size-7 shrink-0 items-center justify-center rounded-full bg-action-primary-bg/10 text-action-primary-bg",
235
+ children: /* @__PURE__ */ p(l, { className: "size-4" })
236
+ }), /* @__PURE__ */ p("h2", {
237
+ className: "truncate text-sm font-semibold text-text-primary",
238
+ children: b
239
+ })]
240
+ }), /* @__PURE__ */ p("button", {
223
241
  type: "button",
224
- onClick: () => void G(),
225
- disabled: M || A.trim().length === 0,
226
- "aria-label": "Send message",
227
- "data-testid": "assistant-widget-send",
228
- className: "flex size-9 shrink-0 items-center justify-center rounded-lg bg-action-primary-bg text-action-primary-text transition-colors hover:bg-action-primary-bg-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong disabled:opacity-50 cursor-pointer",
229
- children: M ? /* @__PURE__ */ m(s, { className: "size-4 animate-spin" }) : /* @__PURE__ */ m(u, { className: "size-4" })
230
- })
231
- ]
232
- })
233
- ]
242
+ onClick: Y,
243
+ "aria-label": "Close AI assistant",
244
+ "data-testid": "assistant-widget-close",
245
+ className: "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong cursor-pointer",
246
+ children: /* @__PURE__ */ p(d, { className: "size-4" })
247
+ })]
248
+ }),
249
+ /* @__PURE__ */ p("div", {
250
+ ref: H,
251
+ className: "flex-1 space-y-3 overflow-y-auto px-4 py-4",
252
+ "data-testid": "assistant-widget-messages",
253
+ children: k.length === 0 && F ? /* @__PURE__ */ m("div", {
254
+ "data-testid": "assistant-widget-restoring",
255
+ className: "flex h-full flex-col items-center justify-center gap-3 text-center",
256
+ children: [/* @__PURE__ */ p(s, { className: "size-5 animate-spin text-text-secondary" }), /* @__PURE__ */ p("p", {
257
+ className: "text-xs leading-relaxed text-text-secondary",
258
+ children: "Restoring your conversation…"
259
+ })]
260
+ }) : k.length === 0 ? /* @__PURE__ */ m("div", {
261
+ className: "flex h-full flex-col items-center justify-center gap-3 text-center",
262
+ children: [/* @__PURE__ */ p("span", {
263
+ className: "inline-flex size-12 items-center justify-center rounded-full bg-bg-sunken text-action-primary-bg",
264
+ children: /* @__PURE__ */ p(ne, { className: "size-6" })
265
+ }), /* @__PURE__ */ p("p", {
266
+ className: "max-w-[16rem] text-xs leading-relaxed text-text-secondary",
267
+ children: x
268
+ })]
269
+ }) : k.map((t) => /* @__PURE__ */ p("div", {
270
+ className: e("flex", t.role === "user" ? "justify-end" : "justify-start"),
271
+ children: /* @__PURE__ */ m("div", {
272
+ "data-testid": `assistant-widget-message-${t.role}`,
273
+ className: e("whitespace-pre-wrap break-words rounded-lg px-3 py-2 text-xs leading-relaxed", G ? "max-w-[92%]" : "max-w-[85%]", t.role === "user" ? "bg-action-primary-bg text-action-primary-text" : t.error ? "bg-status-error-bg/10 text-status-error-bg" : "bg-bg-sunken text-text-primary"),
274
+ children: [t.content ? /* @__PURE__ */ p(n, {
275
+ content: t.content,
276
+ onNavigate: E
277
+ }) : null, t.pending ? /* @__PURE__ */ m("span", {
278
+ "data-testid": "assistant-widget-working",
279
+ className: e("inline-flex items-center gap-1 text-text-secondary", t.content ? "mt-1" : ""),
280
+ children: [/* @__PURE__ */ p(s, { className: "size-3 animate-spin" }), t.content ? null : /* @__PURE__ */ p("span", { children: "Working on it…" })]
281
+ }) : null]
282
+ })
283
+ }, t.id))
284
+ }),
285
+ /* @__PURE__ */ m("div", {
286
+ className: "flex items-end gap-2 border-t border-border-default bg-bg-surface px-3 py-2.5",
287
+ children: [
288
+ q.isSupported ? /* @__PURE__ */ p("button", {
289
+ type: "button",
290
+ onClick: fe,
291
+ "aria-label": q.isListening ? "Stop voice input" : "Start voice input",
292
+ "aria-pressed": q.isListening,
293
+ "data-testid": "assistant-widget-mic",
294
+ className: e("flex size-9 shrink-0 items-center justify-center rounded-lg transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong cursor-pointer", q.isListening ? "animate-pulse bg-status-error-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
295
+ children: /* @__PURE__ */ p(c, { className: "size-4" })
296
+ }) : null,
297
+ /* @__PURE__ */ p("textarea", {
298
+ ref: V,
299
+ value: j,
300
+ onChange: (e) => M(e.target.value),
301
+ onKeyDown: ue,
302
+ onInput: de,
303
+ rows: 1,
304
+ placeholder: ae,
305
+ "aria-label": "Message the assistant",
306
+ "data-testid": "assistant-widget-input",
307
+ className: "flex-1 resize-none rounded-lg border border-border-default bg-bg-sunken px-3 py-2 text-xs leading-relaxed text-text-primary placeholder:text-text-muted focus:border-action-primary-bg focus:outline-none"
308
+ }),
309
+ /* @__PURE__ */ p("button", {
310
+ type: "button",
311
+ onClick: () => void $(),
312
+ disabled: N || j.trim().length === 0,
313
+ "aria-label": "Send message",
314
+ "data-testid": "assistant-widget-send",
315
+ className: "flex size-9 shrink-0 items-center justify-center rounded-lg bg-action-primary-bg text-action-primary-text transition-colors hover:bg-action-primary-bg-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong disabled:opacity-50 cursor-pointer",
316
+ children: N ? /* @__PURE__ */ p(s, { className: "size-4 animate-spin" }) : /* @__PURE__ */ p(ie, { className: "size-4" })
317
+ })
318
+ ]
319
+ })
320
+ ]
321
+ })]
234
322
  }) : null] });
235
323
  };
236
324
  //#endregion
237
- export { g as ASSISTANT_WIDGET_TOGGLE_EVENT, x as AssistantWidget };
325
+ export { h as ASSISTANT_WIDGET_TOGGLE_EVENT, b as AssistantWidget };
@@ -0,0 +1,11 @@
1
+ import { FC } from 'react';
2
+ export interface MessageContentProps {
3
+ content: string;
4
+ /**
5
+ * Called for in-app (`/…`) links so the host can route without a full page
6
+ * reload. When omitted, in-app links fall back to a normal anchor.
7
+ */
8
+ onNavigate?: (href: string) => void;
9
+ }
10
+ export declare const MessageContent: FC<MessageContentProps>;
11
+ //# sourceMappingURL=MessageContent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageContent.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/MessageContent.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAY,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAC;AAW1D,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAqDlD,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { Fragment as e } from "react";
2
+ import { Fragment as t, jsx as n } from "react/jsx-runtime";
3
+ //#region src/shared/components/assistantWidget/MessageContent.tsx
4
+ var r = /\[([^\]]+)\]\(([^)\s]+)\)/g;
5
+ function i(e) {
6
+ return e.startsWith("/") && !e.startsWith("//") ? !0 : e.startsWith("https://");
7
+ }
8
+ var a = ({ content: a, onNavigate: o }) => {
9
+ let s = [], c = 0, l = new RegExp(r.source, "g");
10
+ for (let t of a.matchAll(l)) {
11
+ let [r, l, u] = t, d = t.index ?? 0;
12
+ if (d > c && s.push(/* @__PURE__ */ n(e, { children: a.slice(c, d) }, `t${String(c)}`)), l && u && i(u)) {
13
+ let e = u.startsWith("/");
14
+ s.push(/* @__PURE__ */ n("a", {
15
+ href: u,
16
+ "data-testid": "assistant-message-link",
17
+ ...e ? { onClick: o ? (e) => {
18
+ e.preventDefault(), o(u);
19
+ } : void 0 } : {
20
+ target: "_blank",
21
+ rel: "noopener noreferrer"
22
+ },
23
+ className: "font-medium text-action-primary-bg underline underline-offset-2 hover:opacity-80",
24
+ children: l
25
+ }, `l${String(d)}`));
26
+ } else s.push(/* @__PURE__ */ n(e, { children: l ?? r }, `u${String(d)}`));
27
+ c = d + r.length;
28
+ }
29
+ return c < a.length && s.push(/* @__PURE__ */ n(e, { children: a.slice(c) }, `t${String(c)}`)), /* @__PURE__ */ n(t, { children: s });
30
+ };
31
+ //#endregion
32
+ export { a as MessageContent };
@@ -33,10 +33,27 @@ export interface AssistantSendArgs {
33
33
  * Backend adapter the host product supplies. A single transport instance is
34
34
  * reused across turns so it can keep a warm session/sandbox between sends.
35
35
  */
36
+ /** One past conversation, for the history list. */
37
+ export interface AssistantSessionSummary {
38
+ id: string;
39
+ title: string;
40
+ /** epoch ms — used only for ordering/labelling. */
41
+ updatedAt?: number;
42
+ /** True for the conversation currently on screen. */
43
+ active?: boolean;
44
+ }
36
45
  export interface AssistantTransport {
37
46
  sendPrompt: (args: AssistantSendArgs) => Promise<{
38
47
  text: string;
39
48
  }>;
49
+ /** All conversations for this user/sandbox, newest first. */
50
+ listSessions?: () => Promise<AssistantSessionSummary[]>;
51
+ /** Start an empty conversation and make it active. */
52
+ newSession?: () => Promise<void>;
53
+ /** Delete the active conversation and start a fresh one in its place. */
54
+ clearSession?: () => Promise<void>;
55
+ /** Switch to a past conversation; returns its messages. */
56
+ selectSession?: (sessionId: string) => Promise<AssistantWidgetMessage[]>;
40
57
  /**
41
58
  * Optional: restore the conversation from the backend when the widget opens.
42
59
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,mBAAmB,CAAC;IAC1B,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,8DAA8D;IAC9D,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnE;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;CACvD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,mBAAmB,CAAC;IAC1B,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,8DAA8D;IAC9D,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;GAGG;AACH,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAOnE,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;IACxD,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,2DAA2D;IAC3D,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACzE;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;CACvD"}
@@ -30,5 +30,5 @@ export { AssistantWidget, ASSISTANT_WIDGET_TOGGLE_EVENT } from './assistantWidge
30
30
  export type { AssistantWidgetProps } from './assistantWidget/AssistantWidget';
31
31
  export { useVoiceInput } from './assistantWidget/useVoiceInput';
32
32
  export type { UseVoiceInputReturn } from './assistantWidget/useVoiceInput';
33
- export type { AssistantTransport, AssistantSendArgs, AssistantWidgetMessage, AssistantWidgetRole, } from './assistantWidget/types';
33
+ export type { AssistantTransport, AssistantSendArgs, AssistantSessionSummary, AssistantWidgetMessage, AssistantWidgetRole, } from './assistantWidget/types';
34
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/components/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpF,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAChE,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAI/E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,YAAY,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACjG,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC;AAGlF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAGxE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpD,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAGtE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,eAAe,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AACnG,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/components/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpF,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAChE,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAI/E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,YAAY,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACjG,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,8BAA8B,EAAE,MAAM,6BAA6B,CAAC;AAGlF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAGxE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpD,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAGtE,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,eAAe,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AACnG,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fe-libs",
3
- "version": "2026.713.2",
3
+ "version": "2026.713.3",
4
4
  "description": "Burdenoff frontend primitives and domain libraries",
5
5
  "type": "module",
6
6
  "imports": {