@frankieai/react 0.2.19 → 0.2.21

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.
package/dist/index.js CHANGED
@@ -58,6 +58,8 @@ var FrankieClient = class {
58
58
  session;
59
59
  /** Identity (JWT `sub`, else the raw token) the cached session was issued for. */
60
60
  sessionUserKey;
61
+ /** The host token fetched for the latest turn; sent with it so tools get a live one. */
62
+ latestUserToken;
61
63
  get sessionId() {
62
64
  return this.session?.sessionId;
63
65
  }
@@ -119,6 +121,7 @@ var FrankieClient = class {
119
121
  "user_token_unavailable"
120
122
  );
121
123
  }
124
+ this.latestUserToken = userToken;
122
125
  const userKey = sessionIdentity(userToken);
123
126
  if (userKey !== this.sessionUserKey) this.resetSession();
124
127
  if (this.session && new Date(this.session.expiresAt).getTime() > Date.now() + 3e4) return this.session;
@@ -211,7 +214,11 @@ var FrankieClient = class {
211
214
  message: input.message,
212
215
  ...input.context ? { context: input.context } : {},
213
216
  ...input.model ? { model: input.model } : {},
214
- ...input.attachments?.length ? { attachments: input.attachments } : {}
217
+ ...input.attachments?.length ? { attachments: input.attachments } : {},
218
+ ...this.latestUserToken ? { userToken: this.latestUserToken } : {},
219
+ // This widget shows the approval card, so the server may pause writes for it.
220
+ confirmActions: true,
221
+ ...input.confirm ? { confirm: input.confirm } : {}
215
222
  };
