@burdenoff/fe-libs 2026.713.1 → 2026.713.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantWidget.d.ts","sourceRoot":"","sources":["../../../../src/shared/components/assistantWidget/AssistantWidget.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;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,CA6RpD,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;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"}
@@ -22,11 +22,11 @@ function b() {
22
22
  return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
23
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 = a(null), F = a(null), I = a(null), L = t(T), R = n(() => {
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
26
  y(!0), D(!0);
27
- }, []), z = n(() => {
27
+ }, []), H = n(() => {
28
28
  y(!1), D(!1);
29
- }, []), B = n(() => {
29
+ }, []), U = n(() => {
30
30
  D((e) => {
31
31
  let t = !e;
32
32
  return y(t), t;
@@ -35,27 +35,46 @@ var x = ({ transport: _, title: x = "AI Assistant", subtitle: S = "Ask me to do
35
35
  r(() => {
36
36
  let e = (e) => {
37
37
  let t = e.detail;
38
- t?.open === !0 ? R() : t?.open === !1 ? z() : B();
38
+ t?.open === !0 ? V() : t?.open === !1 ? H() : U();
39
39
  };
40
40
  return window.addEventListener(g, e), () => window.removeEventListener(g, e);
41
41
  }, [
42
- R,
43
- z,
44
- B
42
+ V,
43
+ H,
44
+ U
45
45
  ]), r(() => {
46
- L.isListening && L.transcript && j(L.transcript);
47
- }, [L.transcript, L.isListening]), r(() => {
48
- E && F.current && (F.current.scrollTop = F.current.scrollHeight);
46
+ B.isListening && B.transcript && j(B.transcript);
47
+ }, [B.transcript, B.isListening]), r(() => {
48
+ if (!E || z.current) return;
49
+ let e = _.loadHistory;
50
+ if (!e) {
51
+ z.current = !0;
52
+ return;
53
+ }
54
+ z.current = !0;
55
+ let t = !1;
56
+ return F(!0), (async () => {
57
+ try {
58
+ let n = await e();
59
+ !t && n.length > 0 && k((e) => e.length === 0 ? n : e);
60
+ } catch {} finally {
61
+ t || F(!1);
62
+ }
63
+ })(), () => {
64
+ t = !0;
65
+ };
66
+ }, [E, _]), r(() => {
67
+ E && L.current && (L.current.scrollTop = L.current.scrollHeight);
49
68
  }, [O, E]);
50
- let V = n((e, t) => {
69
+ let W = n((e, t) => {
51
70
  k((n) => n.map((n) => n.id === e ? {
52
71
  ...n,
53
72
  ...t
54
73
  } : n));
55
- }, []), H = n(async () => {
74
+ }, []), G = n(async () => {
56
75
  let e = A.trim();
57
76
  if (!e || M) return;
58
- L.isListening && L.stop(), L.reset(), j(""), P.current && (P.current.style.height = "auto");
77
+ B.isListening && B.stop(), B.reset(), j(""), I.current && (I.current.style.height = "auto");
59
78
  let t = {
60
79
  id: b(),
61
80
  role: "user",
@@ -72,43 +91,43 @@ var x = ({ transport: _, title: x = "AI Assistant", subtitle: S = "Ask me to do
72
91
  }
73
92
  ]), N(!0);
74
93
  let r = new AbortController();
75
- I.current = r;
94
+ R.current = r;
76
95
  try {
77
96
  let { text: t } = await _.sendPrompt({
78
97
  prompt: e,
79
98
  signal: r.signal,
80
- onProgress: (e) => V(n, { content: e })
99
+ onProgress: (e) => W(n, { content: e })
81
100
  });
82
- V(n, {
101
+ W(n, {
83
102
  content: t,
84
103
  pending: !1
85
104
  });
86
105
  } catch (e) {
87
- V(n, {
106
+ W(n, {
88
107
  content: `Sorry, I couldn't complete that: ${e instanceof Error ? e.message : "Something went wrong. Please try again."}`,
89
108
  pending: !1,
90
109
  error: !0
91
110
  });
92
111
  } finally {
93
- N(!1), I.current = null;
112
+ N(!1), R.current = null;
94
113
  }
95
114
  }, [
96
115
  A,
97
116
  M,
98
- V,
117
+ W,
99
118
  _,
100
- L
101
- ]), U = n((e) => {
102
- e.key === "Enter" && !e.shiftKey && (e.preventDefault(), H());
103
- }, [H]), W = n(() => {
104
- let e = P.current;
119
+ B
120
+ ]), K = n((e) => {
121
+ e.key === "Enter" && !e.shiftKey && (e.preventDefault(), G());
122
+ }, [G]), q = n(() => {
123
+ let e = I.current;
105
124
  e && (e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, 120)}px`);
106
- }, []), G = n(() => {
107
- L.isListening ? L.stop() : L.start();
108
- }, [L]);
125
+ }, []), J = n(() => {
126
+ B.isListening ? B.stop() : B.start();
127
+ }, [B]);
109
128
  return /* @__PURE__ */ h(p, { children: [i(() => /* @__PURE__ */ m("button", {
110
129
  type: "button",
111
- onClick: B,
130
+ onClick: U,
112
131
  "aria-label": E ? "Close AI assistant" : "Open AI assistant",
113
132
  "aria-expanded": E,
114
133
  "data-testid": "assistant-widget-launcher",
@@ -116,7 +135,7 @@ var x = ({ transport: _, title: x = "AI Assistant", subtitle: S = "Ask me to do
116
135
  children: m(E ? f : d, { className: "size-6" })
117
136
  }), [
118
137
  E,
119
- B,
138
+ U,
120
139
  w
121
140
  ]), E ? /* @__PURE__ */ h("div", {
122
141
  role: "dialog",
@@ -137,7 +156,7 @@ var x = ({ transport: _, title: x = "AI Assistant", subtitle: S = "Ask me to do
137
156
  })]
138
157
  }), /* @__PURE__ */ m("button", {
139
158
  type: "button",
140
- onClick: z,
159
+ onClick: H,
141
160
  "aria-label": "Close AI assistant",
142
161
  "data-testid": "assistant-widget-close",
143
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",
@@ -145,10 +164,17 @@ var x = ({ transport: _, title: x = "AI Assistant", subtitle: S = "Ask me to do
145
164
  })]
146
165
  }),
147
166
  /* @__PURE__ */ m("div", {
148
- ref: F,
167
+ ref: L,
149
168
  className: "flex-1 space-y-3 overflow-y-auto px-4 py-4",
150
169
  "data-testid": "assistant-widget-messages",
151
- children: O.length === 0 ? /* @__PURE__ */ h("div", {
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", {
152
178
  className: "flex h-full flex-col items-center justify-center gap-3 text-center",
153
179
  children: [/* @__PURE__ */ m("span", {
154
180
  className: "inline-flex size-12 items-center justify-center rounded-full bg-bg-sunken text-action-primary-bg",
@@ -172,21 +198,21 @@ var x = ({ transport: _, title: x = "AI Assistant", subtitle: S = "Ask me to do
172
198
  /* @__PURE__ */ h("div", {
173
199
  className: "flex items-end gap-2 border-t border-border-default bg-bg-surface px-3 py-2.5",
174
200
  children: [
175
- L.isSupported ? /* @__PURE__ */ m("button", {
201
+ B.isSupported ? /* @__PURE__ */ m("button", {
176
202
  type: "button",
177
- onClick: G,
178
- "aria-label": L.isListening ? "Stop voice input" : "Start voice input",
179
- "aria-pressed": L.isListening,
203
+ onClick: J,
204
+ "aria-label": B.isListening ? "Stop voice input" : "Start voice input",
205
+ "aria-pressed": B.isListening,
180
206
  "data-testid": "assistant-widget-mic",
181
- 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", L.isListening ? "animate-pulse bg-status-error-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
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"),
182
208
  children: /* @__PURE__ */ m(l, { className: "size-4" })
183
209
  }) : null,
184
210
  /* @__PURE__ */ m("textarea", {
185
- ref: P,
211
+ ref: I,
186
212
  value: A,
187
213
  onChange: (e) => j(e.target.value),
188
- onKeyDown: U,
189
- onInput: W,
214
+ onKeyDown: K,
215
+ onInput: q,
190
216
  rows: 1,
191
217
  placeholder: C,
192
218
  "aria-label": "Message the assistant",
@@ -195,7 +221,7 @@ var x = ({ transport: _, title: x = "AI Assistant", subtitle: S = "Ask me to do
195
221
  }),
196
222
  /* @__PURE__ */ m("button", {
197
223
  type: "button",
198
- onClick: () => void H(),
224
+ onClick: () => void G(),
199
225
  disabled: M || A.trim().length === 0,
200
226
  "aria-label": "Send message",
201
227
  "data-testid": "assistant-widget-send",
@@ -37,5 +37,18 @@ export interface AssistantTransport {
37
37
  sendPrompt: (args: AssistantSendArgs) => Promise<{
38
38
  text: string;
39
39
  }>;
40
+ /**
41
+ * Optional: restore the conversation from the backend when the widget opens.
42
+ *
43
+ * The widget holds messages in component state, so without this a reload (or
44
+ * any remount) wipes the visible chat. Transports whose backend already owns
45
+ * the transcript — e.g. the sandbox agent, which keeps a durable session —
46
+ * implement this to rehydrate from that source of truth, which also keeps the
47
+ * UI honest: what the user sees is what the agent actually remembers.
48
+ *
49
+ * Return an empty array when there is nothing to restore. Transports that are
50
+ * stateless simply omit this and keep the previous ephemeral behaviour.
51
+ */
52
+ loadHistory?: () => Promise<AssistantWidgetMessage[]>;
40
53
  }
41
54
  //# sourceMappingURL=types.d.ts.map
@@ -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;CACpE"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fe-libs",
3
- "version": "2026.713.1",
3
+ "version": "2026.713.2",
4
4
  "description": "Burdenoff frontend primitives and domain libraries",
5
5
  "type": "module",
6
6
  "imports": {