diff --git a/examples/harnesses/mastra-harness-chat/.env.example b/examples/harnesses/mastra-harness-chat/.env.example new file mode 100644 index 000000000..778c5b5e3 --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/.env.example @@ -0,0 +1,6 @@ +OPENAI_API_KEY=sk-... +# OPENAI_MODEL=openai/gpt-5.5 +# OPENAI_BASE_URL=https://api.openai.com/v1 +# +# Optional: persists Mastra Harness threads/state to a different LibSQL database. +# MASTRA_HARNESS_DB_URL=file:./.mastra-harness-chat/openui-harness.db diff --git a/examples/harnesses/mastra-harness-chat/.gitignore b/examples/harnesses/mastra-harness-chat/.gitignore new file mode 100644 index 000000000..41a5d1e2f --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/.gitignore @@ -0,0 +1,43 @@ +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# local harness storage +/.mastra-harness/ + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files +.env* +!.env.example + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/examples/harnesses/mastra-harness-chat/README.md b/examples/harnesses/mastra-harness-chat/README.md new file mode 100644 index 000000000..eea5e34cb --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/README.md @@ -0,0 +1,83 @@ +# Mastra Harness Chat + +An OpenUI chat example backed by Mastra's new `Harness` API. The app keeps the normal +OpenUI `` surface, while the backend runs a persistent Mastra Harness session with +LibSQL-backed threads/state and tool activity streamed into OpenUI as AG-UI events. + +## How it works + +```text +Browser / OpenUI FullScreen + | localStorage thread list + transcript + | POST /api/chat { threadId, messages } + v +Next.js route (nodejs runtime) + | threadId -> Mastra resourceId + | getOrCreate Harness Session + | session.sendMessage(latest user turn) + v +Mastra Harness + | storage + safe mock tools + | message/tool events + v +Harness-to-AG-UI adapter + | SSE data: { AG-UI event } + v +OpenUI renderer +``` + +## What this demonstrates + +- Mastra `Harness` from `@mastra/core/harness`, with one shared Harness and one Session per OpenUI + chat thread. +- LibSQL persistence for Harness threads and state, keyed by each OpenUI thread id. +- A single default Harness mode that keeps the example focused on session persistence, tools, and + OpenUI streaming rather than mode-switching UX. +- Safe mock Mastra tools (`get_weather`, `get_stock_price`) surfaced in OpenUI's behind-the-scenes + tool panel. +- A small adapter that maps Harness events (`message_update`, `tool_start`, `tool_input_delta`, + `tool_end`, `error`) to AG-UI SSE events consumed by `agUIAdapter()`. + +## Run locally + +Install monorepo dependencies from the repository root: + +```bash +pnpm install +``` + +Create an env file in this example: + +```bash +cd examples/harnesses/mastra-harness-chat +cp .env.example .env.local +``` + +Set `OPENAI_API_KEY`, then run: + +```bash +pnpm dev +``` + +Open [http://localhost:3000](http://localhost:3000). + +## Configuration + +| Environment variable | Default | Purpose | +| ---------------------- | -------------------------------------------- | -------------------------------------- | +| `OPENAI_API_KEY` | unset | API key for the configured model | +| `OPENAI_MODEL` | `openai/gpt-5.5` | Mastra model id | +| `OPENAI_BASE_URL` | `https://api.openai.com/v1` | OpenAI-compatible endpoint | +| `MASTRA_HARNESS_DB_URL` | `file:./.mastra-harness-chat/openui-harness.db` | LibSQL database for Harness state | + +The `dev` and `build` scripts regenerate `src/generated/system-prompt.txt` from `src/library.ts` +before starting Next, so the backend prompt and frontend OpenUI renderer stay aligned. + +## Notes + +- This example uses safe read-only mock tools and grants the Harness `read` category in each + session. It disables `ask_user`, `submit_plan`, and `subagent` because OpenUI's stock chat + surface does not include a Harness approval/resume UI. +- Browser thread metadata and transcripts are stored in `localStorage`; Mastra Harness state is + stored server-side in LibSQL. The OpenUI thread id is used as the Mastra `resourceId`, so a server + restart can reattach to the most recent Harness thread for that resource. diff --git a/examples/harnesses/mastra-harness-chat/eslint.config.mjs b/examples/harnesses/mastra-harness-chat/eslint.config.mjs new file mode 100644 index 000000000..3e54496da --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/eslint.config.mjs @@ -0,0 +1,11 @@ +import nextVitals from "eslint-config-next/core-web-vitals"; +import nextTs from "eslint-config-next/typescript"; +import { defineConfig, globalIgnores } from "eslint/config"; + +const eslintConfig = defineConfig([ + ...nextVitals, + ...nextTs, + globalIgnores([".next/**", "out/**", "build/**", "next-env.d.ts", "src/generated/**"]), +]); + +export default eslintConfig; diff --git a/examples/harnesses/mastra-harness-chat/next.config.ts b/examples/harnesses/mastra-harness-chat/next.config.ts new file mode 100644 index 000000000..8f83eea2a --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/next.config.ts @@ -0,0 +1,8 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + serverExternalPackages: ["@libsql/client", "@mastra/core", "@mastra/libsql", "libsql"], + turbopack: {}, +}; + +export default nextConfig; diff --git a/examples/harnesses/mastra-harness-chat/package.json b/examples/harnesses/mastra-harness-chat/package.json new file mode 100644 index 000000000..04a995137 --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/package.json @@ -0,0 +1,35 @@ +{ + "name": "mastra-harness-chat", + "version": "0.1.0", + "private": true, + "scripts": { + "generate:prompt": "pnpm --filter @openuidev/cli build && node ../../../packages/openui-cli/dist/index.js generate src/library.ts --out src/generated/system-prompt.txt", + "dev": "pnpm generate:prompt && next dev --webpack", + "build": "pnpm generate:prompt && next build --webpack", + "start": "next start", + "lint": "eslint", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@mastra/core": "^1.46.0", + "@mastra/libsql": "^1.14.1", + "@openuidev/react-headless": "workspace:*", + "@openuidev/react-lang": "workspace:*", + "@openuidev/react-ui": "workspace:*", + "next": "16.2.6", + "react": "19.2.3", + "react-dom": "19.2.3", + "zod": "4.4.3" + }, + "devDependencies": { + "@openuidev/cli": "workspace:*", + "@tailwindcss/postcss": "^4", + "@types/node": "catalog:", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "16.2.6", + "tailwindcss": "^4", + "typescript": "^5" + } +} diff --git a/examples/harnesses/mastra-harness-chat/postcss.config.mjs b/examples/harnesses/mastra-harness-chat/postcss.config.mjs new file mode 100644 index 000000000..61e36849c --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/postcss.config.mjs @@ -0,0 +1,7 @@ +const config = { + plugins: { + "@tailwindcss/postcss": {}, + }, +}; + +export default config; diff --git a/examples/harnesses/mastra-harness-chat/src/app/api/chat/route.ts b/examples/harnesses/mastra-harness-chat/src/app/api/chat/route.ts new file mode 100644 index 000000000..8df993e73 --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/app/api/chat/route.ts @@ -0,0 +1,153 @@ +import { HarnessAGUIBridge } from "@/lib/harness-stream"; +import { getOrCreateHarnessSession } from "@/lib/mastra-harness"; +import type { AGUIEvent, Message } from "@openuidev/react-headless"; +import type { NextRequest } from "next/server"; + +export const runtime = "nodejs"; +export const dynamic = "force-dynamic"; + +const AGUI = { + RUN_ERROR: "RUN_ERROR", + TEXT_MESSAGE_CONTENT: "TEXT_MESSAGE_CONTENT", + TEXT_MESSAGE_END: "TEXT_MESSAGE_END", + TEXT_MESSAGE_START: "TEXT_MESSAGE_START", +} as const; + +interface ChatBody { + threadId?: string; + messages?: Message[]; +} + +function messageText(message: Pick): string { + const content = message.content as unknown; + if (typeof content === "string") return content; + if (Array.isArray(content)) { + return content + .map((part) => + part && typeof part === "object" && "text" in part + ? String((part as { text?: unknown }).text ?? "") + : "", + ) + .join("\n"); + } + return ""; +} + +function latestUserText(messages: Message[] | undefined): string { + const user = [...(messages ?? [])].reverse().find((m) => m.role === "user"); + return user ? messageText(user).trim() : ""; +} + +function sse(event: AGUIEvent | "[DONE]"): Uint8Array { + const encoder = new TextEncoder(); + if (event === "[DONE]") return encoder.encode("data: [DONE]\n\n"); + return encoder.encode(`data: ${JSON.stringify(event)}\n\n`); +} + +function textEvent(messageId: string, delta: string): AGUIEvent { + return { type: AGUI.TEXT_MESSAGE_CONTENT, messageId, delta } as AGUIEvent; +} + +function textStreamResponse(content: string): Response { + const messageId = crypto.randomUUID(); + const body = new ReadableStream({ + start(controller) { + controller.enqueue( + sse({ type: AGUI.TEXT_MESSAGE_START, messageId, role: "assistant" } as AGUIEvent), + ); + controller.enqueue(sse(textEvent(messageId, content))); + controller.enqueue(sse({ type: AGUI.TEXT_MESSAGE_END, messageId } as AGUIEvent)); + controller.enqueue(sse("[DONE]")); + controller.close(); + }, + }); + return new Response(body, { + headers: { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache, no-transform", + Connection: "keep-alive", + }, + }); +} + +export async function POST(req: NextRequest) { + const body = (await req.json().catch(() => ({}))) as ChatBody; + const conversationId = body.threadId || crypto.randomUUID(); + const userText = latestUserText(body.messages); + + if (!userText) { + return textStreamResponse("_No user message was provided._"); + } + + let entry: Awaited>; + try { + entry = await getOrCreateHarnessSession(conversationId); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return new Response(JSON.stringify({ error: message }), { + status: 500, + headers: { "Content-Type": "application/json" }, + }); + } + + if (entry.session.run.isRunning()) { + return textStreamResponse("_Still responding to your previous message. Please wait._"); + } + + const bridge = new HarnessAGUIBridge(); + + const stream = new ReadableStream({ + start(controller) { + let closed = false; + const enqueue = (event: AGUIEvent | "[DONE]") => { + if (closed) return; + try { + controller.enqueue(sse(event)); + } catch { + closed = true; + } + }; + const finish = () => { + if (closed) return; + for (const event of bridge.finish()) enqueue(event); + enqueue("[DONE]"); + closed = true; + try { + controller.close(); + } catch { + // already closed + } + }; + + const unsubscribe = entry.session.subscribe((event) => { + for (const aguiEvent of bridge.consume(event)) enqueue(aguiEvent); + }); + + const onAbort = () => entry.session.abort(); + req.signal.addEventListener("abort", onAbort); + + void (async () => { + try { + await entry.session.sendMessage({ content: userText }); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + enqueue({ type: AGUI.RUN_ERROR, message } as AGUIEvent); + } finally { + entry.lastUsed = Date.now(); + req.signal.removeEventListener("abort", onAbort); + unsubscribe(); + finish(); + } + })(); + }, + }); + + return new Response(stream, { + headers: { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache, no-transform", + Connection: "keep-alive", + "x-conversation-id": conversationId, + }, + }); +} diff --git a/examples/harnesses/mastra-harness-chat/src/app/globals.css b/examples/harnesses/mastra-harness-chat/src/app/globals.css new file mode 100644 index 000000000..7107c10c0 --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/app/globals.css @@ -0,0 +1,13 @@ +@import "@openuidev/react-ui/styles/index.css"; + +html, +body { + margin: 0; +} + +.app-shell { + height: 100vh; + overflow: hidden; + position: relative; + width: 100vw; +} diff --git a/examples/harnesses/mastra-harness-chat/src/app/layout.tsx b/examples/harnesses/mastra-harness-chat/src/app/layout.tsx new file mode 100644 index 000000000..e4b680e77 --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/app/layout.tsx @@ -0,0 +1,22 @@ +import { ThemeProvider } from "@/hooks/use-system-theme"; +import type { Metadata } from "next"; +import "./globals.css"; + +export const metadata: Metadata = { + title: "Mastra Harness Chat", + description: "Persistent OpenUI chat backed by Mastra Harness tools and AG-UI streaming", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} diff --git a/examples/harnesses/mastra-harness-chat/src/app/page.tsx b/examples/harnesses/mastra-harness-chat/src/app/page.tsx new file mode 100644 index 000000000..a05b374eb --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/app/page.tsx @@ -0,0 +1,48 @@ +"use client"; + +import { useTheme } from "@/hooks/use-system-theme"; +import { createMastraHarnessChatProps } from "@/lib/mastra-harness-chat"; +import { agUIAdapter } from "@openuidev/react-headless"; +import { FullScreen } from "@openuidev/react-ui"; +import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib"; +import { useMemo } from "react"; + +export default function Page() { + const themeMode = useTheme(); + const chatProps = useMemo(() => createMastraHarnessChatProps(), []); + + return ( +
+ +
+ ); +} diff --git a/examples/harnesses/mastra-harness-chat/src/generated/system-prompt.txt b/examples/harnesses/mastra-harness-chat/src/generated/system-prompt.txt new file mode 100644 index 000000000..cbd28d059 --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/generated/system-prompt.txt @@ -0,0 +1,223 @@ +You are an AI assistant that responds using openui-lang, a declarative UI language. Your ENTIRE response must be valid openui-lang code — no markdown, no explanations, just openui-lang. + +## Syntax Rules + +1. Each statement is on its own line: `identifier = Expression` +2. `root` is the entry point — every program must define `root = Card(...)` +3. Expressions are: strings ("..."), numbers, booleans (true/false), null, arrays ([...]), objects ({...}), or component calls TypeName(arg1, arg2, ...) +4. Use references for readability: define `name = ...` on one line, then use `name` later +5. EVERY variable (except root) MUST be referenced by at least one other variable. Unreferenced variables are silently dropped and will NOT render. Always include defined variables in their parent's children/items array. +6. Arguments are POSITIONAL (order matters, not names). Write `Stack([children], "row", "l")` NOT `Stack([children], direction: "row", gap: "l")` — colon syntax is NOT supported and silently breaks +7. Optional arguments can be omitted from the end +- Strings use double quotes with backslash escaping + +## Component Signatures + +Arguments marked with ? are optional. Sub-components can be inline or referenced; prefer references for better streaming. +Props typed `ActionExpression` accept an Action([@steps...]) expression. See the Action section for available steps (@ToAssistant, @OpenUrl). +Props marked `$binding` accept a `$variable` reference for two-way binding. + +### Content +CardHeader(title?: string, subtitle?: string) — Header with optional title and subtitle +TextContent(text: string, size?: "small" | "default" | "large" | "small-heavy" | "large-heavy") — Text block. Supports markdown. Optional size: "small" | "default" | "large" | "small-heavy" | "large-heavy". +MarkDownRenderer(textMarkdown: string, variant?: "clear" | "card" | "sunk") — Renders markdown text with optional container variant +Callout(variant: "info" | "warning" | "error" | "success" | "neutral", title: string, description: string, visible?: $binding) — Callout banner. Optional visible is a reactive $boolean — auto-dismisses after 3s by setting $visible to false. +TextCallout(variant?: "neutral" | "info" | "warning" | "success" | "danger", title?: string, description?: string) — Text callout with variant, title, and description +Image(alt: string, src?: string) — Image with alt text and optional URL +ImageBlock(src: string, alt?: string) — Image block with loading state +ImageGallery(images: {src: string, alt?: string, details?: string}[]) — Gallery grid of images with modal preview +CodeBlock(language: string, codeString: string) — Syntax-highlighted code block +Separator(orientation?: "horizontal" | "vertical", decorative?: boolean) — Visual divider between content sections + +### Tables +Table(columns: Col[]) — Data table — column-oriented. Each Col holds its own data array. +Col(label: string, data: any, type?: "string" | "number" | "action") — Column definition — holds label + data array + +### Charts (2D) +BarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Vertical bars; use for comparing values across categories with one or more series +LineChart(labels: string[], series: Series[], variant?: "linear" | "natural" | "step", xLabel?: string, yLabel?: string) — Lines over categories; use for trends and continuous data over time +AreaChart(labels: string[], series: Series[], variant?: "linear" | "natural" | "step", xLabel?: string, yLabel?: string) — Filled area under lines; use for cumulative totals or volume trends over time +RadarChart(labels: string[], series: Series[]) — Spider/web chart; use for comparing multiple variables across one or more entities +HorizontalBarChart(labels: string[], series: Series[], variant?: "grouped" | "stacked", xLabel?: string, yLabel?: string) — Horizontal bars; prefer when category labels are long or for ranked lists +Series(category: string, values: number[]) — One data series + +### Charts (1D) +PieChart(labels: string[], values: number[], variant?: "pie" | "donut", appearance?: "circular" | "semiCircular") — Circular slices; use plucked arrays: PieChart(data.categories, data.values) +RadialChart(labels: string[], values: number[]) — Radial bars; use plucked arrays: RadialChart(data.categories, data.values) +SingleStackedBarChart(labels: string[], values: number[]) — Single horizontal stacked bar; use plucked arrays: SingleStackedBarChart(data.categories, data.values) +Slice(category: string, value: number) — One slice with label and numeric value + +### Charts (Scatter) +ScatterChart(datasets: ScatterSeries[], xLabel?: string, yLabel?: string) — X/Y scatter plot; use for correlations, distributions, and clustering +ScatterSeries(name: string, points: Point[]) — Named dataset +Point(x: number, y: number, z?: number) — Data point with numeric coordinates + +### Forms +Form(name: string, buttons: Buttons, fields?: FormControl[]) — Form container with fields and explicit action buttons +FormControl(label: string, input: Input | TextArea | Select | DatePicker | Slider | CheckBoxGroup | RadioGroup, hint?: string) — Field with label, input component, and optional hint text +Label(text: string) — Text label +Input(name: string, placeholder?: string, type?: "text" | "email" | "password" | "number" | "url", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +TextArea(name: string, placeholder?: string, rows?: number, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +Select(name: string, items: SelectItem[], placeholder?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding, size?: "small" | "medium" | "large") +SelectItem(value: string, label: string) — Option for Select +DatePicker(name: string, mode?: "single" | "range", rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +Slider(name: string, variant: "continuous" | "discrete", min: number, max: number, step?: number, defaultValue?: number[], label?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) — Numeric slider input; supports continuous and discrete (stepped) variants +CheckBoxGroup(name: string, items: CheckBoxItem[], rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding>) +CheckBoxItem(label: string, description: string, name: string, defaultChecked?: boolean) +RadioGroup(name: string, items: RadioItem[], defaultValue?: string, rules?: {required?: boolean, email?: boolean, url?: boolean, numeric?: boolean, min?: number, max?: number, minLength?: number, maxLength?: number, pattern?: string}, value?: $binding) +RadioItem(label: string, description: string, value: string) +SwitchGroup(name: string, items: SwitchItem[], variant?: "clear" | "card" | "sunk", value?: $binding>) — Group of switch toggles +SwitchItem(label?: string, description?: string, name: string, defaultChecked?: boolean) — Individual switch toggle +- Define EACH FormControl as its own reference — do NOT inline all controls in one array. +- NEVER nest Form inside Form. +- Form requires explicit buttons. Always pass a Buttons(...) reference as the third Form argument. +- rules is an optional object: { required: true, email: true, min: 8, maxLength: 100 } +- The renderer shows error messages automatically — do NOT generate error text in the UI + +### Buttons +Button(label: string, action?: ActionExpression, variant?: "primary" | "secondary" | "tertiary", type?: "normal" | "destructive", size?: "extra-small" | "small" | "medium" | "large") — Clickable button +Buttons(buttons: Button[], direction?: "row" | "column") — Group of Button components. direction: "row" (default) | "column". + +### Lists & Follow-ups +ListBlock(items: ListItem[], variant?: "number" | "image") — A list of items with number or image indicators. Each item can optionally have an action. +ListItem(title: string, subtitle?: string, image?: {src: string, alt: string}, actionLabel?: string, action?: ActionExpression) — Item in a ListBlock — displays a title with an optional subtitle and image. When action is provided, the item becomes clickable. +FollowUpBlock(items: FollowUpItem[]) — List of clickable follow-up suggestions placed at the end of a response +FollowUpItem(text: string) — Clickable follow-up suggestion — when clicked, sends text as user message +- Use ListBlock with ListItem references for numbered, clickable lists. +- Use FollowUpBlock with FollowUpItem references at the end of a response to suggest next actions. +- Clicking a ListItem or FollowUpItem sends its text to the LLM as a user message. +- Example: list = ListBlock([item1, item2]) item1 = ListItem("Option A", "Details about A") + +### Sections +SectionBlock(sections: SectionItem[], isFoldable?: boolean) — Collapsible accordion sections. Auto-opens sections as they stream in. Use SectionItem for each section. +SectionItem(value: string, trigger: string, content: (TextContent | MarkDownRenderer | CardHeader | Callout | TextCallout | CodeBlock | Image | ImageBlock | ImageGallery | Separator | HorizontalBarChart | RadarChart | PieChart | RadialChart | SingleStackedBarChart | ScatterChart | AreaChart | BarChart | LineChart | Table | TagBlock | Form | Buttons | Steps | ListBlock | FollowUpBlock)[]) — Section with a label and collapsible content — used inside SectionBlock +- SectionBlock renders collapsible accordion sections that auto-open as they stream. +- Each section needs a unique `value` id, a `trigger` label, and a `content` array. +- Example: sections = SectionBlock([s1, s2]) s1 = SectionItem("intro", "Introduction", [content1]) +- Set isFoldable=false to render sections as flat headers instead of accordion. + +### Layout +Tabs(items: TabItem[]) — Tabbed container +TabItem(value: string, trigger: string, content: (TextContent | MarkDownRenderer | CardHeader | Callout | TextCallout | CodeBlock | Image | ImageBlock | ImageGallery | Separator | HorizontalBarChart | RadarChart | PieChart | RadialChart | SingleStackedBarChart | ScatterChart | AreaChart | BarChart | LineChart | Table | TagBlock | Form | Buttons | Steps)[]) — value is unique id, trigger is tab label, content is array of components +Accordion(items: AccordionItem[]) — Collapsible sections +AccordionItem(value: string, trigger: string, content: (TextContent | MarkDownRenderer | CardHeader | Callout | TextCallout | CodeBlock | Image | ImageBlock | ImageGallery | Separator | HorizontalBarChart | RadarChart | PieChart | RadialChart | SingleStackedBarChart | ScatterChart | AreaChart | BarChart | LineChart | Table | TagBlock | Form | Buttons | Steps)[]) — value is unique id, trigger is section title +Steps(items: StepsItem[]) — Step-by-step guide +StepsItem(title: string, details: string) — title and details text for one step +Carousel(children: (TextContent | MarkDownRenderer | CardHeader | Callout | TextCallout | CodeBlock | Image | ImageBlock | ImageGallery | Separator | HorizontalBarChart | RadarChart | PieChart | RadialChart | SingleStackedBarChart | ScatterChart | AreaChart | BarChart | LineChart | Table | TagBlock | Form | Buttons | Steps)[][], variant?: "card" | "sunk") — Horizontal scrollable carousel +- Use Tabs to present alternative views — each TabItem has a value id, trigger label, and content array. +- Carousel takes an array of slides, where each slide is an array of content: carousel = Carousel([[t1, img1], [t2, img2]]) +- IMPORTANT: Every slide in a Carousel must have the same structure — same component types in the same order. +- For image carousels use: [[title, image, description, tags], ...] — every slide must follow this exact pattern. +- Use real, publicly accessible image URLs (e.g. https://picsum.photos/seed/KEYWORD/800/500). Never hallucinate image URLs. + +### Data Display +TagBlock(tags: string[]) — tags is an array of strings +Tag(text: string, icon?: string, size?: "sm" | "md" | "lg", variant?: "neutral" | "info" | "success" | "warning" | "danger") — Styled tag/badge with optional icon and variant + +### Other +Card(children: (TextContent | MarkDownRenderer | CardHeader | Callout | TextCallout | CodeBlock | Image | ImageBlock | ImageGallery | Separator | HorizontalBarChart | RadarChart | PieChart | RadialChart | SingleStackedBarChart | ScatterChart | AreaChart | BarChart | LineChart | Table | TagBlock | Form | Buttons | Steps | ListBlock | FollowUpBlock | SectionBlock | Tabs | Carousel)[]) — Vertical container for all content in a chat response. Children stack top to bottom automatically. + +## Action — Button Behavior + +Action([@steps...]) wires button clicks to operations. Steps are @-prefixed built-in actions. Steps execute in order. +Buttons without an explicit Action prop automatically send their label to the assistant (equivalent to Action([@ToAssistant(label)])). + +Available steps: +- @ToAssistant("message") — Send a message to the assistant (for conversational buttons like "Tell me more", "Explain this") +- @OpenUrl("https://...") — Navigate to a URL + +Example — simple nav: +``` +viewBtn = Button("View", Action([@OpenUrl("https://example.com")])) +``` + +- Action can be assigned to a variable or inlined: Button("Go", onSubmit) and Button("Go", Action([...])) both work + +## Hoisting & Streaming (CRITICAL) + +openui-lang supports hoisting: a reference can be used BEFORE it is defined. The parser resolves all references after the full input is parsed. + +During streaming, the output is re-parsed on every chunk. Undefined references are temporarily unresolved and appear once their definitions stream in. This creates a progressive top-down reveal — structure first, then data fills in. + +**Recommended statement order for optimal streaming:** +1. `root = Card(...)` — UI shell appears immediately +2. Component definitions — fill in as they stream +3. Data values — leaf content last + +Always write the root = Card(...) statement first so the UI shell appears immediately, even before child data has streamed in. + +## Examples + +Example 1 — Table with follow-ups: + +root = Card([title, tbl, followUps]) +title = TextContent("Top Languages", "large-heavy") +tbl = Table([Col("Language", langs), Col("Users (M)", users), Col("Year", years)]) +langs = ["Python", "JavaScript", "Java"] +users = [15.7, 14.2, 12.1] +years = [1991, 1995, 1995] +followUps = FollowUpBlock([fu1, fu2]) +fu1 = FollowUpItem("Tell me more about Python") +fu2 = FollowUpItem("Show me a JavaScript comparison") + +Example 2 — Clickable list: + +root = Card([title, list]) +title = TextContent("Choose a topic", "large-heavy") +list = ListBlock([item1, item2, item3]) +item1 = ListItem("Getting started", "New to the platform? Start here.") +item2 = ListItem("Advanced features", "Deep dives into powerful capabilities.") +item3 = ListItem("Troubleshooting", "Common issues and how to fix them.") + +Example 3 — Image carousel with consistent slides + follow-ups: + +root = Card([header, carousel, followups]) +header = CardHeader("Featured Destinations", "Discover highlights and best time to visit") +carousel = Carousel([[t1, img1, d1, tags1], [t2, img2, d2, tags2], [t3, img3, d3, tags3]], "card") +t1 = TextContent("Paris, France", "large-heavy") +img1 = ImageBlock("https://picsum.photos/seed/paris/800/500", "Eiffel Tower at night") +d1 = TextContent("City of light — best Apr–Jun and Sep–Oct.", "default") +tags1 = TagBlock(["Landmark", "City Break", "Culture"]) +t2 = TextContent("Kyoto, Japan", "large-heavy") +img2 = ImageBlock("https://picsum.photos/seed/kyoto/800/500", "Bamboo grove in Arashiyama") +d2 = TextContent("Temples and bamboo groves — best Mar–Apr and Nov.", "default") +tags2 = TagBlock(["Temples", "Autumn", "Culture"]) +t3 = TextContent("Machu Picchu, Peru", "large-heavy") +img3 = ImageBlock("https://picsum.photos/seed/machupicchu/800/500", "Inca citadel in the clouds") +d3 = TextContent("High-altitude Inca citadel — best May–Sep.", "default") +tags3 = TagBlock(["Andes", "Hike", "UNESCO"]) +followups = FollowUpBlock([fu1, fu2]) +fu1 = FollowUpItem("Show me only beach destinations") +fu2 = FollowUpItem("Turn this into a comparison table") + +Example 4 — Form with validation: + +root = Card([title, form]) +title = TextContent("Contact Us", "large-heavy") +form = Form("contact", btns, [nameField, emailField, msgField]) +nameField = FormControl("Name", Input("name", "Your name", "text", { required: true, minLength: 2 })) +emailField = FormControl("Email", Input("email", "you@example.com", "email", { required: true, email: true })) +msgField = FormControl("Message", TextArea("message", "Tell us more...", 4, { required: true, minLength: 10 })) +btns = Buttons([Button("Submit", Action([@ToAssistant("Submit")]), "primary")]) + +## Important Rules +- When asked about data, generate realistic/plausible data +- Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.) + +## Final Verification +Before finishing, walk your output and verify: +1. root = Card(...) is the FIRST line (for optimal streaming). +2. Every referenced name is defined. Every defined name (other than root) is reachable from root. + +- Every response is a single Card(children) — children stack vertically automatically. No layout params are needed on Card. +- Card is the only layout container. Do NOT use Stack. Use Tabs to switch between sections, Carousel for horizontal scroll. +- Use FollowUpBlock at the END of a Card to suggest what the user can do or ask next. +- Use ListBlock when presenting a set of options or steps the user can click to select. +- Use SectionBlock to group long responses into collapsible sections — good for reports, FAQs, and structured content. +- Use SectionItem inside SectionBlock: each item needs a unique value id, a trigger (header label), and a content array. +- Carousel takes an array of slides, where each slide is an array of content: carousel = Carousel([[t1, img1], [t2, img2]]) +- IMPORTANT: Every slide in a Carousel must use the same component structure in the same order — e.g. all slides: [title, image, description, tags]. +- For image carousels, always use real accessible URLs like https://picsum.photos/seed/KEYWORD/800/500. Never hallucinate or invent image URLs. +- For forms, define one FormControl reference per field so controls can stream progressively. +- For forms, always provide the second Form argument with Buttons(...) actions: Form(name, buttons, fields). +- Never nest Form inside Form. diff --git a/examples/harnesses/mastra-harness-chat/src/hooks/use-system-theme.tsx b/examples/harnesses/mastra-harness-chat/src/hooks/use-system-theme.tsx new file mode 100644 index 000000000..7c110c21d --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/hooks/use-system-theme.tsx @@ -0,0 +1,41 @@ +"use client"; + +import { createContext, useContext, useLayoutEffect, useState } from "react"; + +type ThemeMode = "light" | "dark"; + +interface ThemeContextType { + mode: ThemeMode; +} + +const ThemeContext = createContext(undefined); + +function getSystemMode(): ThemeMode { + if (typeof window === "undefined") return "light"; + return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"; +} + +export function ThemeProvider({ children }: { children: React.ReactNode }) { + const [mode, setMode] = useState(getSystemMode); + + useLayoutEffect(() => { + const mq = window.matchMedia("(prefers-color-scheme: dark)"); + const handler = (e: MediaQueryListEvent) => setMode(e.matches ? "dark" : "light"); + mq.addEventListener("change", handler); + return () => mq.removeEventListener("change", handler); + }, []); + + useLayoutEffect(() => { + document.body.setAttribute("data-theme", mode); + }, [mode]); + + return {children}; +} + +export function useTheme(): ThemeMode { + const ctx = useContext(ThemeContext); + if (!ctx) { + throw new Error("useTheme must be used within a ThemeProvider"); + } + return ctx.mode; +} diff --git a/examples/harnesses/mastra-harness-chat/src/lib/harness-stream.ts b/examples/harnesses/mastra-harness-chat/src/lib/harness-stream.ts new file mode 100644 index 000000000..b5b020501 --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/lib/harness-stream.ts @@ -0,0 +1,184 @@ +import type { HarnessEvent, HarnessMessage, HarnessMessageContent } from "@mastra/core/harness"; +import type { AGUIEvent } from "@openuidev/react-headless"; + +const AGUI = { + RUN_ERROR: "RUN_ERROR", + TEXT_MESSAGE_CONTENT: "TEXT_MESSAGE_CONTENT", + TEXT_MESSAGE_END: "TEXT_MESSAGE_END", + TEXT_MESSAGE_START: "TEXT_MESSAGE_START", + TOOL_CALL_ARGS: "TOOL_CALL_ARGS", + TOOL_CALL_END: "TOOL_CALL_END", + TOOL_CALL_START: "TOOL_CALL_START", +} as const; + +function safeJson(value: unknown): string { + try { + return JSON.stringify(value ?? {}); + } catch { + return String(value); + } +} + +function messageText(message: HarnessMessage): string { + return message.content + .map((part: HarnessMessageContent) => (part.type === "text" ? part.text : "")) + .join(""); +} + +export class HarnessAGUIBridge { + private readonly assistantMessageId = crypto.randomUUID(); + private readonly textByMessageId = new Map(); + private readonly startedToolCalls = new Map(); + private readonly endedToolCalls = new Set(); + private readonly streamedToolArgs = new Set(); + private messageStarted = false; + private messageEnded = false; + + private startMessage(): AGUIEvent[] { + if (this.messageStarted) return []; + this.messageStarted = true; + return [ + { + type: AGUI.TEXT_MESSAGE_START, + messageId: this.assistantMessageId, + role: "assistant", + } as AGUIEvent, + ]; + } + + private textDelta(message: HarnessMessage): AGUIEvent[] { + if (message.role !== "assistant") return []; + + const next = messageText(message); + const previous = this.textByMessageId.get(message.id) ?? ""; + if (next === previous) return []; + + this.textByMessageId.set(message.id, next); + const delta = next.startsWith(previous) ? next.slice(previous.length) : next; + if (!delta) return []; + + return [ + ...this.startMessage(), + { + type: AGUI.TEXT_MESSAGE_CONTENT, + messageId: this.assistantMessageId, + delta, + } as AGUIEvent, + ]; + } + + private startTool(toolCallId: string, toolName: string): AGUIEvent[] { + if (this.startedToolCalls.has(toolCallId)) return []; + this.startedToolCalls.set(toolCallId, toolName); + return [ + ...this.startMessage(), + { + type: AGUI.TOOL_CALL_START, + toolCallId, + toolCallName: toolName, + parentMessageId: this.assistantMessageId, + } as AGUIEvent, + ]; + } + + private endTool(toolCallId: string): AGUIEvent[] { + if (!this.startedToolCalls.has(toolCallId) || this.endedToolCalls.has(toolCallId)) return []; + this.endedToolCalls.add(toolCallId); + return [ + { + type: AGUI.TOOL_CALL_END, + toolCallId, + } as AGUIEvent, + ]; + } + + consume(event: HarnessEvent): AGUIEvent[] { + switch (event.type) { + case "message_update": + case "message_end": + return this.textDelta(event.message); + + case "tool_input_start": + return this.startTool(event.toolCallId, event.toolName); + + case "tool_input_delta": + this.streamedToolArgs.add(event.toolCallId); + return [ + ...this.startTool( + event.toolCallId, + event.toolName ?? this.startedToolCalls.get(event.toolCallId) ?? "Tool", + ), + { + type: AGUI.TOOL_CALL_ARGS, + toolCallId: event.toolCallId, + delta: event.argsTextDelta, + } as AGUIEvent, + ]; + + case "tool_start": { + const args = safeJson(event.args); + const alreadyStreamedArgs = this.streamedToolArgs.has(event.toolCallId); + return [ + ...this.startTool(event.toolCallId, event.toolName), + ...(args && args !== "{}" && !alreadyStreamedArgs + ? [ + { + type: AGUI.TOOL_CALL_ARGS, + toolCallId: event.toolCallId, + delta: args, + } as AGUIEvent, + ] + : []), + ]; + } + + case "tool_approval_required": + return [ + ...this.startTool(event.toolCallId, `${event.toolName} approval`), + { + type: AGUI.TOOL_CALL_ARGS, + toolCallId: event.toolCallId, + delta: safeJson(event.args), + } as AGUIEvent, + ...this.endTool(event.toolCallId), + ]; + + case "tool_suspended": + return [ + ...this.startTool(event.toolCallId, `${event.toolName} suspended`), + { + type: AGUI.TOOL_CALL_ARGS, + toolCallId: event.toolCallId, + delta: safeJson(event.suspendPayload), + } as AGUIEvent, + ...this.endTool(event.toolCallId), + ]; + + case "tool_end": + case "tool_input_end": + return this.endTool(event.toolCallId); + + case "error": + return [ + { + type: AGUI.RUN_ERROR, + message: event.error.message, + } as AGUIEvent, + ]; + + default: + return []; + } + } + + finish(): AGUIEvent[] { + if (!this.messageStarted || this.messageEnded) return []; + this.messageEnded = true; + return [ + { + type: AGUI.TEXT_MESSAGE_END, + messageId: this.assistantMessageId, + } as AGUIEvent, + ]; + } +} diff --git a/examples/harnesses/mastra-harness-chat/src/lib/mastra-harness-chat.ts b/examples/harnesses/mastra-harness-chat/src/lib/mastra-harness-chat.ts new file mode 100644 index 000000000..6bf733707 --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/lib/mastra-harness-chat.ts @@ -0,0 +1,107 @@ +import { EventType, type AGUIEvent, type Message } from "@openuidev/react-headless"; +import { + createThreadStore, + getClientStorage, + type KVStorage, + type ThreadStore, +} from "./thread-store"; + +function sseLinesToEvents(chunk: string): AGUIEvent[] { + return chunk + .split("\n") + .filter((line) => line.startsWith("data: ")) + .flatMap((line) => { + const data = line.slice(6).trim(); + if (!data || data === "[DONE]") return []; + try { + return [JSON.parse(data) as AGUIEvent]; + } catch { + return []; + } + }); +} + +async function persistAssistantFromStream( + body: ReadableStream, + threadId: string, + messages: Message[], + store: ThreadStore, +): Promise { + const reader = body.getReader(); + const decoder = new TextDecoder(); + let assistant = ""; + let buffer = ""; + + try { + for (;;) { + const { done, value } = await reader.read(); + if (done) break; + buffer += decoder.decode(value, { stream: true }); + const lines = buffer.split("\n"); + buffer = lines.pop() ?? ""; + for (const event of sseLinesToEvents(lines.join("\n"))) { + if (event.type === EventType.TEXT_MESSAGE_CONTENT) { + assistant += (event as { delta: string }).delta; + } + } + } + + if (buffer) { + for (const event of sseLinesToEvents(buffer)) { + if (event.type === EventType.TEXT_MESSAGE_CONTENT) { + assistant += (event as { delta: string }).delta; + } + } + } + } finally { + reader.releaseLock(); + } + + if (assistant) { + store.saveMessages(threadId, [ + ...messages, + { id: crypto.randomUUID(), role: "assistant", content: assistant } as Message, + ]); + } +} + +export function createMastraHarnessChatProps( + storage: KVStorage = getClientStorage(), + store: ThreadStore = createThreadStore(storage), +) { + return { + createThread: store.createThread, + fetchThreadList: store.fetchThreadList, + loadThread: store.loadThread, + deleteThread: store.deleteThread, + updateThread: store.updateThread, + processMessage: async ({ + messages, + threadId, + abortController, + }: { + messages: Message[]; + threadId: string; + abortController: AbortController; + }): Promise => { + store.saveMessages(threadId, messages); + + const response = await fetch("/api/chat", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ messages, threadId }), + signal: abortController.signal, + }); + + if (!response.body) return response; + const [clientBody, persistBody] = response.body.tee(); + void persistAssistantFromStream(persistBody, threadId, messages, store); + + return new Response(clientBody, { + status: response.status, + statusText: response.statusText, + headers: response.headers, + }); + }, + }; +} diff --git a/examples/harnesses/mastra-harness-chat/src/lib/mastra-harness.ts b/examples/harnesses/mastra-harness-chat/src/lib/mastra-harness.ts new file mode 100644 index 000000000..20508a50f --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/lib/mastra-harness.ts @@ -0,0 +1,242 @@ +import { Agent } from "@mastra/core/agent"; +import { Harness, type Session, type ToolCategory } from "@mastra/core/harness"; +import { createTool } from "@mastra/core/tools"; +import { LibSQLStore } from "@mastra/libsql"; +import { mkdirSync, readFileSync } from "fs"; +import { join } from "path"; +import { z } from "zod"; + +const systemPrompt = readFileSync( + join(process.cwd(), "src/generated/system-prompt.txt"), + "utf-8", +); + +const HARNESS_CONFIG_VERSION = "2026-07-04.1"; + +const getWeather = createTool({ + id: "get_weather", + description: "Get current weather for a city.", + inputSchema: z.object({ location: z.string().describe("City name") }), + execute: async ({ location }) => { + const knownTemps: Record = { + tokyo: 22, + "san francisco": 18, + london: 14, + "new york": 25, + paris: 19, + sydney: 27, + mumbai: 33, + berlin: 16, + }; + const temp = knownTemps[location.toLowerCase()] ?? Math.floor(Math.random() * 30 + 5); + return { location, temperature_celsius: temp, condition: "Clear" }; + }, +}); + +const getStockPrice = createTool({ + id: "get_stock_price", + description: "Get current stock price for a ticker symbol.", + inputSchema: z.object({ symbol: z.string().describe("Ticker symbol, e.g. AAPL") }), + execute: async ({ symbol }) => { + const prices: Record = { + AAPL: 189.84, + GOOGL: 141.8, + TSLA: 248.42, + MSFT: 378.91, + NVDA: 875.28, + }; + const s = symbol.toUpperCase(); + const price = prices[s] ?? Math.floor(Math.random() * 500 + 50); + return { symbol: s, price, currency: "USD" }; + }, +}); + +function modelConfig() { + return { + id: (process.env.OPENAI_MODEL as `${string}/${string}`) || "openai/gpt-5.5", + apiKey: process.env.OPENAI_API_KEY, + url: process.env.OPENAI_BASE_URL || "https://api.openai.com/v1", + }; +} + +function toolCategoryResolver(toolName: string): ToolCategory { + if ( + toolName === "get_weather" || + toolName === "get_stock_price" || + toolName.startsWith("task_") + ) { + return "read"; + } + return "other"; +} + +function createHarness() { + mkdirSync(join(process.cwd(), ".mastra-harness-chat"), { recursive: true }); + + const agent = new Agent({ + id: "openui-mastra-harness-agent", + name: "OpenUI Mastra Harness Agent", + instructions: + "You are a helpful assistant. Use tools when relevant, and always answer with valid OpenUI Lang for the configured component library.\n\n" + + systemPrompt, + model: modelConfig(), + tools: { get_weather: getWeather, get_stock_price: getStockPrice }, + }); + + return new Harness({ + id: "openui-mastra-harness", + storage: new LibSQLStore({ + id: "openui-mastra-harness-storage", + url: process.env.MASTRA_HARNESS_DB_URL || "file:./.mastra-harness-chat/openui-harness.db", + }), + agent, + defaultModeId: "default", + modes: [ + { + id: "default", + name: "Default", + description: "Use tools and render complete OpenUI responses.", + metadata: { default: true }, + instructions: + [ + "Optimize for useful depth, exploration, and rich generated UI.", + "When the prompt asks for analysis, planning, comparison, status, or data, prefer structured UI such as SectionBlock, Table, TagBlock, ListBlock, charts, and FollowUpBlock.", + "Use tools when relevant and include the tool-derived facts in the rendered UI.", + "Default shape: root = Card([header, overview, details, actions, followups]) or a richer equivalent.", + ].join("\n"), + }, + ], + disableBuiltinTools: ["ask_user", "submit_plan", "subagent"], + toolCategoryResolver, + }); +} + +export interface HarnessSessionEntry { + session: Session; + lastUsed: number; +} + +const IDLE_TTL_MS = 30 * 60 * 1000; +const MAX_SESSIONS = 50; + +const globalStore = globalThis as unknown as { + __openuiMastraHarness?: Harness; + __openuiMastraHarnessConfigSignature?: string; + __openuiMastraHarnessInit?: Promise; + __openuiMastraHarnessSessions?: Map; + __openuiMastraHarnessCreating?: Map>; +}; + +const SESSIONS = (globalStore.__openuiMastraHarnessSessions ??= new Map< + string, + HarnessSessionEntry +>()); +const CREATING = (globalStore.__openuiMastraHarnessCreating ??= new Map< + string, + Promise +>()); + +function harnessConfigSignature(): string { + return JSON.stringify({ + apiKey: process.env.OPENAI_API_KEY ?? "", + baseUrl: process.env.OPENAI_BASE_URL ?? "", + dbUrl: process.env.MASTRA_HARNESS_DB_URL ?? "", + model: process.env.OPENAI_MODEL ?? "", + version: HARNESS_CONFIG_VERSION, + }); +} + +async function getHarness(): Promise { + const signature = harnessConfigSignature(); + if ( + globalStore.__openuiMastraHarness && + globalStore.__openuiMastraHarnessConfigSignature !== signature + ) { + for (const entry of SESSIONS.values()) { + await releaseSession(entry); + } + SESSIONS.clear(); + CREATING.clear(); + await globalStore.__openuiMastraHarness.destroy(); + globalStore.__openuiMastraHarness = undefined; + globalStore.__openuiMastraHarnessInit = undefined; + } + + const harness = (globalStore.__openuiMastraHarness ??= createHarness()); + globalStore.__openuiMastraHarnessConfigSignature = signature; + globalStore.__openuiMastraHarnessInit ??= harness.init(); + await globalStore.__openuiMastraHarnessInit; + return harness; +} + +async function releaseSession(entry: HarnessSessionEntry): Promise { + entry.session.abort(); + await entry.session.thread.clearAndReleaseLock().catch(() => undefined); +} + +async function evictIdle(now: number): Promise { + for (const [id, entry] of SESSIONS) { + if (now - entry.lastUsed > IDLE_TTL_MS && !entry.session.run.isRunning()) { + await releaseSession(entry); + SESSIONS.delete(id); + } + } +} + +async function evictOldestIfFull(): Promise { + if (SESSIONS.size < MAX_SESSIONS) return; + let oldestId: string | undefined; + let oldest = Number.POSITIVE_INFINITY; + for (const [id, entry] of SESSIONS) { + if (entry.session.run.isRunning()) continue; + if (entry.lastUsed < oldest) { + oldest = entry.lastUsed; + oldestId = id; + } + } + if (oldestId) { + const entry = SESSIONS.get(oldestId); + if (entry) await releaseSession(entry); + SESSIONS.delete(oldestId); + } +} + +async function createSession(conversationId: string): Promise { + await evictOldestIfFull(); + + const harness = await getHarness(); + const session = await harness.createSession({ + resourceId: `openui-thread:${conversationId}`, + }); + session.grantCategory("read"); + + return { session, lastUsed: Date.now() }; +} + +export async function getOrCreateHarnessSession( + conversationId: string, +): Promise { + const now = Date.now(); + await evictIdle(now); + + const existing = SESSIONS.get(conversationId); + if (existing) { + existing.lastUsed = now; + return existing; + } + + const inFlight = CREATING.get(conversationId); + if (inFlight) return inFlight; + + const creation = createSession(conversationId) + .then((entry) => { + SESSIONS.set(conversationId, entry); + return entry; + }) + .finally(() => { + CREATING.delete(conversationId); + }); + + CREATING.set(conversationId, creation); + return creation; +} diff --git a/examples/harnesses/mastra-harness-chat/src/lib/thread-store.ts b/examples/harnesses/mastra-harness-chat/src/lib/thread-store.ts new file mode 100644 index 000000000..6deefe923 --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/lib/thread-store.ts @@ -0,0 +1,111 @@ +import type { Message, Thread, UserMessage } from "@openuidev/react-headless"; + +// Kept separate from mastra-harness-chat so the OpenUI chat adapter can focus on +// transport, while this file owns the browser-side thread persistence contract. +export interface KVStorage { + getItem(key: string): string | null; + setItem(key: string, value: string): void; + removeItem(key: string): void; +} + +const THREADS_KEY = "mastra-harness-chat-openui:threads"; +const messagesKey = (threadId: string) => `mastra-harness-chat-openui:messages:${threadId}`; + +function readJson(storage: KVStorage, key: string, fallback: T): T { + try { + const raw = storage.getItem(key); + return raw ? (JSON.parse(raw) as T) : fallback; + } catch { + return fallback; + } +} + +function messageText(message: Pick): string { + const content = message.content as unknown; + if (typeof content === "string") return content; + if (Array.isArray(content)) { + return content + .map((part) => + part && typeof part === "object" && "text" in part + ? String((part as { text?: unknown }).text ?? "") + : "", + ) + .join(" "); + } + return ""; +} + +function deriveTitle(message: UserMessage): string { + const text = messageText(message).trim().replace(/\s+/g, " "); + if (!text) return "New chat"; + return text.length > 60 ? `${text.slice(0, 57)}...` : text; +} + +export interface ThreadStore { + createThread(firstMessage: UserMessage): Promise; + fetchThreadList(): Promise<{ threads: Thread[] }>; + loadThread(threadId: string): Promise; + deleteThread(threadId: string): Promise; + updateThread(updated: Thread): Promise; + saveMessages(threadId: string, messages: Message[]): void; +} + +export function createThreadStore( + storage: KVStorage, + generateId: () => string = () => crypto.randomUUID(), +): ThreadStore { + const listThreads = (): Thread[] => readJson(storage, THREADS_KEY, []); + const writeThreads = (threads: Thread[]) => storage.setItem(THREADS_KEY, JSON.stringify(threads)); + + return { + async createThread(firstMessage) { + const thread: Thread = { + id: generateId(), + title: deriveTitle(firstMessage), + createdAt: Date.now(), + }; + writeThreads([thread, ...listThreads().filter((t) => t.id !== thread.id)]); + return thread; + }, + + async fetchThreadList() { + return { threads: listThreads() }; + }, + + async loadThread(threadId) { + return readJson(storage, messagesKey(threadId), []); + }, + + async deleteThread(threadId) { + writeThreads(listThreads().filter((t) => t.id !== threadId)); + storage.removeItem(messagesKey(threadId)); + }, + + async updateThread(updated) { + writeThreads(listThreads().map((t) => (t.id === updated.id ? updated : t))); + return updated; + }, + + saveMessages(threadId, messages) { + storage.setItem(messagesKey(threadId), JSON.stringify(messages)); + }, + }; +} + +export function createMemoryStorage(): KVStorage { + const map = new Map(); + return { + getItem: (key) => (map.has(key) ? (map.get(key) as string) : null), + setItem: (key, value) => { + map.set(key, value); + }, + removeItem: (key) => { + map.delete(key); + }, + }; +} + +export function getClientStorage(): KVStorage { + if (typeof window !== "undefined" && window.localStorage) return window.localStorage; + return createMemoryStorage(); +} diff --git a/examples/harnesses/mastra-harness-chat/src/library.ts b/examples/harnesses/mastra-harness-chat/src/library.ts new file mode 100644 index 000000000..316f65a7d --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/src/library.ts @@ -0,0 +1,4 @@ +export { + openuiChatLibrary as library, + openuiChatPromptOptions as promptOptions, +} from "@openuidev/react-ui/genui-lib"; diff --git a/examples/harnesses/mastra-harness-chat/tsconfig.json b/examples/harnesses/mastra-harness-chat/tsconfig.json new file mode 100644 index 000000000..b575f7dac --- /dev/null +++ b/examples/harnesses/mastra-harness-chat/tsconfig.json @@ -0,0 +1,41 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./src/*" + ] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 25d6d61b6..a5845ebe4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -146,13 +146,13 @@ importers: version: 0.68.17 fumadocs-core: specifier: 16.9.1 - version: 16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6) + version: 16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6) fumadocs-mdx: specifier: 14.3.2 - version: 14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.14)(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react@19.2.4)(vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)) + version: 14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.14)(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react@19.2.4)(vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)) fumadocs-ui: specifier: 16.9.1 - version: 16.9.1(@emotion/is-prop-valid@1.4.0)(@tailwindcss/oxide@4.2.2)(@takumi-rs/image-response@0.68.17)(@types/mdx@2.0.13)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tailwindcss@4.2.1) + version: 16.9.1(@emotion/is-prop-valid@1.4.0)(@tailwindcss/oxide@4.2.2)(@takumi-rs/image-response@0.68.17)(@types/mdx@2.0.13)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tailwindcss@4.2.1) gpt-tokenizer: specifier: ^3.4.0 version: 3.4.0 @@ -164,7 +164,7 @@ importers: version: 12.34.3(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -268,7 +268,7 @@ importers: version: 0.575.0(react@19.2.3) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) openai: specifier: ^6.22.0 version: 6.39.0(ws@8.21.0)(zod@4.3.6) @@ -338,7 +338,7 @@ importers: version: 1.8.0(react@19.2.4) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) openai: specifier: ^6.34.0 version: 6.39.0(ws@8.21.0)(zod@4.3.6) @@ -380,6 +380,64 @@ importers: specifier: ^5 version: 5.9.3 + examples/harnesses/mastra-harness-chat: + dependencies: + '@mastra/core': + specifier: ^1.46.0 + version: 1.46.0(@bufbuild/protobuf@2.12.0)(@cfworker/json-schema@4.1.1)(ai@6.0.191(zod@4.4.3))(express@5.2.1)(rxjs@7.8.2)(zod@4.4.3) + '@mastra/libsql': + specifier: ^1.14.1 + version: 1.14.1(@mastra/core@1.46.0(@bufbuild/protobuf@2.12.0)(@cfworker/json-schema@4.1.1)(ai@6.0.191(zod@4.4.3))(express@5.2.1)(rxjs@7.8.2)(zod@4.4.3)) + '@openuidev/react-headless': + specifier: workspace:* + version: link:../../../packages/react-headless + '@openuidev/react-lang': + specifier: workspace:* + version: link:../../../packages/react-lang + '@openuidev/react-ui': + specifier: workspace:* + version: link:../../../packages/react-ui + next: + specifier: 16.2.6 + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + react: + specifier: 19.2.3 + version: 19.2.3 + react-dom: + specifier: 19.2.3 + version: 19.2.3(react@19.2.3) + zod: + specifier: 4.4.3 + version: 4.4.3 + devDependencies: + '@openuidev/cli': + specifier: workspace:* + version: link:../../../packages/openui-cli + '@tailwindcss/postcss': + specifier: ^4 + version: 4.2.1 + '@types/node': + specifier: 'catalog:' + version: 22.19.19 + '@types/react': + specifier: ^19 + version: 19.2.14 + '@types/react-dom': + specifier: ^19 + version: 19.2.3(@types/react@19.2.14) + eslint: + specifier: ^9 + version: 9.29.0(jiti@2.7.0) + eslint-config-next: + specifier: 16.2.6 + version: 16.2.6(@typescript-eslint/parser@8.59.4(eslint@9.29.0(jiti@2.7.0))(typescript@5.9.3))(eslint@9.29.0(jiti@2.7.0))(typescript@5.9.3) + tailwindcss: + specifier: ^4 + version: 4.2.2 + typescript: + specifier: ^5 + version: 5.9.3 + examples/harnesses/pi-agent-harness: dependencies: '@earendil-works/pi-coding-agent': @@ -396,7 +454,7 @@ importers: version: link:../../../packages/react-ui next: specifier: 16.1.6 - version: 16.1.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.1.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) react: specifier: 19.2.3 version: 19.2.3 @@ -445,16 +503,16 @@ importers: version: link:../../../packages/react-ui '@vercel/connect': specifier: 0.2.2 - version: 0.2.2(ai@7.0.0-beta.178(zod@4.4.3))(eve@0.11.7(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(ai@7.0.0-beta.178(zod@4.4.3))(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2))(react@19.2.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3))) + version: 0.2.2(ai@7.0.0-beta.178(zod@4.4.3))(eve@0.11.7(@libsql/client@0.17.4)(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(ai@7.0.0-beta.178(zod@4.4.3))(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2))(react@19.2.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3))) ai: specifier: 7.0.0-beta.178 version: 7.0.0-beta.178(zod@4.4.3) eve: specifier: ^0.11.7 - version: 0.11.7(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(ai@7.0.0-beta.178(zod@4.4.3))(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2))(react@19.2.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3)) + version: 0.11.7(@libsql/client@0.17.4)(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(ai@7.0.0-beta.178(zod@4.4.3))(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2))(react@19.2.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3)) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) react: specifier: 19.2.3 version: 19.2.3 @@ -512,7 +570,7 @@ importers: version: link:../../packages/react-ui next: specifier: 16.1.6 - version: 16.1.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.1.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) react: specifier: 19.2.3 version: 19.2.3 @@ -579,7 +637,7 @@ importers: version: 0.575.0(react@19.2.3) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) react: specifier: 19.2.3 version: 19.2.3 @@ -646,7 +704,7 @@ importers: version: link:../../packages/react-ui next: specifier: 16.2.7 - version: 16.2.7(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.7(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) openai: specifier: ^6.22.0 version: 6.39.0(ws@8.21.0)(zod@4.3.6) @@ -707,7 +765,7 @@ importers: version: 0.575.0(react@19.2.3) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) react: specifier: 19.2.3 version: 19.2.3 @@ -762,7 +820,7 @@ importers: version: 0.575.0(react@19.2.3) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) openai: specifier: ^6.22.0 version: 6.39.0(ws@8.21.0)(zod@4.3.6) @@ -826,7 +884,7 @@ importers: version: 0.575.0(react@19.2.3) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) openai: specifier: ^6.22.0 version: 6.39.0(ws@8.21.0)(zod@4.3.6) @@ -893,7 +951,7 @@ importers: version: 0.575.0(react@19.2.3) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) openai: specifier: ^6.22.0 version: 6.39.0(ws@8.21.0)(zod@4.3.6) @@ -938,7 +996,7 @@ importers: dependencies: next: specifier: ^15.2.3 - version: 15.5.18(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) + version: 15.5.18(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) openai: specifier: ^4.90.0 version: 4.104.0(ws@8.21.0)(zod@4.4.3) @@ -1033,7 +1091,7 @@ importers: version: 0.562.0(react@19.2.3) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) openai: specifier: ^6.22.0 version: 6.39.0(ws@8.21.0)(zod@4.3.6) @@ -1169,7 +1227,7 @@ importers: version: 0.575.0(react@19.2.3) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) openai: specifier: ^6.22.0 version: 6.39.0(ws@8.21.0)(zod@4.3.6) @@ -1251,7 +1309,7 @@ importers: version: 2.106.2 next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) openai: specifier: ^6.22.0 version: 6.39.0(ws@8.21.0)(zod@4.4.3) @@ -1358,7 +1416,7 @@ importers: version: 0.575.0(react@19.2.3) next: specifier: 16.2.6 - version: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + version: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) react: specifier: 19.2.3 version: 19.2.3 @@ -1426,7 +1484,7 @@ importers: version: 2.6.1 nuxt: specifier: ^3.17.0 - version: 3.21.6(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4)(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0) + version: 3.21.6(@libsql/client@0.17.4)(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4(@libsql/client@0.17.4))(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0) tailwindcss: specifier: ^4 version: 4.2.1 @@ -1886,6 +1944,21 @@ packages: resolution: {integrity: sha512-VTDuRS5V0ATbJ/LkaQlisMnTAeYKXAK6scMguVBstf+KIBQ7HIuKhiXLv+G/hvejkV+THoXzoNifInAkU81P1g==} engines: {node: '>=18'} + '@a2a-js/sdk@0.3.13': + resolution: {integrity: sha512-BZr0f9JVNQs3GKOM9xINWCh6OKIJWZFPyqqVqTym5mxO2Eemc6I/0zL7zWnljHzGdaf5aZQyQN5xa6PSH62q+A==} + engines: {node: '>=18'} + peerDependencies: + '@bufbuild/protobuf': ^2.10.2 + '@grpc/grpc-js': ^1.11.0 + express: ^4.21.2 || ^5.1.0 + peerDependenciesMeta: + '@bufbuild/protobuf': + optional: true + '@grpc/grpc-js': + optional: true + express: + optional: true + '@adobe/css-tools@4.4.3': resolution: {integrity: sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==} @@ -1988,6 +2061,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider-utils@3.0.25': + resolution: {integrity: sha512-CvsRu+32Y8a167s+lrIBtsybvgTHp8j9y+6BeTvLeoW3Q+okw/b4CnNUFOLIXsRaKHQKAH+IHNJPYWywfpw0LA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider-utils@4.0.0': resolution: {integrity: sha512-HyCyOls9I3a3e38+gtvOJOEjuw9KRcvbBnCL5GBuSmJvS9Jh9v3fz7pRC6ha1EUo/ZH1zwvLWYXBMtic8MTguA==} engines: {node: '>=18'} @@ -3063,9 +3142,6 @@ packages: '@emnapi/runtime@1.11.1': resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - '@emnapi/runtime@1.8.1': - resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} @@ -4401,6 +4477,63 @@ packages: '@langchain/protocol@0.0.16': resolution: {integrity: sha512-ws+J7MaHyhO5dG7f0vdyHQiUn9hoCnki0f3crJPa4MCTGzcRC39jYSCghyrGtBPYQnZbUQiGyRVpW3z3M8IpJg==} + '@libsql/client@0.17.4': + resolution: {integrity: sha512-lYayFWasDV78A+TjlEhr6ubb3odBV6OHjb+wdp8VQcyWWAEIjuwbCHaraEUS4m4yWoo0BvZo96It4VdzZRmRWw==} + + '@libsql/core@0.17.4': + resolution: {integrity: sha512-LqF9gIvnJ38nmAH1y/ChizHqDO/MO1wLgA96XrraulEEbqXxLjleSH92YWTolbuJKgPUmGu4aJk9W3UnAcxLOQ==} + + '@libsql/darwin-arm64@0.5.29': + resolution: {integrity: sha512-K+2RIB1OGFPYQbfay48GakLhqf3ArcbHqPFu7EZiaUcRgFcdw8RoltsMyvbj5ix2fY0HV3Q3Ioa/ByvQdaSM0A==} + cpu: [arm64] + os: [darwin] + + '@libsql/darwin-x64@0.5.29': + resolution: {integrity: sha512-OtT+KFHsKFy1R5FVadr8FJ2Bb1mghtXTyJkxv0trocq7NuHntSki1eUbxpO5ezJesDvBlqFjnWaYYY516QNLhQ==} + cpu: [x64] + os: [darwin] + + '@libsql/hrana-client@0.10.0': + resolution: {integrity: sha512-OoA4EMqRAC7kn7V2P6EQqRcpZf2W+AjsNIyCizBg339Tq/aMC7sRnzs3SklderhmQWAqEzvv8A2vhxVmWpkVvw==} + + '@libsql/isomorphic-ws@0.1.5': + resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==} + + '@libsql/linux-arm-gnueabihf@0.5.29': + resolution: {integrity: sha512-CD4n4zj7SJTHso4nf5cuMoWoMSS7asn5hHygsDuhRl8jjjCTT3yE+xdUvI4J7zsyb53VO5ISh4cwwOtf6k2UhQ==} + cpu: [arm] + os: [linux] + + '@libsql/linux-arm-musleabihf@0.5.29': + resolution: {integrity: sha512-2Z9qBVpEJV7OeflzIR3+l5yAd4uTOLxklScYTwpZnkm2vDSGlC1PRlueLaufc4EFITkLKXK2MWBpexuNJfMVcg==} + cpu: [arm] + os: [linux] + + '@libsql/linux-arm64-gnu@0.5.29': + resolution: {integrity: sha512-gURBqaiXIGGwFNEaUj8Ldk7Hps4STtG+31aEidCk5evMMdtsdfL3HPCpvys+ZF/tkOs2MWlRWoSq7SOuCE9k3w==} + cpu: [arm64] + os: [linux] + + '@libsql/linux-arm64-musl@0.5.29': + resolution: {integrity: sha512-fwgYZ0H8mUkyVqXZHF3mT/92iIh1N94Owi/f66cPVNsk9BdGKq5gVpoKO+7UxaNzuEH1roJp2QEwsCZMvBLpqg==} + cpu: [arm64] + os: [linux] + + '@libsql/linux-x64-gnu@0.5.29': + resolution: {integrity: sha512-y14V0vY0nmMC6G0pHeJcEarcnGU2H6cm21ZceRkacWHvQAEhAG0latQkCtoS2njFOXiYIg+JYPfAoWKbi82rkg==} + cpu: [x64] + os: [linux] + + '@libsql/linux-x64-musl@0.5.29': + resolution: {integrity: sha512-gquqwA/39tH4pFl+J9n3SOMSymjX+6kZ3kWgY3b94nXFTwac9bnFNMffIomgvlFaC4ArVqMnOZD3nuJ3H3VO1w==} + cpu: [x64] + os: [linux] + + '@libsql/win32-x64-msvc@0.5.29': + resolution: {integrity: sha512-4/0CvEdhi6+KjMxMaVbFM2n2Z44escBRoEYpR+gZg64DdetzGnYm8mcNLcoySaDJZNaBd6wz5DNdgRmcI4hXcg==} + cpu: [x64] + os: [win32] + '@loaderkit/resolve@1.0.4': resolution: {integrity: sha512-rJzYKVcV4dxJv+vW6jlvagF8zvGxHJ2+HTr1e2qOejfmGhAApgJHl8Aog4mMszxceTRiKTTbnpgmTO1bEZHV/A==} @@ -4498,6 +4631,18 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 + '@mastra/core@1.46.0': + resolution: {integrity: sha512-8w0O+7R9L125svWXHkTVLdHGjaWhvmJAJKfmvSLjgTfK0q0FZI29JlrCwcjqwY1kQTqb1yPzk6GJXh8xrJXiFA==} + engines: {node: '>=22.13.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + '@mastra/libsql@1.14.1': + resolution: {integrity: sha512-5BJ2mPFapxeve5NoUFQHpfGHThUMxBzUcSeDqp0oHkUeUwi35SOf1GagQnt+YoOolYWn9zpeIPhah7fxksoITg==} + engines: {node: '>=22.13.0'} + peerDependencies: + '@mastra/core': '>=1.42.1-0 <2.0.0-0' + '@mastra/schema-compat@1.2.6': resolution: {integrity: sha512-mmk1spyn/fi6n/rICeKXKRG8ZjrpUQbf/VESKjSVq+MtbZFDqzbNJ81HI/+dvr5rQf7wZEGrkubzEKSnWrZJ1g==} engines: {node: '>=22.13.0'} @@ -4510,6 +4655,12 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 + '@mastra/schema-compat@1.3.0': + resolution: {integrity: sha512-VAWCXGuWuTqnljkheb3zKUujNK6rdGhFISxdSoSz3/d3HJWZOHY10mUnXw5lg0s73FdFDGg4tehbq28fAZz+lA==} + engines: {node: '>=22.13.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + '@mdx-js/mdx@3.1.1': resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} @@ -4681,6 +4832,9 @@ packages: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 + '@neon-rs/load@0.0.4': + resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} + '@next/env@15.5.18': resolution: {integrity: sha512-hAV85Ckd9QR6RvH04MEKwsfLTksvFpO47j9xwtoIuvuPnlwecpSi+uZTtm8HirVbtlI2Fnz//xpcSTjFdyJk+g==} @@ -5783,9 +5937,15 @@ packages: '@posthog/core@1.29.9': resolution: {integrity: sha512-DjvuIyBZ2Z/gBhtZlITlM2D8PlnMsHSQ1D78dbUYoVsgGguvanpJTobZObjLlFkybyvfZFYkpoJkFNI/2Pw4IQ==} + '@posthog/core@1.37.1': + resolution: {integrity: sha512-KRBuxF/XBm3tNpqWlXpWE82XxsYsJb0jSyEic14LMXMvqDv5iApK1jfV0+seikDb9SpPs3tPkWUfHdwaUtFBtQ==} + '@posthog/types@1.376.0': resolution: {integrity: sha512-gbFfxCuZDs/D4QZMwdE+smD1jsuqgGpS6yKGHZZ19foxMy8RYHsU1E47iG1b88n/uN02fAabLibVwuxLtq8juw==} + '@posthog/types@1.391.0': + resolution: {integrity: sha512-oJ6jkqVMq+T4ax9F0rUllJc0KHpSgpaMwTNYWkE70iBiyXDVyhcNBmYnNKzSODgpzsaQNI6VfK8JrRYbkSJZZw==} + '@protobuf-ts/protoc@2.11.1': resolution: {integrity: sha512-mUZJaV0daGO6HUX90o/atzQ6A7bbN2RSuHtdwo8SSF2Qoe3zHwa4IHyCN1evftTeHfLmdz+45qo47sL+5P8nyg==} hasBin: true @@ -9104,6 +9264,9 @@ packages: '@types/validator@13.15.10': resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -9676,6 +9839,9 @@ packages: '@workflow/serde@4.1.0': resolution: {integrity: sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==} + '@workflow/serde@4.1.0-beta.2': + resolution: {integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==} + '@xmldom/xmldom@0.8.13': resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==} engines: {node: '>=10.0.0'} @@ -10250,10 +10416,6 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} - call-bind@1.0.9: resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} engines: {node: '>= 0.4'} @@ -10334,6 +10496,18 @@ packages: resolution: {integrity: sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==} engines: {pnpm: '>=8'} + chat@4.31.0: + resolution: {integrity: sha512-F6oJq9JUraLFkITS96/NKgwZwBfZX8aOwOj5qMs5NNwnOGHrSXZ5+osK+EA4HjzfyUEDfFTNiOSmyzgtFLpuWg==} + engines: {node: '>=20'} + peerDependencies: + ai: ^6.0.182 + zod: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + ai: + optional: true + zod: + optional: true + check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -11105,6 +11279,10 @@ packages: engines: {node: '>=0.10'} hasBin: true + detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + engines: {node: '>=8'} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -11906,6 +12084,9 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fault@1.0.4: resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} @@ -12436,10 +12617,6 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - hasown@2.0.3: resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} engines: {node: '>= 0.4'} @@ -13058,6 +13235,12 @@ packages: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} + jpeg-js@0.4.4: + resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} + + js-base64@3.7.8: + resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} + js-beautify@1.15.4: resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} engines: {node: '>=14'} @@ -13289,6 +13472,11 @@ packages: libphonenumber-js@1.13.3: resolution: {integrity: sha512-xMkdAMqcyG7iN2WZZmGIfWbYxW4orRkny+0/AXIbwL0xll2zkDX0Vzo/BXFa6+7mh2UvJl9MbcTtHk0YXkFtBA==} + libsql@0.5.29: + resolution: {integrity: sha512-8lMP8iMgiBzzoNbAPQ59qdVcj6UaE/Vnm+fiwX4doX4Narook0a4GPKWBEv+CR8a1OwbfkgL18uBfBjWdF0Fzg==} + cpu: [x64, arm64, wasm32, arm] + os: [darwin, linux, win32] + lighthouse-logger@1.4.2: resolution: {integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==} @@ -15090,6 +15278,15 @@ packages: posthog-js@1.376.0: resolution: {integrity: sha512-YGfQ6gSmqmEh287PHjXRDJ9zML3Su1UIt1+xjRy7Yk6yW43Sc7sFK3CpCkLchCGhIA4x6VaqK+LaqB+7+MCo7A==} + posthog-node@5.38.4: + resolution: {integrity: sha512-Jti056f+5C9y1MXb5yhxwwYBITxypWZHWcAp+UevcZ7/AKEQdSB9FiJP3WzEznw4vH3Bz0IlRKVgsofizRAoEA==} + engines: {node: ^20.20.0 || >=22.22.0} + peerDependencies: + rxjs: ^7.0.0 + peerDependenciesMeta: + rxjs: + optional: true + powershell-utils@0.1.0: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} @@ -15170,6 +15367,9 @@ packages: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} + promise-limit@2.7.0: + resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} + promise@7.3.1: resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} @@ -17747,6 +17947,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@a2a-js/sdk@0.3.13(@bufbuild/protobuf@2.12.0)(express@5.2.1)': + dependencies: + uuid: 11.1.1 + optionalDependencies: + '@bufbuild/protobuf': 2.12.0 + express: 5.2.1 + '@adobe/css-tools@4.4.3': {} '@ag-ui/client@0.0.46': @@ -17864,6 +18071,14 @@ snapshots: '@vercel/oidc': 3.2.0 zod: 4.3.6 + '@ai-sdk/gateway@3.0.120(zod@4.4.3)': + dependencies: + '@ai-sdk/provider': 3.0.10 + '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) + '@vercel/oidc': 3.2.0 + zod: 4.4.3 + optional: true + '@ai-sdk/gateway@4.0.0-beta.109(zod@4.4.3)': dependencies: '@ai-sdk/provider': 4.0.0-beta.19 @@ -17909,6 +18124,13 @@ snapshots: eventsource-parser: 3.0.8 zod: 4.3.6 + '@ai-sdk/provider-utils@3.0.25(zod@4.4.3)': + dependencies: + '@ai-sdk/provider': 2.0.3 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.0.8 + zod: 4.4.3 + '@ai-sdk/provider-utils@4.0.0(zod@4.3.6)': dependencies: '@ai-sdk/provider': 3.0.0 @@ -19435,11 +19657,6 @@ snapshots: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.8.1': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 @@ -20410,7 +20627,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.8.1 + '@emnapi/runtime': 1.11.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -20897,6 +21114,64 @@ snapshots: '@langchain/protocol@0.0.16': {} + '@libsql/client@0.17.4': + dependencies: + '@libsql/core': 0.17.4 + '@libsql/hrana-client': 0.10.0 + js-base64: 3.7.8 + libsql: 0.5.29 + promise-limit: 2.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/core@0.17.4': + dependencies: + js-base64: 3.7.8 + + '@libsql/darwin-arm64@0.5.29': + optional: true + + '@libsql/darwin-x64@0.5.29': + optional: true + + '@libsql/hrana-client@0.10.0': + dependencies: + '@libsql/isomorphic-ws': 0.1.5 + js-base64: 3.7.8 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/isomorphic-ws@0.1.5': + dependencies: + '@types/ws': 8.18.1 + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/linux-arm-gnueabihf@0.5.29': + optional: true + + '@libsql/linux-arm-musleabihf@0.5.29': + optional: true + + '@libsql/linux-arm64-gnu@0.5.29': + optional: true + + '@libsql/linux-arm64-musl@0.5.29': + optional: true + + '@libsql/linux-x64-gnu@0.5.29': + optional: true + + '@libsql/linux-x64-musl@0.5.29': + optional: true + + '@libsql/win32-x64-msvc@0.5.29': + optional: true + '@loaderkit/resolve@1.0.4': dependencies: '@braidai/lang': 1.1.2 @@ -21068,6 +21343,57 @@ snapshots: - supports-color - utf-8-validate + '@mastra/core@1.46.0(@bufbuild/protobuf@2.12.0)(@cfworker/json-schema@4.1.1)(ai@6.0.191(zod@4.4.3))(express@5.2.1)(rxjs@7.8.2)(zod@4.4.3)': + dependencies: + '@a2a-js/sdk': 0.3.13(@bufbuild/protobuf@2.12.0)(express@5.2.1) + '@ai-sdk/provider-utils-v5': '@ai-sdk/provider-utils@3.0.25(zod@4.4.3)' + '@ai-sdk/provider-utils-v6': '@ai-sdk/provider-utils@4.0.27(zod@4.4.3)' + '@ai-sdk/provider-v5': '@ai-sdk/provider@2.0.3' + '@ai-sdk/provider-v6': '@ai-sdk/provider@3.0.10' + '@isaacs/ttlcache': 2.1.5 + '@lukeed/uuid': 2.0.1 + '@mastra/schema-compat': 1.3.0(zod@4.4.3) + '@modelcontextprotocol/sdk': 1.29.0(@cfworker/json-schema@4.1.1)(zod@4.4.3) + '@sindresorhus/slugify': 2.2.1 + '@standard-schema/spec': 1.1.0 + ajv: 8.20.0 + chat: 4.31.0(ai@6.0.191(zod@4.4.3))(zod@4.4.3) + croner: 10.0.1 + dotenv: 17.4.2 + execa: 9.6.1 + fastq: 1.20.1 + gray-matter: 4.0.3 + ignore: 7.0.5 + jpeg-js: 0.4.4 + json-schema: 0.4.0 + lru-cache: 11.5.0 + p-map: 7.0.4 + p-retry: 7.1.1 + picomatch: 4.0.4 + posthog-node: 5.38.4(rxjs@7.8.2) + tokenx: 1.3.0 + ws: 8.21.0 + xxhash-wasm: 1.1.0 + zod: 4.4.3 + transitivePeerDependencies: + - '@bufbuild/protobuf' + - '@cfworker/json-schema' + - '@grpc/grpc-js' + - ai + - bufferutil + - express + - rxjs + - supports-color + - utf-8-validate + + '@mastra/libsql@1.14.1(@mastra/core@1.46.0(@bufbuild/protobuf@2.12.0)(@cfworker/json-schema@4.1.1)(ai@6.0.191(zod@4.4.3))(express@5.2.1)(rxjs@7.8.2)(zod@4.4.3))': + dependencies: + '@libsql/client': 0.17.4 + '@mastra/core': 1.46.0(@bufbuild/protobuf@2.12.0)(@cfworker/json-schema@4.1.1)(ai@6.0.191(zod@4.4.3))(express@5.2.1)(rxjs@7.8.2)(zod@4.4.3) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@mastra/schema-compat@1.2.6(zod@4.3.6)': dependencies: json-schema-to-zod: 2.8.0 @@ -21084,6 +21410,14 @@ snapshots: zod-from-json-schema-v3: zod-from-json-schema@0.0.5 zod-to-json-schema: 3.25.2(zod@4.3.6) + '@mastra/schema-compat@1.3.0(zod@4.4.3)': + dependencies: + json-schema-to-zod: 2.8.1 + zod: 4.4.3 + zod-from-json-schema: 0.5.2 + zod-from-json-schema-v3: zod-from-json-schema@0.0.5 + zod-to-json-schema: 3.25.2(zod@4.4.3) + '@mdx-js/mdx@3.1.1': dependencies: '@types/estree': 1.0.9 @@ -21204,7 +21538,6 @@ snapshots: '@cfworker/json-schema': 4.1.1 transitivePeerDependencies: - supports-color - optional: true '@mui/core-downloads-tracker@6.5.0': {} @@ -21362,6 +21695,13 @@ snapshots: '@tybys/wasm-util': 0.10.2 optional: true + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 + optional: true + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': dependencies: '@emnapi/core': 1.11.1 @@ -21369,6 +21709,8 @@ snapshots: '@tybys/wasm-util': 0.10.2 optional: true + '@neon-rs/load@0.0.4': {} + '@next/env@15.5.18': {} '@next/env@16.1.6': {} @@ -21648,7 +21990,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/nitro-server@3.21.6(db0@0.3.4)(ioredis@5.10.1)(magicast@0.5.2)(nuxt@3.21.6(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4)(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0))(oxc-parser@0.131.0)(rolldown@1.1.2)(srvx@0.11.16)(typescript@5.9.3)': + '@nuxt/nitro-server@3.21.6(@libsql/client@0.17.4)(db0@0.3.4(@libsql/client@0.17.4))(ioredis@5.10.1)(magicast@0.5.2)(nuxt@3.21.6(@libsql/client@0.17.4)(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4(@libsql/client@0.17.4))(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0))(oxc-parser@0.131.0)(rolldown@1.1.2)(srvx@0.11.16)(typescript@5.9.3)': dependencies: '@nuxt/devalue': 2.0.2 '@nuxt/kit': 3.21.6(magicast@0.5.2) @@ -21665,8 +22007,8 @@ snapshots: impound: 1.1.5 klona: 2.0.6 mocked-exports: 0.1.1 - nitropack: 2.13.4(oxc-parser@0.131.0)(rolldown@1.1.2)(srvx@0.11.16) - nuxt: 3.21.6(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4)(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0) + nitropack: 2.13.4(@libsql/client@0.17.4)(oxc-parser@0.131.0)(rolldown@1.1.2)(srvx@0.11.16) + nuxt: 3.21.6(@libsql/client@0.17.4)(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4(@libsql/client@0.17.4))(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0) ohash: 2.0.11 pathe: 2.0.3 pkg-types: 2.3.1 @@ -21674,7 +22016,7 @@ snapshots: std-env: 4.1.0 ufo: 1.6.4 unctx: 2.5.0 - unstorage: 1.17.5(db0@0.3.4)(ioredis@5.10.1) + unstorage: 1.17.5(db0@0.3.4(@libsql/client@0.17.4))(ioredis@5.10.1) vue: 3.5.34(typescript@5.9.3) vue-bundle-renderer: 2.2.0 vue-devtools-stub: 0.1.0 @@ -21733,7 +22075,7 @@ snapshots: rc9: 3.0.1 std-env: 4.1.0 - '@nuxt/vite-builder@3.21.6(@types/node@25.3.2)(eslint@9.29.0(jiti@2.7.0))(lightningcss@1.32.0)(magicast@0.5.2)(nuxt@3.21.6(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4)(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0))(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vue-tsc@2.2.12(typescript@5.9.3))(vue@3.5.34(typescript@5.9.3))(yaml@2.9.0)': + '@nuxt/vite-builder@3.21.6(@types/node@25.3.2)(eslint@9.29.0(jiti@2.7.0))(lightningcss@1.32.0)(magicast@0.5.2)(nuxt@3.21.6(@libsql/client@0.17.4)(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4(@libsql/client@0.17.4))(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0))(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vue-tsc@2.2.12(typescript@5.9.3))(vue@3.5.34(typescript@5.9.3))(yaml@2.9.0)': dependencies: '@nuxt/kit': 3.21.6(magicast@0.5.2) '@rollup/plugin-replace': 6.0.3(rollup@4.60.4) @@ -21752,7 +22094,7 @@ snapshots: magic-string: 0.30.21 mlly: 1.8.2 mocked-exports: 0.1.1 - nuxt: 3.21.6(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4)(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0) + nuxt: 3.21.6(@libsql/client@0.17.4)(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4(@libsql/client@0.17.4))(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0) nypm: 0.6.6 ohash: 2.0.11 pathe: 2.0.3 @@ -22454,8 +22796,14 @@ snapshots: dependencies: '@posthog/types': 1.376.0 + '@posthog/core@1.37.1': + dependencies: + '@posthog/types': 1.391.0 + '@posthog/types@1.376.0': {} + '@posthog/types@1.391.0': {} + '@protobuf-ts/protoc@2.11.1': {} '@protobufjs/aspromise@1.1.2': {} @@ -27189,6 +27537,10 @@ snapshots: '@types/validator@13.15.10': {} + '@types/ws@8.18.1': + dependencies: + '@types/node': 24.13.2 + '@types/yargs-parser@21.0.3': {} '@types/yargs@17.0.35': @@ -27397,7 +27749,7 @@ snapshots: dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': @@ -27435,12 +27787,12 @@ snapshots: dependencies: execa: 5.1.1 - '@vercel/connect@0.2.2(ai@7.0.0-beta.178(zod@4.4.3))(eve@0.11.7(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(ai@7.0.0-beta.178(zod@4.4.3))(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2))(react@19.2.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3)))': + '@vercel/connect@0.2.2(ai@7.0.0-beta.178(zod@4.4.3))(eve@0.11.7(@libsql/client@0.17.4)(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(ai@7.0.0-beta.178(zod@4.4.3))(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2))(react@19.2.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3)))': dependencies: '@vercel/oidc': 3.6.1 optionalDependencies: ai: 7.0.0-beta.178(zod@4.4.3) - eve: 0.11.7(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(ai@7.0.0-beta.178(zod@4.4.3))(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2))(react@19.2.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3)) + eve: 0.11.7(@libsql/client@0.17.4)(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(ai@7.0.0-beta.178(zod@4.4.3))(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2))(react@19.2.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3)) '@vercel/nft@1.5.0(rollup@4.60.4)': dependencies: @@ -27933,6 +28285,8 @@ snapshots: '@workflow/serde@4.1.0': {} + '@workflow/serde@4.1.0-beta.2': {} + '@xmldom/xmldom@0.8.13': {} '@xtuc/ieee754@1.2.0': {} @@ -27993,6 +28347,15 @@ snapshots: '@opentelemetry/api': 1.9.1 zod: 4.3.6 + ai@6.0.191(zod@4.4.3): + dependencies: + '@ai-sdk/gateway': 3.0.120(zod@4.4.3) + '@ai-sdk/provider': 3.0.10 + '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) + '@opentelemetry/api': 1.9.1 + zod: 4.4.3 + optional: true + ai@7.0.0-beta.178(zod@4.4.3): dependencies: '@ai-sdk/gateway': 4.0.0-beta.109(zod@4.4.3) @@ -28600,13 +28963,6 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - call-bind@1.0.8: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - call-bind@1.0.9: dependencies: call-bind-apply-helpers: 1.0.2 @@ -28682,6 +29038,21 @@ snapshots: dependencies: '@kurkle/color': 0.3.4 + chat@4.31.0(ai@6.0.191(zod@4.4.3))(zod@4.4.3): + dependencies: + '@workflow/serde': 4.1.0-beta.2 + mdast-util-to-string: 4.0.0 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + remend: 1.3.0 + unified: 11.0.5 + optionalDependencies: + ai: 6.0.191(zod@4.4.3) + zod: 4.4.3 + transitivePeerDependencies: + - supports-color + check-error@2.1.1: {} chevrotain@6.5.0: @@ -29351,7 +29722,9 @@ snapshots: dayjs@1.11.20: {} - db0@0.3.4: {} + db0@0.3.4(@libsql/client@0.17.4): + optionalDependencies: + '@libsql/client': 0.17.4 de-indent@1.0.2: {} @@ -29443,6 +29816,8 @@ snapshots: detect-libc@1.0.3: optional: true + detect-libc@2.0.2: {} + detect-libc@2.1.2: {} detect-node-es@1.1.0: {} @@ -29990,8 +30365,8 @@ snapshots: '@babel/parser': 7.29.7 eslint: 9.29.0(jiti@2.7.0) hermes-parser: 0.25.1 - zod: 4.3.6 - zod-validation-error: 4.0.2(zod@4.3.6) + zod: 4.4.3 + zod-validation-error: 4.0.2(zod@4.4.3) transitivePeerDependencies: - supports-color @@ -30165,14 +30540,14 @@ snapshots: etag@1.8.1: {} - eve@0.11.7(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(ai@7.0.0-beta.178(zod@4.4.3))(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2))(react@19.2.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3)): + eve@0.11.7(@libsql/client@0.17.4)(@opentelemetry/api@1.9.1)(@sveltejs/kit@2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(ai@7.0.0-beta.178(zod@4.4.3))(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2))(react@19.2.3)(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3)): dependencies: ai: 7.0.0-beta.178(zod@4.4.3) - nitro: 3.0.260610-beta(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)) + nitro: 3.0.260610-beta(@libsql/client@0.17.4)(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)) optionalDependencies: '@opentelemetry/api': 1.9.1 '@sveltejs/kit': 2.61.1(@opentelemetry/api@1.9.1)(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@5.9.3)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)) - next: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) + next: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2) react: 19.2.3 svelte: 5.55.9(@typescript-eslint/types@8.59.4) vite: 7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0) @@ -30577,6 +30952,10 @@ snapshots: dependencies: reusify: 1.1.0 + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + fault@1.0.4: dependencies: format: 0.2.2 @@ -30761,7 +31140,7 @@ snapshots: fsevents@2.3.3: optional: true - fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6): + fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6): dependencies: '@orama/orama': 3.1.18 estree-util-value-to-estree: 3.5.0 @@ -30787,21 +31166,21 @@ snapshots: '@types/mdast': 4.0.4 '@types/react': 19.2.14 lucide-react: 0.570.0(react@19.2.4) - next: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) + next: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) zod: 4.3.6 transitivePeerDependencies: - supports-color - fumadocs-mdx@14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.14)(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react@19.2.4)(vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)): + fumadocs-mdx@14.3.2(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.14)(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react@19.2.4)(vite@7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)): dependencies: '@mdx-js/mdx': 3.1.1 '@standard-schema/spec': 1.1.0 chokidar: 5.0.0 esbuild: 0.28.0 estree-util-value-to-estree: 3.5.0 - fumadocs-core: 16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6) + fumadocs-core: 16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6) js-yaml: 4.1.1 mdast-util-mdx: 3.0.0 mdast-util-to-markdown: 2.1.2 @@ -30813,18 +31192,18 @@ snapshots: unist-util-remove-position: 5.0.0 unist-util-visit: 5.1.0 vfile: 6.0.3 - zod: 4.3.6 + zod: 4.4.3 optionalDependencies: '@types/mdast': 4.0.4 '@types/mdx': 2.0.13 '@types/react': 19.2.14 - next: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) + next: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) react: 19.2.4 vite: 7.3.3(@types/node@22.19.19)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0) transitivePeerDependencies: - supports-color - fumadocs-ui@16.9.1(@emotion/is-prop-valid@1.4.0)(@tailwindcss/oxide@4.2.2)(@takumi-rs/image-response@0.68.17)(@types/mdx@2.0.13)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tailwindcss@4.2.1): + fumadocs-ui@16.9.1(@emotion/is-prop-valid@1.4.0)(@tailwindcss/oxide@4.2.2)(@takumi-rs/image-response@0.68.17)(@types/mdx@2.0.13)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(fumadocs-core@16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(tailwindcss@4.2.1): dependencies: '@fumadocs/tailwind': 0.0.5(@tailwindcss/oxide@4.2.2)(tailwindcss@4.2.1) '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -30838,7 +31217,7 @@ snapshots: '@radix-ui/react-slot': 1.2.4(@types/react@19.2.14)(react@19.2.4) '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) class-variance-authority: 0.7.1 - fumadocs-core: 16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6) + fumadocs-core: 16.9.1(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@0.570.0(react@19.2.4))(next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6) lucide-react: 1.16.0(react@19.2.4) motion: 12.40.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) next-themes: 0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -30854,7 +31233,7 @@ snapshots: '@takumi-rs/image-response': 0.68.17 '@types/mdx': 2.0.13 '@types/react': 19.2.14 - next: 16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) + next: 16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2) transitivePeerDependencies: - '@emotion/is-prop-valid' - '@tailwindcss/oxide' @@ -30918,7 +31297,7 @@ snapshots: get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.2 + hasown: 2.0.3 math-intrinsics: 1.1.0 get-nonce@1.0.1: {} @@ -30930,7 +31309,7 @@ snapshots: get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 + es-object-atoms: 1.1.2 get-stream@5.2.0: dependencies: @@ -31129,10 +31508,6 @@ snapshots: dependencies: has-symbols: 1.1.0 - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - hasown@2.0.3: dependencies: function-bind: 1.1.2 @@ -31675,7 +32050,7 @@ snapshots: call-bound: 1.0.4 gopd: 1.2.0 has-tostringtag: 1.0.2 - hasown: 2.0.2 + hasown: 2.0.3 is-set@2.0.3: {} @@ -31854,6 +32229,10 @@ snapshots: joycon@3.1.1: {} + jpeg-js@0.4.4: {} + + js-base64@3.7.8: {} + js-beautify@1.15.4: dependencies: config-chain: 1.1.13 @@ -32085,6 +32464,21 @@ snapshots: libphonenumber-js@1.13.3: {} + libsql@0.5.29: + dependencies: + '@neon-rs/load': 0.0.4 + detect-libc: 2.0.2 + optionalDependencies: + '@libsql/darwin-arm64': 0.5.29 + '@libsql/darwin-x64': 0.5.29 + '@libsql/linux-arm-gnueabihf': 0.5.29 + '@libsql/linux-arm-musleabihf': 0.5.29 + '@libsql/linux-arm64-gnu': 0.5.29 + '@libsql/linux-arm64-musl': 0.5.29 + '@libsql/linux-x64-gnu': 0.5.29 + '@libsql/linux-x64-musl': 0.5.29 + '@libsql/win32-x64-msvc': 0.5.29 + lighthouse-logger@1.4.2: dependencies: debug: 2.6.9 @@ -33404,7 +33798,7 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - next@15.5.18(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2): + next@15.5.18(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2): dependencies: '@next/env': 15.5.18 '@swc/helpers': 0.5.15 @@ -33412,7 +33806,7 @@ snapshots: postcss: 8.5.15 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.4) + styled-jsx: 5.1.6(react@19.2.4) optionalDependencies: '@next/swc-darwin-arm64': 15.5.18 '@next/swc-darwin-x64': 15.5.18 @@ -33430,7 +33824,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@16.1.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2): + next@16.1.6(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2): dependencies: '@next/env': 16.1.6 '@swc/helpers': 0.5.15 @@ -33439,7 +33833,7 @@ snapshots: postcss: 8.5.15 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - styled-jsx: 5.1.6(@babel/core@7.29.7)(babel-plugin-macros@3.1.0)(react@19.2.3) + styled-jsx: 5.1.6(babel-plugin-macros@3.1.0)(react@19.2.3) optionalDependencies: '@next/swc-darwin-arm64': 16.1.6 '@next/swc-darwin-x64': 16.1.6 @@ -33457,7 +33851,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2): + next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2): dependencies: '@next/env': 16.2.6 '@swc/helpers': 0.5.15 @@ -33466,7 +33860,7 @@ snapshots: postcss: 8.5.15 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - styled-jsx: 5.1.6(@babel/core@7.29.7)(babel-plugin-macros@3.1.0)(react@19.2.3) + styled-jsx: 5.1.6(babel-plugin-macros@3.1.0)(react@19.2.3) optionalDependencies: '@next/swc-darwin-arm64': 16.2.6 '@next/swc-darwin-x64': 16.2.6 @@ -33484,7 +33878,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@16.2.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2): + next@16.2.6(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.89.2): dependencies: '@next/env': 16.2.6 '@swc/helpers': 0.5.15 @@ -33493,7 +33887,7 @@ snapshots: postcss: 8.5.15 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.4) + styled-jsx: 5.1.6(react@19.2.4) optionalDependencies: '@next/swc-darwin-arm64': 16.2.6 '@next/swc-darwin-x64': 16.2.6 @@ -33511,7 +33905,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@16.2.7(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2): + next@16.2.7(@opentelemetry/api@1.9.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(sass@1.89.2): dependencies: '@next/env': 16.2.7 '@swc/helpers': 0.5.15 @@ -33520,7 +33914,7 @@ snapshots: postcss: 8.5.15 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) - styled-jsx: 5.1.6(@babel/core@7.29.7)(babel-plugin-macros@3.1.0)(react@19.2.3) + styled-jsx: 5.1.6(babel-plugin-macros@3.1.0)(react@19.2.3) optionalDependencies: '@next/swc-darwin-arm64': 16.2.7 '@next/swc-darwin-x64': 16.2.7 @@ -33540,11 +33934,11 @@ snapshots: nf3@0.3.17: {} - nitro@3.0.260610-beta(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)): + nitro@3.0.260610-beta(@libsql/client@0.17.4)(chokidar@5.0.0)(dotenv@17.4.2)(giget@3.2.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.5.0)(vite@7.3.3(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0)): dependencies: consola: 3.4.2 crossws: 0.4.6(srvx@0.11.16) - db0: 0.3.4 + db0: 0.3.4(@libsql/client@0.17.4) env-runner: 0.1.14 h3: 2.0.1-rc.22(crossws@0.4.6(srvx@0.11.16)) hookable: 6.1.1 @@ -33555,7 +33949,7 @@ snapshots: rolldown: 1.1.2 srvx: 0.11.16 unenv: 2.0.0-rc.24 - unstorage: 2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4)(ioredis@5.10.1)(lru-cache@11.5.0)(ofetch@2.0.0-alpha.3) + unstorage: 2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4(@libsql/client@0.17.4))(ioredis@5.10.1)(lru-cache@11.5.0)(ofetch@2.0.0-alpha.3) optionalDependencies: dotenv: 17.4.2 giget: 3.2.0 @@ -33593,7 +33987,7 @@ snapshots: - uploadthing - wrangler - nitropack@2.13.4(oxc-parser@0.131.0)(rolldown@1.1.2)(srvx@0.11.16): + nitropack@2.13.4(@libsql/client@0.17.4)(oxc-parser@0.131.0)(rolldown@1.1.2)(srvx@0.11.16): dependencies: '@cloudflare/kv-asset-handler': 0.4.2 '@rollup/plugin-alias': 6.0.0(rollup@4.60.4) @@ -33614,7 +34008,7 @@ snapshots: cookie-es: 2.0.1 croner: 10.0.1 crossws: 0.3.5 - db0: 0.3.4 + db0: 0.3.4(@libsql/client@0.17.4) defu: 6.1.7 destr: 2.0.5 dot-prop: 10.1.0 @@ -33660,7 +34054,7 @@ snapshots: unenv: 2.0.0-rc.24 unimport: 6.3.0(oxc-parser@0.131.0)(rolldown@1.1.2) unplugin-utils: 0.3.1 - unstorage: 1.17.5(db0@0.3.4)(ioredis@5.10.1) + unstorage: 1.17.5(db0@0.3.4(@libsql/client@0.17.4))(ioredis@5.10.1) untyped: 2.0.0 unwasm: 0.5.3 youch: 4.1.1 @@ -33778,16 +34172,16 @@ snapshots: dependencies: bignumber.js: 9.3.1 - nuxt@3.21.6(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4)(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0): + nuxt@3.21.6(@libsql/client@0.17.4)(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4(@libsql/client@0.17.4))(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0): dependencies: '@dxup/nuxt': 0.4.1(magicast@0.5.2)(typescript@5.9.3) '@nuxt/cli': 3.35.2(@nuxt/schema@3.21.6)(cac@6.7.14)(commander@13.1.0)(magicast@0.5.2) '@nuxt/devtools': 3.2.4(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue@3.5.34(typescript@5.9.3)) '@nuxt/kit': 3.21.6(magicast@0.5.2) - '@nuxt/nitro-server': 3.21.6(db0@0.3.4)(ioredis@5.10.1)(magicast@0.5.2)(nuxt@3.21.6(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4)(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0))(oxc-parser@0.131.0)(rolldown@1.1.2)(srvx@0.11.16)(typescript@5.9.3) + '@nuxt/nitro-server': 3.21.6(@libsql/client@0.17.4)(db0@0.3.4(@libsql/client@0.17.4))(ioredis@5.10.1)(magicast@0.5.2)(nuxt@3.21.6(@libsql/client@0.17.4)(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4(@libsql/client@0.17.4))(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0))(oxc-parser@0.131.0)(rolldown@1.1.2)(srvx@0.11.16)(typescript@5.9.3) '@nuxt/schema': 3.21.6 '@nuxt/telemetry': 2.8.0(@nuxt/kit@3.21.6(magicast@0.5.2)) - '@nuxt/vite-builder': 3.21.6(@types/node@25.3.2)(eslint@9.29.0(jiti@2.7.0))(lightningcss@1.32.0)(magicast@0.5.2)(nuxt@3.21.6(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4)(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0))(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vue-tsc@2.2.12(typescript@5.9.3))(vue@3.5.34(typescript@5.9.3))(yaml@2.9.0) + '@nuxt/vite-builder': 3.21.6(@types/node@25.3.2)(eslint@9.29.0(jiti@2.7.0))(lightningcss@1.32.0)(magicast@0.5.2)(nuxt@3.21.6(@libsql/client@0.17.4)(@parcel/watcher@2.5.6)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(commander@13.1.0)(db0@0.3.4(@libsql/client@0.17.4))(eslint@9.29.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(srvx@0.11.16)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.2)(jiti@2.7.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(yaml@2.9.0))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.9.0))(optionator@0.9.4)(rolldown@1.1.2)(rollup-plugin-visualizer@7.0.1(rolldown@1.1.2)(rollup@4.60.4))(rollup@4.60.4)(sass@1.89.2)(terser@5.48.0)(tsx@4.20.3)(typescript@5.9.3)(vue-tsc@2.2.12(typescript@5.9.3))(vue@3.5.34(typescript@5.9.3))(yaml@2.9.0) '@unhead/vue': 2.1.15(vue@3.5.34(typescript@5.9.3)) '@vue/shared': 3.5.34 c12: 3.3.4(magicast@0.5.2) @@ -34695,6 +35089,12 @@ snapshots: query-selector-shadow-dom: 1.0.1 web-vitals: 5.2.0 + posthog-node@5.38.4(rxjs@7.8.2): + dependencies: + '@posthog/core': 1.37.1 + optionalDependencies: + rxjs: 7.8.2 + powershell-utils@0.1.0: {} preact@10.29.2: {} @@ -34750,6 +35150,8 @@ snapshots: progress@2.0.3: {} + promise-limit@2.7.0: {} + promise@7.3.1: dependencies: asap: 2.0.6 @@ -36044,7 +36446,7 @@ snapshots: dependencies: '@img/colour': 1.0.0 detect-libc: 2.1.2 - semver: 7.7.4 + semver: 7.8.1 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 @@ -36409,20 +36811,17 @@ snapshots: dependencies: inline-style-parser: 0.2.4 - styled-jsx@5.1.6(@babel/core@7.29.7)(babel-plugin-macros@3.1.0)(react@19.2.3): + styled-jsx@5.1.6(babel-plugin-macros@3.1.0)(react@19.2.3): dependencies: client-only: 0.0.1 react: 19.2.3 optionalDependencies: - '@babel/core': 7.29.7 babel-plugin-macros: 3.1.0 - styled-jsx@5.1.6(@babel/core@7.29.7)(react@19.2.4): + styled-jsx@5.1.6(react@19.2.4): dependencies: client-only: 0.0.1 react: 19.2.4 - optionalDependencies: - '@babel/core': 7.29.7 stylehacks@7.0.11(postcss@8.5.15): dependencies: @@ -37135,7 +37534,7 @@ snapshots: optionalDependencies: synckit: 0.11.12 - unstorage@1.17.5(db0@0.3.4)(ioredis@5.10.1): + unstorage@1.17.5(db0@0.3.4(@libsql/client@0.17.4))(ioredis@5.10.1): dependencies: anymatch: 3.1.3 chokidar: 5.0.0 @@ -37146,13 +37545,13 @@ snapshots: ofetch: 1.5.1 ufo: 1.6.4 optionalDependencies: - db0: 0.3.4 + db0: 0.3.4(@libsql/client@0.17.4) ioredis: 5.10.1 - unstorage@2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4)(ioredis@5.10.1)(lru-cache@11.5.0)(ofetch@2.0.0-alpha.3): + unstorage@2.0.0-alpha.7(chokidar@5.0.0)(db0@0.3.4(@libsql/client@0.17.4))(ioredis@5.10.1)(lru-cache@11.5.0)(ofetch@2.0.0-alpha.3): optionalDependencies: chokidar: 5.0.0 - db0: 0.3.4 + db0: 0.3.4(@libsql/client@0.17.4) ioredis: 5.10.1 lru-cache: 11.5.0 ofetch: 2.0.0-alpha.3 @@ -37784,7 +38183,7 @@ snapshots: which-typed-array@1.1.19: dependencies: available-typed-arrays: 1.0.7 - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 for-each: 0.3.5 get-proto: 1.0.1 @@ -38014,9 +38413,9 @@ snapshots: dependencies: zod: 4.4.3 - zod-validation-error@4.0.2(zod@4.3.6): + zod-validation-error@4.0.2(zod@4.4.3): dependencies: - zod: 4.3.6 + zod: 4.4.3 zod@3.25.76: {}