@syncagent/react 0.1.4 → 0.1.6

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 (3) hide show
  1. package/dist/index.js +320 -288
  2. package/dist/index.mjs +320 -288
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -125,62 +125,107 @@ function useSyncAgent(options = {}) {
125
125
  // src/chat.tsx
126
126
  var import_react3 = require("react");
127
127
  var import_jsx_runtime2 = require("react/jsx-runtime");
128
- function renderMarkdown(text) {
129
- return text.replace(/```[\w]*\n?([\s\S]*?)```/g, `<pre style="background:#1e1e2e;color:#cdd6f4;padding:12px 14px;border-radius:8px;overflow-x:auto;font-size:12px;line-height:1.6;margin:8px 0;font-family:'Fira Code','Cascadia Code',monospace">$1</pre>`).replace(/`([^`]+)`/g, '<code style="background:rgba(0,0,0,0.08);padding:2px 6px;border-radius:4px;font-size:12px;font-family:monospace">$1</code>').replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>").replace(/\*(.+?)\*/g, "<em>$1</em>").replace(/^### (.+)$/gm, '<div style="font-weight:700;font-size:13px;margin:10px 0 4px">$1</div>').replace(/^## (.+)$/gm, '<div style="font-weight:700;font-size:14px;margin:12px 0 4px">$1</div>').replace(/^# (.+)$/gm, '<div style="font-weight:700;font-size:15px;margin:12px 0 6px">$1</div>').replace(/\|(.+)\|\n\|[-| :]+\|\n((?:\|.+\|\n?)+)/g, (_, header, rows) => {
130
- const ths = header.split("|").filter((c) => c.trim()).map((c) => `<th style="padding:6px 10px;text-align:left;font-weight:600;border-bottom:2px solid rgba(0,0,0,0.1)">${c.trim()}</th>`).join("");
131
- const trs = rows.trim().split("\n").map((row) => {
132
- const tds = row.split("|").filter((c) => c.trim()).map((c) => `<td style="padding:6px 10px;border-bottom:1px solid rgba(0,0,0,0.06)">${c.trim()}</td>`).join("");
128
+ var GLOBAL_CSS = (accent) => `
129
+ @keyframes sa-bounce { 0%,80%,100%{transform:translateY(0);opacity:.35} 40%{transform:translateY(-5px);opacity:1} }
130
+ @keyframes sa-fadein { from{opacity:0;transform:translateY(8px)} to{opacity:1;transform:translateY(0)} }
131
+ @keyframes sa-cursor { 0%,100%{opacity:1} 50%{opacity:0} }
132
+ @keyframes sa-pulse { 0%,100%{opacity:.6} 50%{opacity:1} }
133
+ .sa-msg { animation: sa-fadein .22s cubic-bezier(.16,1,.3,1) }
134
+ .sa-fab { transition: transform .2s, box-shadow .2s }
135
+ .sa-fab:hover { transform: scale(1.08) }
136
+ .sa-fab:active { transform: scale(.96) }
137
+ .sa-chip:hover { background: ${accent}22 !important; border-color: ${accent}88 !important }
138
+ .sa-send:hover:not(:disabled) { filter: brightness(1.1); transform: scale(1.05) }
139
+ .sa-send:active:not(:disabled) { transform: scale(.96) }
140
+ .sa-send:disabled { opacity: .4; cursor: not-allowed }
141
+ .sa-copy:hover { opacity: 1 !important; background: rgba(0,0,0,.06) !important }
142
+ .sa-scroll::-webkit-scrollbar { width: 4px }
143
+ .sa-scroll::-webkit-scrollbar-track { background: transparent }
144
+ .sa-scroll::-webkit-scrollbar-thumb { background: rgba(0,0,0,.12); border-radius: 4px }
145
+ .sa-cursor { display:inline-block; width:2px; height:1em; background:currentColor; margin-left:1px; vertical-align:text-bottom; animation: sa-cursor .7s infinite }
146
+ .sa-md table { width:100%; border-collapse:collapse; font-size:12.5px; margin:10px 0 }
147
+ .sa-md th { padding:7px 10px; text-align:left; font-weight:600; background:rgba(0,0,0,.04); border-bottom:2px solid rgba(0,0,0,.1); white-space:nowrap }
148
+ .sa-md td { padding:6px 10px; border-bottom:1px solid rgba(0,0,0,.06); vertical-align:top }
149
+ .sa-md tr:last-child td { border-bottom:none }
150
+ .sa-md tr:hover td { background:rgba(0,0,0,.02) }
151
+ .sa-md pre { background:#0f1117; color:#e2e8f0; padding:14px 16px; border-radius:10px; overflow-x:auto; font-size:12px; line-height:1.7; margin:10px 0; font-family:'Fira Code','Cascadia Code','JetBrains Mono',monospace; border:1px solid rgba(255,255,255,.06) }
152
+ .sa-md code { background:rgba(0,0,0,.07); padding:2px 6px; border-radius:4px; font-size:12px; font-family:monospace; color:#1e293b }
153
+ .sa-md pre code { background:none; padding:0; color:inherit; font-size:inherit }
154
+ .sa-md ul,.sa-md ol { margin:6px 0; padding-left:20px }
155
+ .sa-md li { margin:3px 0; line-height:1.6 }
156
+ .sa-md h1 { font-size:16px; font-weight:700; margin:14px 0 6px; color:#0f172a }
157
+ .sa-md h2 { font-size:14px; font-weight:700; margin:12px 0 5px; color:#0f172a }
158
+ .sa-md h3 { font-size:13px; font-weight:600; margin:10px 0 4px; color:#1e293b }
159
+ .sa-md p { margin:4px 0; line-height:1.65 }
160
+ .sa-md strong { font-weight:600; color:#0f172a }
161
+ .sa-md em { font-style:italic; color:#475569 }
162
+ .sa-md blockquote { border-left:3px solid rgba(0,0,0,.15); padding:4px 12px; margin:8px 0; color:#64748b; font-style:italic }
163
+ .sa-md hr { border:none; border-top:1px solid rgba(0,0,0,.1); margin:12px 0 }
164
+ .sa-md a { color:${accent}; text-decoration:underline }
165
+ @media (max-width:480px) {
166
+ .sa-panel-float { width:calc(100vw - 24px) !important; right:12px !important; left:12px !important; bottom:76px !important }
167
+ .sa-panel { border-radius:14px !important; height:calc(100vh - 100px) !important; max-height:none !important }
168
+ }
169
+ `;
170
+ function md(text) {
171
+ let s = text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/```(\w*)\n?([\s\S]*?)```/g, (_, lang, code) => `<pre><code class="lang-${lang}">${code.trimEnd()}</code></pre>`).replace(/`([^`\n]+)`/g, "<code>$1</code>").replace(/^### (.+)$/gm, "<h3>$1</h3>").replace(/^## (.+)$/gm, "<h2>$1</h2>").replace(/^# (.+)$/gm, "<h1>$1</h1>").replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>").replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>").replace(/\*(.+?)\*/g, "<em>$1</em>").replace(/^> (.+)$/gm, "<blockquote>$1</blockquote>").replace(/^---$/gm, "<hr/>").replace(/\|(.+)\|\r?\n\|[-| :]+\|\r?\n((?:\|.+\|\r?\n?)+)/g, (_, hdr, body) => {
172
+ const ths = hdr.split("|").filter((c) => c.trim()).map((c) => `<th>${c.trim()}</th>`).join("");
173
+ const trs = body.trim().split("\n").map((row) => {
174
+ const tds = row.split("|").filter((c) => c.trim()).map((c) => `<td>${c.trim()}</td>`).join("");
133
175
  return `<tr>${tds}</tr>`;
134
176
  }).join("");
135
- return `<div style="overflow-x:auto;margin:8px 0"><table style="width:100%;border-collapse:collapse;font-size:13px"><thead><tr>${ths}</tr></thead><tbody>${trs}</tbody></table></div>`;
136
- }).replace(/^[-*] (.+)$/gm, '<li style="margin:2px 0;padding-left:4px">$1</li>').replace(/(<li[^>]*>.*<\/li>\n?)+/g, (m) => `<ul style="margin:6px 0;padding-left:18px;list-style:disc">${m}</ul>`).replace(/^\d+\. (.+)$/gm, '<li style="margin:2px 0;padding-left:4px">$1</li>').replace(/\n\n/g, "<br/><br/>").replace(/\n/g, "<br/>");
177
+ return `<div style="overflow-x:auto"><table><thead><tr>${ths}</tr></thead><tbody>${trs}</tbody></table></div>`;
178
+ }).replace(/^[-*+] (.+)$/gm, "<li>$1</li>").replace(/(<li>[\s\S]*?<\/li>\n?)+/g, (m) => `<ul>${m}</ul>`).replace(/^\d+\. (.+)$/gm, "<li>$1</li>").replace(/\n\n+/g, "</p><p>").replace(/\n/g, "<br/>");
179
+ return `<p>${s}</p>`;
137
180
  }
138
- function TypingDots({ color }) {
139
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { display: "inline-flex", gap: 4, alignItems: "center", padding: "2px 0" }, children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: {
140
- width: 6,
141
- height: 6,
181
+ function Dots({ color }) {
182
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { display: "inline-flex", gap: 4, alignItems: "center", padding: "4px 2px" }, children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: {
183
+ width: 7,
184
+ height: 7,
142
185
  borderRadius: "50%",
143
186
  background: color,
144
- animation: "sa-bounce 1.2s infinite",
145
- animationDelay: `${i * 0.2}s`,
146
- display: "inline-block"
187
+ display: "inline-block",
188
+ animation: "sa-bounce 1.3s infinite",
189
+ animationDelay: `${i * 0.18}s`
147
190
  } }, i)) });
148
191
  }
149
- function CopyBtn({ text }) {
150
- const [copied, setCopied] = (0, import_react3.useState)(false);
151
- const copy = (0, import_react3.useCallback)(() => {
192
+ function Copy({ text }) {
193
+ const [ok, setOk] = (0, import_react3.useState)(false);
194
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "sa-copy", onClick: () => {
152
195
  navigator.clipboard?.writeText(text).then(() => {
153
- setCopied(true);
154
- setTimeout(() => setCopied(false), 1500);
196
+ setOk(true);
197
+ setTimeout(() => setOk(false), 1600);
155
198
  });
156
- }, [text]);
157
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: copy, title: "Copy", style: {
199
+ }, title: "Copy response", style: {
158
200
  background: "none",
159
201
  border: "none",
160
202
  cursor: "pointer",
161
- padding: "2px 6px",
162
- borderRadius: 4,
203
+ padding: "3px 7px",
204
+ borderRadius: 5,
163
205
  fontSize: 11,
164
- color: "#9ca3af",
165
- opacity: 0.7,
166
- transition: "opacity 0.15s"
167
- }, children: copied ? "\u2713" : "\u2398" });
206
+ color: "#94a3b8",
207
+ opacity: 0.65,
208
+ transition: "all .15s",
209
+ display: "flex",
210
+ alignItems: "center",
211
+ gap: 3
212
+ }, children: ok ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
213
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" }) }),
214
+ " Copied"
215
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
216
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" }) }),
217
+ " Copy"
218
+ ] }) });
168
219
  }
