@burdenoff/fe-libs 2026.713.3 → 2026.713.5

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 (42) hide show
  1. package/dist/chrome/ProductPickerSheet.d.ts.map +1 -1
  2. package/dist/chrome/ProductSwitcher.d.ts.map +1 -1
  3. package/dist/chrome/notificationCenter/NotificationList.d.ts.map +1 -1
  4. package/dist/shared/assistant/api.d.ts +34 -0
  5. package/dist/shared/assistant/api.d.ts.map +1 -0
  6. package/dist/shared/assistant/api.js +226 -0
  7. package/dist/shared/assistant/capabilities.d.ts +21 -0
  8. package/dist/shared/assistant/capabilities.d.ts.map +1 -0
  9. package/dist/shared/assistant/capabilities.js +21 -0
  10. package/dist/shared/assistant/createSandboxAssistantTransport.d.ts +7 -0
  11. package/dist/shared/assistant/createSandboxAssistantTransport.d.ts.map +1 -0
  12. package/dist/shared/assistant/createSandboxAssistantTransport.js +91 -0
  13. package/dist/shared/assistant/gatewayClient.d.ts +11 -0
  14. package/dist/shared/assistant/gatewayClient.d.ts.map +1 -0
  15. package/dist/shared/assistant/gatewayClient.js +56 -0
  16. package/dist/shared/assistant/images.d.ts +16 -0
  17. package/dist/shared/assistant/images.d.ts.map +1 -0
  18. package/dist/shared/assistant/images.js +34 -0
  19. package/dist/shared/assistant/index.d.ts +14 -0
  20. package/dist/shared/assistant/index.d.ts.map +1 -0
  21. package/dist/shared/assistant/operations.d.ts +19 -0
  22. package/dist/shared/assistant/operations.d.ts.map +1 -0
  23. package/dist/shared/assistant/operations.js +4 -0
  24. package/dist/shared/assistant/progress.d.ts +26 -0
  25. package/dist/shared/assistant/progress.d.ts.map +1 -0
  26. package/dist/shared/assistant/progress.js +74 -0
  27. package/dist/shared/assistant/runtime.d.ts +34 -0
  28. package/dist/shared/assistant/runtime.d.ts.map +1 -0
  29. package/dist/shared/assistant/runtime.js +91 -0
  30. package/dist/shared/assistant/types.d.ts +109 -0
  31. package/dist/shared/assistant/types.d.ts.map +1 -0
  32. package/dist/shared/assistant/useSandboxAssistantTransport.d.ts +3 -0
  33. package/dist/shared/assistant/useSandboxAssistantTransport.d.ts.map +1 -0
  34. package/dist/shared/assistant/useSandboxAssistantTransport.js +41 -0
  35. package/dist/shared/components/assistantWidget/AssistantWidget.d.ts +1 -1
  36. package/dist/shared/components/assistantWidget/AssistantWidget.d.ts.map +1 -1
  37. package/dist/shared/components/assistantWidget/AssistantWidget.js +130 -111
  38. package/dist/shared/components/assistantWidget/types.d.ts +12 -2
  39. package/dist/shared/components/assistantWidget/types.d.ts.map +1 -1
  40. package/dist/shared-assistant.d.ts +2 -0
  41. package/dist/shared-assistant.js +6 -0
  42. package/package.json +5 -1
@@ -1,8 +1,8 @@
1
1
  import { cn as e } from "../../utils/cn.js";
2
2
  import { useVoiceInput as t } from "./useVoiceInput.js";