216
223
  const response = await this.doFetch(`${this.baseUrl}/v1/chat`, {
217
224
  method: "POST",
@@ -246,7 +253,7 @@ var FrankieClient = class {
246
253
  await this.postToolResult(session, callId, result).catch(() => void 0);
247
254
  }
248
255
  async callHostApi(request) {
249
- const api = this.options.api;
256
+ const api = this.options.api ?? (typeof window !== "undefined" ? { baseUrl: window.location.origin } : void 0);
250
257
  if (!api) {
251
258
  return {
252
259
  status: 0,
@@ -353,6 +360,10 @@ function luminance([r, g, b]) {
353
360
  };
354
361
  return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);
355
362
  }
363
+ function colorful([r, g, b]) {
364
+ const max = Math.max(r, g, b), min = Math.min(r, g, b);
365
+ return max - min >= 40;
366
+ }
356
367
  function contrastRatio(a, b) {
357
368
  const la = luminance(a), lb = luminance(b);
358
369
  return (Math.max(la, lb) + 0.05) / (Math.min(la, lb) + 0.05);
@@ -461,7 +472,7 @@ function inferHostTheme() {
461
472
  break;
462
473
  }
463
474
  const text = parseRgb(style.color);
464
- if (text && text[3] > 0.5 && !sameColor(text, foreground)) {
475
+ if (text && text[3] > 0.5 && !sameColor(text, foreground) && colorful(text)) {
465
476
  accent = text;
466
477
  break;
467
478
  }
@@ -539,6 +550,11 @@ function applyEvent(message, event) {
539
550
  } : tool
540
551
  )
541
552
  };
553
+ case "action_confirm":
554
+ return {
555
+ ...message,
556
+ action: { toolUseId: event.toolUseId, name: event.name, label: event.label, preview: event.preview, state: "pending" }
557
+ };
542
558
  case "tool_denied":
543
559
  return {
544
560
  ...message,
@@ -758,6 +774,7 @@ function useFrankieChatState() {
758
774
  ...context ? { context } : {},
759
775
  ...opts?.model ? { model: opts.model } : {},
760
776
  ...attachments.length ? { attachments } : {},
777
+ ...opts?.confirm ? { confirm: opts.confirm } : {},
761
778
  signal: abort.signal
762
779
  },
763
780
  (event) => {
@@ -828,6 +845,21 @@ function useFrankieChatState() {
828
845
  },
829
846
  [busy, client, context, patchAssistant, restored, followRunningTurn]
830
847
  );
848
+ const answerAction = useCallback(
849
+ async (toolUseId, approved) => {
850
+ if (abortRef.current) return;
851
+ const holder = messagesRef.current.find(
852
+ (message) => message.role === "assistant" && message.action?.toolUseId === toolUseId && message.action.state === "pending"
853
+ );
854
+ if (!holder) return;
855
+ patchAssistant(
856
+ holder.id,
857
+ (message) => message.action ? { ...message, action: { ...message.action, state: approved ? "approved" : "cancelled" } } : message
858
+ );
859
+ await send(approved ? "Go ahead" : "Cancel", { confirm: { toolUseId, approved } });
860
+ },
861
+ [patchAssistant, send]
862
+ );
831
863
  const stop = useCallback(() => {
832
864
  if (!abortRef.current) return;
833
865
  void client.stopTurn();
@@ -848,7 +880,7 @@ function useFrankieChatState() {
848
880
  } catch {
849
881
  }
850
882
  }, [client]);
851
- return { messages, busy, loadedSkills, activeApis, restoring: !restored, ...error ? { error } : {}, send, stop, reset };
883
+ return { messages, busy, loadedSkills, activeApis, restoring: !restored, ...error ? { error } : {}, send, answerAction, stop, reset };
852
884
  }
853
885
  function conversationTitle(messages) {
854
886
  const first = messages.find((message) => message.role === "user" && message.text.trim());
@@ -865,6 +897,7 @@ function stillWorking(messages) {
865
897
  // src/hooks/FrankieProvider.tsx
866
898
  import { jsx } from "react/jsx-runtime";
867
899
  var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect2 : useLayoutEffect;
900
+ var THEME_WAIT_MS = 5e3;
868
901
  var FrankieContext = createContext2(null);
869
902
  function FrankieProvider({
870
903
  children,
@@ -918,6 +951,13 @@ function FrankieProvider({
918
951
  setHostSampled(true);
919
952
  return watchHostTheme(sample);
920
953
  }, [inheriting]);
954
+ const themeKnown = Boolean(config || configError) && (!inheriting || hostSampled);
955
+ const [waitedForTheme, setWaitedForTheme] = useState2(false);
956
+ useEffect2(() => {
957
+ if (themeKnown) return;
958
+ const timer = setTimeout(() => setWaitedForTheme(true), THEME_WAIT_MS);
959
+ return () => clearTimeout(timer);
960
+ }, [themeKnown]);
921
961
  const value = useMemo(
922
962
  () => ({
923
963
  client,
@@ -928,9 +968,9 @@ function FrankieProvider({
928
968
  ...theme ? { theme } : {},
929
969
  injectStyles,
930
970
  hostTheme,
931
- themeReady: Boolean(config || configError) && (!inheriting || hostSampled)
971
+ themeReady: themeKnown || waitedForTheme
932
972
  }),
933
- [client, config, configError, loading, context, theme, injectStyles, hostTheme, inheriting, hostSampled]
973
+ [client, config, configError, loading, context, theme, injectStyles, hostTheme, themeKnown, waitedForTheme]
934
974
  );
935
975
  return /* @__PURE__ */ jsx(FrankieContext.Provider, { value, children: /* @__PURE__ */ jsx(ConversationState, { children }, client.namespace + ":" + (client.conversationId ?? "")) });
936
976
  }
@@ -954,7 +994,7 @@ function useFrankieTheme() {
954
994
  }
955
995
 
956
996
  // src/components/chat/FrankieWidget.tsx
957
- import { MessageCircle, X as X4 } from "lucide-react";
997
+ import { MessageCircle, X as X5 } from "lucide-react";
958
998
  import { useEffect as useEffect6, useRef as useRef5, useState as useState7 } from "react";
959
999
 
960
1000
  // src/lib/styles-ready.ts
@@ -962,7 +1002,7 @@ import { useEffect as useEffect3, useLayoutEffect as useLayoutEffect2, useState
962
1002
 
963
1003
  // src/generated/css-content.ts
964
1004
  var FRANKIE_CSS_CONTENT = `/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
965
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-ease:initial}}}@layer theme{.frankie-root{--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--leading-tight:1.25;--radius-md:.375rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--color-background:var(--frankie-background);--color-foreground:var(--frankie-foreground);--color-primary:var(--frankie-primary)}}@layer components{.frankie-page-shell{background:var(--frankie-background);height:100%;min-height:0;color:var(--frankie-foreground);flex:1;display:flex}.frankie-page-main{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.frankie-history-desktop{border-right:1px solid var(--frankie-border);background:var(--frankie-secondary);flex-direction:column;flex-shrink:0;gap:16px;width:260px;padding:20px 14px;transition:width .16s,padding .16s;display:flex;overflow:auto}.frankie-history-toggle{border:1px solid var(--frankie-border);background:var(--frankie-background);width:32px;height:32px;color:var(--frankie-muted-foreground);cursor:pointer;border-radius:8px;flex-shrink:0;justify-content:center;align-self:flex-end;align-items:center;display:flex}.frankie-history-toggle:hover{color:var(--frankie-foreground)}.frankie-history-collapsed{width:56px;padding:20px 8px;overflow:visible}.frankie-history-collapsed .frankie-history-toggle{align-self:center}.frankie-history-heading{justify-content:space-between;align-items:center;font-size:14px;display:flex}.frankie-new-chat{border:1px solid var(--frankie-border);background:var(--frankie-background);cursor:pointer;border-radius:10px;justify-content:center;align-items:center;gap:8px;min-height:44px;font-weight:600;display:flex}.frankie-history-search>span{color:var(--frankie-muted-foreground);margin-bottom:6px;font-size:12px;display:block}.frankie-history-search input{border:1px solid var(--frankie-border);background:var(--frankie-background);border-radius:8px;width:100%;min-height:40px;padding:8px 10px}.frankie-history-list{flex-direction:column;flex:1;gap:4px;display:flex}.frankie-history-list button{text-align:left;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:8px;flex-direction:column;align-items:flex-start;gap:5px;min-height:54px;padding:10px;display:flex}.frankie-history-list button span{text-overflow:ellipsis;white-space:nowrap;width:100%;font-size:13px;overflow:hidden}.frankie-history-list small{color:var(--frankie-muted-foreground);font-size:11px}.frankie-history-list button:hover,.frankie-history-list button[aria-current]{background:var(--frankie-background);border-color:var(--frankie-border)}.frankie-history-desktop>p,.frankie-history-dialog p{color:var(--frankie-muted-foreground);font-size:13px}.frankie-header-caption{color:var(--frankie-muted-foreground);font-size:12px}.frankie-page-header button{cursor:pointer;justify-content:center;align-items:center;gap:6px;min-width:40px;min-height:40px;display:inline-flex}.frankie-chat-settings{position:relative}.frankie-chat-settings summary{cursor:pointer;border-radius:8px;place-items:center;width:40px;height:40px;list-style:none;display:grid}.frankie-chat-settings summary::-webkit-details-marker{display:none}.frankie-chat-settings>div{z-index:5;border:1px solid var(--frankie-border);background:var(--frankie-background);border-radius:12px;gap:12px;width:min(280px,80vw);padding:16px;font-size:13px;display:grid;position:absolute;top:46px;right:0;box-shadow:0 10px 30px #0002}.frankie-chat-settings p{color:var(--frankie-muted-foreground);margin:0}.frankie-loaded-skills{width:100%;max-width:760px;color:var(--frankie-muted-foreground);font-size:12px}.frankie-loaded-skills summary{cursor:pointer;padding:6px 0}.frankie-loaded-skills ul{margin:0;padding:4px 0;list-style:none}.frankie-loaded-skills li{gap:8px;padding:4px 0;display:flex}.frankie-loaded-skills small{opacity:.7}.frankie-history-dialog{background:var(--frankie-secondary);width:min(320px,86vw);max-width:none;height:100dvh;max-height:none;color:var(--frankie-foreground);border:0;margin:0;padding:0}.frankie-history-dialog::backdrop{background:#0008}.frankie-history-dialog>aside{height:100%;padding:calc(20px + env(safe-area-inset-top)) 16px calc(20px + env(safe-area-inset-bottom));flex-direction:column;gap:16px;display:flex;overflow:auto}.frankie-mobile-only{display:none!important}.frankie-widget-panel{max-height:calc(100dvh - 100px - var(--frankie-lift,0px))}.frankie-root button:focus-visible,.frankie-root summary:focus-visible,.frankie-root input:focus-visible{outline:2px solid var(--frankie-primary);outline-offset:3px}.frankie-root button:disabled{opacity:.5;cursor:not-allowed}@media (max-width:760px){.frankie-history-desktop{display:none}.frankie-mobile-only{display:inline-flex!important}.frankie-header-caption{display:none}.frankie-page-header{padding:6px 10px}.frankie-history-heading button{background:0 0;border:0;justify-content:center;align-items:center;min-width:44px;min-height:44px}.frankie-page-prompts{gap:8px}.frankie-widget-panel{width:calc(100vw - 32px)}}.frankie-root{--frankie-styles-ready:1;--frankie-background:#fff;--frankie-foreground:#0a0a0a;--frankie-primary:#171717;--frankie-primary-foreground:#fafafa;--frankie-secondary:#f5f5f5;--frankie-secondary-foreground:#171717;--frankie-muted:#f5f5f5;--frankie-muted-foreground:#737373;--frankie-border:#e5e5e5;--frankie-radius:.625rem;--frankie-font:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;font-family:var(--frankie-font);color:var(--frankie-foreground);-webkit-font-smoothing:antialiased;line-height:1.5}.frankie-root.dark{--frankie-background:#0a0a0a;--frankie-foreground:#fafafa;--frankie-primary:#fafafa;--frankie-primary-foreground:#171717;--frankie-secondary:#262626;--frankie-secondary-foreground:#fafafa;--frankie-muted:#262626;--frankie-muted-foreground:#a3a3a3;--frankie-border:#262626}.frankie-root,.frankie-root *,.frankie-root :before,.frankie-root :after{box-sizing:border-box}.frankie-root button,.frankie-root textarea,.frankie-root input{font:inherit;color:inherit;margin:0}.frankie-root button{background-color:#0000;border:0 solid}.frankie-root textarea{background-color:var(--frankie-background)}.frankie-focus:focus-visible{outline:2px solid var(--frankie-primary);outline-offset:2px}.frankie-scroll{scrollbar-width:thin;scrollbar-color:var(--frankie-border) transparent}.frankie-prose>*+*{margin-top:.6rem}.frankie-prose p{white-space:pre-wrap;overflow-wrap:anywhere;margin:0;line-height:1.6}.frankie-prose>.frankie-h{letter-spacing:-.01em;margin-top:1.15rem;line-height:1.3}.frankie-prose>.frankie-h:first-child{margin-top:0}.frankie-prose h3.frankie-h{font-size:1.06em;font-weight:700}.frankie-prose h4.frankie-h{font-size:1em;font-weight:600}.frankie-prose h5.frankie-h{color:var(--frankie-muted-foreground);font-size:.92em;font-weight:600}.frankie-prose strong{font-weight:600}.frankie-prose ul,.frankie-prose ol{flex-direction:column;gap:.35rem;margin:0;padding-left:1.4rem;display:flex}.frankie-prose li{padding-left:.15rem;line-height:1.55}.frankie-prose li::marker{color:var(--frankie-muted-foreground)}.frankie-prose ul{list-style:outside}.frankie-prose ol{list-style:decimal}.frankie-prose a{color:var(--frankie-primary);text-underline-offset:2px;text-decoration:underline}.frankie-prose code{background-color:var(--frankie-muted);border-radius:.25rem;padding:.1em .3em;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,monospace;font-size:.85em}.frankie-prose pre{border-radius:var(--frankie-radius);background-color:var(--frankie-muted);margin:0;padding:.625rem .75rem;overflow-x:auto}.frankie-prose pre code{background:0 0;padding:0}.frankie-chat-page{background:radial-gradient(60rem 24rem at 50% -12rem, var(--frankie-primary), transparent 65%), var(--frankie-background);flex-direction:column;min-width:0;display:flex;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.frankie-chat-page{background:radial-gradient(60rem 24rem at 50% -12rem, color-mix(in srgb, var(--frankie-primary) 8%, transparent), transparent 65%), var(--frankie-background)}}.frankie-chat-page{color:var(--frankie-foreground)}.frankie-page-header{border-bottom:1px solid var(--frankie-border);background:var(--frankie-background);flex:0 0 56px;justify-content:space-between;align-items:center;gap:16px;min-height:56px;padding:0 24px;display:flex}@supports (color:color-mix(in lab, red, red)){.frankie-page-header{background:color-mix(in srgb, var(--frankie-background) 92%, transparent)}}.frankie-page-header{-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.frankie-page-header>div{align-items:center;gap:10px;display:flex}.frankie-page-header strong{font-size:.925rem;font-weight:650}.frankie-page-status{background:var(--frankie-primary);width:10px;height:10px;box-shadow:0 0 0 4px var(--frankie-primary);border-radius:999px}@supports (color:color-mix(in lab, red, red)){.frankie-page-status{box-shadow:0 0 0 4px color-mix(in srgb, var(--frankie-primary) 16%, transparent)}}.frankie-page-header button{border:1px solid var(--frankie-border);border-radius:calc(var(--frankie-radius) * .9);background:var(--frankie-secondary);cursor:pointer;min-height:36px;padding:0 13px}.frankie-page-header button:hover{border-color:var(--frankie-primary)}.frankie-page-canvas{flex:1;min-width:0;min-height:0;display:flex}.frankie-page-canvas>.frankie-inline{width:100%;max-width:56rem;margin:0 auto}.frankie-page-canvas .frankie-scroll{padding:2rem clamp(1rem,4vw,4rem) 1.25rem}.frankie-page-canvas .frankie-root>.border-t{background:linear-gradient(180deg, transparent, var(--frankie-background) 30%);border-top:0;padding:.75rem clamp(1rem,4vw,4rem) 1.5rem}.frankie-page-empty{text-align:center;flex-direction:column;flex-shrink:0;justify-content:safe center;align-items:center;gap:2rem;width:min(100%,44rem);min-height:100%;margin:auto;padding:clamp(2rem,7vh,4.5rem) 1rem 2rem;display:flex;container-type:inline-size}.frankie-page-welcome h1{letter-spacing:-.02em;margin:0;font-size:clamp(1.55rem,3.4vw,2rem);font-weight:700;line-height:1.15}.frankie-page-welcome p{max-width:34rem;color:var(--frankie-muted-foreground);margin:.6rem auto 0;font-size:1rem}.frankie-page-suggest{flex-direction:column;align-items:center;gap:1rem;width:100%;display:flex}.frankie-page-suggest-label{color:var(--frankie-muted-foreground);letter-spacing:.12em;text-transform:uppercase;margin:0;font-size:.72rem;font-weight:600}.frankie-page-prompts{grid-template-columns:1fr;gap:.75rem;width:100%;display:grid}@container (min-width:30rem){.frankie-page-prompts{grid-template-columns:repeat(2,minmax(0,1fr))}}.frankie-page-prompts button{border:1px solid var(--frankie-border);background:var(--frankie-background);text-align:left;cursor:pointer;border-radius:14px;align-items:flex-start;gap:.85rem;min-height:64px;padding:.9rem 1rem;transition:border-color .15s,background-color .15s,transform .12s;display:flex}.frankie-page-prompts button:hover:not(:disabled){border-color:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-page-prompts button:hover:not(:disabled){border-color:color-mix(in srgb, var(--frankie-primary) 45%, var(--frankie-border))}}.frankie-page-prompts button:hover:not(:disabled){background:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-page-prompts button:hover:not(:disabled){background:color-mix(in srgb, var(--frankie-primary) 4%, var(--frankie-background))}}.frankie-page-prompts button:hover:not(:disabled){transform:translateY(-1px)}.frankie-prompt-icon{background:var(--frankie-muted);width:34px;height:34px;color:var(--frankie-foreground);border-radius:9px;flex:none;place-items:center;display:grid}.frankie-prompt-text{flex-direction:column;gap:2px;min-width:0;display:flex}.frankie-prompt-text strong{font-size:.9rem;font-weight:600;line-height:1.3}.frankie-prompt-text small{color:var(--frankie-muted-foreground);font-size:.8rem;line-height:1.35;overflow:hidden}.frankie-page-suggest-hint{color:var(--frankie-muted-foreground);margin:0;font-size:.85rem}.frankie-widget-panel .frankie-page-empty{gap:1rem;padding:1rem .25rem}.frankie-widget-panel .frankie-page-welcome h1{font-size:1.25rem}.frankie-widget-panel .frankie-page-welcome p{margin-top:.35rem;font-size:.88rem;line-height:1.45}.frankie-widget-panel .frankie-page-suggest{gap:.55rem}.frankie-widget-panel .frankie-page-suggest-label{font-size:.66rem}.frankie-widget-panel .frankie-page-prompts{flex-wrap:wrap;justify-content:center;gap:.4rem;display:flex}.frankie-widget-panel .frankie-page-prompts button{border-radius:999px;align-items:center;gap:.4rem;max-width:100%;min-height:34px;padding:.3rem .8rem .3rem .45rem}.frankie-widget-panel .frankie-prompt-icon{border-radius:999px;width:22px;height:22px}.frankie-widget-panel .frankie-prompt-icon svg{width:13px;height:13px}.frankie-widget-panel .frankie-prompt-text strong{white-space:nowrap;text-overflow:ellipsis;font-size:.82rem;font-weight:550;overflow:hidden}.frankie-widget-panel .frankie-prompt-text small,.frankie-widget-panel .frankie-page-suggest-hint{display:none}@media (max-width:640px){.frankie-page-header{flex-basis:52px;min-height:52px;padding:0 12px}.frankie-page-canvas .frankie-scroll{padding:1.25rem .75rem .5rem}.frankie-page-canvas .frankie-root>.border-t{padding:.65rem .75rem calc(.65rem + env(safe-area-inset-bottom))}}}@layer utilities;.frankie-root .\\@container{container-type:inline-size}.frankie-root .invisible{visibility:hidden}.frankie-root .visible{visibility:visible}.frankie-root .absolute{position:absolute}.frankie-root .fixed{position:fixed}.frankie-root .relative{position:relative}.frankie-root .static{position:static}.frankie-root .sticky{position:sticky}.frankie-root .isolate{isolation:isolate}.frankie-root .container{width:100%}@media (min-width:40rem){.frankie-root .container{max-width:40rem}}@media (min-width:48rem){.frankie-root .container{max-width:48rem}}@media (min-width:64rem){.frankie-root .container{max-width:64rem}}@media (min-width:80rem){.frankie-root .container{max-width:80rem}}@media (min-width:96rem){.frankie-root .container{max-width:96rem}}.frankie-root .mt-0{margin-top:0}.frankie-root .mt-0\\.5{margin-top:calc(var(--spacing) * .5)}.frankie-root .mt-1{margin-top:var(--spacing)}.frankie-root .mt-2{margin-top:calc(var(--spacing) * 2)}.frankie-root .block{display:block}.frankie-root .contents{display:contents}.frankie-root .flex{display:flex}.frankie-root .grid{display:grid}.frankie-root .hidden{display:none}.frankie-root .inline{display:inline}.frankie-root .inline-flex{display:inline-flex}.frankie-root .table{display:table}.frankie-root .size-1{width:var(--spacing);height:var(--spacing)}.frankie-root .size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.frankie-root .size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.frankie-root .size-3\\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.frankie-root .size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.frankie-root .size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.frankie-root .size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.frankie-root .size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.frankie-root .size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.frankie-root .size-12{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.frankie-root .size-full{width:100%;height:100%}.frankie-root .h-8{height:calc(var(--spacing) * 8)}.frankie-root .h-9{height:calc(var(--spacing) * 9)}.frankie-root .h-10{height:calc(var(--spacing) * 10)}.frankie-root .h-\\[32rem\\]{height:32rem}.frankie-root .h-full{height:100%}.frankie-root .h-px{height:1px}.frankie-root .min-h-7{min-height:calc(var(--spacing) * 7)}.frankie-root .min-h-\\[2\\.25rem\\]{min-height:2.25rem}.frankie-root .min-h-screen{min-height:100vh}.frankie-root .w-\\[22rem\\]{width:22rem}.frankie-root .w-full{width:100%}.frankie-root .max-w-\\[12rem\\]{max-width:12rem}.frankie-root .max-w-\\[14rem\\]{max-width:14rem}.frankie-root .max-w-\\[85\\%\\]{max-width:85%}.frankie-root .max-w-\\[calc\\(100vw-2rem\\)\\]{max-width:calc(100vw - 2rem)}.frankie-root .min-w-0{min-width:0}.frankie-root .flex-1{flex:1}.frankie-root .shrink-0{flex-shrink:0}.frankie-root .grow{flex-grow:1}.frankie-root .animate-pulse{animation:var(--animate-pulse)}.frankie-root .animate-spin{animation:var(--animate-spin)}.frankie-root .cursor-pointer{cursor:pointer}.frankie-root .resize{resize:both}.frankie-root .resize-none{resize:none}.frankie-root .list-none{list-style-type:none}.frankie-root .flex-col{flex-direction:column}.frankie-root .flex-wrap{flex-wrap:wrap}.frankie-root .items-center{align-items:center}.frankie-root .items-end{align-items:flex-end}.frankie-root .items-start{align-items:flex-start}.frankie-root .justify-center{justify-content:center}.frankie-root .justify-end{justify-content:flex-end}.frankie-root .gap-1{gap:var(--spacing)}.frankie-root .gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.frankie-root .gap-2{gap:calc(var(--spacing) * 2)}.frankie-root .gap-3{gap:calc(var(--spacing) * 3)}.frankie-root .gap-4{gap:calc(var(--spacing) * 4)}.frankie-root .truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.frankie-root .overflow-hidden{overflow:hidden}.frankie-root .overflow-y-auto{overflow-y:auto}.frankie-root .overscroll-contain{overscroll-behavior:contain}.frankie-root .rounded{border-radius:.25rem}.frankie-root .rounded-\\[calc\\(var\\(--frankie-radius\\)\\+4px\\)\\]{border-radius:calc(var(--frankie-radius) + 4px)}.frankie-root .rounded-\\[calc\\(var\\(--frankie-radius\\)-2px\\)\\]{border-radius:calc(var(--frankie-radius) - 2px)}.frankie-root .rounded-\\[var\\(--frankie-radius\\)\\]{border-radius:var(--frankie-radius)}.frankie-root .rounded-full{border-radius:3.40282e38px}.frankie-root .rounded-md{border-radius:var(--radius-md)}.frankie-root .rounded-none{border-radius:0}.frankie-root .border{border-style:var(--tw-border-style);border-width:1px}.frankie-root .border-0{border-style:var(--tw-border-style);border-width:0}.frankie-root .border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.frankie-root .border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.frankie-root .border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.frankie-root .border-border{border-color:var(--frankie-border)}.frankie-root .border-transparent{border-color:#0000}.frankie-root .bg-background{background-color:var(--frankie-background)}.frankie-root .bg-border{background-color:var(--frankie-border)}.frankie-root .bg-emerald-500{background-color:var(--color-emerald-500)}.frankie-root .bg-emerald-500\\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab, red, red)){.frankie-root .bg-emerald-500\\/10{background-color:color-mix(in oklab, var(--color-emerald-500) 10%, transparent)}}.frankie-root .bg-muted{background-color:var(--frankie-muted)}.frankie-root .bg-muted-foreground{background-color:var(--frankie-muted-foreground)}.frankie-root .bg-primary{background-color:var(--frankie-primary)}.frankie-root .bg-red-500{background-color:var(--color-red-500)}.frankie-root .bg-red-500\\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.frankie-root .bg-red-500\\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.frankie-root .bg-secondary{background-color:var(--frankie-secondary)}.frankie-root .object-cover{object-fit:cover}.frankie-root .p-3{padding:calc(var(--spacing) * 3)}.frankie-root .p-4{padding:calc(var(--spacing) * 4)}.frankie-root .px-1{padding-inline:var(--spacing)}.frankie-root .px-2{padding-inline:calc(var(--spacing) * 2)}.frankie-root .px-3{padding-inline:calc(var(--spacing) * 3)}.frankie-root .px-4{padding-inline:calc(var(--spacing) * 4)}.frankie-root .px-6{padding-inline:calc(var(--spacing) * 6)}.frankie-root .py-0{padding-block:0}.frankie-root .py-0\\.5{padding-block:calc(var(--spacing) * .5)}.frankie-root .py-1{padding-block:var(--spacing)}.frankie-root .py-2{padding-block:calc(var(--spacing) * 2)}.frankie-root .py-3{padding-block:calc(var(--spacing) * 3)}.frankie-root .pl-2{padding-left:calc(var(--spacing) * 2)}.frankie-root .text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.frankie-root .text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.frankie-root .text-\\[0\\.625rem\\]{font-size:.625rem}.frankie-root .text-\\[0\\.6875rem\\]{font-size:.6875rem}.frankie-root .text-\\[11px\\]{font-size:11px}.frankie-root .leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.frankie-root .font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.frankie-root .font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.frankie-root .whitespace-nowrap{white-space:nowrap}.frankie-root .text-emerald-600{color:var(--color-emerald-600)}.frankie-root .text-foreground{color:var(--frankie-foreground)}.frankie-root .text-muted-foreground{color:var(--frankie-muted-foreground)}.frankie-root .text-primary{color:var(--frankie-primary)}.frankie-root .text-primary-foreground{color:var(--frankie-primary-foreground)}.frankie-root .text-red-600{color:var(--color-red-600)}.frankie-root .text-secondary-foreground{color:var(--frankie-secondary-foreground)}.frankie-root .italic{font-style:italic}.frankie-root .underline-offset-4{text-underline-offset:4px}.frankie-root .opacity-60{opacity:.6}.frankie-root .opacity-70{opacity:.7}.frankie-root .shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.frankie-root .shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.frankie-root .shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.frankie-root .outline{outline-style:var(--tw-outline-style);outline-width:1px}.frankie-root .transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.frankie-root .transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.frankie-root .transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.frankie-root .ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.frankie-root .select-all{-webkit-user-select:all;user-select:all}.frankie-root .placeholder\\:text-muted-foreground::placeholder{color:var(--frankie-muted-foreground)}@media (hover:hover){.frankie-root .hover\\:border-border:hover{border-color:var(--frankie-border)}.frankie-root .hover\\:bg-muted:hover{background-color:var(--frankie-muted)}.frankie-root .hover\\:text-foreground:hover{color:var(--frankie-foreground)}.frankie-root .hover\\:underline:hover{text-decoration-line:underline}.frankie-root .hover\\:opacity-90:hover{opacity:.9}.frankie-root .hover\\:opacity-100:hover{opacity:1}}.frankie-root .focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.frankie-root .focus-visible\\:ring-primary:focus-visible{--tw-ring-color:var(--frankie-primary)}.frankie-root .focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.frankie-root .disabled\\:pointer-events-none:disabled{pointer-events:none}.frankie-root .disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.frankie-root .disabled\\:opacity-50:disabled{opacity:.5}.frankie-root .dark\\:text-emerald-400:where(.dark,.dark *){color:var(--color-emerald-400)}.frankie-root .dark\\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.frankie-root .\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.frankie-root .\\[\\&_svg\\]\\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.frankie-root .\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.frankie-root .\\[\\&\\:\\:-webkit-details-marker\\]\\:hidden::-webkit-details-marker{display:none}.frankie-root.frankie-chat-panel{min-height:0;position:relative}.frankie-root.frankie-widget-panel{box-shadow:0 32px 72px -18px var(--frankie-primary), 0 12px 28px -12px #0f172a47, 0 0 0 1px var(--frankie-foreground)}@supports (color:color-mix(in lab, red, red)){.frankie-root.frankie-widget-panel{box-shadow:0 32px 72px -18px color-mix(in srgb, var(--frankie-primary) 22%, #0f172a6b), 0 12px 28px -12px #0f172a47, 0 0 0 1px color-mix(in srgb, var(--frankie-foreground) 8%, transparent)}}.frankie-root.frankie-widget-panel.dark{box-shadow:0 34px 80px -16px #000000b8, 0 14px 32px -12px #0009, 0 0 0 1px var(--frankie-foreground)}@supports (color:color-mix(in lab, red, red)){.frankie-root.frankie-widget-panel.dark{box-shadow:0 34px 80px -16px #000000b8, 0 14px 32px -12px #0009, 0 0 0 1px color-mix(in srgb, var(--frankie-foreground) 12%, transparent)}}.frankie-root .frankie-agent-context-wrap{flex:none;justify-content:center;padding:12px 10px;display:flex}.frankie-root .frankie-agent-context{max-width:100%;color:var(--frankie-foreground);font-size:13px;position:relative}.frankie-root .frankie-agent-context>summary{border:1px solid var(--frankie-border);background:var(--frankie-background);cursor:pointer;white-space:nowrap;border-radius:999px;justify-content:center;align-items:center;gap:10px;min-height:44px;padding:7px 13px;list-style:none;display:flex;box-shadow:0 1px 3px #0000000d}.frankie-root .frankie-agent-context>summary::-webkit-details-marker{display:none}.frankie-root .frankie-agent-context>summary>svg{color:var(--frankie-muted-foreground);flex:none}.frankie-root .frankie-context-count{background:var(--frankie-muted);color:var(--frankie-muted-foreground);border-radius:999px;padding:2px 10px;font-size:12px}.frankie-root .frankie-context-status{color:var(--frankie-muted-foreground);align-items:center;gap:6px;font-size:12px;display:flex}.frankie-root .frankie-context-status i{background:currentColor;border-radius:50%;width:7px;height:7px}.frankie-root .frankie-context-status[data-active=true]{color:#00976b}.frankie-root .frankie-context-detail{z-index:10;border:1px solid var(--frankie-border);background:var(--frankie-background);border-radius:16px;width:340px;max-width:calc(100vw - 32px);padding:18px;position:absolute;top:calc(100% + 10px);left:50%;transform:translate(-50%);box-shadow:0 12px 32px #00000016}.frankie-root .frankie-context-detail p{color:var(--frankie-muted-foreground);margin:10px 0 0;font-size:12px;line-height:1.6}.frankie-root .frankie-context-detail ul{max-height:220px;margin:12px 0;padding:0;list-style:none;overflow:auto}.frankie-root .frankie-context-detail li{border-bottom:1px solid var(--frankie-border);overflow-wrap:anywhere;justify-content:space-between;gap:12px;padding:8px 0;display:flex}.frankie-root .frankie-context-detail small{color:var(--frankie-muted-foreground);flex:none}.frankie-root .frankie-sr-only{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.frankie-root.frankie-chat-panel-fill{--frankie-canvas:var(--frankie-background)}@supports (color:color-mix(in lab, red, red)){.frankie-root.frankie-chat-panel-fill{--frankie-canvas:color-mix(in srgb,var(--frankie-background) 60%,var(--frankie-muted))}}.frankie-root.frankie-chat-panel-fill{background:var(--frankie-canvas)}.frankie-root.frankie-chat-panel-fill .frankie-agent-context-wrap{padding:44px 16px 26px}.frankie-root.frankie-chat-panel-fill .frankie-transcript{padding:14px max(24px,50% - 480px) 24px}.frankie-root.frankie-chat-panel-fill .frankie-message-list{gap:38px}.frankie-root.frankie-chat-panel-fill .frankie-user-bubble{background:var(--frankie-muted);color:var(--frankie-foreground);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:24px;padding:12px 20px;font-size:15px}.frankie-root.frankie-chat-panel-fill .frankie-assistant-content{flex:1;max-width:100%;font-size:15px;line-height:1.7}.frankie-root.frankie-chat-panel-fill .frankie-assistant-message{gap:14px}.frankie-root .frankie-thinking{color:var(--frankie-muted-foreground);gap:5px}.frankie-root .frankie-thinking-label{margin-right:6px;font-size:14px}.frankie-root.frankie-chat-panel-fill .frankie-composer-footer{background:0 0;border:0;flex:none;padding:16px max(24px,50% - 500px) 24px}.frankie-root.frankie-chat-panel-fill .frankie-composer{border:1px solid var(--frankie-border);background:var(--frankie-background);border-radius:28px;padding:14px;box-shadow:0 2px 4px #0000000a}.frankie-root.frankie-chat-panel-fill .frankie-composer:focus-within{border-color:var(--frankie-foreground)}@supports (color:color-mix(in lab, red, red)){.frankie-root.frankie-chat-panel-fill .frankie-composer:focus-within{border-color:color-mix(in srgb,var(--frankie-foreground) 32%,var(--frankie-border))}}.frankie-root.frankie-chat-panel-fill .frankie-composer:focus-within{box-shadow:0 0 0 2px var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-root.frankie-chat-panel-fill .frankie-composer:focus-within{box-shadow:0 0 0 2px color-mix(in srgb,var(--frankie-primary) 8%,transparent)}}.frankie-root.frankie-chat-panel-fill .frankie-composer-controls{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.frankie-root.frankie-chat-panel-fill .frankie-composer textarea{resize:none;width:100%;min-height:32px;max-height:140px;color:var(--frankie-foreground);box-shadow:none;background:0 0;border:0;border-radius:0;outline:none;flex:0 0 100%;order:-1;margin-bottom:4px;padding:2px 6px;font-size:16px}.frankie-root.frankie-chat-panel-fill .frankie-composer button[aria-label=Send],.frankie-root.frankie-chat-panel-fill .frankie-composer button[aria-label=Stop]{background:var(--frankie-primary);width:42px;height:42px;color:var(--frankie-primary-foreground);border:0;border-radius:50%;margin-left:auto}.frankie-root.frankie-chat-panel-fill .frankie-composer button[aria-label=Attach\\ files]{border-radius:50%;width:42px;height:42px}.frankie-root .frankie-composer-actions{align-items:center;gap:6px;min-width:0;display:flex}.frankie-root .frankie-composer-meta{align-items:center;gap:8px;margin-top:6px;padding:0 2px;display:flex}.frankie-root .frankie-model-picker{align-items:center;min-width:0;display:inline-flex}.frankie-root .frankie-model-select{appearance:none;max-width:12rem;color:var(--frankie-muted-foreground);font:inherit;cursor:pointer;text-overflow:ellipsis;background-color:#0000;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238b8b8b' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");background-position:right 6px center;background-repeat:no-repeat;background-size:11px;border:0;border-radius:8px;padding:5px 22px 5px 8px;font-size:12px;font-weight:500;line-height:1;transition:background-color .12s,color .12s}.frankie-root .frankie-model-select:hover{background-color:var(--frankie-muted);color:var(--frankie-foreground)}.frankie-root .frankie-model-select:disabled{opacity:.5;cursor:not-allowed}.frankie-root .frankie-model-select option{color:var(--frankie-foreground);background:var(--frankie-background);font-weight:400}.frankie-root .frankie-history-desktop{background:var(--frankie-background);width:290px;padding:20px 12px}.frankie-root .frankie-history-collapsed{width:56px;padding:20px 8px}.frankie-root .frankie-new-chat{background:0 0;border:0;justify-content:flex-start;padding:8px 12px;font-size:15px}.frankie-root .frankie-history-heading{color:var(--frankie-muted-foreground);padding:0 12px;font-size:12px;font-weight:400}.frankie-root .frankie-history-list button{min-height:44px;padding:10px 12px}.frankie-root .frankie-history-list button span{font-size:14px}.frankie-root .frankie-history-list button[aria-current],.frankie-root .frankie-history-list button:hover{background:var(--frankie-muted);border-color:#0000}.frankie-root .frankie-history-list small{display:none}.frankie-root .frankie-history-group{flex-direction:column;gap:2px;display:flex}.frankie-root .frankie-history-group+.frankie-history-group{margin-top:12px}.frankie-root .frankie-history-group-label{letter-spacing:.04em;color:var(--frankie-muted-foreground);margin:0;padding:4px 12px;font-size:11px;font-weight:600}.frankie-root .frankie-page-header{background:var(--frankie-background);height:56px;min-height:56px}.frankie-root .frankie-page-header>div{min-width:0}.frankie-root .frankie-thread-title{text-overflow:ellipsis;white-space:nowrap;max-width:55vw;font-weight:500;overflow:hidden}.frankie-root .frankie-page-header button{background:0 0;border-color:#0000}.frankie-root .frankie-page-canvas>.frankie-inline{max-width:none}@media (max-width:760px){.frankie-root.frankie-chat-panel-fill .frankie-agent-context-wrap{padding:20px 8px 14px}.frankie-root.frankie-chat-panel-fill .frankie-transcript{padding:12px 16px 16px}.frankie-root.frankie-chat-panel-fill .frankie-composer-footer{padding:10px 12px calc(12px + env(safe-area-inset-bottom))}.frankie-root .frankie-agent-context>summary{gap:6px;padding:7px 9px;font-size:12px}.frankie-root .frankie-context-count{padding:2px 7px;font-size:11px}.frankie-root .frankie-context-status{gap:4px;font-size:11px}.frankie-root .frankie-agent-context>summary>svg{width:14px}.frankie-root .frankie-thread-title{max-width:42vw}}.frankie-root .frankie-agent-context>summary>svg:first-child{box-sizing:content-box;background:var(--frankie-muted);border-radius:50%;padding:4px}.frankie-root.frankie-chat-panel-fill .frankie-agent-context>summary{font-size:14px}.frankie-root .frankie-agent-context>summary>span:first-of-type{border-right:1px solid var(--frankie-border);padding-right:10px}@media (max-width:760px){.frankie-root .frankie-page-header button>span{display:none}}.frankie-root .frankie-choices{flex-direction:column;gap:8px;margin-top:12px;display:flex}.frankie-root .frankie-choice{text-align:left;cursor:pointer;border:1px solid var(--frankie-border);border-radius:var(--frankie-radius);background:var(--frankie-background);width:100%;color:var(--frankie-foreground);font:inherit;align-items:center;gap:12px;padding:11px 14px;font-size:14px;line-height:1.4;transition:border-color .15s,background-color .15s,transform .12s;display:flex}.frankie-root .frankie-choice:hover:not(:disabled){border-color:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-choice:hover:not(:disabled){border-color:color-mix(in srgb, var(--frankie-primary) 55%, var(--frankie-border))}}.frankie-root .frankie-choice:hover:not(:disabled){background:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-choice:hover:not(:disabled){background:color-mix(in srgb, var(--frankie-primary) 6%, var(--frankie-background))}}.frankie-root .frankie-choice:active:not(:disabled){transform:scale(.99)}.frankie-root .frankie-choice:focus-visible{box-shadow:0 0 0 2px var(--frankie-primary);outline:none}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-choice:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, var(--frankie-primary) 40%, transparent)}}.frankie-root .frankie-choice:disabled{opacity:.6;cursor:default}.frankie-root .frankie-choice-index{border:1px solid var(--frankie-border);background:var(--frankie-muted);width:24px;height:24px;color:var(--frankie-muted-foreground);border-radius:50%;flex:none;place-items:center;font-size:12px;font-weight:600;transition:background-color .15s,color .15s,border-color .15s;display:grid}.frankie-root .frankie-choice:hover:not(:disabled) .frankie-choice-index{background:var(--frankie-primary);border-color:var(--frankie-primary);color:var(--frankie-primary-foreground)}.frankie-root .frankie-choice-label{flex:1;min-width:0}.frankie-root .frankie-choice-go{color:var(--frankie-muted-foreground);opacity:0;flex:none;transition:opacity .15s,transform .15s;transform:translate(-4px)}.frankie-root .frankie-choice:hover:not(:disabled) .frankie-choice-go{opacity:1;color:var(--frankie-primary);transform:none}@media (prefers-reduced-motion:reduce){.frankie-root .frankie-choice,.frankie-root .frankie-choice-go,.frankie-root .frankie-choice-index{transition:none}}.frankie-root .frankie-choice-other{color:var(--frankie-muted-foreground);border-style:dashed}.frankie-root .frankie-choice-other .frankie-choice-index{background:0 0}.frankie-root .frankie-choice-other:hover:not(:disabled){color:var(--frankie-foreground)}.frankie-root .frankie-choice-other:hover:not(:disabled) .frankie-choice-index{background:var(--frankie-muted);border-color:var(--frankie-border);color:var(--frankie-foreground)}.frankie-root .frankie-choice-hint{color:var(--frankie-muted-foreground);flex:none;font-size:12px}.frankie-root .frankie-skeleton{flex-direction:column;gap:8px;max-width:min(420px,100%);padding:4px 0 6px;display:flex}.frankie-root .frankie-skeleton-line{background:linear-gradient(90deg, var(--frankie-muted-foreground) 25%, var(--frankie-muted-foreground) 37%, var(--frankie-muted-foreground) 63%);border-radius:6px;height:12px}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-skeleton-line{background:linear-gradient(90deg, color-mix(in srgb, var(--frankie-muted-foreground) 11%, transparent) 25%, color-mix(in srgb, var(--frankie-muted-foreground) 19%, transparent) 37%, color-mix(in srgb, var(--frankie-muted-foreground) 11%, transparent) 63%)}}.frankie-root .frankie-skeleton-line{background-size:400% 100%;animation:2.2s ease-in-out infinite frankie-shimmer}.frankie-root .frankie-skeleton.is-delayed{animation:.25s .35s both frankie-skeleton-in}@keyframes frankie-skeleton-in{0%{opacity:0}to{opacity:1}}@keyframes frankie-shimmer{0%{background-position:100%}to{background-position:0}}@keyframes frankie-skeleton-pulse{0%,to{opacity:.45}50%{opacity:.85}}@media (prefers-reduced-motion:reduce){.frankie-root .frankie-skeleton-line{background:var(--frankie-muted-foreground)}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-skeleton-line{background:color-mix(in srgb, var(--frankie-muted-foreground) 16%, transparent)}}.frankie-root .frankie-skeleton-line{animation:1.6s ease-in-out infinite frankie-skeleton-pulse}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}`;
1005
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-ease:initial}}}@layer theme{.frankie-root{--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--leading-tight:1.25;--radius-md:.375rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--color-background:var(--frankie-background);--color-foreground:var(--frankie-foreground);--color-primary:var(--frankie-primary)}}@layer components{.frankie-page-shell{background:var(--frankie-background);height:100%;min-height:0;color:var(--frankie-foreground);flex:1;display:flex}.frankie-page-main{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.frankie-history-desktop{border-right:1px solid var(--frankie-border);background:var(--frankie-secondary);flex-direction:column;flex-shrink:0;gap:16px;width:260px;padding:20px 14px;transition:width .16s,padding .16s;display:flex;overflow:auto}.frankie-history-toggle{border:1px solid var(--frankie-border);background:var(--frankie-background);width:32px;height:32px;color:var(--frankie-muted-foreground);cursor:pointer;border-radius:8px;flex-shrink:0;justify-content:center;align-self:flex-end;align-items:center;display:flex}.frankie-history-toggle:hover{color:var(--frankie-foreground)}.frankie-history-collapsed{width:56px;padding:20px 8px;overflow:visible}.frankie-history-collapsed .frankie-history-toggle{align-self:center}.frankie-history-heading{justify-content:space-between;align-items:center;font-size:14px;display:flex}.frankie-new-chat{border:1px solid var(--frankie-border);background:var(--frankie-background);cursor:pointer;border-radius:10px;justify-content:center;align-items:center;gap:8px;min-height:44px;font-weight:600;display:flex}.frankie-history-search>span{color:var(--frankie-muted-foreground);margin-bottom:6px;font-size:12px;display:block}.frankie-history-search input{border:1px solid var(--frankie-border);background:var(--frankie-background);border-radius:8px;width:100%;min-height:40px;padding:8px 10px}.frankie-history-list{flex-direction:column;flex:1;gap:4px;display:flex}.frankie-history-list button{text-align:left;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:8px;flex-direction:column;align-items:flex-start;gap:5px;min-height:54px;padding:10px;display:flex}.frankie-history-list button span{text-overflow:ellipsis;white-space:nowrap;width:100%;font-size:13px;overflow:hidden}.frankie-history-list small{color:var(--frankie-muted-foreground);font-size:11px}.frankie-history-list button:hover,.frankie-history-list button[aria-current]{background:var(--frankie-background);border-color:var(--frankie-border)}.frankie-history-desktop>p,.frankie-history-dialog p{color:var(--frankie-muted-foreground);font-size:13px}.frankie-header-caption{color:var(--frankie-muted-foreground);font-size:12px}.frankie-page-header button{cursor:pointer;justify-content:center;align-items:center;gap:6px;min-width:40px;min-height:40px;display:inline-flex}.frankie-chat-settings{position:relative}.frankie-chat-settings summary{cursor:pointer;border-radius:8px;place-items:center;width:40px;height:40px;list-style:none;display:grid}.frankie-chat-settings summary::-webkit-details-marker{display:none}.frankie-chat-settings>div{z-index:5;border:1px solid var(--frankie-border);background:var(--frankie-background);border-radius:12px;gap:12px;width:min(280px,80vw);padding:16px;font-size:13px;display:grid;position:absolute;top:46px;right:0;box-shadow:0 10px 30px #0002}.frankie-chat-settings p{color:var(--frankie-muted-foreground);margin:0}.frankie-loaded-skills{width:100%;max-width:760px;color:var(--frankie-muted-foreground);font-size:12px}.frankie-loaded-skills summary{cursor:pointer;padding:6px 0}.frankie-loaded-skills ul{margin:0;padding:4px 0;list-style:none}.frankie-loaded-skills li{gap:8px;padding:4px 0;display:flex}.frankie-loaded-skills small{opacity:.7}.frankie-history-dialog{background:var(--frankie-secondary);width:min(320px,86vw);max-width:none;height:100dvh;max-height:none;color:var(--frankie-foreground);border:0;margin:0;padding:0}.frankie-history-dialog::backdrop{background:#0008}.frankie-history-dialog>aside{height:100%;padding:calc(20px + env(safe-area-inset-top)) 16px calc(20px + env(safe-area-inset-bottom));flex-direction:column;gap:16px;display:flex;overflow:auto}.frankie-mobile-only{display:none!important}.frankie-widget-panel{max-height:calc(100dvh - 100px - var(--frankie-lift,0px))}.frankie-root button:focus-visible,.frankie-root summary:focus-visible,.frankie-root input:focus-visible{outline:2px solid var(--frankie-primary);outline-offset:3px}.frankie-root button:disabled{opacity:.5;cursor:not-allowed}@media (max-width:760px){.frankie-history-desktop{display:none}.frankie-mobile-only{display:inline-flex!important}.frankie-header-caption{display:none}.frankie-page-header{padding:6px 10px}.frankie-history-heading button{background:0 0;border:0;justify-content:center;align-items:center;min-width:44px;min-height:44px}.frankie-page-prompts{gap:8px}.frankie-widget-panel{width:calc(100vw - 32px)}}.frankie-root{--frankie-styles-ready:1;--frankie-background:#fff;--frankie-foreground:#0a0a0a;--frankie-primary:#171717;--frankie-primary-foreground:#fafafa;--frankie-secondary:#f5f5f5;--frankie-secondary-foreground:#171717;--frankie-muted:#f5f5f5;--frankie-muted-foreground:#737373;--frankie-border:#e5e5e5;--frankie-radius:.625rem;--frankie-font:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;font-family:var(--frankie-font);color:var(--frankie-foreground);-webkit-font-smoothing:antialiased;line-height:1.5}.frankie-root.dark{--frankie-background:#0a0a0a;--frankie-foreground:#fafafa;--frankie-primary:#fafafa;--frankie-primary-foreground:#171717;--frankie-secondary:#262626;--frankie-secondary-foreground:#fafafa;--frankie-muted:#262626;--frankie-muted-foreground:#a3a3a3;--frankie-border:#262626}.frankie-root,.frankie-root *,.frankie-root :before,.frankie-root :after{box-sizing:border-box}.frankie-root button,.frankie-root textarea,.frankie-root input{font:inherit;color:inherit;margin:0}.frankie-root button{background-color:#0000;border:0 solid}.frankie-root textarea{background-color:var(--frankie-background)}.frankie-focus:focus-visible{outline:2px solid var(--frankie-primary);outline-offset:2px}.frankie-scroll{scrollbar-width:thin;scrollbar-color:var(--frankie-border) transparent}.frankie-prose>*+*{margin-top:.6rem}.frankie-prose p{white-space:pre-wrap;overflow-wrap:anywhere;margin:0;line-height:1.6}.frankie-prose>.frankie-h{letter-spacing:-.01em;margin-top:1.15rem;line-height:1.3}.frankie-prose>.frankie-h:first-child{margin-top:0}.frankie-prose h3.frankie-h{font-size:1.06em;font-weight:700}.frankie-prose h4.frankie-h{font-size:1em;font-weight:600}.frankie-prose h5.frankie-h{color:var(--frankie-muted-foreground);font-size:.92em;font-weight:600}.frankie-prose strong{font-weight:600}.frankie-prose ul,.frankie-prose ol{flex-direction:column;gap:.35rem;margin:0;padding-left:1.4rem;display:flex}.frankie-prose li{padding-left:.15rem;line-height:1.55}.frankie-prose li::marker{color:var(--frankie-muted-foreground)}.frankie-prose ul{list-style:outside}.frankie-prose ol{list-style:decimal}.frankie-prose a{color:var(--frankie-primary);text-underline-offset:2px;text-decoration:underline}.frankie-prose code{background-color:var(--frankie-muted);border-radius:.25rem;padding:.1em .3em;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,monospace;font-size:.85em}.frankie-prose pre{border-radius:var(--frankie-radius);background-color:var(--frankie-muted);margin:0;padding:.625rem .75rem;overflow-x:auto}.frankie-prose pre code{background:0 0;padding:0}.frankie-chat-page{background:radial-gradient(60rem 24rem at 50% -12rem, var(--frankie-primary), transparent 65%), var(--frankie-background);flex-direction:column;min-width:0;display:flex;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.frankie-chat-page{background:radial-gradient(60rem 24rem at 50% -12rem, color-mix(in srgb, var(--frankie-primary) 8%, transparent), transparent 65%), var(--frankie-background)}}.frankie-chat-page{color:var(--frankie-foreground)}.frankie-page-header{border-bottom:1px solid var(--frankie-border);background:var(--frankie-background);flex:0 0 56px;justify-content:space-between;align-items:center;gap:16px;min-height:56px;padding:0 24px;display:flex}@supports (color:color-mix(in lab, red, red)){.frankie-page-header{background:color-mix(in srgb, var(--frankie-background) 92%, transparent)}}.frankie-page-header{-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.frankie-page-header>div{align-items:center;gap:10px;display:flex}.frankie-page-header strong{font-size:.925rem;font-weight:650}.frankie-page-status{background:var(--frankie-primary);width:10px;height:10px;box-shadow:0 0 0 4px var(--frankie-primary);border-radius:999px}@supports (color:color-mix(in lab, red, red)){.frankie-page-status{box-shadow:0 0 0 4px color-mix(in srgb, var(--frankie-primary) 16%, transparent)}}.frankie-page-header button{border:1px solid var(--frankie-border);border-radius:calc(var(--frankie-radius) * .9);background:var(--frankie-secondary);cursor:pointer;min-height:36px;padding:0 13px}.frankie-page-header button:hover{border-color:var(--frankie-primary)}.frankie-page-canvas{flex:1;min-width:0;min-height:0;display:flex}.frankie-page-canvas>.frankie-inline{width:100%;max-width:56rem;margin:0 auto}.frankie-page-canvas .frankie-scroll{padding:2rem clamp(1rem,4vw,4rem) 1.25rem}.frankie-page-canvas .frankie-root>.border-t{background:linear-gradient(180deg, transparent, var(--frankie-background) 30%);border-top:0;padding:.75rem clamp(1rem,4vw,4rem) 1.5rem}.frankie-page-empty{text-align:center;flex-direction:column;flex-shrink:0;justify-content:safe center;align-items:center;gap:2rem;width:min(100%,44rem);min-height:100%;margin:auto;padding:clamp(2rem,7vh,4.5rem) 1rem 2rem;display:flex;container-type:inline-size}.frankie-page-welcome h1{letter-spacing:-.02em;margin:0;font-size:clamp(1.55rem,3.4vw,2rem);font-weight:700;line-height:1.15}.frankie-page-welcome p{max-width:34rem;color:var(--frankie-muted-foreground);margin:.6rem auto 0;font-size:1rem}.frankie-page-suggest{flex-direction:column;align-items:center;gap:1rem;width:100%;display:flex}.frankie-page-suggest-label{color:var(--frankie-muted-foreground);letter-spacing:.12em;text-transform:uppercase;margin:0;font-size:.72rem;font-weight:600}.frankie-page-prompts{grid-template-columns:1fr;gap:.75rem;width:100%;display:grid}@container (min-width:30rem){.frankie-page-prompts{grid-template-columns:repeat(2,minmax(0,1fr))}}.frankie-page-prompts button{border:1px solid var(--frankie-border);background:var(--frankie-background);text-align:left;cursor:pointer;border-radius:14px;align-items:flex-start;gap:.85rem;min-height:64px;padding:.9rem 1rem;transition:border-color .15s,background-color .15s,transform .12s;display:flex}.frankie-page-prompts button:hover:not(:disabled){border-color:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-page-prompts button:hover:not(:disabled){border-color:color-mix(in srgb, var(--frankie-primary) 45%, var(--frankie-border))}}.frankie-page-prompts button:hover:not(:disabled){background:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-page-prompts button:hover:not(:disabled){background:color-mix(in srgb, var(--frankie-primary) 4%, var(--frankie-background))}}.frankie-page-prompts button:hover:not(:disabled){transform:translateY(-1px)}.frankie-prompt-icon{background:var(--frankie-muted);width:34px;height:34px;color:var(--frankie-foreground);border-radius:9px;flex:none;place-items:center;display:grid}.frankie-prompt-text{flex-direction:column;gap:2px;min-width:0;display:flex}.frankie-prompt-text strong{font-size:.9rem;font-weight:600;line-height:1.3}.frankie-prompt-text small{color:var(--frankie-muted-foreground);font-size:.8rem;line-height:1.35;overflow:hidden}.frankie-page-suggest-hint{color:var(--frankie-muted-foreground);margin:0;font-size:.85rem}.frankie-widget-panel .frankie-page-empty{gap:1rem;padding:1rem .25rem}.frankie-widget-panel .frankie-page-welcome h1{font-size:1.25rem}.frankie-widget-panel .frankie-page-welcome p{margin-top:.35rem;font-size:.88rem;line-height:1.45}.frankie-widget-panel .frankie-page-suggest{gap:.55rem}.frankie-widget-panel .frankie-page-suggest-label{font-size:.66rem}.frankie-widget-panel .frankie-page-prompts{flex-wrap:wrap;justify-content:center;gap:.4rem;display:flex}.frankie-widget-panel .frankie-page-prompts button{border-radius:999px;align-items:center;gap:.4rem;max-width:100%;min-height:34px;padding:.3rem .8rem .3rem .45rem}.frankie-widget-panel .frankie-prompt-icon{border-radius:999px;width:22px;height:22px}.frankie-widget-panel .frankie-prompt-icon svg{width:13px;height:13px}.frankie-widget-panel .frankie-prompt-text strong{white-space:nowrap;text-overflow:ellipsis;font-size:.82rem;font-weight:550;overflow:hidden}.frankie-widget-panel .frankie-prompt-text small,.frankie-widget-panel .frankie-page-suggest-hint{display:none}@media (max-width:640px){.frankie-page-header{flex-basis:52px;min-height:52px;padding:0 12px}.frankie-page-canvas .frankie-scroll{padding:1.25rem .75rem .5rem}.frankie-page-canvas .frankie-root>.border-t{padding:.65rem .75rem calc(.65rem + env(safe-area-inset-bottom))}}}@layer utilities;.frankie-root .\\@container{container-type:inline-size}.frankie-root .invisible{visibility:hidden}.frankie-root .visible{visibility:visible}.frankie-root .absolute{position:absolute}.frankie-root .fixed{position:fixed}.frankie-root .relative{position:relative}.frankie-root .static{position:static}.frankie-root .sticky{position:sticky}.frankie-root .isolate{isolation:isolate}.frankie-root .container{width:100%}@media (min-width:40rem){.frankie-root .container{max-width:40rem}}@media (min-width:48rem){.frankie-root .container{max-width:48rem}}@media (min-width:64rem){.frankie-root .container{max-width:64rem}}@media (min-width:80rem){.frankie-root .container{max-width:80rem}}@media (min-width:96rem){.frankie-root .container{max-width:96rem}}.frankie-root .mt-0{margin-top:0}.frankie-root .mt-0\\.5{margin-top:calc(var(--spacing) * .5)}.frankie-root .mt-1{margin-top:var(--spacing)}.frankie-root .mt-2{margin-top:calc(var(--spacing) * 2)}.frankie-root .block{display:block}.frankie-root .contents{display:contents}.frankie-root .flex{display:flex}.frankie-root .grid{display:grid}.frankie-root .hidden{display:none}.frankie-root .inline{display:inline}.frankie-root .inline-flex{display:inline-flex}.frankie-root .table{display:table}.frankie-root .size-1{width:var(--spacing);height:var(--spacing)}.frankie-root .size-1\\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.frankie-root .size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.frankie-root .size-3\\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.frankie-root .size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.frankie-root .size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.frankie-root .size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.frankie-root .size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.frankie-root .size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.frankie-root .size-12{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.frankie-root .size-full{width:100%;height:100%}.frankie-root .h-8{height:calc(var(--spacing) * 8)}.frankie-root .h-9{height:calc(var(--spacing) * 9)}.frankie-root .h-10{height:calc(var(--spacing) * 10)}.frankie-root .h-\\[32rem\\]{height:32rem}.frankie-root .h-full{height:100%}.frankie-root .h-px{height:1px}.frankie-root .min-h-7{min-height:calc(var(--spacing) * 7)}.frankie-root .min-h-\\[2\\.25rem\\]{min-height:2.25rem}.frankie-root .min-h-screen{min-height:100vh}.frankie-root .w-\\[22rem\\]{width:22rem}.frankie-root .w-full{width:100%}.frankie-root .max-w-\\[12rem\\]{max-width:12rem}.frankie-root .max-w-\\[14rem\\]{max-width:14rem}.frankie-root .max-w-\\[85\\%\\]{max-width:85%}.frankie-root .max-w-\\[calc\\(100vw-2rem\\)\\]{max-width:calc(100vw - 2rem)}.frankie-root .min-w-0{min-width:0}.frankie-root .flex-1{flex:1}.frankie-root .shrink-0{flex-shrink:0}.frankie-root .grow{flex-grow:1}.frankie-root .animate-pulse{animation:var(--animate-pulse)}.frankie-root .animate-spin{animation:var(--animate-spin)}.frankie-root .cursor-pointer{cursor:pointer}.frankie-root .resize{resize:both}.frankie-root .resize-none{resize:none}.frankie-root .list-none{list-style-type:none}.frankie-root .flex-col{flex-direction:column}.frankie-root .flex-wrap{flex-wrap:wrap}.frankie-root .items-center{align-items:center}.frankie-root .items-end{align-items:flex-end}.frankie-root .items-start{align-items:flex-start}.frankie-root .justify-center{justify-content:center}.frankie-root .justify-end{justify-content:flex-end}.frankie-root .gap-1{gap:var(--spacing)}.frankie-root .gap-1\\.5{gap:calc(var(--spacing) * 1.5)}.frankie-root .gap-2{gap:calc(var(--spacing) * 2)}.frankie-root .gap-3{gap:calc(var(--spacing) * 3)}.frankie-root .gap-4{gap:calc(var(--spacing) * 4)}.frankie-root .truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.frankie-root .overflow-hidden{overflow:hidden}.frankie-root .overflow-y-auto{overflow-y:auto}.frankie-root .overscroll-contain{overscroll-behavior:contain}.frankie-root .rounded{border-radius:.25rem}.frankie-root .rounded-\\[calc\\(var\\(--frankie-radius\\)\\+4px\\)\\]{border-radius:calc(var(--frankie-radius) + 4px)}.frankie-root .rounded-\\[calc\\(var\\(--frankie-radius\\)-2px\\)\\]{border-radius:calc(var(--frankie-radius) - 2px)}.frankie-root .rounded-\\[var\\(--frankie-radius\\)\\]{border-radius:var(--frankie-radius)}.frankie-root .rounded-full{border-radius:3.40282e38px}.frankie-root .rounded-md{border-radius:var(--radius-md)}.frankie-root .rounded-none{border-radius:0}.frankie-root .border{border-style:var(--tw-border-style);border-width:1px}.frankie-root .border-0{border-style:var(--tw-border-style);border-width:0}.frankie-root .border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.frankie-root .border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.frankie-root .border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.frankie-root .border-border{border-color:var(--frankie-border)}.frankie-root .border-transparent{border-color:#0000}.frankie-root .bg-background{background-color:var(--frankie-background)}.frankie-root .bg-border{background-color:var(--frankie-border)}.frankie-root .bg-emerald-500{background-color:var(--color-emerald-500)}.frankie-root .bg-emerald-500\\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab, red, red)){.frankie-root .bg-emerald-500\\/10{background-color:color-mix(in oklab, var(--color-emerald-500) 10%, transparent)}}.frankie-root .bg-muted{background-color:var(--frankie-muted)}.frankie-root .bg-muted-foreground{background-color:var(--frankie-muted-foreground)}.frankie-root .bg-primary{background-color:var(--frankie-primary)}.frankie-root .bg-red-500{background-color:var(--color-red-500)}.frankie-root .bg-red-500\\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.frankie-root .bg-red-500\\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.frankie-root .bg-secondary{background-color:var(--frankie-secondary)}.frankie-root .object-cover{object-fit:cover}.frankie-root .p-3{padding:calc(var(--spacing) * 3)}.frankie-root .p-4{padding:calc(var(--spacing) * 4)}.frankie-root .px-1{padding-inline:var(--spacing)}.frankie-root .px-2{padding-inline:calc(var(--spacing) * 2)}.frankie-root .px-3{padding-inline:calc(var(--spacing) * 3)}.frankie-root .px-4{padding-inline:calc(var(--spacing) * 4)}.frankie-root .px-6{padding-inline:calc(var(--spacing) * 6)}.frankie-root .py-0{padding-block:0}.frankie-root .py-0\\.5{padding-block:calc(var(--spacing) * .5)}.frankie-root .py-1{padding-block:var(--spacing)}.frankie-root .py-2{padding-block:calc(var(--spacing) * 2)}.frankie-root .py-3{padding-block:calc(var(--spacing) * 3)}.frankie-root .pl-2{padding-left:calc(var(--spacing) * 2)}.frankie-root .text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.frankie-root .text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.frankie-root .text-\\[0\\.625rem\\]{font-size:.625rem}.frankie-root .text-\\[0\\.6875rem\\]{font-size:.6875rem}.frankie-root .text-\\[11px\\]{font-size:11px}.frankie-root .leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.frankie-root .font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.frankie-root .font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.frankie-root .whitespace-nowrap{white-space:nowrap}.frankie-root .text-emerald-600{color:var(--color-emerald-600)}.frankie-root .text-foreground{color:var(--frankie-foreground)}.frankie-root .text-muted-foreground{color:var(--frankie-muted-foreground)}.frankie-root .text-primary{color:var(--frankie-primary)}.frankie-root .text-primary-foreground{color:var(--frankie-primary-foreground)}.frankie-root .text-red-600{color:var(--color-red-600)}.frankie-root .text-secondary-foreground{color:var(--frankie-secondary-foreground)}.frankie-root .italic{font-style:italic}.frankie-root .underline-offset-4{text-underline-offset:4px}.frankie-root .opacity-60{opacity:.6}.frankie-root .opacity-70{opacity:.7}.frankie-root .shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.frankie-root .shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.frankie-root .shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.frankie-root .outline{outline-style:var(--tw-outline-style);outline-width:1px}.frankie-root .transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.frankie-root .transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.frankie-root .transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.frankie-root .ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.frankie-root .select-all{-webkit-user-select:all;user-select:all}.frankie-root .placeholder\\:text-muted-foreground::placeholder{color:var(--frankie-muted-foreground)}@media (hover:hover){.frankie-root .hover\\:border-border:hover{border-color:var(--frankie-border)}.frankie-root .hover\\:bg-muted:hover{background-color:var(--frankie-muted)}.frankie-root .hover\\:text-foreground:hover{color:var(--frankie-foreground)}.frankie-root .hover\\:underline:hover{text-decoration-line:underline}.frankie-root .hover\\:opacity-90:hover{opacity:.9}.frankie-root .hover\\:opacity-100:hover{opacity:1}}.frankie-root .focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.frankie-root .focus-visible\\:ring-primary:focus-visible{--tw-ring-color:var(--frankie-primary)}.frankie-root .focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.frankie-root .disabled\\:pointer-events-none:disabled{pointer-events:none}.frankie-root .disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.frankie-root .disabled\\:opacity-50:disabled{opacity:.5}.frankie-root .dark\\:text-emerald-400:where(.dark,.dark *){color:var(--color-emerald-400)}.frankie-root .dark\\:text-red-400:where(.dark,.dark *){color:var(--color-red-400)}.frankie-root .\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.frankie-root .\\[\\&_svg\\]\\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.frankie-root .\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.frankie-root .\\[\\&\\:\\:-webkit-details-marker\\]\\:hidden::-webkit-details-marker{display:none}.frankie-root.frankie-chat-panel{min-height:0;position:relative}.frankie-root.frankie-widget-panel{box-shadow:0 32px 72px -18px var(--frankie-primary), 0 12px 28px -12px #0f172a47, 0 0 0 1px var(--frankie-foreground)}@supports (color:color-mix(in lab, red, red)){.frankie-root.frankie-widget-panel{box-shadow:0 32px 72px -18px color-mix(in srgb, var(--frankie-primary) 22%, #0f172a6b), 0 12px 28px -12px #0f172a47, 0 0 0 1px color-mix(in srgb, var(--frankie-foreground) 8%, transparent)}}.frankie-root.frankie-widget-panel.dark{box-shadow:0 34px 80px -16px #000000b8, 0 14px 32px -12px #0009, 0 0 0 1px var(--frankie-foreground)}@supports (color:color-mix(in lab, red, red)){.frankie-root.frankie-widget-panel.dark{box-shadow:0 34px 80px -16px #000000b8, 0 14px 32px -12px #0009, 0 0 0 1px color-mix(in srgb, var(--frankie-foreground) 12%, transparent)}}.frankie-root .frankie-agent-context-wrap{flex:none;justify-content:center;padding:12px 10px;display:flex}.frankie-root .frankie-agent-context{max-width:100%;color:var(--frankie-foreground);font-size:13px;position:relative}.frankie-root .frankie-agent-context>summary{border:1px solid var(--frankie-border);background:var(--frankie-background);cursor:pointer;white-space:nowrap;border-radius:999px;justify-content:center;align-items:center;gap:10px;min-height:44px;padding:7px 13px;list-style:none;display:flex;box-shadow:0 1px 3px #0000000d}.frankie-root .frankie-agent-context>summary::-webkit-details-marker{display:none}.frankie-root .frankie-agent-context>summary>svg{color:var(--frankie-muted-foreground);flex:none}.frankie-root .frankie-context-count{background:var(--frankie-muted);color:var(--frankie-muted-foreground);border-radius:999px;padding:2px 10px;font-size:12px}.frankie-root .frankie-context-status{color:var(--frankie-muted-foreground);align-items:center;gap:6px;font-size:12px;display:flex}.frankie-root .frankie-context-status i{background:currentColor;border-radius:50%;width:7px;height:7px}.frankie-root .frankie-context-status[data-active=true]{color:#00976b}.frankie-root .frankie-context-detail{z-index:10;border:1px solid var(--frankie-border);background:var(--frankie-background);border-radius:16px;width:340px;max-width:calc(100vw - 32px);padding:18px;position:absolute;top:calc(100% + 10px);left:50%;transform:translate(-50%);box-shadow:0 12px 32px #00000016}.frankie-root .frankie-context-detail p{color:var(--frankie-muted-foreground);margin:10px 0 0;font-size:12px;line-height:1.6}.frankie-root .frankie-context-detail ul{max-height:220px;margin:12px 0;padding:0;list-style:none;overflow:auto}.frankie-root .frankie-context-detail li{border-bottom:1px solid var(--frankie-border);overflow-wrap:anywhere;justify-content:space-between;gap:12px;padding:8px 0;display:flex}.frankie-root .frankie-context-detail small{color:var(--frankie-muted-foreground);flex:none}.frankie-root .frankie-sr-only{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.frankie-root.frankie-chat-panel-fill{--frankie-canvas:var(--frankie-background)}@supports (color:color-mix(in lab, red, red)){.frankie-root.frankie-chat-panel-fill{--frankie-canvas:color-mix(in srgb,var(--frankie-background) 60%,var(--frankie-muted))}}.frankie-root.frankie-chat-panel-fill{background:var(--frankie-canvas)}.frankie-root.frankie-chat-panel-fill .frankie-agent-context-wrap{padding:44px 16px 26px}.frankie-root.frankie-chat-panel-fill .frankie-transcript{padding:14px max(24px,50% - 480px) 24px}.frankie-root.frankie-chat-panel-fill .frankie-message-list{gap:38px}.frankie-root.frankie-chat-panel-fill .frankie-user-bubble{background:var(--frankie-muted);color:var(--frankie-foreground);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:24px;padding:12px 20px;font-size:15px}.frankie-root.frankie-chat-panel-fill .frankie-assistant-content{flex:1;max-width:100%;font-size:15px;line-height:1.7}.frankie-root.frankie-chat-panel-fill .frankie-assistant-message{gap:14px}.frankie-root .frankie-thinking{color:var(--frankie-muted-foreground);gap:5px}.frankie-root .frankie-thinking-label{margin-right:6px;font-size:14px}.frankie-root.frankie-chat-panel-fill .frankie-composer-footer{background:0 0;border:0;flex:none;padding:16px max(24px,50% - 500px) 24px}.frankie-root.frankie-chat-panel-fill .frankie-composer{border:1px solid var(--frankie-border);background:var(--frankie-background);border-radius:28px;padding:14px;box-shadow:0 2px 4px #0000000a}.frankie-root.frankie-chat-panel-fill .frankie-composer:focus-within{border-color:var(--frankie-foreground)}@supports (color:color-mix(in lab, red, red)){.frankie-root.frankie-chat-panel-fill .frankie-composer:focus-within{border-color:color-mix(in srgb,var(--frankie-foreground) 32%,var(--frankie-border))}}.frankie-root.frankie-chat-panel-fill .frankie-composer:focus-within{box-shadow:0 0 0 2px var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-root.frankie-chat-panel-fill .frankie-composer:focus-within{box-shadow:0 0 0 2px color-mix(in srgb,var(--frankie-primary) 8%,transparent)}}.frankie-root.frankie-chat-panel-fill .frankie-composer-controls{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.frankie-root.frankie-chat-panel-fill .frankie-composer textarea{resize:none;width:100%;min-height:32px;max-height:140px;color:var(--frankie-foreground);box-shadow:none;background:0 0;border:0;border-radius:0;outline:none;flex:0 0 100%;order:-1;margin-bottom:4px;padding:2px 6px;font-size:16px}.frankie-root.frankie-chat-panel-fill .frankie-composer button[aria-label=Send],.frankie-root.frankie-chat-panel-fill .frankie-composer button[aria-label=Stop]{background:var(--frankie-primary);width:42px;height:42px;color:var(--frankie-primary-foreground);border:0;border-radius:50%;margin-left:auto}.frankie-root.frankie-chat-panel-fill .frankie-composer button[aria-label=Attach\\ files]{border-radius:50%;width:42px;height:42px}.frankie-root .frankie-composer-actions{align-items:center;gap:6px;min-width:0;display:flex}.frankie-root .frankie-composer-meta{align-items:center;gap:8px;margin-top:6px;padding:0 2px;display:flex}.frankie-root .frankie-model-picker{align-items:center;min-width:0;display:inline-flex}.frankie-root .frankie-model-select{appearance:none;max-width:12rem;color:var(--frankie-muted-foreground);font:inherit;cursor:pointer;text-overflow:ellipsis;background-color:#0000;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238b8b8b' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");background-position:right 6px center;background-repeat:no-repeat;background-size:11px;border:0;border-radius:8px;padding:5px 22px 5px 8px;font-size:12px;font-weight:500;line-height:1;transition:background-color .12s,color .12s}.frankie-root .frankie-model-select:hover{background-color:var(--frankie-muted);color:var(--frankie-foreground)}.frankie-root .frankie-model-select:disabled{opacity:.5;cursor:not-allowed}.frankie-root .frankie-model-select option{color:var(--frankie-foreground);background:var(--frankie-background);font-weight:400}.frankie-root .frankie-history-desktop{background:var(--frankie-background);width:290px;padding:20px 12px}.frankie-root .frankie-history-collapsed{width:56px;padding:20px 8px}.frankie-root .frankie-new-chat{background:0 0;border:0;justify-content:flex-start;padding:8px 12px;font-size:15px}.frankie-root .frankie-history-heading{color:var(--frankie-muted-foreground);padding:0 12px;font-size:12px;font-weight:400}.frankie-root .frankie-history-list button{min-height:44px;padding:10px 12px}.frankie-root .frankie-history-list button span{font-size:14px}.frankie-root .frankie-history-list button[aria-current],.frankie-root .frankie-history-list button:hover{background:var(--frankie-muted);border-color:#0000}.frankie-root .frankie-history-list small{display:none}.frankie-root .frankie-history-group{flex-direction:column;gap:2px;display:flex}.frankie-root .frankie-history-group+.frankie-history-group{margin-top:12px}.frankie-root .frankie-history-group-label{letter-spacing:.04em;color:var(--frankie-muted-foreground);margin:0;padding:4px 12px;font-size:11px;font-weight:600}.frankie-root .frankie-page-header{background:var(--frankie-background);height:56px;min-height:56px}.frankie-root .frankie-page-header>div{min-width:0}.frankie-root .frankie-thread-title{text-overflow:ellipsis;white-space:nowrap;max-width:55vw;font-weight:500;overflow:hidden}.frankie-root .frankie-page-header button{background:0 0;border-color:#0000}.frankie-root .frankie-page-canvas>.frankie-inline{max-width:none}@media (max-width:760px){.frankie-root.frankie-chat-panel-fill .frankie-agent-context-wrap{padding:20px 8px 14px}.frankie-root.frankie-chat-panel-fill .frankie-transcript{padding:12px 16px 16px}.frankie-root.frankie-chat-panel-fill .frankie-composer-footer{padding:10px 12px calc(12px + env(safe-area-inset-bottom))}.frankie-root .frankie-agent-context>summary{gap:6px;padding:7px 9px;font-size:12px}.frankie-root .frankie-context-count{padding:2px 7px;font-size:11px}.frankie-root .frankie-context-status{gap:4px;font-size:11px}.frankie-root .frankie-agent-context>summary>svg{width:14px}.frankie-root .frankie-thread-title{max-width:42vw}}.frankie-root .frankie-agent-context>summary>svg:first-child{box-sizing:content-box;background:var(--frankie-muted);border-radius:50%;padding:4px}.frankie-root.frankie-chat-panel-fill .frankie-agent-context>summary{font-size:14px}.frankie-root .frankie-agent-context>summary>span:first-of-type{border-right:1px solid var(--frankie-border);padding-right:10px}@media (max-width:760px){.frankie-root .frankie-page-header button>span{display:none}}.frankie-root .frankie-choices{flex-direction:column;gap:8px;margin-top:12px;display:flex}.frankie-root .frankie-choice{text-align:left;cursor:pointer;border:1px solid var(--frankie-border);border-radius:var(--frankie-radius);background:var(--frankie-background);width:100%;color:var(--frankie-foreground);font:inherit;align-items:center;gap:12px;padding:11px 14px;font-size:14px;line-height:1.4;transition:border-color .15s,background-color .15s,transform .12s;display:flex}.frankie-root .frankie-choice:hover:not(:disabled){border-color:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-choice:hover:not(:disabled){border-color:color-mix(in srgb, var(--frankie-primary) 55%, var(--frankie-border))}}.frankie-root .frankie-choice:hover:not(:disabled){background:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-choice:hover:not(:disabled){background:color-mix(in srgb, var(--frankie-primary) 6%, var(--frankie-background))}}.frankie-root .frankie-choice:active:not(:disabled){transform:scale(.99)}.frankie-root .frankie-choice:focus-visible{box-shadow:0 0 0 2px var(--frankie-primary);outline:none}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-choice:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, var(--frankie-primary) 40%, transparent)}}.frankie-root .frankie-choice:disabled{opacity:.6;cursor:default}.frankie-root .frankie-choice-index{border:1px solid var(--frankie-border);background:var(--frankie-muted);width:24px;height:24px;color:var(--frankie-muted-foreground);border-radius:50%;flex:none;place-items:center;font-size:12px;font-weight:600;transition:background-color .15s,color .15s,border-color .15s;display:grid}.frankie-root .frankie-choice:hover:not(:disabled) .frankie-choice-index{background:var(--frankie-primary);border-color:var(--frankie-primary);color:var(--frankie-primary-foreground)}.frankie-root .frankie-choice-label{flex:1;min-width:0}.frankie-root .frankie-choice-go{color:var(--frankie-muted-foreground);opacity:0;flex:none;transition:opacity .15s,transform .15s;transform:translate(-4px)}.frankie-root .frankie-choice:hover:not(:disabled) .frankie-choice-go{opacity:1;color:var(--frankie-primary);transform:none}@media (prefers-reduced-motion:reduce){.frankie-root .frankie-choice,.frankie-root .frankie-choice-go,.frankie-root .frankie-choice-index{transition:none}}.frankie-root .frankie-choice-other{color:var(--frankie-muted-foreground);border-style:dashed}.frankie-root .frankie-choice-other .frankie-choice-index{background:0 0}.frankie-root .frankie-choice-other:hover:not(:disabled){color:var(--frankie-foreground)}.frankie-root .frankie-choice-other:hover:not(:disabled) .frankie-choice-index{background:var(--frankie-muted);border-color:var(--frankie-border);color:var(--frankie-foreground)}.frankie-root .frankie-choice-hint{color:var(--frankie-muted-foreground);flex:none;font-size:12px}.frankie-root .frankie-skeleton{flex-direction:column;gap:8px;max-width:min(420px,100%);padding:4px 0 6px;display:flex}.frankie-root .frankie-skeleton-line{background:linear-gradient(90deg, var(--frankie-muted-foreground) 25%, var(--frankie-muted-foreground) 37%, var(--frankie-muted-foreground) 63%);border-radius:6px;height:12px}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-skeleton-line{background:linear-gradient(90deg, color-mix(in srgb, var(--frankie-muted-foreground) 11%, transparent) 25%, color-mix(in srgb, var(--frankie-muted-foreground) 19%, transparent) 37%, color-mix(in srgb, var(--frankie-muted-foreground) 11%, transparent) 63%)}}.frankie-root .frankie-skeleton-line{background-size:400% 100%;animation:2.2s ease-in-out infinite frankie-shimmer}.frankie-root .frankie-skeleton.is-delayed{animation:.25s .35s both frankie-skeleton-in}@keyframes frankie-skeleton-in{0%{opacity:0}to{opacity:1}}@keyframes frankie-shimmer{0%{background-position:100%}to{background-position:0}}@keyframes frankie-skeleton-pulse{0%,to{opacity:.45}50%{opacity:.85}}@media (prefers-reduced-motion:reduce){.frankie-root .frankie-skeleton-line{background:var(--frankie-muted-foreground)}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-skeleton-line{background:color-mix(in srgb, var(--frankie-muted-foreground) 16%, transparent)}}.frankie-root .frankie-skeleton-line{animation:1.6s ease-in-out infinite frankie-skeleton-pulse}}.frankie-root:not(.frankie-chat-panel-fill) .frankie-composer-controls:has(.frankie-composer-actions>:not(input[hidden])){flex-wrap:wrap;align-items:center;row-gap:8px}.frankie-root:not(.frankie-chat-panel-fill) .frankie-composer-controls:has(.frankie-composer-actions>:not(input[hidden]))>textarea{flex:1 0 100%;order:-1;width:100%}.frankie-root:not(.frankie-chat-panel-fill) .frankie-composer-controls:has(.frankie-composer-actions>:not(input[hidden]))>.frankie-composer-actions{flex:auto}.frankie-root:not(.frankie-chat-panel-fill) .frankie-composer-controls:has(.frankie-composer-actions>:not(input[hidden]))>button{margin-left:auto}.frankie-root .frankie-action{border:1px solid var(--frankie-border);border-radius:var(--frankie-radius);background:var(--frankie-background);color:var(--frankie-foreground);flex-direction:column;gap:10px;margin-top:12px;padding:12px 14px;font-size:14px;line-height:1.4;display:flex}.frankie-root .frankie-action.is-pending{border-color:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-action.is-pending{border-color:color-mix(in srgb, var(--frankie-primary) 45%, var(--frankie-border))}}.frankie-root .frankie-action.is-pending{background:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-action.is-pending{background:color-mix(in srgb, var(--frankie-primary) 5%, var(--frankie-background))}}.frankie-root .frankie-action-head{align-items:flex-start;gap:10px;display:flex}.frankie-root .frankie-action-icon{color:var(--frankie-primary);flex-shrink:0;margin-top:2px}.frankie-root .frankie-action-title{flex-direction:column;gap:2px;min-width:0;display:flex}.frankie-root .frankie-action-title strong{overflow-wrap:anywhere;font-weight:600}.frankie-root .frankie-action-title span{color:var(--frankie-muted-foreground);font-size:12px}.frankie-root .frankie-action-route{border-radius:calc(var(--frankie-radius) * .6);background:var(--frankie-muted);overflow-wrap:anywhere;padding:6px 8px;font-size:12px;display:block}.frankie-root .frankie-action-route span{font-weight:600}.frankie-root .frankie-action-fields{gap:6px;margin:0;display:grid}.frankie-root .frankie-action-fields>div{grid-template-columns:minmax(0,35%) minmax(0,1fr);gap:10px;display:grid}.frankie-root .frankie-action-fields dt{color:var(--frankie-muted-foreground);overflow-wrap:anywhere;font-size:12px}.frankie-root .frankie-action-fields dd{white-space:pre-wrap;overflow-wrap:anywhere;max-height:8.5em;margin:0;font-size:13px;overflow:auto}.frankie-root .frankie-action-buttons{flex-wrap:wrap;gap:8px;display:flex}.frankie-root .frankie-action-buttons button{cursor:pointer;font:inherit;border-radius:var(--frankie-radius);border:1px solid var(--frankie-border);align-items:center;gap:6px;padding:7px 14px;font-size:14px;font-weight:500;transition:background-color .15s,border-color .15s;display:inline-flex}.frankie-root .frankie-action-approve{background:var(--frankie-primary);color:var(--frankie-primary-foreground);border-color:var(--frankie-primary)}.frankie-root .frankie-action-approve:hover:not(:disabled){background:var(--frankie-primary)}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-action-approve:hover:not(:disabled){background:color-mix(in srgb, var(--frankie-primary) 88%, black)}}.frankie-root .frankie-action-cancel{background:var(--frankie-background);color:var(--frankie-foreground)}.frankie-root .frankie-action-cancel:hover:not(:disabled){background:var(--frankie-muted)}.frankie-root .frankie-action-buttons button:disabled{opacity:.55;cursor:not-allowed}.frankie-root .frankie-action-buttons button:focus-visible{box-shadow:0 0 0 2px var(--frankie-primary);outline:none}@supports (color:color-mix(in lab, red, red)){.frankie-root .frankie-action-buttons button:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, var(--frankie-primary) 40%, transparent)}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}`;
966
1006
 
967
1007
  // src/lib/ensure-frankie-styles.ts
968
1008
  var STYLE_ELEMENT_ID = "frankie-fallback-styles";
@@ -1036,8 +1076,8 @@ function bottomObstruction(root, position, offset) {
1036
1076
  seen.add(bar);
1037
1077
  const rect = bar.getBoundingClientRect();
1038
1078
  const anchoredToBottom = rect.bottom >= height - 4;
1039
- const short = rect.height > 0 && rect.height < height * 0.4;
1040
- if (anchoredToBottom && short) lift = Math.max(lift, height - rect.top);
1079
+ const short2 = rect.height > 0 && rect.height < height * 0.4;
1080
+ if (anchoredToBottom && short2) lift = Math.max(lift, height - rect.top);
1041
1081
  }
1042
1082
  }
1043
1083
  return Math.round(lift);
@@ -1123,7 +1163,7 @@ function Button({ className, variant, size, asChild = false, ...props }) {
1123
1163
  }
1124
1164
 
1125
1165
  // src/components/chat/ChatPanel.tsx
1126
- import { RotateCcw, X as X3 } from "lucide-react";
1166
+ import { RotateCcw, X as X4 } from "lucide-react";
1127
1167
  import { useEffect as useEffect5, useRef as useRef4, useState as useState6 } from "react";
1128
1168
 
1129
1169
  // src/components/ui/avatar.tsx
@@ -1499,7 +1539,7 @@ function readAsBase64(file) {
1499
1539
  }
1500
1540
 
1501
1541
  // src/components/chat/MessageBubble.tsx
1502
- import { Check as Check2, Copy, Paperclip as Paperclip2 } from "lucide-react";
1542
+ import { Check as Check3, Copy, Paperclip as Paperclip2 } from "lucide-react";
1503
1543
  import { memo as memo2, useState as useState5 } from "react";
1504
1544
 
1505
1545
  // src/lib/choices.ts
@@ -1520,9 +1560,68 @@ function parseOptionLines(block) {
1520
1560
  return block.split("\n").map((line) => line.trim().replace(/^([-*+]|\d+[.)])\s+/, "").trim()).filter(Boolean);
1521
1561
  }
1522
1562
 
1563
+ // src/components/chat/ActionConfirm.tsx
1564
+ import { Check, ShieldAlert, X as X2 } from "lucide-react";
1565
+ import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
1566
+ function ActionConfirm({
1567
+ action,
1568
+ onAnswer,
1569
+ disabled,
1570
+ live
1571
+ }) {
1572
+ const pending = action.state === "pending";
1573
+ const fields = inputFields(action.preview.input);
1574
+ const status = pending ? live ? void 0 : "Not run" : action.state === "approved" ? "Approved" : "Cancelled";
1575
+ return /* @__PURE__ */ jsxs4("div", { className: "frankie-action" + (pending && live ? " is-pending" : ""), role: "group", "aria-label": `Approve: ${action.label}`, children: [
1576
+ /* @__PURE__ */ jsxs4("div", { className: "frankie-action-head", children: [
1577
+ /* @__PURE__ */ jsx10(ShieldAlert, { className: "frankie-action-icon size-4", "aria-hidden": true }),
1578
+ /* @__PURE__ */ jsxs4("div", { className: "frankie-action-title", children: [
1579
+ /* @__PURE__ */ jsx10("strong", { children: action.label }),
1580
+ /* @__PURE__ */ jsx10("span", { children: pending && live ? "Needs your approval before it runs" : status })
1581
+ ] })
1582
+ ] }),
1583
+ action.preview.method && action.preview.path ? /* @__PURE__ */ jsxs4("code", { className: "frankie-action-route", children: [
1584
+ /* @__PURE__ */ jsx10("span", { children: action.preview.method }),
1585
+ " ",
1586
+ action.preview.path
1587
+ ] }) : null,
1588
+ fields.length ? /* @__PURE__ */ jsx10("dl", { className: "frankie-action-fields", children: fields.map(([key, value]) => /* @__PURE__ */ jsxs4("div", { children: [
1589
+ /* @__PURE__ */ jsx10("dt", { children: key }),
1590
+ /* @__PURE__ */ jsx10("dd", { children: value })
1591
+ ] }, key)) }) : null,
1592
+ pending && live && onAnswer ? /* @__PURE__ */ jsxs4("div", { className: "frankie-action-buttons", children: [
1593
+ /* @__PURE__ */ jsxs4("button", { type: "button", className: "frankie-action-approve", disabled, onClick: () => onAnswer(action.toolUseId, true), children: [
1594
+ /* @__PURE__ */ jsx10(Check, { className: "size-4", "aria-hidden": true }),
1595
+ " Approve"
1596
+ ] }),
1597
+ /* @__PURE__ */ jsxs4("button", { type: "button", className: "frankie-action-cancel", disabled, onClick: () => onAnswer(action.toolUseId, false), children: [
1598
+ /* @__PURE__ */ jsx10(X2, { className: "size-4", "aria-hidden": true }),
1599
+ " Cancel"
1600
+ ] })
1601
+ ] }) : null
1602
+ ] });
1603
+ }
1604
+ function inputFields(input) {
1605
+ if (input === void 0 || input === null) return [];
1606
+ if (typeof input !== "object" || Array.isArray(input)) return [["input", short(input)]];
1607
+ const rows = [];
1608
+ for (const [key, value] of Object.entries(input)) {
1609
+ if (value === void 0) continue;
1610
+ if (key === "body" && value && typeof value === "object" && !Array.isArray(value)) {
1611
+ for (const [field, inner] of Object.entries(value)) rows.push([field, short(inner)]);
1612
+ continue;
1613
+ }
1614
+ rows.push([key, short(value)]);
1615
+ }
1616
+ return rows;
1617
+ }
1618
+ function short(value) {
1619
+ return typeof value === "string" ? value : JSON.stringify(value, null, 1);
1620
+ }
1621
+
1523
1622
  // src/components/chat/Choices.tsx
1524
1623
  import { ArrowRight, PencilLine } from "lucide-react";
1525
- import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
1624
+ import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
1526
1625
  function Choices({
1527
1626
  options,
1528
1627
  onPick,
@@ -1530,8 +1629,8 @@ function Choices({
1530
1629
  disabled
1531
1630
  }) {
1532
1631
  if (options.length === 0) return null;
1533
- return /* @__PURE__ */ jsxs4("div", { className: "frankie-choices", role: "group", "aria-label": "Choose an option", children: [
1534
- options.map((option, index) => /* @__PURE__ */ jsxs4(
1632
+ return /* @__PURE__ */ jsxs5("div", { className: "frankie-choices", role: "group", "aria-label": "Choose an option", children: [
1633
+ options.map((option, index) => /* @__PURE__ */ jsxs5(
1535
1634
  "button",
1536
1635
  {
1537
1636
  type: "button",
@@ -1539,14 +1638,14 @@ function Choices({
1539
1638
  disabled,
1540
1639
  onClick: () => onPick(option),
1541
1640
  children: [
1542
- /* @__PURE__ */ jsx10("span", { className: "frankie-choice-index", "aria-hidden": true, children: index + 1 }),
1543
- /* @__PURE__ */ jsx10("span", { className: "frankie-choice-label", children: option }),
1544
- /* @__PURE__ */ jsx10(ArrowRight, { className: "frankie-choice-go size-4", "aria-hidden": true })
1641
+ /* @__PURE__ */ jsx11("span", { className: "frankie-choice-index", "aria-hidden": true, children: index + 1 }),
1642
+ /* @__PURE__ */ jsx11("span", { className: "frankie-choice-label", children: option }),
1643
+ /* @__PURE__ */ jsx11(ArrowRight, { className: "frankie-choice-go size-4", "aria-hidden": true })
1545
1644
  ]
1546
1645
  },
1547
1646
  `${index}-${option}`
1548
1647
  )),
1549
- onSomethingElse ? /* @__PURE__ */ jsxs4(
1648
+ onSomethingElse ? /* @__PURE__ */ jsxs5(
1550
1649
  "button",
1551
1650
  {
1552
1651
  type: "button",
@@ -1554,9 +1653,9 @@ function Choices({
1554
1653
  disabled,
1555
1654
  onClick: onSomethingElse,
1556
1655
  children: [
1557
- /* @__PURE__ */ jsx10("span", { className: "frankie-choice-index", "aria-hidden": true, children: /* @__PURE__ */ jsx10(PencilLine, { className: "size-3.5" }) }),
1558
- /* @__PURE__ */ jsx10("span", { className: "frankie-choice-label", children: "Something else\u2026" }),
1559
- /* @__PURE__ */ jsx10("span", { className: "frankie-choice-hint", "aria-hidden": true, children: "Type your own" })
1656
+ /* @__PURE__ */ jsx11("span", { className: "frankie-choice-index", "aria-hidden": true, children: /* @__PURE__ */ jsx11(PencilLine, { className: "size-3.5" }) }),
1657
+ /* @__PURE__ */ jsx11("span", { className: "frankie-choice-label", children: "Something else\u2026" }),
1658
+ /* @__PURE__ */ jsx11("span", { className: "frankie-choice-hint", "aria-hidden": true, children: "Type your own" })
1560
1659
  ]
1561
1660
  }
1562
1661
  ) : null
@@ -1565,10 +1664,10 @@ function Choices({
1565
1664
 
1566
1665
  // src/components/chat/Markdown.tsx
1567
1666
  import { Fragment as Fragment2, memo, useMemo as useMemo2 } from "react";
1568
- import { jsx as jsx11 } from "react/jsx-runtime";
1667
+ import { jsx as jsx12 } from "react/jsx-runtime";
1569
1668
  var Markdown = memo(function Markdown2({ text, className }) {
1570
1669
  const blocks = useMemo2(() => renderBlocks(text), [text]);
1571
- return /* @__PURE__ */ jsx11("div", { className: cn("frankie-prose", className), children: blocks });
1670
+ return /* @__PURE__ */ jsx12("div", { className: cn("frankie-prose", className), children: blocks });
1572
1671
  });
1573
1672
  function renderBlocks(text) {
1574
1673
  const lines = text.split("\n");
@@ -1578,13 +1677,13 @@ function renderBlocks(text) {
1578
1677
  let code = null;
1579
1678
  const flushParagraph = () => {
1580
1679
  if (paragraph.length === 0) return;
1581
- blocks.push(/* @__PURE__ */ jsx11("p", { children: renderInline(paragraph.join(" ")) }, `p${blocks.length}`));
1680
+ blocks.push(/* @__PURE__ */ jsx12("p", { children: renderInline(paragraph.join(" ")) }, `p${blocks.length}`));
1582
1681
  paragraph = [];
1583
1682
  };
1584
1683
  const flushList = () => {
1585
1684
  if (!list) return;
1586
- const items = list.items.map((item, index) => /* @__PURE__ */ jsx11("li", { children: renderInline(item) }, index));
1587
- blocks.push(list.ordered ? /* @__PURE__ */ jsx11("ol", { children: items }, `l${blocks.length}`) : /* @__PURE__ */ jsx11("ul", { children: items }, `l${blocks.length}`));
1685
+ const items = list.items.map((item, index) => /* @__PURE__ */ jsx12("li", { children: renderInline(item) }, index));
1686
+ blocks.push(list.ordered ? /* @__PURE__ */ jsx12("ol", { children: items }, `l${blocks.length}`) : /* @__PURE__ */ jsx12("ul", { children: items }, `l${blocks.length}`));
1588
1687
  list = null;
1589
1688
  };
1590
1689
  for (const line of lines) {
@@ -1592,7 +1691,7 @@ function renderBlocks(text) {
1592
1691
  if (fence) {
1593
1692
  if (code) {
1594
1693
  blocks.push(
1595
- /* @__PURE__ */ jsx11("pre", { children: /* @__PURE__ */ jsx11("code", { children: code.lines.join("\n") }) }, `c${blocks.length}`)
1694
+ /* @__PURE__ */ jsx12("pre", { children: /* @__PURE__ */ jsx12("code", { children: code.lines.join("\n") }) }, `c${blocks.length}`)
1596
1695
  );
1597
1696
  code = null;
1598
1697
  } else {
@@ -1629,7 +1728,7 @@ function renderBlocks(text) {
1629
1728
  flushList();
1630
1729
  const level = (heading[1] ?? "#").length;
1631
1730
  const Tag = level <= 1 ? "h3" : level === 2 ? "h4" : "h5";
1632
- blocks.push(/* @__PURE__ */ jsx11(Tag, { className: "frankie-h", children: renderInline(heading[2] ?? "") }, `h${blocks.length}`));
1731
+ blocks.push(/* @__PURE__ */ jsx12(Tag, { className: "frankie-h", children: renderInline(heading[2] ?? "") }, `h${blocks.length}`));
1633
1732
  continue;
1634
1733
  }
1635
1734
  flushList();
@@ -1637,7 +1736,7 @@ function renderBlocks(text) {
1637
1736
  }
1638
1737
  if (code) {
1639
1738
  blocks.push(
1640
- /* @__PURE__ */ jsx11("pre", { children: /* @__PURE__ */ jsx11("code", { children: code.lines.join("\n") }) }, `c${blocks.length}`)
1739
+ /* @__PURE__ */ jsx12("pre", { children: /* @__PURE__ */ jsx12("code", { children: code.lines.join("\n") }) }, `c${blocks.length}`)
1641
1740
  );
1642
1741
  }
1643
1742
  flushParagraph();
@@ -1652,30 +1751,30 @@ function renderInline(text) {
1652
1751
  const token = match[0];
1653
1752
  const start = match.index;
1654
1753
  if (start > lastIndex) nodes.push(text.slice(lastIndex, start));
1655
- nodes.push(/* @__PURE__ */ jsx11(Fragment2, { children: renderToken(token) }, start));
1754
+ nodes.push(/* @__PURE__ */ jsx12(Fragment2, { children: renderToken(token) }, start));
1656
1755
  lastIndex = start + token.length;
1657
1756
  }
1658
1757
  if (lastIndex < text.length) nodes.push(text.slice(lastIndex));
1659
1758
  return nodes;
1660
1759
  }
1661
1760
  function renderToken(token) {
1662
- if (token.startsWith("**")) return /* @__PURE__ */ jsx11("strong", { children: token.slice(2, -2) });
1663
- if (token.startsWith("*")) return /* @__PURE__ */ jsx11("em", { children: token.slice(1, -1) });
1664
- if (token.startsWith("`")) return /* @__PURE__ */ jsx11("code", { children: token.slice(1, -1) });
1761
+ if (token.startsWith("**")) return /* @__PURE__ */ jsx12("strong", { children: token.slice(2, -2) });
1762
+ if (token.startsWith("*")) return /* @__PURE__ */ jsx12("em", { children: token.slice(1, -1) });
1763
+ if (token.startsWith("`")) return /* @__PURE__ */ jsx12("code", { children: token.slice(1, -1) });
1665
1764
  const link = /^\[([^\]]+)\]\(([^)]+)\)$/.exec(token);
1666
1765
  const href = link ? link[2] ?? "" : token;
1667
1766
  const label = link ? link[1] ?? "" : token;
1668
- if (!/^(https?:\/\/|\/)/.test(href)) return token;
1669
- return /* @__PURE__ */ jsx11("a", { href, target: "_blank", rel: "noopener noreferrer nofollow", children: label });
1767
+ if (!/^(https?:\/\/|\/(?![\/\\]))/.test(href)) return token;
1768
+ return /* @__PURE__ */ jsx12("a", { href, target: "_blank", rel: "noopener noreferrer nofollow", children: label });
1670
1769
  }
1671
1770
 
1672
1771
  // src/components/chat/ToolActivityList.tsx
1673
- import { Check, ChevronDown, Loader2, ShieldAlert, Sparkles as Sparkles3, Wrench, X as X2 } from "lucide-react";
1772
+ import { Check as Check2, ChevronDown, Loader2, ShieldAlert as ShieldAlert2, Sparkles as Sparkles3, Wrench, X as X3 } from "lucide-react";
1674
1773
  import { SKILL_TOOL_NAME } from "@frankieai/core";
1675
1774
 
1676
1775
  // src/components/ui/badge.tsx
1677
1776
  import { cva as cva2 } from "class-variance-authority";
1678
- import { jsx as jsx12 } from "react/jsx-runtime";
1777
+ import { jsx as jsx13 } from "react/jsx-runtime";
1679
1778
  var badgeVariants = cva2(
1680
1779
  "inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[0.6875rem] font-medium",
1681
1780
  {
@@ -1695,46 +1794,46 @@ function Badge({
1695
1794
  variant,
1696
1795
  ...props
1697
1796
  }) {
1698
- return /* @__PURE__ */ jsx12("span", { className: cn(badgeVariants({ variant }), className), ...props });
1797
+ return /* @__PURE__ */ jsx13("span", { className: cn(badgeVariants({ variant }), className), ...props });
1699
1798
  }
1700
1799
 
1701
1800
  // src/components/chat/ToolActivityList.tsx
1702
- import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
1801
+ import { jsx as jsx14, jsxs as jsxs6 } from "react/jsx-runtime";
1703
1802
  function ToolActivityList({ tools, renderTool }) {
1704
1803
  if (tools.length === 0) return null;
1705
1804
  const running = tools.some((tool) => tool.status === "running");
1706
- return /* @__PURE__ */ jsxs5("details", { className: "frankie-tool-activity mt-2", open: running, children: [
1707
- /* @__PURE__ */ jsxs5("summary", { className: "inline-flex min-h-7 cursor-pointer list-none items-center gap-1.5 rounded-md px-1 text-xs font-medium text-muted-foreground hover:bg-muted hover:text-foreground [&::-webkit-details-marker]:hidden", children: [
1708
- /* @__PURE__ */ jsx13(ChevronDown, { className: "frankie-tool-chevron size-3.5 transition-transform", "aria-hidden": "true" }),
1709
- running ? /* @__PURE__ */ jsx13(Loader2, { className: "size-3.5 animate-spin", "aria-hidden": "true" }) : /* @__PURE__ */ jsx13(Wrench, { className: "size-3.5", "aria-hidden": "true" }),
1710
- /* @__PURE__ */ jsx13("span", { children: running ? "Working" : "Activity" }),
1711
- /* @__PURE__ */ jsxs5("span", { className: "text-[11px]", children: [
1805
+ return /* @__PURE__ */ jsxs6("details", { className: "frankie-tool-activity mt-2", open: running, children: [
1806
+ /* @__PURE__ */ jsxs6("summary", { className: "inline-flex min-h-7 cursor-pointer list-none items-center gap-1.5 rounded-md px-1 text-xs font-medium text-muted-foreground hover:bg-muted hover:text-foreground [&::-webkit-details-marker]:hidden", children: [
1807
+ /* @__PURE__ */ jsx14(ChevronDown, { className: "frankie-tool-chevron size-3.5 transition-transform", "aria-hidden": "true" }),
1808
+ running ? /* @__PURE__ */ jsx14(Loader2, { className: "size-3.5 animate-spin", "aria-hidden": "true" }) : /* @__PURE__ */ jsx14(Wrench, { className: "size-3.5", "aria-hidden": "true" }),
1809
+ /* @__PURE__ */ jsx14("span", { children: running ? "Working" : "Activity" }),
1810
+ /* @__PURE__ */ jsxs6("span", { className: "text-[11px]", children: [
1712
1811
  "\xB7 ",
1713
1812
  tools.length,
1714
1813
  " tool call",
1715
1814
  tools.length === 1 ? "" : "s"
1716
1815
  ] })
1717
1816
  ] }),
1718
- /* @__PURE__ */ jsx13("ul", { className: "mt-1 flex flex-col gap-1 border-l border-border pl-2", children: tools.map((tool) => /* @__PURE__ */ jsx13("li", { children: renderTool ? renderTool(tool) : /* @__PURE__ */ jsx13(ToolActivityRow, { tool }) }, tool.id)) })
1817
+ /* @__PURE__ */ jsx14("ul", { className: "mt-1 flex flex-col gap-1 border-l border-border pl-2", children: tools.map((tool) => /* @__PURE__ */ jsx14("li", { children: renderTool ? renderTool(tool) : /* @__PURE__ */ jsx14(ToolActivityRow, { tool }) }, tool.id)) })
1719
1818
  ] });
1720
1819
  }
1721
1820
  function ToolActivityRow({ tool }) {
1722
1821
  const isSkill = tool.name === SKILL_TOOL_NAME;
1723
- return /* @__PURE__ */ jsxs5(Badge, { variant: badgeVariant(tool.status), title: tool.detail ?? tool.name, children: [
1724
- isSkill && tool.status !== "running" ? /* @__PURE__ */ jsx13(Sparkles3, { className: "size-3", "aria-hidden": "true" }) : /* @__PURE__ */ jsx13(ToolIcon, { status: tool.status }),
1725
- /* @__PURE__ */ jsx13("span", { className: "truncate", children: tool.label })
1822
+ return /* @__PURE__ */ jsxs6(Badge, { variant: badgeVariant(tool.status), title: tool.detail ?? tool.name, children: [
1823
+ isSkill && tool.status !== "running" ? /* @__PURE__ */ jsx14(Sparkles3, { className: "size-3", "aria-hidden": "true" }) : /* @__PURE__ */ jsx14(ToolIcon, { status: tool.status }),
1824
+ /* @__PURE__ */ jsx14("span", { className: "truncate", children: tool.label })
1726
1825
  ] });
1727
1826
  }
1728
1827
  function ToolIcon({ status }) {
1729
1828
  switch (status) {
1730
1829
  case "running":
1731
- return /* @__PURE__ */ jsx13(Loader2, { className: "size-3 animate-spin", "aria-hidden": "true" });
1830
+ return /* @__PURE__ */ jsx14(Loader2, { className: "size-3 animate-spin", "aria-hidden": "true" });
1732
1831
  case "done":
1733
- return /* @__PURE__ */ jsx13(Check, { className: "size-3", "aria-hidden": "true" });
1832
+ return /* @__PURE__ */ jsx14(Check2, { className: "size-3", "aria-hidden": "true" });
1734
1833
  case "denied":
1735
- return /* @__PURE__ */ jsx13(ShieldAlert, { className: "size-3", "aria-hidden": "true" });
1834
+ return /* @__PURE__ */ jsx14(ShieldAlert2, { className: "size-3", "aria-hidden": "true" });
1736
1835
  default:
1737
- return /* @__PURE__ */ jsx13(X2, { className: "size-3", "aria-hidden": "true" });
1836
+ return /* @__PURE__ */ jsx14(X3, { className: "size-3", "aria-hidden": "true" });
1738
1837
  }
1739
1838
  }
1740
1839
  function badgeVariant(status) {
@@ -1745,7 +1844,7 @@ function badgeVariant(status) {
1745
1844
  }
1746
1845
 
1747
1846
  // src/components/chat/MessageBubble.tsx
1748
- import { jsx as jsx14, jsxs as jsxs6 } from "react/jsx-runtime";
1847
+ import { jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
1749
1848
  var MessageBubble = memo2(function MessageBubble2({
1750
1849
  message,
1751
1850
  assistantName,
@@ -1755,40 +1854,50 @@ var MessageBubble = memo2(function MessageBubble2({
1755
1854
  onChoose,
1756
1855
  onRequestInput,
1757
1856
  active,
1758
- busy
1857
+ busy,
1858
+ onAction
1759
1859
  }) {
1760
1860
  if (message.role === "user") {
1761
- return /* @__PURE__ */ jsxs6("div", { className: "frankie-user-message flex flex-col items-end gap-1", children: [
1762
- message.attachments?.length ? /* @__PURE__ */ jsx14("div", { className: "flex max-w-[85%] flex-wrap justify-end gap-1", children: message.attachments.map((file, index) => /* @__PURE__ */ jsxs6(
1861
+ return /* @__PURE__ */ jsxs7("div", { className: "frankie-user-message flex flex-col items-end gap-1", children: [
1862
+ message.attachments?.length ? /* @__PURE__ */ jsx15("div", { className: "flex max-w-[85%] flex-wrap justify-end gap-1", children: message.attachments.map((file, index) => /* @__PURE__ */ jsxs7(
1763
1863
  "span",
1764
1864
  {
1765
1865
  className: "inline-flex max-w-[12rem] items-center gap-1 rounded-[var(--frankie-radius)] border border-border bg-muted px-2 py-1 text-xs",
1766
1866
  children: [
1767
- /* @__PURE__ */ jsx14(Paperclip2, { className: "size-3 shrink-0 opacity-70" }),
1768
- /* @__PURE__ */ jsx14("span", { className: "truncate", children: file.name })
1867
+ /* @__PURE__ */ jsx15(Paperclip2, { className: "size-3 shrink-0 opacity-70" }),
1868
+ /* @__PURE__ */ jsx15("span", { className: "truncate", children: file.name })
1769
1869
  ]
1770
1870
  },
1771
1871
  `${file.name}-${index}`
1772
1872
  )) }) : null,
1773
- message.text ? /* @__PURE__ */ jsxs6("div", { className: "flex max-w-[85%] items-end gap-1", children: [
1774
- /* @__PURE__ */ jsx14("div", { className: "frankie-user-bubble rounded-[var(--frankie-radius)] bg-primary px-3 py-2 text-sm text-primary-foreground", children: message.text }),
1775
- /* @__PURE__ */ jsx14(MessageCopyButton, { text: message.text })
1873
+ message.text ? /* @__PURE__ */ jsxs7("div", { className: "flex max-w-[85%] items-end gap-1", children: [
1874
+ /* @__PURE__ */ jsx15("div", { className: "frankie-user-bubble rounded-[var(--frankie-radius)] bg-primary px-3 py-2 text-sm text-primary-foreground", children: message.text }),
1875
+ /* @__PURE__ */ jsx15(MessageCopyButton, { text: message.text })
1776
1876
  ] }) : null
1777
1877
  ] });
1778
1878
  }
1779
1879
  const { body, options } = extractChoices(message.text);
1780
1880
  const showChoices = Boolean(active && onChoose && options && message.status === "done");
1781
1881
  const waiting = message.status === "streaming" && body.length === 0 && message.tools.length === 0;
1782
- return /* @__PURE__ */ jsxs6("div", { className: "frankie-assistant-message flex gap-2", children: [
1783
- /* @__PURE__ */ jsxs6("div", { className: "frankie-assistant-actions mt-0.5 flex shrink-0 flex-col items-center gap-1", children: [
1784
- /* @__PURE__ */ jsx14(Avatar, { ...avatarUrl ? { src: avatarUrl } : {}, name: assistantName }),
1785
- body ? /* @__PURE__ */ jsx14(MessageCopyButton, { text: body }) : null
1882
+ return /* @__PURE__ */ jsxs7("div", { className: "frankie-assistant-message flex gap-2", children: [
1883
+ /* @__PURE__ */ jsxs7("div", { className: "frankie-assistant-actions mt-0.5 flex shrink-0 flex-col items-center gap-1", children: [
1884
+ /* @__PURE__ */ jsx15(Avatar, { ...avatarUrl ? { src: avatarUrl } : {}, name: assistantName }),
1885
+ body ? /* @__PURE__ */ jsx15(MessageCopyButton, { text: body }) : null
1786
1886
  ] }),
1787
- /* @__PURE__ */ jsxs6("div", { className: "frankie-assistant-content min-w-0 max-w-[85%]", children: [
1788
- message.status === "error" ? /* @__PURE__ */ jsx14("p", { className: "rounded-[var(--frankie-radius)] bg-red-500/10 px-3 py-2 text-sm text-red-600 dark:text-red-400", children: message.error }) : body ? /* @__PURE__ */ jsx14(Markdown, { text: body, className: "text-sm" }) : null,
1789
- showChoices ? /* @__PURE__ */ jsx14(Choices, { options: options ?? [], onPick: onChoose, ...onRequestInput ? { onSomethingElse: onRequestInput } : {}, disabled: busy }) : null,
1790
- showToolActivity ? /* @__PURE__ */ jsx14(ToolActivityList, { tools: message.tools, ...renderTool ? { renderTool } : {} }) : null,
1791
- waiting ? /* @__PURE__ */ jsx14(Thinking, { delayed: true }) : null
1887
+ /* @__PURE__ */ jsxs7("div", { className: "frankie-assistant-content min-w-0 max-w-[85%]", children: [
1888
+ message.status === "error" ? /* @__PURE__ */ jsx15("p", { className: "rounded-[var(--frankie-radius)] bg-red-500/10 px-3 py-2 text-sm text-red-600 dark:text-red-400", children: message.error }) : body ? /* @__PURE__ */ jsx15(Markdown, { text: body, className: "text-sm" }) : null,
1889
+ message.action ? /* @__PURE__ */ jsx15(
1890
+ ActionConfirm,
1891
+ {
1892
+ action: message.action,
1893
+ live: Boolean(active),
1894
+ disabled: busy || message.status === "streaming",
1895
+ ...onAction ? { onAnswer: onAction } : {}
1896
+ }
1897
+ ) : null,
1898
+ showChoices ? /* @__PURE__ */ jsx15(Choices, { options: options ?? [], onPick: onChoose, ...onRequestInput ? { onSomethingElse: onRequestInput } : {}, disabled: busy }) : null,
1899
+ showToolActivity ? /* @__PURE__ */ jsx15(ToolActivityList, { tools: message.tools, ...renderTool ? { renderTool } : {} }) : null,
1900
+ waiting ? /* @__PURE__ */ jsx15(Thinking, { delayed: true }) : null
1792
1901
  ] })
1793
1902
  ] });
1794
1903
  });
@@ -1802,12 +1911,12 @@ function MessageCopyButton({ text }) {
1802
1911
  } catch {
1803
1912
  }
1804
1913
  };
1805
- return /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => void copy(), className: "frankie-message-copy inline-flex size-8 shrink-0 items-center justify-center rounded-md border border-transparent text-muted-foreground transition hover:border-border hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary", "aria-label": copied ? "Copied" : "Copy message", title: copied ? "Copied" : "Copy message", children: copied ? /* @__PURE__ */ jsx14(Check2, { className: "size-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ jsx14(Copy, { className: "size-3.5", "aria-hidden": "true" }) });
1914
+ return /* @__PURE__ */ jsx15("button", { type: "button", onClick: () => void copy(), className: "frankie-message-copy inline-flex size-8 shrink-0 items-center justify-center rounded-md border border-transparent text-muted-foreground transition hover:border-border hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary", "aria-label": copied ? "Copied" : "Copy message", title: copied ? "Copied" : "Copy message", children: copied ? /* @__PURE__ */ jsx15(Check3, { className: "size-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ jsx15(Copy, { className: "size-3.5", "aria-hidden": "true" }) });
1806
1915
  }
1807
1916
  function TypingDots() {
1808
- return /* @__PURE__ */ jsxs6("span", { className: "frankie-thinking inline-flex items-center gap-1 py-2", role: "status", "aria-label": "Thinking", children: [
1809
- /* @__PURE__ */ jsx14("span", { className: "frankie-thinking-label", children: "Thinking" }),
1810
- [0, 1, 2].map((index) => /* @__PURE__ */ jsx14(
1917
+ return /* @__PURE__ */ jsxs7("span", { className: "frankie-thinking inline-flex items-center gap-1 py-2", role: "status", "aria-label": "Thinking", children: [
1918
+ /* @__PURE__ */ jsx15("span", { className: "frankie-thinking-label", children: "Thinking" }),
1919
+ [0, 1, 2].map((index) => /* @__PURE__ */ jsx15(
1811
1920
  "span",
1812
1921
  {
1813
1922
  className: cn("size-1.5 animate-pulse rounded-full bg-muted-foreground"),
@@ -1818,15 +1927,15 @@ function TypingDots() {
1818
1927
  ] });
1819
1928
  }
1820
1929
  function Thinking({ delayed = false }) {
1821
- return /* @__PURE__ */ jsxs6("div", { className: "frankie-skeleton" + (delayed ? " is-delayed" : ""), role: "status", "aria-label": "Thinking", children: [
1822
- /* @__PURE__ */ jsx14("span", { className: "frankie-skeleton-line", style: { width: "62%" } }),
1823
- /* @__PURE__ */ jsx14("span", { className: "frankie-skeleton-line", style: { width: "92%" } }),
1824
- /* @__PURE__ */ jsx14("span", { className: "frankie-skeleton-line", style: { width: "48%" } })
1930
+ return /* @__PURE__ */ jsxs7("div", { className: "frankie-skeleton" + (delayed ? " is-delayed" : ""), role: "status", "aria-label": "Thinking", children: [
1931
+ /* @__PURE__ */ jsx15("span", { className: "frankie-skeleton-line", style: { width: "62%" } }),
1932
+ /* @__PURE__ */ jsx15("span", { className: "frankie-skeleton-line", style: { width: "92%" } }),
1933
+ /* @__PURE__ */ jsx15("span", { className: "frankie-skeleton-line", style: { width: "48%" } })
1825
1934
  ] });
1826
1935
  }
1827
1936
 
1828
1937
  // src/components/chat/ChatPanel.tsx
1829
- import { jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
1938
+ import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
1830
1939
  function ChatPanel({
1831
1940
  className,
1832
1941
  header,
@@ -1841,7 +1950,7 @@ function ChatPanel({
1841
1950
  }) {
1842
1951
  const { config, configError, loading } = useFrankie();
1843
1952
  const theme = useFrankieTheme();
1844
- const { messages, busy, restoring, error, send, stop, reset } = useFrankieChat();
1953
+ const { messages, busy, restoring, error, send, answerAction, stop, reset } = useFrankieChat();
1845
1954
  const scrollRef = useRef4(null);
1846
1955
  const atBottomRef = useRef4(true);
1847
1956
  const features = config?.features;
@@ -1870,7 +1979,7 @@ function ChatPanel({
1870
1979
  }, [messages]);
1871
1980
  const name = config?.branding.name ?? "Assistant";
1872
1981
  const mode = useResolvedMode(theme?.mode);
1873
- return /* @__PURE__ */ jsxs7(
1982
+ return /* @__PURE__ */ jsxs8(
1874
1983
  Card,
1875
1984
  {
1876
1985
  className: cn(
@@ -1883,22 +1992,22 @@ function ChatPanel({
1883
1992
  style: themeToCssVars(theme),
1884
1993
  "data-frankie-mode": mode,
1885
1994
  children: [
1886
- header === false ? null : header !== void 0 ? header : /* @__PURE__ */ jsxs7(CardHeader, { children: [
1887
- /* @__PURE__ */ jsx15(Avatar, { ...config?.branding.avatarUrl ? { src: config.branding.avatarUrl } : {}, name }),
1888
- /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
1889
- /* @__PURE__ */ jsx15(CardTitle, { children: name }),
1890
- config?.branding.tagline ? /* @__PURE__ */ jsx15(CardDescription, { children: config.branding.tagline }) : null
1995
+ header === false ? null : header !== void 0 ? header : /* @__PURE__ */ jsxs8(CardHeader, { children: [
1996
+ /* @__PURE__ */ jsx16(Avatar, { ...config?.branding.avatarUrl ? { src: config.branding.avatarUrl } : {}, name }),
1997
+ /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
1998
+ /* @__PURE__ */ jsx16(CardTitle, { children: name }),
1999
+ config?.branding.tagline ? /* @__PURE__ */ jsx16(CardDescription, { children: config.branding.tagline }) : null
1891
2000
  ] }),
1892
- /* @__PURE__ */ jsx15(Button, { size: "icon", variant: "ghost", onClick: reset, "aria-label": "Start a new conversation", title: "New conversation", children: /* @__PURE__ */ jsx15(RotateCcw, {}) }),
1893
- onClose ? /* @__PURE__ */ jsx15(Button, { size: "icon", variant: "ghost", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx15(X3, {}) }) : null
2001
+ /* @__PURE__ */ jsx16(Button, { size: "icon", variant: "ghost", onClick: reset, "aria-label": "Start a new conversation", title: "New conversation", children: /* @__PURE__ */ jsx16(RotateCcw, {}) }),
2002
+ onClose ? /* @__PURE__ */ jsx16(Button, { size: "icon", variant: "ghost", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx16(X4, {}) }) : null
1894
2003
  ] }),
1895
- /* @__PURE__ */ jsx15(AgentContext, {}),
1896
- /* @__PURE__ */ jsx15(CardContent, { className: "frankie-conversation-content", children: /* @__PURE__ */ jsx15(ScrollArea, { ref: scrollRef, className: "frankie-transcript flex h-full flex-col gap-4 p-4", "aria-live": "polite", children: configError ? /* @__PURE__ */ jsxs7("div", { className: "frankie-config-error", role: "alert", children: [
1897
- /* @__PURE__ */ jsx15("strong", { children: "Frankie couldn\u2019t start" }),
1898
- /* @__PURE__ */ jsx15("p", { children: configError }),
1899
- /* @__PURE__ */ jsx15("p", { children: "Refresh this page after checking the workspace\u2019s allowed origin and sign-in settings." })
1900
- ] }) : loading ? /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "Starting Frankie\u2026" }) : messages.length === 0 ? emptyState ?? /* @__PURE__ */ jsx15(ChatEmptyState, {}) : /* @__PURE__ */ jsx15("div", { className: "frankie-message-list flex flex-col gap-4", children: messages.map(
1901
- (message, index) => renderMessage ? /* @__PURE__ */ jsx15("div", { children: renderMessage(message) }, message.id) : /* @__PURE__ */ jsx15(
2004
+ config?.agentContext === false ? null : /* @__PURE__ */ jsx16(AgentContext, {}),
2005
+ /* @__PURE__ */ jsx16(CardContent, { className: "frankie-conversation-content", children: /* @__PURE__ */ jsx16(ScrollArea, { ref: scrollRef, className: "frankie-transcript flex h-full flex-col gap-4 p-4", "aria-live": "polite", children: configError ? /* @__PURE__ */ jsxs8("div", { className: "frankie-config-error", role: "alert", children: [
2006
+ /* @__PURE__ */ jsx16("strong", { children: "Frankie couldn\u2019t start" }),
2007
+ /* @__PURE__ */ jsx16("p", { children: configError }),
2008
+ /* @__PURE__ */ jsx16("p", { children: "Refresh this page after checking the workspace\u2019s allowed origin and sign-in settings." })
2009
+ ] }) : loading ? /* @__PURE__ */ jsx16("p", { className: "text-sm text-muted-foreground", children: "Starting Frankie\u2026" }) : messages.length === 0 ? emptyState ?? /* @__PURE__ */ jsx16(ChatEmptyState, {}) : /* @__PURE__ */ jsx16("div", { className: "frankie-message-list flex flex-col gap-4", children: messages.map(
2010
+ (message, index) => renderMessage ? /* @__PURE__ */ jsx16("div", { children: renderMessage(message) }, message.id) : /* @__PURE__ */ jsx16(
1902
2011
  MessageBubble,
1903
2012
  {
1904
2013
  message,
@@ -1909,14 +2018,15 @@ function ChatPanel({
1909
2018
  onChoose: send,
1910
2019
  onRequestInput: focusComposer,
1911
2020
  active: index === messages.length - 1,
1912
- busy
2021
+ busy,
2022
+ onAction: (toolUseId, approved) => void answerAction(toolUseId, approved)
1913
2023
  },
1914
2024
  message.id
1915
2025
  )
1916
2026
  ) }) }) }),
1917
- /* @__PURE__ */ jsxs7(CardFooter, { className: "frankie-composer-footer flex flex-col gap-2", children: [
1918
- error ? /* @__PURE__ */ jsx15("p", { className: "w-full text-xs text-red-600 dark:text-red-400", children: error }) : null,
1919
- /* @__PURE__ */ jsx15("div", { className: "w-full", children: /* @__PURE__ */ jsx15(
2027
+ /* @__PURE__ */ jsxs8(CardFooter, { className: "frankie-composer-footer flex flex-col gap-2", children: [
2028
+ error ? /* @__PURE__ */ jsx16("p", { className: "w-full text-xs text-red-600 dark:text-red-400", children: error }) : null,
2029
+ /* @__PURE__ */ jsx16("div", { className: "w-full", children: /* @__PURE__ */ jsx16(
1920
2030
  Composer,
1921
2031
  {
1922
2032
  onSend: send,
@@ -1938,7 +2048,7 @@ function ChatPanel({
1938
2048
  }
1939
2049
 
1940
2050
  // src/components/chat/FrankieWidget.tsx
1941
- import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
2051
+ import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
1942
2052
  function FrankieWidget({
1943
2053
  position = "bottom-right",
1944
2054
  offset = 24,
@@ -1949,6 +2059,7 @@ function FrankieWidget({
1949
2059
  renderLauncher,
1950
2060
  launcher = true,
1951
2061
  avoidBottomBars = true,
2062
+ closeOnOutsideClick = true,
1952
2063
  ...panelProps
1953
2064
  }) {
1954
2065
  const { config, injectStyles, themeReady } = useFrankie();
@@ -1969,6 +2080,17 @@ function FrankieWidget({
1969
2080
  window.addEventListener("keydown", onKeyDown);
1970
2081
  return () => window.removeEventListener("keydown", onKeyDown);
1971
2082
  }, [open]);
2083
+ useEffect6(() => {
2084
+ if (!open || !closeOnOutsideClick) return;
2085
+ const onPointerDown = (event) => {
2086
+ const target = event.target;
2087
+ if (!(target instanceof Node) || !target.isConnected || rootRef.current?.contains(target)) return;
2088
+ if (target instanceof Element && target.closest("[data-frankie-open], [data-frankie-keep-open]")) return;
2089
+ setOpen(false);
2090
+ };
2091
+ document.addEventListener("pointerdown", onPointerDown, true);
2092
+ return () => document.removeEventListener("pointerdown", onPointerDown, true);
2093
+ }, [open, closeOnOutsideClick]);
1972
2094
  useEffect6(() => {
1973
2095
  const onClick = (event) => {
1974
2096
  const target = event.target instanceof Element ? event.target.closest("[data-frankie-open]") : null;
@@ -2012,7 +2134,7 @@ function FrankieWidget({
2012
2134
  const label = config?.branding.launcherLabel ?? "Need a hand?";
2013
2135
  const mode = useResolvedMode(theme?.mode);
2014
2136
  const side = position === "bottom-right" ? { right: offset } : { left: offset };
2015
- return /* @__PURE__ */ jsx16(
2137
+ return /* @__PURE__ */ jsx17(
2016
2138
  "div",
2017
2139
  {
2018
2140
  ref: rootRef,
@@ -2020,9 +2142,9 @@ function FrankieWidget({
2020
2142
  style: { ...themeToCssVars(theme), position: "fixed", bottom: lift ? lift + Math.min(offset, 12) : offset, ...side, zIndex, pointerEvents: "none", ["--frankie-lift"]: `${lift}px`, ...stylesReady && themeReady ? null : { opacity: 0 } },
2021
2143
  "data-frankie-mode": mode,
2022
2144
  "data-frankie-styles": stylesReady ? "ready" : "pending",
2023
- children: /* @__PURE__ */ jsxs8("div", { className: cn("flex flex-col gap-3", position === "bottom-left" ? "items-start" : "items-end"), children: [
2024
- open ? /* @__PURE__ */ jsx16("div", { style: { pointerEvents: "auto" }, children: /* @__PURE__ */ jsx16(ChatPanel, { ...panelProps, className: cn("frankie-widget-panel", panelProps.className), onClose: () => setOpen(false), autoFocus: true }) }) : null,
2025
- launcher || renderLauncher ? /* @__PURE__ */ jsx16("div", { style: { pointerEvents: "auto" }, children: renderLauncher ? renderLauncher({ open, toggle: () => setOpen(!open), label }) : /* @__PURE__ */ jsx16(
2145
+ children: /* @__PURE__ */ jsxs9("div", { className: cn("flex flex-col gap-3", position === "bottom-left" ? "items-start" : "items-end"), children: [
2146
+ open ? /* @__PURE__ */ jsx17("div", { style: { pointerEvents: "auto" }, children: /* @__PURE__ */ jsx17(ChatPanel, { ...panelProps, className: cn("frankie-widget-panel", panelProps.className), onClose: () => setOpen(false), autoFocus: true }) }) : null,
2147
+ launcher || renderLauncher ? /* @__PURE__ */ jsx17("div", { style: { pointerEvents: "auto" }, children: renderLauncher ? renderLauncher({ open, toggle: () => setOpen(!open), label }) : /* @__PURE__ */ jsx17(
2026
2148
  Button,
2027
2149
  {
2028
2150
  size: "icon",
@@ -2031,7 +2153,7 @@ function FrankieWidget({
2031
2153
  "aria-expanded": open,
2032
2154
  "aria-label": open ? "Close the assistant" : label,
2033
2155
  title: label,
2034
- children: open ? /* @__PURE__ */ jsx16(X4, { className: "size-5" }) : /* @__PURE__ */ jsx16(MessageCircle, { className: "size-5" })
2156
+ children: open ? /* @__PURE__ */ jsx17(X5, { className: "size-5" }) : /* @__PURE__ */ jsx17(MessageCircle, { className: "size-5" })
2035
2157
  }
2036
2158
  ) }) : null
2037
2159
  ] })
@@ -2041,14 +2163,14 @@ function FrankieWidget({
2041
2163
 
2042
2164
  // src/components/chat/FrankieInline.tsx
2043
2165
  import { useRef as useRef6 } from "react";
2044
- import { jsx as jsx17 } from "react/jsx-runtime";
2166
+ import { jsx as jsx18 } from "react/jsx-runtime";
2045
2167
  function FrankieInline({ className, style, ...panelProps }) {
2046
2168
  const { injectStyles, themeReady } = useFrankie();
2047
2169
  const theme = useFrankieTheme();
2048
2170
  const mode = useResolvedMode(theme?.mode);
2049
2171
  const rootRef = useRef6(null);
2050
2172
  const stylesReady = useStylesReady(rootRef, void 0, injectStyles);
2051
- return /* @__PURE__ */ jsx17(
2173
+ return /* @__PURE__ */ jsx18(
2052
2174
  "div",
2053
2175
  {
2054
2176
  ref: rootRef,
@@ -2056,14 +2178,14 @@ function FrankieInline({ className, style, ...panelProps }) {
2056
2178
  style: { ...themeToCssVars(theme), display: "flex", height: "100%", width: "100%", ...style, ...stylesReady && themeReady ? null : { opacity: 0 } },
2057
2179
  "data-frankie-mode": mode,
2058
2180
  "data-frankie-styles": stylesReady ? "ready" : "pending",
2059
- children: /* @__PURE__ */ jsx17(ChatPanel, { ...panelProps, fill: true })
2181
+ children: /* @__PURE__ */ jsx18(ChatPanel, { ...panelProps, fill: true })
2060
2182
  }
2061
2183
  );
2062
2184
  }
2063
2185
 
2064
2186
  // src/components/chat/FrankieChatPage.tsx
2065
2187
  import { useCallback as useCallback3, useEffect as useEffect8, useRef as useRef7, useState as useState9 } from "react";
2066
- import { ChevronsLeft, ChevronsRight, History, Menu, Plus as Plus2, Settings, X as X5 } from "lucide-react";
2188
+ import { ChevronsLeft, ChevronsRight, History, Menu, Plus as Plus2, Settings, X as X6 } from "lucide-react";
2067
2189
 
2068
2190
  // src/lib/viewport-fill.ts
2069
2191
  import { useEffect as useEffect7, useState as useState8 } from "react";
@@ -2105,7 +2227,7 @@ function useViewportFill(ref, enabled) {
2105
2227
  }
2106
2228
 
2107
2229
  // src/components/chat/FrankieChatPage.tsx
2108
- import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
2230
+ import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
2109
2231
  function groupByDate(items) {
2110
2232
  const now = /* @__PURE__ */ new Date();
2111
2233
  const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
@@ -2198,70 +2320,70 @@ function PageChrome({ showHistory, navigation, currentId, onSelect, onNew, histo
2198
2320
  close();
2199
2321
  }
2200
2322
  };
2201
- const history = /* @__PURE__ */ jsxs9(Fragment3, { children: [
2202
- /* @__PURE__ */ jsxs9("div", { className: "frankie-history-heading", children: [
2203
- /* @__PURE__ */ jsx18("strong", { children: "Conversations" }),
2204
- /* @__PURE__ */ jsx18("button", { type: "button", className: "frankie-mobile-only", "aria-label": "Close conversations", onClick: close, children: /* @__PURE__ */ jsx18(X5, { size: 18 }) })
2323
+ const history = /* @__PURE__ */ jsxs10(Fragment3, { children: [
2324
+ /* @__PURE__ */ jsxs10("div", { className: "frankie-history-heading", children: [
2325
+ /* @__PURE__ */ jsx19("strong", { children: "Conversations" }),
2326
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "frankie-mobile-only", "aria-label": "Close conversations", onClick: close, children: /* @__PURE__ */ jsx19(X6, { size: 18 }) })
2205
2327
  ] }),
2206
- /* @__PURE__ */ jsxs9("button", { type: "button", className: "frankie-new-chat", disabled: busy, onClick: () => {
2328
+ /* @__PURE__ */ jsxs10("button", { type: "button", className: "frankie-new-chat", disabled: busy, onClick: () => {
2207
2329
  onNew();
2208
2330
  close();
2209
2331
  }, children: [
2210
- /* @__PURE__ */ jsx18(Plus2, { size: 17 }),
2332
+ /* @__PURE__ */ jsx19(Plus2, { size: 17 }),
2211
2333
  "New chat"
2212
2334
  ] }),
2213
- /* @__PURE__ */ jsxs9("label", { className: "frankie-history-search", children: [
2214
- /* @__PURE__ */ jsx18("span", { children: "Search conversations" }),
2215
- /* @__PURE__ */ jsx18("input", { type: "search", placeholder: "Search chats\u2026", value: query, onChange: (event) => setQuery(event.target.value) })
2335
+ /* @__PURE__ */ jsxs10("label", { className: "frankie-history-search", children: [
2336
+ /* @__PURE__ */ jsx19("span", { children: "Search conversations" }),
2337
+ /* @__PURE__ */ jsx19("input", { type: "search", placeholder: "Search chats\u2026", value: query, onChange: (event) => setQuery(event.target.value) })
2216
2338
  ] }),
2217
- /* @__PURE__ */ jsx18("nav", { className: "frankie-history-list", "aria-label": "Conversations", children: groupByDate(conversations.filter((item) => item.title.toLowerCase().includes(query.toLowerCase()))).map((group) => /* @__PURE__ */ jsxs9("div", { className: "frankie-history-group", children: [
2218
- /* @__PURE__ */ jsx18("p", { className: "frankie-history-group-label", children: group.label }),
2219
- group.items.map((item) => /* @__PURE__ */ jsxs9("button", { type: "button", "aria-current": item.id === currentId ? "page" : void 0, disabled: busy, onClick: () => select(item.id), children: [
2220
- /* @__PURE__ */ jsx18("span", { children: item.title }),
2221
- /* @__PURE__ */ jsx18("small", { children: new Date(item.updatedAt).toLocaleDateString() })
2339
+ /* @__PURE__ */ jsx19("nav", { className: "frankie-history-list", "aria-label": "Conversations", children: groupByDate(conversations.filter((item) => item.title.toLowerCase().includes(query.toLowerCase()))).map((group) => /* @__PURE__ */ jsxs10("div", { className: "frankie-history-group", children: [
2340
+ /* @__PURE__ */ jsx19("p", { className: "frankie-history-group-label", children: group.label }),
2341
+ group.items.map((item) => /* @__PURE__ */ jsxs10("button", { type: "button", "aria-current": item.id === currentId ? "page" : void 0, disabled: busy, onClick: () => select(item.id), children: [
2342
+ /* @__PURE__ */ jsx19("span", { children: item.title }),
2343
+ /* @__PURE__ */ jsx19("small", { children: new Date(item.updatedAt).toLocaleDateString() })
2222
2344
  ] }, item.id))
2223
2345
  ] }, group.label)) }),
2224
- historyLoading && !conversations.length ? /* @__PURE__ */ jsx18("p", { role: "status", children: "Loading history\u2026" }) : historyError ? /* @__PURE__ */ jsxs9("p", { role: "status", children: [
2346
+ historyLoading && !conversations.length ? /* @__PURE__ */ jsx19("p", { role: "status", children: "Loading history\u2026" }) : historyError ? /* @__PURE__ */ jsxs10("p", { role: "status", children: [
2225
2347
  historyError,
2226
- /* @__PURE__ */ jsx18("button", { type: "button", onClick: () => void refresh(), children: "Try again" })
2227
- ] }) : !conversations.length && !historyLoading ? /* @__PURE__ */ jsx18("p", { children: config?.allowAnonymous ? "Sign in to sync conversations across devices." : "Your conversations will appear here." }) : null,
2228
- navigation ? /* @__PURE__ */ jsx18("div", { className: "frankie-host-navigation", children: navigation }) : null
2348
+ /* @__PURE__ */ jsx19("button", { type: "button", onClick: () => void refresh(), children: "Try again" })
2349
+ ] }) : !conversations.length && !historyLoading ? /* @__PURE__ */ jsx19("p", { children: config?.allowAnonymous ? "Sign in to sync conversations across devices." : "Your conversations will appear here." }) : null,
2350
+ navigation ? /* @__PURE__ */ jsx19("div", { className: "frankie-host-navigation", children: navigation }) : null
2229
2351
  ] });
2230
- return /* @__PURE__ */ jsxs9("div", { className: "frankie-page-shell" + (mode === "dark" ? " dark" : ""), style: { ...themeToCssVars(theme), ...themeReady ? null : { opacity: 0 } }, children: [
2231
- showHistory ? /* @__PURE__ */ jsxs9("aside", { className: "frankie-history-desktop" + (collapsed ? " frankie-history-collapsed" : ""), children: [
2232
- /* @__PURE__ */ jsx18("button", { type: "button", className: "frankie-history-toggle", "aria-label": collapsed ? "Expand conversations" : "Collapse conversations", "aria-expanded": !collapsed, onClick: () => setCollapsed((value) => !value), children: collapsed ? /* @__PURE__ */ jsx18(ChevronsRight, { size: 16 }) : /* @__PURE__ */ jsx18(ChevronsLeft, { size: 16 }) }),
2352
+ return /* @__PURE__ */ jsxs10("div", { className: "frankie-page-shell" + (mode === "dark" ? " dark" : ""), style: { ...themeToCssVars(theme), ...themeReady ? null : { opacity: 0 } }, children: [
2353
+ showHistory ? /* @__PURE__ */ jsxs10("aside", { className: "frankie-history-desktop" + (collapsed ? " frankie-history-collapsed" : ""), children: [
2354
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "frankie-history-toggle", "aria-label": collapsed ? "Expand conversations" : "Collapse conversations", "aria-expanded": !collapsed, onClick: () => setCollapsed((value) => !value), children: collapsed ? /* @__PURE__ */ jsx19(ChevronsRight, { size: 16 }) : /* @__PURE__ */ jsx19(ChevronsLeft, { size: 16 }) }),
2233
2355
  collapsed ? null : history
2234
2356
  ] }) : null,
2235
- /* @__PURE__ */ jsxs9("div", { className: "frankie-page-main", children: [
2236
- /* @__PURE__ */ jsxs9("header", { className: "frankie-page-header", children: [
2237
- /* @__PURE__ */ jsxs9("div", { children: [
2238
- showHistory ? /* @__PURE__ */ jsx18("button", { type: "button", className: "frankie-mobile-only", ref: menu, "aria-label": "Open conversations", "aria-haspopup": "dialog", "aria-expanded": drawerOpen, onClick: () => setDrawerOpen(true), children: /* @__PURE__ */ jsx18(Menu, { size: 20 }) }) : null,
2239
- /* @__PURE__ */ jsx18("strong", { className: "frankie-thread-title", children: conversations.find((item) => item.id === currentId)?.title ?? messages.find((message) => message.role === "user")?.text ?? "New chat" })
2357
+ /* @__PURE__ */ jsxs10("div", { className: "frankie-page-main", children: [
2358
+ /* @__PURE__ */ jsxs10("header", { className: "frankie-page-header", children: [
2359
+ /* @__PURE__ */ jsxs10("div", { children: [
2360
+ showHistory ? /* @__PURE__ */ jsx19("button", { type: "button", className: "frankie-mobile-only", ref: menu, "aria-label": "Open conversations", "aria-haspopup": "dialog", "aria-expanded": drawerOpen, onClick: () => setDrawerOpen(true), children: /* @__PURE__ */ jsx19(Menu, { size: 20 }) }) : null,
2361
+ /* @__PURE__ */ jsx19("strong", { className: "frankie-thread-title", children: conversations.find((item) => item.id === currentId)?.title ?? messages.find((message) => message.role === "user")?.text ?? "New chat" })
2240
2362
  ] }),
2241
- /* @__PURE__ */ jsxs9("div", { children: [
2242
- /* @__PURE__ */ jsxs9("button", { type: "button", disabled: busy, onClick: onNew, "aria-label": "Start a new conversation", children: [
2243
- /* @__PURE__ */ jsx18(Plus2, { size: 16 }),
2244
- /* @__PURE__ */ jsx18("span", { children: "New chat" })
2363
+ /* @__PURE__ */ jsxs10("div", { children: [
2364
+ /* @__PURE__ */ jsxs10("button", { type: "button", disabled: busy, onClick: onNew, "aria-label": "Start a new conversation", children: [
2365
+ /* @__PURE__ */ jsx19(Plus2, { size: 16 }),
2366
+ /* @__PURE__ */ jsx19("span", { children: "New chat" })
2245
2367
  ] }),
2246
- /* @__PURE__ */ jsxs9("details", { className: "frankie-chat-settings", children: [
2247
- /* @__PURE__ */ jsx18("summary", { "aria-label": "Chat settings", children: /* @__PURE__ */ jsx18(Settings, { size: 19 }) }),
2248
- /* @__PURE__ */ jsxs9("div", { children: [
2249
- /* @__PURE__ */ jsx18("strong", { children: "Chat settings" }),
2250
- /* @__PURE__ */ jsx18("p", { children: "History syncs automatically for signed-in users." }),
2251
- /* @__PURE__ */ jsxs9("button", { type: "button", onClick: () => void refresh(), disabled: historyLoading || !showHistory, children: [
2252
- /* @__PURE__ */ jsx18(History, { size: 16 }),
2368
+ /* @__PURE__ */ jsxs10("details", { className: "frankie-chat-settings", children: [
2369
+ /* @__PURE__ */ jsx19("summary", { "aria-label": "Chat settings", children: /* @__PURE__ */ jsx19(Settings, { size: 19 }) }),
2370
+ /* @__PURE__ */ jsxs10("div", { children: [
2371
+ /* @__PURE__ */ jsx19("strong", { children: "Chat settings" }),
2372
+ /* @__PURE__ */ jsx19("p", { children: "History syncs automatically for signed-in users." }),
2373
+ /* @__PURE__ */ jsxs10("button", { type: "button", onClick: () => void refresh(), disabled: historyLoading || !showHistory, children: [
2374
+ /* @__PURE__ */ jsx19(History, { size: 16 }),
2253
2375
  "Refresh history"
2254
2376
  ] }),
2255
- /* @__PURE__ */ jsx18("small", { children: "Skills are checked at the start of each message." })
2377
+ /* @__PURE__ */ jsx19("small", { children: "Skills are checked at the start of each message." })
2256
2378
  ] })
2257
2379
  ] })
2258
2380
  ] })
2259
2381
  ] }),
2260
- /* @__PURE__ */ jsx18("div", { className: "frankie-page-canvas", children: /* @__PURE__ */ jsx18(FrankieInline, { ...panel, header: panel.header ?? false, placeholder: panel.placeholder ?? `Ask anything about your ${config?.branding.name ?? "Frankie"} workspace\u2026`, emptyState: panel.emptyState }) })
2382
+ /* @__PURE__ */ jsx19("div", { className: "frankie-page-canvas", children: /* @__PURE__ */ jsx19(FrankieInline, { ...panel, header: panel.header ?? false, placeholder: panel.placeholder ?? `Ask anything about your ${config?.branding.name ?? "Frankie"} workspace\u2026`, emptyState: panel.emptyState }) })
2261
2383
  ] }),
2262
- showHistory ? /* @__PURE__ */ jsx18("dialog", { ref: dialog, className: "frankie-history-dialog frankie-root", "aria-label": "Chat conversations", style: themeToCssVars(theme), onCancel: close, onClick: (event) => {
2384
+ showHistory ? /* @__PURE__ */ jsx19("dialog", { ref: dialog, className: "frankie-history-dialog frankie-root", "aria-label": "Chat conversations", style: themeToCssVars(theme), onCancel: close, onClick: (event) => {
2263
2385
  if (event.target === event.currentTarget) close();
2264
- }, children: /* @__PURE__ */ jsx18("aside", { children: history }) }) : null
2386
+ }, children: /* @__PURE__ */ jsx19("aside", { children: history }) }) : null
2265
2387
  ] });
2266
2388
  }
2267
2389
  function FrankieChatPage({ className, style, header, footer, emptyState, renderMessage, renderTool, placeholder, autoFocus, showHistory = true, navigation, fillViewport = true, ...provider }) {
@@ -2271,18 +2393,18 @@ function FrankieChatPage({ className, style, header, footer, emptyState, renderM
2271
2393
  const pageRef = useRef7(null);
2272
2394
  const stylesReady = useStylesReady(pageRef, void 0, provider.injectStyles);
2273
2395
  const fill = useViewportFill(pageRef, fillViewport);
2274
- return /* @__PURE__ */ jsx18("div", { ref: pageRef, className: ["frankie-root", "frankie-chat-page", className].filter(Boolean).join(" "), style: { height: "100%", minHeight: fill > 360 ? `${fill}px` : "min(36rem, 100dvh)", width: "100%", ...style, ...stylesReady ? null : { opacity: 0 } }, "data-frankie-styles": stylesReady ? "ready" : "pending", children: /* @__PURE__ */ jsx18(FrankieProvider, { ...provider, conversationId: id, storageNamespace: (provider.storageNamespace ?? "frankie." + provider.publishableKey) + "." + id, children: /* @__PURE__ */ jsx18(PageChrome, { showHistory, navigation, currentId: id, onSelect: setId, onNew, history, header, footer, emptyState, renderMessage, renderTool, placeholder, autoFocus }) }) });
2396
+ return /* @__PURE__ */ jsx19("div", { ref: pageRef, className: ["frankie-root", "frankie-chat-page", className].filter(Boolean).join(" "), style: { height: "100%", minHeight: fill > 360 ? `${fill}px` : "min(36rem, 100dvh)", width: "100%", ...style, ...stylesReady ? null : { opacity: 0 } }, "data-frankie-styles": stylesReady ? "ready" : "pending", children: /* @__PURE__ */ jsx19(FrankieProvider, { ...provider, conversationId: id, storageNamespace: (provider.storageNamespace ?? "frankie." + provider.publishableKey) + "." + id, children: /* @__PURE__ */ jsx19(PageChrome, { showHistory, navigation, currentId: id, onSelect: setId, onNew, history, header, footer, emptyState, renderMessage, renderTool, placeholder, autoFocus }) }) });
2275
2397
  }
2276
2398
 
2277
2399
  // src/components/chat/SuggestedPrompts.tsx
2278
- import { jsx as jsx19 } from "react/jsx-runtime";
2400
+ import { jsx as jsx20 } from "react/jsx-runtime";
2279
2401
  function SuggestedPrompts({
2280
2402
  prompts,
2281
2403
  onPick,
2282
2404
  disabled
2283
2405
  }) {
2284
2406
  if (prompts.length === 0) return null;
2285
- return /* @__PURE__ */ jsx19("div", { className: "flex flex-wrap gap-2", children: prompts.map((prompt) => /* @__PURE__ */ jsx19(
2407
+ return /* @__PURE__ */ jsx20("div", { className: "flex flex-wrap gap-2", children: prompts.map((prompt) => /* @__PURE__ */ jsx20(
2286
2408
  Button,
2287
2409
  {
2288
2410
  type: "button",
@@ -2297,11 +2419,12 @@ function SuggestedPrompts({
2297
2419
  }
2298
2420
 
2299
2421
  // src/components/ui/separator.tsx
2300
- import { jsx as jsx20 } from "react/jsx-runtime";
2422
+ import { jsx as jsx21 } from "react/jsx-runtime";
2301
2423
  function Separator({ className }) {
2302
- return /* @__PURE__ */ jsx20("div", { role: "separator", className: cn("h-px w-full bg-border", className) });
2424
+ return /* @__PURE__ */ jsx21("div", { role: "separator", className: cn("h-px w-full bg-border", className) });
2303
2425
  }
2304
2426
  export {
2427
+ ActionConfirm,
2305
2428
  Avatar,
2306
2429
  Badge,
2307
2430
  Button,