169
- function MessageBubble({
170
- role,
171
- content,
172
- isStreaming,
173
- accentColor,
174
- timestamp
175
- }) {
220
+ function Bubble({ role, content, streaming, accent, time }) {
176
221
  const isUser = role === "user";
177
- const timeStr = timestamp.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
178
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
222
+ const t = time.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
223
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sa-msg", style: {
179
224
  display: "flex",
180
225
  flexDirection: "column",
181
226
  alignItems: isUser ? "flex-end" : "flex-start",
182
- gap: 3,
183
- maxWidth: "88%",
227
+ gap: 4,
228
+ maxWidth: "90%",
184
229
  alignSelf: isUser ? "flex-end" : "flex-start"
185
230
  }, children: [
186
231
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
@@ -190,48 +235,53 @@ function MessageBubble({
190
235
  flexDirection: isUser ? "row-reverse" : "row"
191
236
  }, children: [
192
237
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
193
- width: 24,
194
- height: 24,
238
+ width: 26,
239
+ height: 26,
195
240
  borderRadius: "50%",
196
- background: isUser ? accentColor : "linear-gradient(135deg,#6366f1,#8b5cf6)",
241
+ flexShrink: 0,
242
+ background: isUser ? `linear-gradient(135deg,${accent},${adj(accent, -25)})` : "linear-gradient(135deg,#6366f1,#8b5cf6)",
197
243
  display: "flex",
198
244
  alignItems: "center",
199
245
  justifyContent: "center",
200
246
  fontSize: 11,
201
247
  color: "white",
202
248
  fontWeight: 700,
203
- flexShrink: 0
249
+ boxShadow: isUser ? `0 2px 8px ${accent}44` : "0 2px 8px #6366f144"
204
250
  }, children: isUser ? "U" : "\u2726" }),
205
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 11, color: "#9ca3af", fontWeight: 500 }, children: isUser ? "You" : "SyncAgent" }),
206
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 10, color: "#d1d5db" }, children: timeStr })
251
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 11.5, fontWeight: 600, color: isUser ? "#475569" : "#6366f1" }, children: isUser ? "You" : "SyncAgent" }),
252
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 10, color: "#cbd5e1" }, children: t })
207
253
  ] }),