3
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";
4
+ import { useCallback as r, useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
5
+ import { History as ee, Loader2 as c, MessageCircle as l, Mic as te, Plus as ne, Send as re, Sparkles as u, Trash2 as ie, X as d } from "lucide-react";
6
6
  import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
7
7
  //#region src/shared/components/assistantWidget/AssistantWidget.tsx
8
8
  var h = "bf:toggle-assistant-widget", g = "bf:assistant-widget:isOpen";
@@ -22,17 +22,17 @@ function v(e) {
22
22
  function y() {
23
23
  return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
24
24
  }
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) => {
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: S = "Ask anything, or describe what to create…", launcherClassName: C, voiceLang: w = "en-US", layout: T = "floating", showSessionPanel: ae = !1, onNavigate: oe }) => {
26
+ let [E, D] = s(() => _()), [O, k] = s([]), [A, j] = s(""), [M, N] = s(!1), [P, F] = s(!1), [I, L] = s([]), [R, z] = s(!1), [B, V] = s(!1), H = o(null), U = o(null), W = o(null), G = o(!1), K = T === "sidebar", se = ae && !!g.newSession, q = t(w), J = r(() => {
27
+ v(!0), D(!0), g.prewarm?.("full");
28
+ }, [g]), Y = r(() => {
29
+ v(!1), D(!1), g.suspend?.();
30
+ }, [g]), X = r(() => {
31
+ D((e) => {
32
32
  let t = !e;
33
- return v(t), t;
33
+ return v(t), t ? g.prewarm?.("full") : g.suspend?.(), t;
34
34
  });
35
- }, []);
35
+ }, [g]);
36
36
  i(() => {
37
37
  let e = (e) => {
38
38
  let t = e.detail;
@@ -44,77 +44,85 @@ var b = ({ transport: g, title: b = "AI Assistant", subtitle: x = "Ask me to do
44
44
  Y,
45
45
  X
46
46
  ]), i(() => {
47
- q.isListening && q.transcript && M(q.transcript);
47
+ q.isListening && q.transcript && j(q.transcript);
48
48
  }, [q.transcript, q.isListening]), i(() => {
49
- if (!D || W.current) return;
49
+ if (!E || G.current) return;
50
50
  let e = g.loadHistory;
51
51
  if (!e) {
52
- W.current = !0;
52
+ G.current = !0;
53
53
  return;
54
54
  }
55
- W.current = !0;
55
+ G.current = !0;
56
56
  let t = !1;
57
- return I(!0), (async () => {
57
+ return F(!0), (async () => {
58
58
  try {
59
59
  let n = await e();
60
- !t && n.length > 0 && A((e) => e.length === 0 ? n : e);
60
+ !t && n.length > 0 && k((e) => e.length === 0 ? n : e);
61
61
  } catch {} finally {
62
- t || I(!1);
62
+ t || F(!1);
63
63
  }
64
64
  })(), () => {
65
65
  t = !0;
66
66
  };
67
- }, [D, g]), i(() => {
68
- D && H.current && (H.current.scrollTop = H.current.scrollHeight);
69
- }, [k, D]);
67
+ }, [E, g]), i(() => {
68
+ E && U.current && (U.current.scrollTop = U.current.scrollHeight);
69
+ }, [O, E]);
70
70
  let Z = r((e, t) => {
71
- A((n) => n.map((n) => n.id === e ? {
71
+ k((n) => n.map((n) => n.id === e ? {
72
72
  ...n,
73
73
  ...t
74
74
  } : n));
75
75
  }, []), Q = r(async () => {
76
- if (g.listSessions) try {
77
- R(await g.listSessions());
78
- } catch {
79
- R([]);
76
+ if (g.listSessions) {
77
+ V(!0);
78
+ try {
79
+ L(await g.listSessions());
80
+ } catch {
81
+ L([]);
82
+ } finally {
83
+ V(!1);
84
+ }
85
+ }
86
+ }, [g]), ce = r(async () => {
87
+ !g.newSession || M || (k([]), j(""), z(!1), await g.newSession());
88
+ }, [g, M]), le = r(async (e, t) => {
89
+ if (!(!g.deleteSession || M)) {
90
+ L((t) => t.filter((t) => t.id !== e)), t && (k([]), j(""));
91
+ try {
92
+ await g.deleteSession(e);
93
+ } finally {
94
+ Q();
95
+ }
80
96
  }
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
97
  }, [
90
98
  g,
91
- N,
99
+ M,
92
100
  Q
93
- ]), ce = r(() => {
94
- B((e) => (e || Q(), !e));
95
- }, [Q]), le = r(async (e) => {
96
- if (!(!g.selectSession || N)) {
97
- I(!0);
101
+ ]), ue = r(() => {
102
+ z((e) => (e || Q(), !e));
103
+ }, [Q]), de = r(async (e) => {
104
+ if (!(!g.selectSession || M)) {
105
+ F(!0);
98
106
  try {
99
- A(await g.selectSession(e)), B(!1), Q();
107
+ k(await g.selectSession(e)), z(!1), Q();
100
108
  } catch {} finally {
101
- I(!1);
109
+ F(!1);
102
110
  }
103
111
  }
104
112
  }, [
105
113
  g,
106
- N,
114
+ M,
107
115
  Q
108
116
  ]), $ = 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");
117
+ let e = A.trim();
118
+ if (!e || M) return;
119
+ q.isListening && q.stop(), q.reset(), j(""), H.current && (H.current.style.height = "auto");
112
120
  let t = {
113
121
  id: y(),
114
122
  role: "user",
115
123
  content: e
116
124
  }, n = y();
117
- A((e) => [
125
+ k((e) => [
118
126
  ...e,
119
127
  t,
120
128
  {
@@ -123,9 +131,9 @@ var b = ({ transport: g, title: b = "AI Assistant", subtitle: x = "Ask me to do
123
131
  content: "",
124
132
  pending: !0
125
133
  }
126
- ]), P(!0);
134
+ ]), N(!0);
127
135
  let r = new AbortController();
128
- U.current = r;
136
+ W.current = r;
129
137
  try {
130
138
  let { text: t } = await g.sendPrompt({
131
139
  prompt: e,
@@ -143,83 +151,94 @@ var b = ({ transport: g, title: b = "AI Assistant", subtitle: x = "Ask me to do
143
151
  error: !0
144
152
  });
145
153
  } finally {
146
- P(!1), U.current = null, z && Q();
154
+ N(!1), W.current = null, R && Q();
147
155
  }
148
156
  }, [
149
- j,
150
- N,
157
+ A,
158
+ M,
151
159
  Z,
152
160
  g,
153
161
  q,
154
- z,
162
+ R,
155
163
  Q
156
- ]), ue = r((e) => {
164
+ ]), fe = r((e) => {
157
165
  e.key === "Enter" && !e.shiftKey && (e.preventDefault(), $());
158
- }, [$]), de = r(() => {
159
- let e = V.current;
166
+ }, [$]), pe = r(() => {
167
+ let e = H.current;
160
168
  e && (e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, 120)}px`);
161
- }, []), fe = r(() => {
169
+ }, []), me = r(() => {
162
170
  q.isListening ? q.stop() : q.start();
163
171
  }, [q]);
164
- return /* @__PURE__ */ m(f, { children: [ee(() => /* @__PURE__ */ p("button", {
172
+ return /* @__PURE__ */ m(f, { children: [a(() => /* @__PURE__ */ p("button", {
165
173
  type: "button",
166
174
  onClick: X,
167
- "aria-label": D ? "Close AI assistant" : "Open AI assistant",
168
- "aria-expanded": D,
175
+ onMouseEnter: () => !E && g.prewarm?.("probe"),
176
+ onFocus: () => !E && g.prewarm?.("probe"),
177
+ "aria-label": E ? "Close AI assistant" : "Open AI assistant",
178
+ "aria-expanded": E,
169
179
  "data-testid": "assistant-widget-launcher",
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" })
180
+ 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", C),
181
+ children: p(E ? d : u, { className: "size-6" })
172
182
  }), [
173
- D,
183
+ E,
174
184
  X,
175
- S
176
- ]), D ? /* @__PURE__ */ m("div", {
185
+ C,
186
+ g
187
+ ]), E ? /* @__PURE__ */ m("div", {
177
188
  role: "dialog",
178
189
  "aria-label": b,
179
190
  "data-testid": "assistant-widget-window",
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", {
191
+ "data-layout": T,
192
+ className: e("fixed z-[100] flex overflow-hidden border-border-default bg-bg-surface shadow-2xl", K ? "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"),
193
+ children: [K && se ? /* @__PURE__ */ m("aside", {
183
194
  "data-testid": "assistant-session-panel",
184
195
  className: "flex w-[168px] shrink-0 flex-col gap-1 border-r border-border-subtle bg-bg-sunken p-2",
185
196
  children: [
186
197
  /* @__PURE__ */ m("button", {
187
198
  type: "button",
188
- onClick: () => void oe(),
189
- disabled: N,
199
+ onClick: () => void ce(),
200
+ disabled: M,
190
201
  "data-testid": "assistant-new-chat",
191
202
  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"]
203
+ children: [/* @__PURE__ */ p(ne, { className: "size-4 shrink-0" }), "New chat"]
193
204
  }),
194
205
  /* @__PURE__ */ m("button", {
195
206
  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,
207
+ onClick: ue,
208
+ "aria-expanded": R,
206
209
  "data-testid": "assistant-history-toggle",
207
210
  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"]
211
+ children: [/* @__PURE__ */ p(ee, { className: "size-4 shrink-0" }), "History"]
209
212
  }),
210
- z ? /* @__PURE__ */ p("div", {
213
+ R ? /* @__PURE__ */ p("div", {
211
214
  "data-testid": "assistant-history-list",
212
215
  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", {
216
+ children: B && I.length === 0 ? /* @__PURE__ */ m("p", {
217
+ className: "flex items-center gap-1.5 px-2 py-1 text-[11px] text-text-muted",
218
+ children: [/* @__PURE__ */ p(c, { className: "size-3 animate-spin" }), "Loading…"]
219
+ }) : I.length === 0 ? /* @__PURE__ */ p("p", {
214
220
  className: "px-2 py-1 text-[11px] leading-relaxed text-text-muted",
215
221
  children: "No past chats yet."
216
- }) : L.map((t) => /* @__PURE__ */ p("button", {
217
- type: "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
222
+ }) : I.map((t) => /* @__PURE__ */ m("div", {
223
+ "data-testid": "assistant-history-row",
224
+ className: e("group flex items-center gap-1 rounded pr-1 transition-colors", t.active ? "bg-bg-surface" : "hover:bg-bg-surface"),
225
+ children: [/* @__PURE__ */ p("button", {
226
+ type: "button",
227
+ onClick: () => void de(t.id),
228
+ title: t.title,
229
+ "data-testid": "assistant-history-item",
230
+ className: e("min-w-0 flex-1 truncate rounded px-2 py-1.5 text-left text-[11px] leading-relaxed cursor-pointer", t.active ? "font-medium text-text-primary" : "text-text-secondary group-hover:text-text-primary"),
231
+ children: t.title
232
+ }), g.deleteSession ? /* @__PURE__ */ p("button", {
233
+ type: "button",
234
+ onClick: () => void le(t.id, !!t.active),
235
+ disabled: M,
236
+ "aria-label": `Delete chat: ${t.title}`,
237
+ title: "Delete this chat",
238
+ "data-testid": "assistant-delete-chat",
239
+ className: "inline-flex size-6 shrink-0 items-center justify-center rounded text-text-muted opacity-0 transition-opacity hover:text-status-error-bg focus-visible:opacity-100 group-hover:opacity-100 disabled:opacity-30 cursor-pointer",
240
+ children: /* @__PURE__ */ p(ie, { className: "size-3.5" })
241
+ }) : null]
223
242
  }, t.id))
224
243
  }) : null
225
244
  ]
@@ -232,7 +251,7 @@ var b = ({ transport: g, title: b = "AI Assistant", subtitle: x = "Ask me to do
232
251
  className: "flex min-w-0 items-center gap-2",
233
252
  children: [/* @__PURE__ */ p("span", {
234
253
  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" })
254
+ children: /* @__PURE__ */ p(u, { className: "size-4" })
236
255
  }), /* @__PURE__ */ p("h2", {
237
256
  className: "truncate text-sm font-semibold text-text-primary",
238
257
  children: b
@@ -247,37 +266,37 @@ var b = ({ transport: g, title: b = "AI Assistant", subtitle: x = "Ask me to do
247
266
  })]
248
267
  }),
249
268
  /* @__PURE__ */ p("div", {
250
- ref: H,
269
+ ref: U,
251
270
  className: "flex-1 space-y-3 overflow-y-auto px-4 py-4",
252
271
  "data-testid": "assistant-widget-messages",
253
- children: k.length === 0 && F ? /* @__PURE__ */ m("div", {
272
+ children: O.length === 0 && P ? /* @__PURE__ */ m("div", {
254
273
  "data-testid": "assistant-widget-restoring",
255
274
  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", {
275
+ children: [/* @__PURE__ */ p(c, { className: "size-5 animate-spin text-text-secondary" }), /* @__PURE__ */ p("p", {
257
276
  className: "text-xs leading-relaxed text-text-secondary",
258
277
  children: "Restoring your conversation…"
259
278
  })]
260
- }) : k.length === 0 ? /* @__PURE__ */ m("div", {
279
+ }) : O.length === 0 ? /* @__PURE__ */ m("div", {
261
280
  className: "flex h-full flex-col items-center justify-center gap-3 text-center",
262
281
  children: [/* @__PURE__ */ p("span", {
263
282
  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" })
283
+ children: /* @__PURE__ */ p(l, { className: "size-6" })
265
284
  }), /* @__PURE__ */ p("p", {
266
285
  className: "max-w-[16rem] text-xs leading-relaxed text-text-secondary",
267
286
  children: x
268
287
  })]
269
- }) : k.map((t) => /* @__PURE__ */ p("div", {
288
+ }) : O.map((t) => /* @__PURE__ */ p("div", {
270
289
  className: e("flex", t.role === "user" ? "justify-end" : "justify-start"),
271
290
  children: /* @__PURE__ */ m("div", {
272
291
  "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"),
292
+ className: e("whitespace-pre-wrap break-words rounded-lg px-3 py-2 text-xs leading-relaxed", K ? "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
293
  children: [t.content ? /* @__PURE__ */ p(n, {
275
294
  content: t.content,
276
- onNavigate: E
295
+ onNavigate: oe
277
296
  }) : null, t.pending ? /* @__PURE__ */ m("span", {
278
297
  "data-testid": "assistant-widget-working",
279
298
  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…" })]
299
+ children: [/* @__PURE__ */ p(c, { className: "size-3 animate-spin" }), t.content ? null : /* @__PURE__ */ p("span", { children: "Working on it…" })]
281
300
  }) : null]
282
301
  })
283
302
  }, t.id))
@@ -287,21 +306,21 @@ var b = ({ transport: g, title: b = "AI Assistant", subtitle: x = "Ask me to do
287
306
  children: [
288
307
  q.isSupported ? /* @__PURE__ */ p("button", {
289
308
  type: "button",
290
- onClick: fe,
309
+ onClick: me,
291
310
  "aria-label": q.isListening ? "Stop voice input" : "Start voice input",
292
311
  "aria-pressed": q.isListening,
293
312
  "data-testid": "assistant-widget-mic",
294
313
  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" })
314
+ children: /* @__PURE__ */ p(te, { className: "size-4" })
296
315
  }) : null,
297
316
  /* @__PURE__ */ p("textarea", {
298
- ref: V,
299
- value: j,
300
- onChange: (e) => M(e.target.value),
301
- onKeyDown: ue,
302
- onInput: de,
317
+ ref: H,
318
+ value: A,
319
+ onChange: (e) => j(e.target.value),
320
+ onKeyDown: fe,
321
+ onInput: pe,
303
322
  rows: 1,
304
- placeholder: ae,
323
+ placeholder: S,
305
324
  "aria-label": "Message the assistant",
306
325
  "data-testid": "assistant-widget-input",
307
326
  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"
@@ -309,11 +328,11 @@ var b = ({ transport: g, title: b = "AI Assistant", subtitle: x = "Ask me to do
309
328
  /* @__PURE__ */ p("button", {
310
329
  type: "button",
311
330
  onClick: () => void $(),
312
- disabled: N || j.trim().length === 0,
331
+ disabled: M || A.trim().length === 0,
313
332
  "aria-label": "Send message",
314
333
  "data-testid": "assistant-widget-send",
315
334
  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" })
335
+ children: M ? /* @__PURE__ */ p(c, { className: "size-4 animate-spin" }) : /* @__PURE__ */ p(re, { className: "size-4" })
317
336
  })
318
337
  ]
319
338
  })
@@ -46,12 +46,22 @@ export interface AssistantTransport {
46
46
  sendPrompt: (args: AssistantSendArgs) => Promise<{
47
47
  text: string;
48
48
  }>;
49
+ /** Warm the runtime ahead of the first prompt. 'probe' must not create a sandbox. */
50
+ prewarm?: (level?: 'probe' | 'full') => void;
51
+ /** Stop keep-warm work (widget closed / hidden). */
52
+ suspend?: () => void;
49
53
  /** All conversations for this user/sandbox, newest first. */
50
54
  listSessions?: () => Promise<AssistantSessionSummary[]>;
51
55
  /** Start an empty conversation and make it active. */
52
56
  newSession?: () => Promise<void>;
53
- /** Delete the active conversation and start a fresh one in its place. */
54
- clearSession?: () => Promise<void>;
57
+ /**
58
+ * Delete one conversation by id.
59
+ *
60
+ * Replaces a blanket "clear chat", which could only ever remove whichever chat
61
+ * happened to be open — ambiguous, and useless for tidying up an old one. A
62
+ * delete control on each history row says exactly what it will remove.
63
+ */
64
+ deleteSession?: (sessionId: string) => Promise<void>;
55
65
  /** Switch to a past conversation; returns its messages. */
56
66
  selectSession?: (sessionId: string) => Promise<AssistantWidgetMessage[]>;
57
67
  /**
@@ -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,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"}
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;IAQnE,qFAAqF;IACrF,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7C,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAOrB,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;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,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"}
@@ -0,0 +1,2 @@
1
+ export * from './shared/assistant/index'
2
+ export {}
@@ -0,0 +1,6 @@
1
+ import { isQuotaExhaustedError as e } from "./shared/assistant/gatewayClient.js";
2
+ import { AssistantRuntimeManager as t } from "./shared/assistant/runtime.js";
3
+ import { buildProgress as n, isRecoverable as r, mapSessionToHistory as i, mergeMessagesById as a, sanitize as o } from "./shared/assistant/progress.js";
4
+ import { createSandboxAssistantTransport as s } from "./shared/assistant/createSandboxAssistantTransport.js";
5
+ import { useSandboxAssistantTransport as c } from "./shared/assistant/useSandboxAssistantTransport.js";
6
+ export { t as AssistantRuntimeManager, n as buildProgress, s as createSandboxAssistantTransport, e as isQuotaExhaustedError, r as isRecoverable, i as mapSessionToHistory, a as mergeMessagesById, o as sanitize, c as useSandboxAssistantTransport };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fe-libs",
3
- "version": "2026.713.3",
3
+ "version": "2026.713.5",
4
4
  "description": "Burdenoff frontend primitives and domain libraries",
5
5
  "type": "module",
6
6
  "imports": {
@@ -102,6 +102,10 @@
102
102
  "types": "./dist/shared/graphql/index.d.ts",
103
103
  "import": "./dist/shared-graphql.js"
104
104
  },
105
+ "./shared/assistant": {
106
+ "types": "./dist/shared/assistant/index.d.ts",
107
+ "import": "./dist/shared-assistant.js"
108
+ },
105
109
  "./shared/graphql/client": {
106
110
  "types": "./dist/shared/graphql/client.d.ts",
107
111
  "import": "./dist/shared/graphql/client.js"