208
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
209
- padding: "10px 14px",
210
- borderRadius: isUser ? "16px 4px 16px 16px" : "4px 16px 16px 16px",
211
- background: isUser ? accentColor : "#f8fafc",
254
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
255
+ padding: isUser ? "10px 14px" : "12px 16px",
256
+ borderRadius: isUser ? "18px 4px 18px 18px" : "4px 18px 18px 18px",
257
+ background: isUser ? `linear-gradient(135deg,${accent},${adj(accent, -20)})` : "#ffffff",
212
258
  color: isUser ? "white" : "#1e293b",
213
259
  fontSize: 13.5,
214
- lineHeight: 1.6,
260
+ lineHeight: 1.65,
215
261
  wordBreak: "break-word",
216
- border: isUser ? "none" : "1px solid #e2e8f0",
217
- boxShadow: isUser ? `0 2px 8px ${accentColor}33` : "0 1px 4px rgba(0,0,0,0.06)",
218
- position: "relative"
219
- }, children: isStreaming && !content ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TypingDots, { color: accentColor }) : isUser ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { whiteSpace: "pre-wrap" }, children: content }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { dangerouslySetInnerHTML: { __html: renderMarkdown(content) } }) }),
220
- !isUser && content && !isStreaming && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { paddingLeft: 30 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CopyBtn, { text: content }) })
262
+ border: isUser ? "none" : "1px solid #e8edf3",
263
+ boxShadow: isUser ? `0 4px 16px ${accent}33` : "0 2px 12px rgba(0,0,0,0.07)",
264
+ maxWidth: "100%"
265
+ }, children: [
266
+ streaming && !content ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Dots, { color: accent }) : isUser ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { whiteSpace: "pre-wrap" }, children: content }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sa-md", dangerouslySetInnerHTML: { __html: md(content) } }),
267
+ streaming && content && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sa-cursor", style: { color: accent } })
268
+ ] }),
269
+ !isUser && content && !streaming && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { paddingLeft: 32, display: "flex", gap: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Copy, { text: content }) })
221
270
  ] });
222
271
  }
223
- function Suggestions({ items, onSelect, accentColor }) {
224
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, padding: "0 16px 12px" }, children: items.map((s2) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: () => onSelect(s2), style: {
225
- padding: "5px 12px",
272
+ function Chips({ items, onPick, accent }) {
273
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, padding: "0 14px 10px" }, children: items.map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "sa-chip", onClick: () => onPick(s), style: {
274
+ padding: "5px 13px",
226
275
  borderRadius: 20,
227
276
  fontSize: 12,
228
277
  cursor: "pointer",
229
- border: `1px solid ${accentColor}44`,
230
- background: `${accentColor}0d`,
231
- color: accentColor,
278
+ border: `1px solid ${accent}33`,
279
+ background: `${accent}0a`,
280
+ color: accent,
232
281
  fontWeight: 500,
233
- transition: "all 0.15s"
234
- }, children: s2 }, s2)) });
282
+ transition: "all .15s",
283
+ whiteSpace: "nowrap"
284
+ }, children: s }, s)) });
235
285
  }
236
286
  function ChatInner({
237
287
  mode = "floating",
@@ -240,135 +290,152 @@ function ChatInner({
240
290
  title = "SyncAgent",
241
291
  subtitle = "AI Database Assistant",
242
292
  placeholder = "Ask anything about your data...",
243
- welcomeMessage = "Hi! I can query, analyze, and manage your database using natural language. What would you like to know?",
293
+ welcomeMessage = "Hi! I can query, analyze, and manage your database using natural language.",
244
294
  accentColor = "#10b981",
245
295
  className,
246
296
  style: customStyle,
247
297
  suggestions = ["Show all records", "Count total entries", "Show recent activity"]
248
298
  }) {
249
299
  const { messages, isLoading, error, sendMessage, stop, reset } = useSyncAgent();
250
- const [isOpen, setIsOpen] = (0, import_react3.useState)(defaultOpen);
300
+ const [open, setOpen] = (0, import_react3.useState)(defaultOpen);
251
301
  const [input, setInput] = (0, import_react3.useState)("");
252
- const [timestamps] = (0, import_react3.useState)(() => /* @__PURE__ */ new Map());
253
- const messagesEndRef = (0, import_react3.useRef)(null);
302
+ const [ts] = (0, import_react3.useState)(() => /* @__PURE__ */ new Map());
303
+ const endRef = (0, import_react3.useRef)(null);
254
304
  const inputRef = (0, import_react3.useRef)(null);
255
- const msgCount = (0, import_react3.useRef)(0);
256
- if (messages.length > msgCount.current) {
257
- for (let i = msgCount.current; i < messages.length; i++) {
258
- if (!timestamps.has(i)) timestamps.set(i, /* @__PURE__ */ new Date());
259
- }
260
- msgCount.current = messages.length;
305
+ const prevLen = (0, import_react3.useRef)(0);
306
+ if (messages.length > prevLen.current) {
307
+ for (let i = prevLen.current; i < messages.length; i++)
308
+ if (!ts.has(i)) ts.set(i, /* @__PURE__ */ new Date());
309
+ prevLen.current = messages.length;
261
310
  }
262
311
  (0, import_react3.useEffect)(() => {
263
- messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
312
+ endRef.current?.scrollIntoView({ behavior: "smooth" });
264
313
  }, [messages, isLoading]);
265
314
  (0, import_react3.useEffect)(() => {
266
- if (isOpen) setTimeout(() => inputRef.current?.focus(), 100);
267
- }, [isOpen]);
268
- const handleSend = (0, import_react3.useCallback)(() => {
269
- const text = input.trim();
270
- if (!text || isLoading) return;
315
+ if (open) setTimeout(() => inputRef.current?.focus(), 120);
316
+ }, [open]);
317
+ const send = (0, import_react3.useCallback)(() => {
318
+ const t = input.trim();
319
+ if (!t || isLoading) return;
271
320
  setInput("");
272
- sendMessage(text);
321
+ sendMessage(t);
273
322
  }, [input, isLoading, sendMessage]);
274
- const handleKeyDown = (e) => {
323
+ const onKey = (e) => {
275
324
  if (e.key === "Enter" && !e.shiftKey) {
276
325
  e.preventDefault();
277
- handleSend();
326
+ send();
278
327
  }
279
328
  };
280
- const showSuggestions = messages.length === 0 && suggestions.length > 0;
281
- const panel = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
282
- ...s.panel,
283
- ...mode === "inline" ? s.panelInline : {},
329
+ const noMsgs = messages.length === 0;
330
+ const panel = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `sa-panel ${className || ""}`, style: {
331
+ height: mode === "inline" ? "100%" : 600,
332
+ maxHeight: mode === "inline" ? "none" : "calc(100vh - 110px)",
333
+ background: "#f8fafc",
334
+ borderRadius: mode === "inline" ? 14 : 20,
335
+ boxShadow: mode === "inline" ? "0 2px 20px rgba(0,0,0,.08)" : "0 24px 64px rgba(0,0,0,.18), 0 4px 24px rgba(0,0,0,.08)",
336
+ display: "flex",
337
+ flexDirection: "column",
338
+ overflow: "hidden",
339
+ fontFamily: "-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif",
340
+ border: "1px solid rgba(0,0,0,.07)",
284
341
  ...customStyle
285
- }, className, children: [
286
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: `
287
- @keyframes sa-bounce {
288
- 0%,80%,100% { transform: translateY(0); opacity:0.4 }
289
- 40% { transform: translateY(-5px); opacity:1 }
290
- }
291
- @keyframes sa-fadein {
292
- from { opacity:0; transform:translateY(6px) }
293
- to { opacity:1; transform:translateY(0) }
294
- }
295
- .sa-msg-wrap { animation: sa-fadein 0.2s ease }
296
- .sa-input:focus { outline:none; border-color:${accentColor} !important; box-shadow:0 0 0 3px ${accentColor}22 !important }
297
- .sa-send:hover:not(:disabled) { opacity:0.88; transform:scale(1.04) }
298
- .sa-send:disabled { opacity:0.4; cursor:not-allowed }
299
- .sa-fab-btn:hover { transform:scale(1.08) }
300
- ` }),
342
+ }, children: [
343
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: GLOBAL_CSS(accentColor) }),
301
344
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
302
- padding: "14px 16px",
303
- background: `linear-gradient(135deg, ${accentColor}, ${adjustColor(accentColor, -30)})`,
345
+ padding: "13px 16px",
346
+ background: `linear-gradient(135deg,${accentColor},${adj(accentColor, -28)})`,
304
347
  display: "flex",
305
348
  alignItems: "center",
306
349
  justifyContent: "space-between",
307
- flexShrink: 0
350
+ flexShrink: 0,
351
+ boxShadow: "0 2px 12px rgba(0,0,0,.12)"
308
352
  }, children: [
309
353
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
310
354
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
311
- width: 34,
312
- height: 34,
355
+ width: 36,
356
+ height: 36,
313
357
  borderRadius: "50%",
314
- background: "rgba(255,255,255,0.2)",
358
+ background: "rgba(255,255,255,.18)",
359
+ backdropFilter: "blur(8px)",
315
360
  display: "flex",
316
361
  alignItems: "center",
317
362
  justifyContent: "center",
318
- fontSize: 16
363
+ fontSize: 17,
364
+ boxShadow: "0 2px 8px rgba(0,0,0,.15)"
319
365
  }, children: "\u2726" }),
320
366
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
321
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { color: "white", fontWeight: 700, fontSize: 14, lineHeight: 1.2 }, children: title }),
322
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { color: "rgba(255,255,255,0.75)", fontSize: 11 }, children: subtitle })
367
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { color: "white", fontWeight: 700, fontSize: 14, lineHeight: 1.2, letterSpacing: "-0.01em" }, children: title }),
368
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { color: "rgba(255,255,255,.72)", fontSize: 11, marginTop: 1 }, children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { animation: "sa-pulse 1.2s infinite" }, children: "\u25CF Thinking..." }) : subtitle })
323
369
  ] })
324
370
  ] }),
325
371
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: 4 }, children: [
326
- messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: reset, title: "Clear chat", style: {
327
- background: "rgba(255,255,255,0.15)",
372
+ messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: reset, style: {
373
+ background: "rgba(255,255,255,.15)",
328
374
  border: "none",
329
375
  color: "white",
330
376
  cursor: "pointer",
331
- borderRadius: 6,
332
- padding: "4px 8px",
333
- fontSize: 11
377
+ borderRadius: 7,
378
+ padding: "4px 9px",
379
+ fontSize: 11,
380
+ fontWeight: 500,
381
+ backdropFilter: "blur(4px)"
334
382
  }, children: "Clear" }),
335
- mode === "floating" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: () => setIsOpen(false), style: {
336
- background: "rgba(255,255,255,0.15)",
383
+ mode === "floating" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: () => setOpen(false), style: {
384
+ background: "rgba(255,255,255,.15)",
337
385
  border: "none",
338
386
  color: "white",
339
387
  cursor: "pointer",
340
- borderRadius: 6,
341
- padding: "4px 8px",
342
- fontSize: 16,
343
- lineHeight: 1
388
+ borderRadius: 7,
389
+ padding: "4px 9px",
390
+ fontSize: 18,
391
+ lineHeight: 1,
392
+ backdropFilter: "blur(4px)"
344
393
  }, children: "\xD7" })
345
394
  ] })
346
395
  ] }),
347
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: s.messages, children: [
348
- messages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: s.welcome, children: [
396
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sa-scroll", style: {
397
+ flex: 1,
398
+ overflowY: "auto",
399
+ padding: "16px 14px 8px",
400
+ display: "flex",
401
+ flexDirection: "column",
402
+ gap: 16,
403
+ background: "#f8fafc"
404
+ }, children: [
405
+ noMsgs && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
406
+ flex: 1,
407
+ display: "flex",
408
+ flexDirection: "column",
409
+ alignItems: "center",
410
+ justifyContent: "center",
411
+ padding: "32px 20px",
412
+ textAlign: "center"
413
+ }, children: [
349
414
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
350
- width: 48,
351
- height: 48,
415
+ width: 56,
416
+ height: 56,
352
417
  borderRadius: "50%",
353
- margin: "0 auto 12px",
354
- background: `linear-gradient(135deg, ${accentColor}22, ${accentColor}44)`,
418
+ marginBottom: 14,
419
+ background: `linear-gradient(135deg,${accentColor}18,${accentColor}35)`,
355
420
  display: "flex",
356
421
  alignItems: "center",
357
422
  justifyContent: "center",
358
- fontSize: 22
423
+ fontSize: 24,
424
+ boxShadow: `0 4px 20px ${accentColor}22`
359
425
  }, children: "\u2726" }),
360
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { fontSize: 14, color: "#64748b", lineHeight: 1.6, maxWidth: 260, margin: "0 auto" }, children: welcomeMessage })
426
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { fontSize: 14, color: "#64748b", lineHeight: 1.65, maxWidth: 260, margin: 0 }, children: welcomeMessage })
361
427
  ] }),
362
- messages.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sa-msg-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
363
- MessageBubble,
428
+ messages.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
429
+ Bubble,
364
430
  {
365
431
  role: msg.role,
366
432
  content: msg.content,
367
- isStreaming: isLoading && i === messages.length - 1 && msg.role === "assistant",
368
- accentColor,
369
- timestamp: timestamps.get(i) ?? /* @__PURE__ */ new Date()
370
- }
371
- ) }, i)),
433
+ streaming: isLoading && i === messages.length - 1 && msg.role === "assistant",
434
+ accent: accentColor,
435
+ time: ts.get(i) ?? /* @__PURE__ */ new Date()
436
+ },
437
+ i
438
+ )),
372
439
  error && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
373
440
  padding: "10px 14px",
374
441
  borderRadius: 10,
@@ -376,52 +443,61 @@ function ChatInner({
376
443
  background: "#fef2f2",
377
444
  color: "#dc2626",
378
445
  border: "1px solid #fecaca",
379
- alignSelf: "flex-start"
446
+ alignSelf: "flex-start",
447
+ display: "flex",
448
+ alignItems: "center",
449
+ gap: 6
380
450
  }, children: [
381
- "\u26A0\uFE0F ",
451
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z" }) }),
382
452
  error.message
383
453
  ] }),
384
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref: messagesEndRef })
454
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref: endRef })
385
455
  ] }),
386
- showSuggestions && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
387
- Suggestions,
388
- {
389
- items: suggestions,
390
- onSelect: (s2) => {
391
- setInput(s2);
392
- inputRef.current?.focus();
393
- },
394
- accentColor
395
- }
396
- ),
456
+ noMsgs && suggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Chips, { items: suggestions, onPick: (s) => {
457
+ setInput(s);
458
+ inputRef.current?.focus();
459
+ }, accent: accentColor }),
397
460
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
398
- padding: "10px 12px",
399
- borderTop: "1px solid #f1f5f9",
400
- background: "#fff",
461
+ padding: "10px 12px 12px",
462
+ borderTop: "1px solid #e8edf3",
463
+ background: "#ffffff",
401
464
  flexShrink: 0
402
465
  }, children: [
403
466
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
404
467
  display: "flex",
405
468
  gap: 8,
406
469
  alignItems: "flex-end",
407
- background: "#f8fafc",
408
- borderRadius: 12,
409
- border: "1px solid #e2e8f0",
410
- padding: "6px 6px 6px 12px",
411
- transition: "border-color 0.15s, box-shadow 0.15s"
470
+ background: "#f1f5f9",
471
+ borderRadius: 14,
472
+ border: "1.5px solid #e2e8f0",
473
+ padding: "8px 8px 8px 14px",
474
+ transition: "border-color .15s, box-shadow .15s"
412
475
  }, children: [
413
476
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
414
477
  "textarea",
415
478
  {
416
479
  ref: inputRef,
417
- className: "sa-input",
418
480
  value: input,
419
481
  onChange: (e) => {
420
482
  setInput(e.target.value);
421
483
  e.target.style.height = "auto";
422
- e.target.style.height = Math.min(e.target.scrollHeight, 120) + "px";
484
+ e.target.style.height = Math.min(e.target.scrollHeight, 130) + "px";
485
+ },
486
+ onKeyDown: onKey,
487
+ onFocus: (e) => {
488
+ const p = e.target.parentElement;
489
+ if (p) {
490
+ p.style.borderColor = accentColor;
491
+ p.style.boxShadow = `0 0 0 3px ${accentColor}1a`;
492
+ }
493
+ },
494
+ onBlur: (e) => {
495
+ const p = e.target.parentElement;
496
+ if (p) {
497
+ p.style.borderColor = "#e2e8f0";
498
+ p.style.boxShadow = "none";
499
+ }
423
500
  },
424
- onKeyDown: handleKeyDown,
425
501
  placeholder,
426
502
  disabled: isLoading,
427
503
  rows: 1,
@@ -431,161 +507,117 @@ function ChatInner({
431
507
  border: "none",
432
508
  resize: "none",
433
509
  fontSize: 13.5,
434
- lineHeight: 1.5,
510
+ lineHeight: 1.55,
435
511
  color: "#1e293b",
436
512
  fontFamily: "inherit",
437
513
  padding: 0,
438
- maxHeight: 120,
514
+ maxHeight: 130,
439
515
  outline: "none"
440
516
  }
441
517
  }
442
518
  ),
443
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: 4, alignItems: "flex-end", flexShrink: 0 }, children: [
444
- isLoading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: stop, title: "Stop", style: {
519
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: 5, alignItems: "flex-end", flexShrink: 0 }, children: [
520
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { onClick: stop, style: {
445
521
  background: "#fef2f2",
446
522
  border: "1px solid #fecaca",
447
523
  color: "#dc2626",
448
- borderRadius: 8,
449
- padding: "6px 10px",
524
+ borderRadius: 9,
525
+ padding: "6px 11px",
450
526
  cursor: "pointer",
451
- fontSize: 12,
452
- fontWeight: 600
453
- }, children: "\u25A0 Stop" }),
454
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
455
- "button",
456
- {
457
- className: "sa-send",
458
- onClick: handleSend,
459
- disabled: isLoading || !input.trim(),
460
- style: {
461
- width: 34,
462
- height: 34,
463
- borderRadius: 8,
464
- border: "none",
465
- background: input.trim() && !isLoading ? accentColor : "#e2e8f0",
466
- color: input.trim() && !isLoading ? "white" : "#94a3b8",
467
- cursor: "pointer",
468
- display: "flex",
469
- alignItems: "center",
470
- justifyContent: "center",
471
- transition: "all 0.15s",
472
- flexShrink: 0
473
- },
474
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" }) })
475
- }
476
- )
527
+ fontSize: 11.5,
528
+ fontWeight: 600,
529
+ display: "flex",
530
+ alignItems: "center",
531
+ gap: 4
532
+ }, children: [
533
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "4", y: "4", width: "16", height: "16" }) }),
534
+ "Stop"
535
+ ] }),
536
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { className: "sa-send", onClick: send, disabled: isLoading || !input.trim(), style: {
537
+ width: 36,
538
+ height: 36,
539
+ borderRadius: 10,
540
+ border: "none",
541
+ background: input.trim() && !isLoading ? `linear-gradient(135deg,${accentColor},${adj(accentColor, -20)})` : "#e2e8f0",
542
+ color: input.trim() && !isLoading ? "white" : "#94a3b8",
543
+ cursor: "pointer",
544
+ display: "flex",
545
+ alignItems: "center",
546
+ justifyContent: "center",
547
+ transition: "all .15s",
548
+ flexShrink: 0,
549
+ boxShadow: input.trim() && !isLoading ? `0 3px 12px ${accentColor}44` : "none"
550
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" }) }) })
477
551
  ] })
478
552
  ] }),
479
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { textAlign: "center", marginTop: 6, fontSize: 10, color: "#cbd5e1" }, children: [
553
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { textAlign: "center", marginTop: 7, fontSize: 10, color: "#c4cdd8", letterSpacing: ".01em" }, children: [
480
554
  "Powered by ",
481
555
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: accentColor, fontWeight: 600 }, children: "SyncAgent" }),
482
- " \xB7 Enter to send \xB7 Shift+Enter for new line"
556
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { margin: "0 5px", opacity: 0.5 }, children: "\xB7" }),
557
+ "Enter to send \xB7 Shift+Enter for new line"
483
558
  ] })
484
559
  ] })
485
560
  ] });
486
561
  if (mode === "inline") return panel;
487
- const isLeft = position === "bottom-left";
562
+ const left = position === "bottom-left";
488
563
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
489
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
564
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sa-panel-float", style: {
490
565
  position: "fixed",
491
- bottom: 88,
566
+ bottom: 84,
492
567
  zIndex: 99998,
493
- ...isLeft ? { left: 20 } : { right: 20 },
494
- width: 420,
495
- maxWidth: "calc(100vw - 40px)",
496
- transition: "opacity 0.25s, transform 0.25s",
497
- opacity: isOpen ? 1 : 0,
498
- transform: isOpen ? "translateY(0) scale(1)" : "translateY(16px) scale(0.96)",
499
- pointerEvents: isOpen ? "auto" : "none"
568
+ ...left ? { left: 16 } : { right: 16 },
569
+ width: 430,
570
+ maxWidth: "calc(100vw - 32px)",
571
+ transition: "opacity .28s cubic-bezier(.16,1,.3,1), transform .28s cubic-bezier(.16,1,.3,1)",
572
+ opacity: open ? 1 : 0,
573
+ transform: open ? "translateY(0) scale(1)" : "translateY(20px) scale(.95)",
574
+ pointerEvents: open ? "auto" : "none"
500
575
  }, children: panel }),
501
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
502
- "button",
503
- {
504
- className: "sa-fab-btn",
505
- onClick: () => setIsOpen(!isOpen),
506
- style: {
507
- position: "fixed",
508
- bottom: 20,
509
- zIndex: 99999,
510
- ...isLeft ? { left: 20 } : { right: 20 },
511
- width: 56,
512
- height: 56,
513
- borderRadius: "50%",
514
- border: "none",
515
- background: `linear-gradient(135deg, ${accentColor}, ${adjustColor(accentColor, -30)})`,
516
- cursor: "pointer",
517
- boxShadow: `0 4px 20px ${accentColor}55, 0 2px 8px rgba(0,0,0,0.15)`,
518
- display: "flex",
519
- alignItems: "center",
520
- justifyContent: "center",
521
- transition: "transform 0.2s, box-shadow 0.2s"
522
- },
523
- children: [
524
- isOpen ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z" }) }),
525
- !isOpen && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
526
- position: "absolute",
527
- top: 2,
528
- right: 2,
529
- width: 12,
530
- height: 12,
531
- borderRadius: "50%",
532
- background: "#ef4444",
533
- border: "2px solid white"
534
- } })
535
- ]
536
- }
537
- )
576
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { className: "sa-fab", onClick: () => setOpen((o) => !o), style: {
577
+ position: "fixed",
578
+ bottom: 16,
579
+ zIndex: 99999,
580
+ ...left ? { left: 16 } : { right: 16 },
581
+ width: 58,
582
+ height: 58,
583
+ borderRadius: "50%",
584
+ border: "none",
585
+ background: `linear-gradient(135deg,${accentColor},${adj(accentColor, -28)})`,
586
+ cursor: "pointer",
587
+ boxShadow: `0 6px 24px ${accentColor}55, 0 2px 8px rgba(0,0,0,.18)`,
588
+ display: "flex",
589
+ alignItems: "center",
590
+ justifyContent: "center"
591
+ }, children: [
592
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
593
+ transition: "transform .3s cubic-bezier(.16,1,.3,1), opacity .2s",
594
+ transform: open ? "rotate(90deg) scale(.9)" : "rotate(0) scale(1)",
595
+ opacity: open ? 0.85 : 1,
596
+ display: "flex"
597
+ }, children: open ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "white", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z" }) }) }),
598
+ !open && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
599
+ position: "absolute",
600
+ top: 3,
601
+ right: 3,
602
+ width: 13,
603
+ height: 13,
604
+ borderRadius: "50%",
605
+ background: "#ef4444",
606
+ border: "2.5px solid white",
607
+ animation: "sa-pulse 2s infinite"
608
+ } })
609
+ ] })
538
610
  ] });
539
611
  }
540
- var s = {
541
- panel: {
542
- height: 580,
543
- maxHeight: "calc(100vh - 110px)",
544
- background: "#ffffff",
545
- borderRadius: 18,
546
- boxShadow: "0 20px 60px rgba(0,0,0,0.15), 0 4px 20px rgba(0,0,0,0.08)",
547
- display: "flex",
548
- flexDirection: "column",
549
- overflow: "hidden",
550
- fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
551
- border: "1px solid rgba(0,0,0,0.06)"
552
- },
553
- panelInline: {
554
- height: "100%",
555
- maxHeight: "none",
556
- borderRadius: 14,
557
- boxShadow: "0 2px 16px rgba(0,0,0,0.08)"
558
- },
559
- messages: {
560
- flex: 1,
561
- overflowY: "auto",
562
- padding: "16px 16px 8px",
563
- display: "flex",
564
- flexDirection: "column",
565
- gap: 14,
566
- scrollbarWidth: "thin"
567
- },
568
- welcome: {
569
- textAlign: "center",
570
- padding: "32px 20px",
571
- flex: 1,
572
- display: "flex",
573
- flexDirection: "column",
574
- alignItems: "center",
575
- justifyContent: "center"
576
- }
577
- };
578
- function adjustColor(hex, amount) {
579
- const num = parseInt(hex.replace("#", ""), 16);
580
- const r = Math.min(255, Math.max(0, (num >> 16 & 255) + amount));
581
- const g = Math.min(255, Math.max(0, (num >> 8 & 255) + amount));
582
- const b = Math.min(255, Math.max(0, (num & 255) + amount));
612
+ function adj(hex, amt) {
613
+ const n = parseInt(hex.replace("#", ""), 16);
614
+ const r = Math.min(255, Math.max(0, (n >> 16 & 255) + amt));
615
+ const g = Math.min(255, Math.max(0, (n >> 8 & 255) + amt));
616
+ const b = Math.min(255, Math.max(0, (n & 255) + amt));
583
617
  return `#${(r << 16 | g << 8 | b).toString(16).padStart(6, "0")}`;
584
618
  }
585
619
  function SyncAgentChat({ config, ...props }) {
586
- if (config) {
587
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SyncAgentProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatInner, { ...props }) });
588
- }
620
+ if (config) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SyncAgentProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatInner, { ...props }) });
589
621
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatInner, { ...props });
590
622
  }
591
623