diff --git a/examples/openui-tui-chat/README.md b/examples/openui-tui-chat/README.md
new file mode 100644
index 000000000..b637316d2
--- /dev/null
+++ b/examples/openui-tui-chat/README.md
@@ -0,0 +1,86 @@
+# OpenUI TUI Chat (Ink)
+
+A proof-of-concept **terminal** chat client that renders streamed **OpenUI Lang**
+as an interactive TUI, built with [Ink](https://github.com/vadimdemedes/ink)
+(React for the terminal).
+
+It demonstrates that OpenUI Lang is renderer-agnostic: the same language,
+prompt, parser, and headless chat runtime that power the browser SDK also drive
+a terminal UI — you just swap the view layer.
+
+```
+you ──▶ prompt
+ ──▶ OpenAI-compatible stream (react-headless)
+ ──▶ createStreamingParser().set(text) (lang-core, incremental)
+ ──▶ evaluateElementProps (lang-core runtime/store)
+ ──▶ Ink components (Card→box, BarChart→ASCII, Table→grid, Form→inputs)
+```
+
+## What it reuses
+
+- **`@openuidev/lang-core`** — `createStreamingParser`, `evaluateElementProps`, and the runtime store. No React/DOM.
+- **`@openuidev/react-headless`** — `ChatProvider` chat state + `openAIReadableStreamAdapter` streaming. DOM-free (Ink is React).
+- **New here** — an Ink component library (`src/genui/`) that maps `typeName → Ink component`, and a small tree walker (`RenderValue`) that mirrors react-lang's renderer.
+
+## Run
+
+Requires Node 20+ and an OpenAI-compatible key.
+
+```sh
+export OPENAI_API_KEY=sk-...
+# optional: export OPENAI_BASE_URL=... OPENAI_MODEL=...
+pnpm --filter openui-tui-chat dev
+```
+
+Then type a prompt, e.g. _"Compare the 4 largest countries by population as a bar chart"_
+or _"Build a contact form with name, email and a topic dropdown"_.
+
+### Controls
+
+- Type + **Enter** — send a message.
+- **Tab / Shift+Tab** — move focus between the composer and interactive UI (follow-ups, buttons, form fields).
+- **Enter** — activate the focused follow-up/button (also confirms the highlighted Select option).
+- **↑ / ↓** or **number keys** — choose an option in a focused Select; the highlighted option is selected immediately.
+- **Mouse click** — click a dropdown option to select it, a button/follow-up to activate it, or a text field to focus it (see caveats below).
+- **Ctrl+C** — quit.
+
+### Mouse support (form elements)
+
+Clicking targets the **latest** turn's interactive elements (dropdown options, buttons, follow-ups, text fields). It uses click-only SGR mouse tracking (`?1000`/`?1006`) enabled once at the root; clicks are hit-tested against the live region using Yoga layout offsets.
+
+Caveats (inherent to terminal mouse tracking + natural-height layout):
+
+- Hit-testing anchors to the bottom of the terminal (where the live region ends), so it's reliable for content that fills the screen — including a long form's visible fields. For a short exchange with empty space below, clicks may be slightly off; keyboard (Tab + number keys/arrows) is exact everywhere.
+- While mouse tracking is active, the terminal's native click-drag **text selection/copy is disabled** (hold Shift in most terminals to bypass and select text).
+- Run the app **directly in a terminal** so it receives mouse events; through tmux you must `set -g mouse on` (otherwise tmux captures the mouse). Keyboard is the fully-portable path.
+
+## Supported components
+
+`Card`, `CardHeader`, `TextContent`, `Callout` (colored banner), `TagBlock` (colored pills),
+`Table`/`Col`, `BarChart`/`Series` (gradient bars), `FollowUpBlock`/`FollowUpItem`,
+`Form`/`FormControl`/`Input`/`Select`/`Buttons`/`Button`.
+
+Headings, chart bars and the header use a truecolor gradient; `ink-spinner` shows while
+streaming and `ink-big-text` renders the welcome logo. Follow-ups, buttons and form submits
+drive the assistant loop via the OpenUI `@ToAssistant` action.
+
+## Test
+
+```sh
+pnpm --filter openui-tui-chat test # vitest + ink-testing-library
+pnpm --filter openui-tui-chat typecheck
+```
+
+## Chat UI
+
+- A gradient header, a welcome splash (big-text logo) with example prompts, and a bordered composer with key hints.
+- The current exchange renders at **natural height**. Content taller than the terminal (e.g. a long form) scrolls in the terminal's native scrollback rather than corrupting the layout — the composer stays intact and the app never "breaks". Short exchanges stay compact.
+- User messages render as bubbles; the assistant turn renders as generative UI with an animated spinner while streaming.
+
+## Limitations (POC)
+
+- Read-oriented charts/tables render as ASCII; not pixel-faithful.
+- On a form taller than the screen, upper fields scroll out of view — reach them with keyboard focus (Tab) or by scrolling the terminal; mouse clicks target the visible (on-screen) fields.
+- Mouse hit-testing is best-effort for short exchanges (see caveats above); keyboard works everywhere.
+- Only the current exchange is shown; there is no in-app multi-turn history log.
+- Queries/`$state` two-way binding beyond simple form fields are out of scope for v1.
diff --git a/examples/openui-tui-chat/package.json b/examples/openui-tui-chat/package.json
new file mode 100644
index 000000000..bc19fb89e
--- /dev/null
+++ b/examples/openui-tui-chat/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "openui-tui-chat",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "description": "A terminal (Ink/TUI) chat client that renders streamed OpenUI Lang as an interactive terminal UI.",
+ "bin": {
+ "openui-tui-chat": "src/cli.tsx"
+ },
+ "scripts": {
+ "dev": "tsx src/cli.tsx",
+ "start": "tsx src/cli.tsx",
+ "test": "vitest run",
+ "typecheck": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@openuidev/lang-core": "workspace:*",
+ "@openuidev/react-headless": "workspace:*",
+ "ink": "^5.1.0",
+ "ink-big-text": "^2.0.0",
+ "ink-spinner": "^5.0.0",
+ "openai": "^6.22.0",
+ "react": "^18.3.1",
+ "zod": "^4.3.6",
+ "zustand": "^4.5.5"
+ },
+ "devDependencies": {
+ "@types/node": "^20",
+ "@types/react": "^19",
+ "ink-testing-library": "^4.0.0",
+ "tsx": "^4.19.2",
+ "typescript": "^5.9.3",
+ "vitest": "^4.0.18"
+ }
+}
diff --git a/examples/openui-tui-chat/src/__tests__/genui.test.tsx b/examples/openui-tui-chat/src/__tests__/genui.test.tsx
new file mode 100644
index 000000000..fa716d2d1
--- /dev/null
+++ b/examples/openui-tui-chat/src/__tests__/genui.test.tsx
@@ -0,0 +1,253 @@
+import {
+ createStore,
+ createStreamingParser,
+ evaluateElementProps,
+} from "@openuidev/lang-core";
+import { render } from "ink-testing-library";
+import { createElement, type ReactNode } from "react";
+import { describe, expect, it } from "vitest";
+import { RenderValue } from "../genui/components.js";
+import { TuiProvider, type TuiContextValue } from "../genui/context.js";
+import { tuiLibrary } from "../genui/library.js";
+import { useGenUi } from "../genui/state.js";
+
+const delay = (ms: number) => new Promise((r) => setTimeout(r, ms));
+
+// Strip ANSI SGR codes so assertions match text even when it's colored/gradient
+// (gradient text inserts a color code between every character).
+// eslint-disable-next-line no-control-regex
+const plain = (s: string | undefined) => (s ?? "").replace(/\u001B\[[0-9;]*m/g, "");
+
+/** Parse + evaluate an OpenUI Lang program with the TUI library. */
+function evalProgram(src: string) {
+ const sp = createStreamingParser(tuiLibrary.toJSONSchema(), tuiLibrary.root);
+ const pr = sp.set(src);
+ const store = createStore();
+ store.initialize(pr.stateDeclarations ?? {}, {});
+ const root = pr.root
+ ? evaluateElementProps(pr.root, {
+ ctx: { getState: (n) => store.get(n), resolveRef: () => undefined },
+ library: tuiLibrary,
+ store,
+ errors: [],
+ })
+ : null;
+ return root;
+}
+
+const noopCtx: TuiContextValue = {
+ library: tuiLibrary,
+ interactive: true,
+ triggerAction: () => {},
+ getFieldValue: () => undefined,
+ setFieldValue: () => {},
+};
+
+/** Drives the real state hook (parse → evaluate → action loop), no LLM/react-headless. */
+function Harness({ src, onSend }: { src: string; onSend: (c: string) => void }): ReactNode {
+ const { result, ctx } = useGenUi(tuiLibrary, "m1", src, false, onSend);
+ return createElement(
+ TuiProvider,
+ { value: ctx },
+ result?.root ? createElement(RenderValue, { value: result.root }) : null,
+ );
+}
+
+describe("TUI renderer", () => {
+ it("renders header, bar chart and table from streamed OpenUI Lang", () => {
+ const src = [
+ "root = Card([h, chart, tbl])",
+ 'h = CardHeader("Setup Status", "All green")',
+ 'chart = BarChart(["lang-core", "react-headless"], [s1], "Package", "Tests")',
+ 's1 = Series("Tests", [68, 70])',
+ "tbl = Table([c1, c2])",
+ 'c1 = Col("Step", ["install", "build"])',
+ 'c2 = Col("Result", ["ok", "ok"])',
+ ].join("\n");
+
+ const root = evalProgram(src);
+ const { lastFrame } = render(
+ createElement(TuiProvider, { value: noopCtx }, createElement(RenderValue, { value: root })),
+ );
+
+ const frame = plain(lastFrame());
+ expect(frame).toContain("Setup Status");
+ expect(frame).toContain("All green");
+ expect(frame).toContain("█"); // chart bars
+ expect(frame).toContain("Step"); // table header
+ expect(frame).toContain("install"); // table cell
+ expect(frame).toContain("react-headless");
+ });
+
+ it("renders rich Callout and TagBlock components", () => {
+ const src = [
+ "root = Card([c, tags])",
+ 'c = Callout("success", "All set", "Your Pro plan is active")',
+ 'tags = TagBlock(["Pro", "Fast", "New"])',
+ ].join("\n");
+ const root = evalProgram(src);
+ const { lastFrame } = render(
+ createElement(TuiProvider, { value: noopCtx }, createElement(RenderValue, { value: root })),
+ );
+ const frame = plain(lastFrame());
+ expect(frame).toContain("All set");
+ expect(frame).toContain("Your Pro plan is active");
+ expect(frame).toContain("Pro");
+ expect(frame).toContain("Fast");
+ expect(frame).toContain("New");
+ });
+
+ it("renders unknown components as a visible marker instead of crashing", () => {
+ const root = evalProgram('root = Card([x])\nx = TextContent("hello world")');
+ const { lastFrame } = render(
+ createElement(TuiProvider, { value: noopCtx }, createElement(RenderValue, { value: root })),
+ );
+ expect(plain(lastFrame())).toContain("hello world");
+ });
+
+ it("renders finalized turns display-only (buttons are not interactive)", () => {
+ const root = evalProgram(
+ 'root = Card([btns])\nbtns = Buttons([b1])\nb1 = Button("Retry", Action([@ToAssistant("retry")]))',
+ );
+ const staticCtx: TuiContextValue = { ...noopCtx, interactive: false };
+ const { lastFrame } = render(
+ createElement(TuiProvider, { value: staticCtx }, createElement(RenderValue, { value: root })),
+ );
+ expect(plain(lastFrame())).toContain("[ Retry ]");
+ });
+});
+
+describe("TUI interactivity", () => {
+ it("sends a follow-up's text to the assistant on Enter", async () => {
+ const sent: string[] = [];
+ const src = [
+ "root = Card([fu])",
+ "fu = FollowUpBlock([f1])",
+ 'f1 = FollowUpItem("Show this as a table")',
+ ].join("\n");
+
+ const { stdin } = render(createElement(Harness, { src, onSend: (c) => sent.push(c) }));
+ await delay(30);
+ stdin.write("\t"); // focus the follow-up
+ await delay(30);
+ stdin.write("\r"); // activate it
+ await delay(30);
+
+ expect(sent).toContain("Show this as a table");
+ });
+
+ it("shows a Select choice immediately after Enter (no extra keypress needed)", async () => {
+ const src = [
+ "root = Card([form])",
+ 'form = Form("f", btns, [topicField])',
+ 'topicField = FormControl("Topic", topic)',
+ 'topic = Select("topic", [o1, o2])',
+ 'o1 = SelectItem("sales", "Sales")',
+ 'o2 = SelectItem("support", "Support")',
+ "btns = Buttons([submit])",
+ 'submit = Button("Send", Action([@ToAssistant("go")]))',
+ ].join("\n");
+
+ const { stdin, lastFrame } = render(createElement(Harness, { src, onSend: () => {} }));
+ await delay(40);
+ stdin.write("\t"); // focus the Select (first focusable)
+ await delay(30);
+ stdin.write("\u001B[B"); // Down arrow → move cursor to Support
+ await delay(30);
+ stdin.write("\r"); // Enter → select Support
+ await delay(40);
+
+ const frame = plain(lastFrame());
+ expect(frame).toContain("(•) 2. Support");
+ expect(frame).not.toContain("(•) 1. Sales");
+ });
+
+ it("selects a Select option by number key (no cursor movement)", async () => {
+ const src = [
+ "root = Card([form])",
+ 'form = Form("f", btns, [topicField])',
+ 'topicField = FormControl("Topic", topic)',
+ 'topic = Select("topic", [o1, o2])',
+ 'o1 = SelectItem("sales", "Sales")',
+ 'o2 = SelectItem("support", "Support")',
+ "btns = Buttons([submit])",
+ 'submit = Button("Send")',
+ ].join("\n");
+ const { stdin, lastFrame } = render(createElement(Harness, { src, onSend: () => {} }));
+ await delay(40);
+ stdin.write("\t"); // focus the Select
+ await delay(30);
+ stdin.write("2"); // press "2" → pick the 2nd option directly
+ await delay(40);
+ const frame = plain(lastFrame());
+ expect(frame).toContain("(•) 2. Support");
+ expect(frame).not.toContain("(•) 1. Sales");
+ });
+
+ it("selects a Select option immediately on arrow (no Enter needed)", async () => {
+ const src = [
+ "root = Card([form])",
+ 'form = Form("f", btns, [topicField])',
+ 'topicField = FormControl("Topic", topic)',
+ 'topic = Select("topic", [o1, o2])',
+ 'o1 = SelectItem("sales", "Sales")',
+ 'o2 = SelectItem("support", "Support")',
+ "btns = Buttons([submit])",
+ 'submit = Button("Send")',
+ ].join("\n");
+ const { stdin, lastFrame } = render(createElement(Harness, { src, onSend: () => {} }));
+ await delay(40);
+ stdin.write("\t"); // focus the Select
+ await delay(30);
+ stdin.write("\u001B[B"); // Down arrow only — should select immediately
+ await delay(40);
+ expect(plain(lastFrame())).toContain("(•) 2. Support");
+ });
+
+ it("shows typed Input text immediately", async () => {
+ const src = [
+ "root = Card([form])",
+ 'form = Form("f", btns, [nameField])',
+ 'nameField = FormControl("Name", nameInput)',
+ 'nameInput = Input("name", "Your name")',
+ "btns = Buttons([submit])",
+ 'submit = Button("Send")',
+ ].join("\n");
+ const { stdin, lastFrame } = render(createElement(Harness, { src, onSend: () => {} }));
+ await delay(40);
+ stdin.write("\t");
+ await delay(30);
+ stdin.write("Hi");
+ await delay(40);
+ expect(plain(lastFrame())).toContain("Hi");
+ });
+
+ it("collects form field values and submits them via the button's action", async () => {
+ const sent: string[] = [];
+ const src = [
+ "root = Card([form])",
+ "form = Form(\"contact\", btns, [nameField])",
+ 'nameField = FormControl("Name", nameInput)',
+ 'nameInput = Input("name", "Your name")',
+ "btns = Buttons([submit])",
+ 'submit = Button("Send", Action([@ToAssistant("Contact submitted")]))',
+ ].join("\n");
+
+ const { stdin } = render(createElement(Harness, { src, onSend: (c) => sent.push(c) }));
+ await delay(30);
+ stdin.write("\t"); // focus the name input
+ await delay(20);
+ for (const ch of "Ada") {
+ stdin.write(ch);
+ await delay(5);
+ }
+ stdin.write("\t"); // focus the submit button
+ await delay(20);
+ stdin.write("\r"); // submit
+ await delay(30);
+
+ expect(sent.length).toBe(1);
+ expect(sent[0]).toContain("Contact submitted");
+ expect(sent[0]).toContain('"name":"Ada"');
+ });
+});
diff --git a/examples/openui-tui-chat/src/app.tsx b/examples/openui-tui-chat/src/app.tsx
new file mode 100644
index 000000000..d8e9372a0
--- /dev/null
+++ b/examples/openui-tui-chat/src/app.tsx
@@ -0,0 +1,180 @@
+import type { Message } from "@openuidev/react-headless";
+import BigText from "ink-big-text";
+import Spinner from "ink-spinner";
+import { Box, Text, useFocus, useInput, type DOMElement } from "ink";
+import { useRef, useState } from "react";
+import { useLocalChat, type ProcessFn } from "./chat.js";
+import { RenderValue } from "./genui/components.js";
+import { TuiProvider } from "./genui/context.js";
+import { GradientText } from "./genui/gradient.js";
+import { tuiLibrary } from "./genui/library.js";
+import { isTypedText, MouseProvider } from "./genui/mouse.js";
+import { useGenUi } from "./genui/state.js";
+
+function messageText(content: unknown): string {
+ if (typeof content === "string") return content;
+ if (Array.isArray(content)) {
+ return content
+ .map((p) => (p && typeof p === "object" && "text" in p ? String((p as { text: unknown }).text) : ""))
+ .join("");
+ }
+ return "";
+}
+
+const firstLine = (s: string) => s.split("\n")[0] ?? "";
+
+// ─────────────────────────── chrome ───────────────────────────
+
+function Header() {
+ return (
+
+
+ {" generative UI, streamed into your terminal"}
+
+ );
+}
+
+function Welcome() {
+ return (
+
+
+ Ask for UI and it renders live, right here in your terminal. Try:
+ · Compare the 4 largest countries by population as a bar chart
+ · Build a contact form with a name field and a topic dropdown
+ · A pricing callout with tags for a Pro plan
+
+ );
+}
+
+function UserBubble({ text }: { text: string }) {
+ return (
+
+
+ {text}
+
+
+ );
+}
+
+function Thinking() {
+ return (
+
+
+
+
+
+
+ );
+}
+
+function Composer({
+ draft,
+ focused,
+ isRunning,
+}: {
+ draft: string;
+ focused: boolean;
+ isRunning: boolean;
+}) {
+ return (
+
+
+ {"❯ "}
+ {draft}
+ {focused ? ▏ : null}
+ {draft.length === 0 ? (
+ {isRunning ? "waiting for response…" : "Message OpenUI…"}
+ ) : null}
+
+ {" Enter send · Tab/click focus · ↑↓ or number keys choose · Ctrl+C quit"}
+
+ );
+}
+
+// ─────────────────────────── assistant message ───────────────────────────
+
+function AssistantMessageView({
+ message,
+ isStreaming,
+ onSend,
+}: {
+ message: Message;
+ isStreaming: boolean;
+ onSend: (content: string) => void;
+}) {
+ const content = messageText(message.content);
+ const { result, ctx } = useGenUi(tuiLibrary, message.id, content, isStreaming, onSend, true);
+
+ if (!result?.root) {
+ if (isStreaming) return null;
+ return (
+
+ {content ? content : "(no renderable UI)"}
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
+ );
+}
+
+// ─────────────────────────── app ───────────────────────────
+
+export function App({ processMessage }: { processMessage: ProcessFn }) {
+ const { messages, isRunning, send } = useLocalChat(processMessage);
+ const [draft, setDraft] = useState("");
+ const dynamicRef = useRef(null);
+
+ const { isFocused: composerFocused } = useFocus({ id: "composer", autoFocus: true });
+ useInput(
+ (input, key) => {
+ if (key.return) {
+ const text = draft.trim();
+ if (text && !isRunning) {
+ send(text);
+ setDraft("");
+ }
+ return;
+ }
+ if (key.backspace || key.delete) {
+ setDraft((d) => d.slice(0, -1));
+ return;
+ }
+ if (isTypedText(input) && !key.ctrl && !key.meta) {
+ setDraft((d) => d + input);
+ }
+ },
+ { isActive: composerFocused },
+ );
+
+ const last = messages[messages.length - 1];
+ const liveAssistant = last && last.role === "assistant" ? last : null;
+ const liveContent = liveAssistant ? messageText(liveAssistant.content) : "";
+ const showThinking = isRunning && liveContent.trim() === "";
+ const lastUser = [...messages].reverse().find((m) => m.role === "user") ?? null;
+
+ // Natural-height frame (no fixed height): the current exchange renders at its
+ // true size. Content taller than the terminal scrolls natively instead of
+ // corrupting the layout, so a long form never breaks. Mouse hit-testing tracks
+ // the region via a cursor-position query (see mouse.tsx).
+ return (
+
+
+
+ {messages.length === 0 ? : null}
+ {lastUser ? : null}
+ {liveAssistant ? (
+
+ ) : null}
+ {showThinking ? : null}
+
+
+
+ );
+}
diff --git a/examples/openui-tui-chat/src/chat.ts b/examples/openui-tui-chat/src/chat.ts
new file mode 100644
index 000000000..8d735134c
--- /dev/null
+++ b/examples/openui-tui-chat/src/chat.ts
@@ -0,0 +1,77 @@
+import {
+ openAIReadableStreamAdapter,
+ processStreamedMessage,
+ type AssistantMessage,
+ type Message,
+} from "@openuidev/react-headless";
+import { useCallback, useRef, useState } from "react";
+
+export type ProcessFn = (params: {
+ threadId: string;
+ messages: Message[];
+ abortController: AbortController;
+}) => Promise;
+
+export interface LocalChat {
+ messages: Message[];
+ isRunning: boolean;
+ send: (content: string) => void;
+}
+
+/**
+ * Minimal chat store that runs on the SAME React instance Ink uses. It reuses
+ * react-headless's DOM-free streaming pipeline (`processStreamedMessage` +
+ * `openAIReadableStreamAdapter`) without its React `ChatProvider`, which would
+ * otherwise pull in a second React copy and break Ink's reconciler.
+ */
+export function useLocalChat(processMessage: ProcessFn): LocalChat {
+ const [messages, setMessages] = useState([]);
+ const [isRunning, setIsRunning] = useState(false);
+ const messagesRef = useRef([]);
+ messagesRef.current = messages;
+ const runningRef = useRef(false);
+
+ const send = useCallback(
+ async (content: string) => {
+ if (!content.trim() || runningRef.current) return;
+ runningRef.current = true;
+
+ const userMessage = {
+ id: crypto.randomUUID(),
+ role: "user",
+ content,
+ } as unknown as Message;
+
+ const next = [...messagesRef.current, userMessage];
+ setMessages(next);
+ setIsRunning(true);
+
+ const abortController = new AbortController();
+ try {
+ const response = await processMessage({ threadId: "tui", messages: next, abortController });
+ await processStreamedMessage({
+ response,
+ adapter: openAIReadableStreamAdapter(),
+ createMessage: (m: AssistantMessage) => setMessages((cur) => [...cur, m]),
+ updateMessage: (m: AssistantMessage) =>
+ setMessages((cur) => cur.map((x) => (x.id === m.id ? { ...m } : x))),
+ deleteMessage: (id: string) => setMessages((cur) => cur.filter((x) => x.id !== id)),
+ });
+ } catch (e) {
+ const message = e instanceof Error ? e.message : String(e);
+ const errorMessage = {
+ id: crypto.randomUUID(),
+ role: "assistant",
+ content: `root = Card([e])\ne = TextContent("Error: ${message.replace(/"/g, "'")}")`,
+ } as unknown as Message;
+ setMessages((cur) => [...cur, errorMessage]);
+ } finally {
+ runningRef.current = false;
+ setIsRunning(false);
+ }
+ },
+ [processMessage],
+ );
+
+ return { messages, isRunning, send };
+}
diff --git a/examples/openui-tui-chat/src/cli.tsx b/examples/openui-tui-chat/src/cli.tsx
new file mode 100644
index 000000000..26042c436
--- /dev/null
+++ b/examples/openui-tui-chat/src/cli.tsx
@@ -0,0 +1,27 @@
+// Polyfill requestAnimationFrame for react-headless's streaming updates (it
+// debounces message updates via rAF, which bare Node does not provide).
+const g = globalThis as unknown as {
+ requestAnimationFrame?: (cb: (t: number) => void) => unknown;
+ cancelAnimationFrame?: (id: unknown) => void;
+};
+if (typeof g.requestAnimationFrame !== "function") {
+ g.requestAnimationFrame = (cb) => setTimeout(() => cb(Date.now()), 16);
+ g.cancelAnimationFrame = (id) => clearTimeout(id as ReturnType);
+}
+
+import { render } from "ink";
+import { createElement } from "react";
+import { App } from "./app.js";
+import { tuiLibrary } from "./genui/library.js";
+import { makeProcessMessage } from "./llm.js";
+
+if (!process.env.OPENAI_API_KEY) {
+ console.error(
+ "\nOPENAI_API_KEY is not set. Export it (optionally OPENAI_BASE_URL / OPENAI_MODEL) and retry.\n",
+ );
+ process.exit(1);
+}
+
+const systemPrompt = tuiLibrary.prompt();
+
+render(createElement(App, { processMessage: makeProcessMessage(systemPrompt) }));
diff --git a/examples/openui-tui-chat/src/genui/chart.ts b/examples/openui-tui-chat/src/genui/chart.ts
new file mode 100644
index 000000000..38276e4d9
--- /dev/null
+++ b/examples/openui-tui-chat/src/genui/chart.ts
@@ -0,0 +1,44 @@
+/** Element-node shape after evaluation (only the bits the chart needs). */
+interface SeriesNode {
+ props?: { category?: unknown; values?: unknown };
+}
+
+function padEnd(s: string, w: number): string {
+ return s.length >= w ? s : s + " ".repeat(w - s.length);
+}
+
+/**
+ * Render a horizontal ASCII bar chart. Single-series charts show one bar per
+ * label; multi-series charts show one bar per (label, series) pair.
+ */
+export function renderBars(
+ labels: string[],
+ seriesNodes: SeriesNode[],
+ width = 32,
+): string[] {
+ const series = seriesNodes.map((s) => ({
+ category: String(s?.props?.category ?? ""),
+ values: Array.isArray(s?.props?.values) ? (s!.props!.values as unknown[]).map(Number) : [],
+ }));
+
+ const rows: { name: string; value: number }[] = [];
+ labels.forEach((label, i) => {
+ series.forEach((s) => {
+ rows.push({
+ name: series.length > 1 ? `${label} · ${s.category}` : label,
+ value: Number.isFinite(s.values[i]) ? s.values[i]! : 0,
+ });
+ });
+ });
+
+ if (rows.length === 0) return ["(no data)"];
+
+ const max = Math.max(1, ...rows.map((r) => Math.abs(r.value)));
+ const nameW = Math.max(0, ...rows.map((r) => r.name.length));
+
+ return rows.map((r) => {
+ const barLen = Math.max(0, Math.round((Math.abs(r.value) / max) * width));
+ const bar = "█".repeat(barLen) || "▏";
+ return `${padEnd(r.name, nameW)} │ ${bar} ${r.value}`;
+ });
+}
diff --git a/examples/openui-tui-chat/src/genui/components.tsx b/examples/openui-tui-chat/src/genui/components.tsx
new file mode 100644
index 000000000..d80a29355
--- /dev/null
+++ b/examples/openui-tui-chat/src/genui/components.tsx
@@ -0,0 +1,471 @@
+import { Box, Text, useFocus, useFocusManager, useInput } from "ink";
+import { Component, Fragment, type ReactNode, useState } from "react";
+import { renderBars } from "./chart.js";
+import { FormNameProvider, useFormName, useTui } from "./context.js";
+import { GradientText } from "./gradient.js";
+import { Clickable, isTypedText } from "./mouse.js";
+
+/** The render contract each library component receives (matches lang-core's ComponentRenderProps). */
+interface ViewProps {
+ props: Record;
+ renderNode: (value: unknown) => ReactNode;
+ statementId?: string;
+}
+
+/** Common signature for every library view (keeps the library's component type uniform). */
+export type View = (p: ViewProps) => ReactNode;
+
+const str = (v: unknown): string => (v == null ? "" : String(v));
+
+// ─────────────────────────── tree walker ───────────────────────────
+
+/** Walk any evaluated value into Ink nodes (mirrors react-lang's renderDeep). */
+export function RenderValue({ value }: { value: unknown }): ReactNode {
+ if (value == null || value === false) return null;
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
+ return {String(value)};
+ }
+ if (Array.isArray(value)) {
+ return (
+ <>
+ {value.map((v, i) => (
+
+
+
+ ))}
+ >
+ );
+ }
+ if (typeof value === "object" && (value as { type?: string }).type === "element") {
+ return ;
+ }
+ return null;
+}
+
+interface ElementLike {
+ type: "element";
+ typeName: string;
+ props: Record;
+ statementId?: string;
+}
+
+function RenderNode({ node }: { node: ElementLike }): ReactNode {
+ const { library } = useTui();
+ const Comp = library.components[node.typeName]?.component as
+ | ((p: ViewProps) => ReactNode)
+ | undefined;
+
+ if (!Comp) return [unknown component: {node.typeName}];
+
+ return (
+
+ }
+ statementId={node.statementId}
+ />
+
+ );
+}
+
+class ElementErrorBoundary extends Component<
+ { name: string; children: ReactNode },
+ { failed: boolean }
+> {
+ state = { failed: false };
+ static getDerivedStateFromError() {
+ return { failed: true };
+ }
+ render() {
+ if (this.state.failed) {
+ return [render error in {this.props.name}];
+ }
+ return this.props.children;
+ }
+}
+
+// ─────────────────────────── content components ───────────────────────────
+
+function CardView({ props, renderNode }: ViewProps) {
+ const children = Array.isArray(props.children) ? props.children : [];
+ return (
+
+ {children.map((c, i) => (
+
+ {renderNode(c)}
+
+ ))}
+
+ );
+}
+
+function CardHeaderView({ props }: ViewProps) {
+ return (
+
+ {props.title ? : null}
+ {props.subtitle ? {str(props.subtitle)} : null}
+
+ );
+}
+
+function TextContentView({ props }: ViewProps) {
+ const size = str(props.size);
+ const heavy = size.includes("heavy");
+ const large = size === "large" || size === "large-heavy";
+ const text = str(props.text);
+ // Headline-sized text gets a gradient for a richer look.
+ if (large) {
+ return ;
+ }
+ return (
+
+ {text}
+
+ );
+}
+
+const CALLOUT_STYLES: Record = {
+ info: { color: "cyan", icon: "ℹ" },
+ success: { color: "green", icon: "✓" },
+ warning: { color: "yellow", icon: "⚠" },
+ error: { color: "red", icon: "✕" },
+ neutral: { color: "gray", icon: "•" },
+};
+
+function CalloutView({ props }: ViewProps) {
+ const variant = str(props.variant) || "info";
+ const style = CALLOUT_STYLES[variant] ?? CALLOUT_STYLES.info!;
+ return (
+
+
+
+ {style.icon} {str(props.title)}
+
+
+ {props.description ? {str(props.description)} : null}
+
+ );
+}
+
+const TAG_COLORS = ["cyan", "magenta", "green", "yellow", "blue", "red"] as const;
+
+function TagBlockView({ props }: ViewProps) {
+ const tags = Array.isArray(props.tags) ? props.tags.map(str) : [];
+ return (
+
+ {tags.map((t, i) => (
+
+ {` ${t} `}
+
+ ))}
+
+ );
+}
+
+function TableView({ props }: ViewProps) {
+ const columns = Array.isArray(props.columns) ? props.columns : [];
+ const headers = columns.map((c) => str((c as ElementLike)?.props?.label));
+ const data = columns.map((c) => {
+ const d = (c as ElementLike)?.props?.data;
+ return Array.isArray(d) ? d.map((x) => str(x)) : [];
+ });
+ const rowCount = Math.max(0, ...data.map((d) => d.length));
+ const widths = headers.map((h, ci) =>
+ Math.max(h.length, ...(data[ci]!.length ? data[ci]!.map((s) => s.length) : [0])),
+ );
+ const pad = (s: string, w: number) => (s.length >= w ? s : s + " ".repeat(w - s.length));
+ const line = (cells: string[]) => cells.map((c, ci) => pad(c, widths[ci]!)).join(" ");
+
+ return (
+
+ {line(headers)}
+ {widths.map((w) => "─".repeat(w)).join(" ")}
+ {Array.from({ length: rowCount }).map((_, ri) => (
+ {line(headers.map((_, ci) => data[ci]![ri] ?? ""))}
+ ))}
+
+ );
+}
+
+function BarChartView({ props }: ViewProps) {
+ const labels = Array.isArray(props.labels) ? props.labels.map(str) : [];
+ const series = Array.isArray(props.series) ? (props.series as { props?: Record }[]) : [];
+ const lines = renderBars(labels, series);
+ return (
+
+ {props.yLabel ? {str(props.yLabel)} : null}
+ {lines.map((ln, i) => (
+
+ ))}
+ {props.xLabel ? {str(props.xLabel)} : null}
+
+ );
+}
+
+// ─────────────────────────── interactive components ───────────────────────────
+
+function FollowUpBlockView({ props, renderNode }: ViewProps) {
+ const items = Array.isArray(props.items) ? props.items : [];
+ return (
+
+ Related (Tab to focus, Enter to ask):
+ {items.map((it, i) => (
+ {renderNode(it)}
+ ))}
+
+ );
+}
+
+function FollowUpItemView({ props }: ViewProps) {
+ const { interactive } = useTui();
+ const text = str(props.text);
+ return interactive ? (
+
+ ) : (
+ {"• "}{text}
+ );
+}
+
+function FollowUpItemInteractive({ text }: { text: string }) {
+ const { isFocused } = useFocus();
+ const { triggerAction } = useTui();
+ useInput(
+ (_input, key) => {
+ if (key.return) triggerAction(text);
+ },
+ { isActive: isFocused },
+ );
+ return (
+ triggerAction(text)}>
+
+ {isFocused ? "❯ " : "• "}
+ {text}
+
+
+ );
+}
+
+function ButtonsView({ props, renderNode }: ViewProps) {
+ const buttons = Array.isArray(props.buttons) ? props.buttons : [];
+ const direction = props.direction === "column" ? "column" : "row";
+ return (
+
+ {buttons.map((b, i) => (
+ {renderNode(b)}
+ ))}
+
+ );
+}
+
+function ButtonView({ props }: ViewProps) {
+ const { interactive } = useTui();
+ const label = str(props.label) || "Button";
+ return interactive ? (
+
+ ) : (
+ {`[ ${label} ]`}
+ );
+}
+
+function ButtonInteractive({ label, action }: { label: string; action: unknown }) {
+ const { isFocused } = useFocus();
+ const formName = useFormName();
+ const { triggerAction } = useTui();
+ useInput(
+ (_input, key) => {
+ if (key.return) triggerAction(label, formName, action);
+ },
+ { isActive: isFocused },
+ );
+ return (
+ triggerAction(label, formName, action)}>
+
+ {` ${label} `}
+
+
+ );
+}
+
+function FormView({ props, renderNode }: ViewProps) {
+ const name = str(props.name) || "form";
+ const fields = Array.isArray(props.fields) ? props.fields : [];
+ return (
+
+
+ Tab between fields · type to fill · number keys or ↑↓ to choose · Enter on a button to submit
+ {fields.map((f, i) => (
+ {renderNode(f)}
+ ))}
+ {renderNode(props.buttons)}
+
+
+ );
+}
+
+function FormControlView({ props, renderNode }: ViewProps) {
+ return (
+
+ {str(props.label)}
+ {props.hint ? {str(props.hint)} : null}
+ {renderNode(props.input)}
+
+ );
+}
+
+function InputView({ props }: ViewProps) {
+ const { interactive } = useTui();
+ if (!interactive) {
+ return (
+
+ {" "}
+ {str(props.placeholder) || str(props.name)}
+
+ );
+ }
+ return ;
+}
+
+function InputInteractive({ props }: { props: Record }) {
+ const formName = useFormName();
+ const { getFieldValue, setFieldValue } = useTui();
+ const name = str(props.name);
+ const focusId = `input:${formName ?? ""}:${name}`;
+ const { isFocused } = useFocus({ id: focusId });
+ const { focus } = useFocusManager();
+ const value = str(getFieldValue(formName, name));
+ useInput(
+ (input, key) => {
+ if (key.backspace || key.delete) {
+ setFieldValue(formName, "Input", name, value.slice(0, -1));
+ return;
+ }
+ if (key.return || key.tab || key.upArrow || key.downArrow || key.leftArrow || key.rightArrow)
+ return;
+ // Accept printable text; drop mouse escape sequences that share stdin.
+ if (isTypedText(input) && !key.ctrl && !key.meta) {
+ setFieldValue(formName, "Input", name, value + input);
+ }
+ },
+ { isActive: isFocused },
+ );
+ const shown = value.length ? value : str(props.placeholder);
+ return (
+ focus(focusId)}>
+
+ {isFocused ? "❯ " : " "}
+ {shown}
+ {isFocused ? "▏" : ""}
+
+
+ );
+}
+
+function SelectView({ props }: ViewProps) {
+ const { interactive } = useTui();
+ const items = Array.isArray(props.items) ? props.items : [];
+ if (!interactive) {
+ return (
+
+ {items.map((it, i) => (
+
+ {" ( ) "}
+ {str((it as ElementLike)?.props?.label ?? (it as ElementLike)?.props?.value)}
+
+ ))}
+
+ );
+ }
+ return ;
+}
+
+function SelectInteractive({ props }: { props: Record }) {
+ const { isFocused } = useFocus();
+ const formName = useFormName();
+ const { getFieldValue, setFieldValue } = useTui();
+ const name = str(props.name);
+ const items = Array.isArray(props.items) ? props.items : [];
+ const options = items.map((it) => ({
+ value: str((it as ElementLike)?.props?.value),
+ label: str((it as ElementLike)?.props?.label ?? (it as ElementLike)?.props?.value),
+ }));
+ const current = str(getFieldValue(formName, name));
+ const initialIndex = Math.max(
+ 0,
+ options.findIndex((o) => o.value === current),
+ );
+ const [cursor, setCursor] = useState(initialIndex);
+ // Bumped on every choice so the row re-renders immediately, even when the
+ // cursor index is unchanged (e.g. pressing Enter) where a store-only update
+ // may not repaint on the next frame.
+ const [, bump] = useState(0);
+
+ // Arrow keys select immediately (radio-group behaviour) for instant feedback;
+ // Enter also confirms the current row.
+ const choose = (index: number) => {
+ const clamped = Math.max(0, Math.min(options.length - 1, index));
+ const option = options[clamped];
+ setCursor(clamped);
+ bump((n) => n + 1);
+ if (option) setFieldValue(formName, "Select", name, option.value);
+ };
+
+ useInput(
+ (input, key) => {
+ // Number keys pick an option directly — no cursor movement needed.
+ if (/^[1-9]$/.test(input) && !key.ctrl && !key.meta) {
+ const index = Number(input) - 1;
+ if (index < options.length) choose(index);
+ return;
+ }
+ if (key.upArrow) choose(cursor - 1);
+ else if (key.downArrow) choose(cursor + 1);
+ else if (key.return) choose(cursor);
+ },
+ { isActive: isFocused },
+ );
+
+ return (
+
+ {options.map((o, i) => {
+ const isSel = o.value === current;
+ const isCursor = isFocused && i === cursor;
+ return (
+ choose(i)}>
+
+ {isCursor ? "❯ " : " "}
+ {isSel ? "(•) " : "( ) "}
+ {i + 1}. {o.label}
+
+
+ );
+ })}
+ {isFocused ? click, press 1-{options.length}, or ↑↓ to choose : null}
+
+ );
+}
+
+/** No-op view for purely structural nodes (parent reads their props directly). */
+function StructuralView(_props: ViewProps): ReactNode {
+ return null;
+}
+
+export const views: Record = {
+ Card: CardView,
+ CardHeader: CardHeaderView,
+ TextContent: TextContentView,
+ Callout: CalloutView,
+ TagBlock: TagBlockView,
+ Table: TableView,
+ Col: StructuralView,
+ BarChart: BarChartView,
+ Series: StructuralView,
+ FollowUpBlock: FollowUpBlockView,
+ FollowUpItem: FollowUpItemView,
+ Form: FormView,
+ FormControl: FormControlView,
+ Input: InputView,
+ Select: SelectView,
+ SelectItem: StructuralView,
+ Buttons: ButtonsView,
+ Button: ButtonView,
+};
diff --git a/examples/openui-tui-chat/src/genui/context.tsx b/examples/openui-tui-chat/src/genui/context.tsx
new file mode 100644
index 000000000..ebe44174d
--- /dev/null
+++ b/examples/openui-tui-chat/src/genui/context.tsx
@@ -0,0 +1,46 @@
+import type { Library } from "@openuidev/lang-core";
+import { createContext, useContext } from "react";
+
+/**
+ * Everything the Ink component library needs at render time. Mirrors the role
+ * of react-lang's OpenUIContext, but scoped to what a terminal renderer uses.
+ */
+export interface TuiContextValue {
+ library: Library;
+ /** When false, components render display-only (no focus/keyboard) — used for finalized turns. */
+ interactive: boolean;
+ /** Fire an action (button / follow-up / form submit) → sends a message to the assistant. */
+ triggerAction: (
+ userMessage: string,
+ formName?: string,
+ action?: unknown,
+ ) => void;
+ /** Read a form field value (unwrapped) from the runtime store. */
+ getFieldValue: (formName: string | undefined, name: string) => unknown;
+ /** Write a form field value into the runtime store. */
+ setFieldValue: (
+ formName: string | undefined,
+ componentType: string,
+ name: string,
+ value: unknown,
+ ) => void;
+}
+
+const TuiContext = createContext(null);
+
+export const TuiProvider = TuiContext.Provider;
+
+export function useTui(): TuiContextValue {
+ const ctx = useContext(TuiContext);
+ if (!ctx) throw new Error("useTui must be used within a TuiProvider");
+ return ctx;
+}
+
+/** The name of the enclosing Form, so inputs know where to store their value. */
+const FormNameContext = createContext(undefined);
+
+export const FormNameProvider = FormNameContext.Provider;
+
+export function useFormName(): string | undefined {
+ return useContext(FormNameContext);
+}
diff --git a/examples/openui-tui-chat/src/genui/gradient.tsx b/examples/openui-tui-chat/src/genui/gradient.tsx
new file mode 100644
index 000000000..c53fc2036
--- /dev/null
+++ b/examples/openui-tui-chat/src/genui/gradient.tsx
@@ -0,0 +1,56 @@
+import { Text } from "ink";
+
+type RGB = [number, number, number];
+
+// Two-stop gradient presets (start → end).
+const PRESETS: Record = {
+ mind: [
+ [0, 224, 255],
+ [180, 90, 255],
+ ], // cyan → violet
+ pastel: [
+ [255, 140, 200],
+ [255, 214, 120],
+ ], // pink → gold
+ ocean: [
+ [0, 170, 255],
+ [0, 255, 190],
+ ], // blue → aqua
+};
+
+function toHex([r, g, b]: RGB): string {
+ const h = (v: number) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, "0");
+ return `#${h(r)}${h(g)}${h(b)}`;
+}
+
+function lerp(a: RGB, b: RGB, t: number): RGB {
+ return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
+}
+
+/**
+ * Gradient text using Ink's own truecolor support — one per
+ * character. Reliable (no external gradient dep) and degrades to plain text on
+ * terminals without color.
+ */
+export function GradientText({
+ text,
+ preset = "mind",
+ bold,
+}: {
+ text: string;
+ preset?: keyof typeof PRESETS | string;
+ bold?: boolean;
+}) {
+ const [from, to] = PRESETS[preset] ?? PRESETS.mind!;
+ const chars = [...text];
+ const n = Math.max(1, chars.length - 1);
+ return (
+
+ {chars.map((ch, i) => (
+
+ {ch}
+
+ ))}
+
+ );
+}
diff --git a/examples/openui-tui-chat/src/genui/library.ts b/examples/openui-tui-chat/src/genui/library.ts
new file mode 100644
index 000000000..ee541b6c4
--- /dev/null
+++ b/examples/openui-tui-chat/src/genui/library.ts
@@ -0,0 +1,196 @@
+import { createLibrary, defineComponent } from "@openuidev/lang-core";
+import { z } from "zod";
+import { views } from "./components.js";
+
+// Leaf / structural components first so containers can reference `.ref`.
+
+const Series = defineComponent({
+ name: "Series",
+ description: "One data series for a chart.",
+ props: z.object({ category: z.string(), values: z.array(z.number()) }),
+ component: views.Series,
+});
+
+const Col = defineComponent({
+ name: "Col",
+ description: "A table column: a label plus its column data (one entry per row).",
+ props: z.object({
+ label: z.string(),
+ data: z.array(z.union([z.string(), z.number()])),
+ type: z.enum(["string", "number"]).optional(),
+ }),
+ component: views.Col,
+});
+
+const SelectItem = defineComponent({
+ name: "SelectItem",
+ description: "An option inside a Select.",
+ props: z.object({ value: z.string(), label: z.string() }),
+ component: views.SelectItem,
+});
+
+const FollowUpItem = defineComponent({
+ name: "FollowUpItem",
+ description: "A clickable follow-up suggestion. Its text is sent to the assistant when chosen.",
+ props: z.object({ text: z.string() }),
+ component: views.FollowUpItem,
+});
+
+const Button = defineComponent({
+ name: "Button",
+ description:
+ "A clickable button. Provide an action Action([@ToAssistant(\"message\")]) to control what is sent to the assistant.",
+ props: z.object({
+ label: z.string(),
+ action: z.any().optional(),
+ variant: z.enum(["primary", "secondary", "tertiary"]).optional(),
+ }),
+ component: views.Button,
+});
+
+const Input = defineComponent({
+ name: "Input",
+ description: "A single-line text field inside a Form.",
+ props: z.object({
+ name: z.string(),
+ placeholder: z.string().optional(),
+ type: z.enum(["text", "email", "password", "number", "url"]).optional(),
+ }),
+ component: views.Input,
+});
+
+const Select = defineComponent({
+ name: "Select",
+ description: "A single-choice dropdown inside a Form.",
+ props: z.object({
+ name: z.string(),
+ items: z.array(SelectItem.ref),
+ placeholder: z.string().optional(),
+ }),
+ component: views.Select,
+});
+
+const FormControl = defineComponent({
+ name: "FormControl",
+ description: "A labelled form field wrapping one Input or Select.",
+ props: z.object({
+ label: z.string(),
+ input: z.union([Input.ref, Select.ref]),
+ hint: z.string().optional(),
+ }),
+ component: views.FormControl,
+});
+
+const Buttons = defineComponent({
+ name: "Buttons",
+ description: "A group of Button components.",
+ props: z.object({
+ buttons: z.array(Button.ref),
+ direction: z.enum(["row", "column"]).optional(),
+ }),
+ component: views.Buttons,
+});
+
+const Form = defineComponent({
+ name: "Form",
+ description: "A form with fields and explicit action buttons. Provide Buttons(...) as the second argument.",
+ props: z.object({
+ name: z.string(),
+ buttons: Buttons.ref,
+ fields: z.array(FormControl.ref).default([]),
+ }),
+ component: views.Form,
+});
+
+const BarChart = defineComponent({
+ name: "BarChart",
+ description: "A bar chart. Use for comparing values across categories.",
+ props: z.object({
+ labels: z.array(z.string()),
+ series: z.array(Series.ref),
+ xLabel: z.string().optional(),
+ yLabel: z.string().optional(),
+ }),
+ component: views.BarChart,
+});
+
+const Table = defineComponent({
+ name: "Table",
+ description: "A column-oriented data table. Each Col holds its own data array.",
+ props: z.object({ columns: z.array(Col.ref) }),
+ component: views.Table,
+});
+
+const TextContent = defineComponent({
+ name: "TextContent",
+ description: "A block of text. Optional size controls emphasis.",
+ props: z.object({
+ text: z.string(),
+ size: z.enum(["small", "default", "large", "small-heavy", "large-heavy"]).optional(),
+ }),
+ component: views.TextContent,
+});
+
+const CardHeader = defineComponent({
+ name: "CardHeader",
+ description: "A header with an optional title and subtitle.",
+ props: z.object({ title: z.string().optional(), subtitle: z.string().optional() }),
+ component: views.CardHeader,
+});
+
+const Callout = defineComponent({
+ name: "Callout",
+ description:
+ "A colored callout banner for highlights, tips, or status. Choose a variant that matches the tone.",
+ props: z.object({
+ variant: z.enum(["info", "success", "warning", "error", "neutral"]),
+ title: z.string(),
+ description: z.string().optional(),
+ }),
+ component: views.Callout,
+});
+
+const TagBlock = defineComponent({
+ name: "TagBlock",
+ description: "A row of short colored tags/pills (keywords, categories, or labels).",
+ props: z.object({ tags: z.array(z.string()) }),
+ component: views.TagBlock,
+});
+
+const FollowUpBlock = defineComponent({
+ name: "FollowUpBlock",
+ description: "A list of follow-up suggestions shown at the end of a response.",
+ props: z.object({ items: z.array(FollowUpItem.ref) }),
+ component: views.FollowUpBlock,
+});
+
+const Card = defineComponent({
+ name: "Card",
+ description: "The root container. Children stack vertically. Every response is a single Card.",
+ props: z.object({ children: z.array(z.any()) }),
+ component: views.Card,
+});
+
+export const tuiLibrary = createLibrary({
+ components: [
+ Card,
+ CardHeader,
+ TextContent,
+ Callout,
+ TagBlock,
+ Table,
+ Col,
+ BarChart,
+ Series,
+ FollowUpBlock,
+ FollowUpItem,
+ Form,
+ FormControl,
+ Input,
+ Select,
+ SelectItem,
+ Buttons,
+ Button,
+ ],
+ root: "Card",
+});
diff --git a/examples/openui-tui-chat/src/genui/mouse.tsx b/examples/openui-tui-chat/src/genui/mouse.tsx
new file mode 100644
index 000000000..ceaed788e
--- /dev/null
+++ b/examples/openui-tui-chat/src/genui/mouse.tsx
@@ -0,0 +1,170 @@
+import { appendFileSync } from "node:fs";
+import { Box, measureElement, useStdin, useStdout, type DOMElement } from "ink";
+import {
+ createContext,
+ useCallback,
+ useContext,
+ useEffect,
+ useRef,
+ type ReactNode,
+ type RefObject,
+} from "react";
+
+// Click-only SGR mouse tracking (?1000) + SGR extended coords (?1006). We use
+// click-only (not all-motion ?1003) to avoid flooding stdin on every move.
+const SGR_ENABLE = "\u001B[?1000h\u001B[?1006h";
+const SGR_DISABLE = "\u001B[?1000l\u001B[?1006l";
+// Press events end with "M"; release with "m". We only act on press.
+const PRESS_RE = /\u001B\[<(\d+);(\d+);(\d+)M/g;
+
+const DEBUG = process.env.TUI_MOUSE_DEBUG === "1";
+
+interface Zone {
+ ref: RefObject;
+ onClick: () => void;
+}
+
+interface MouseContextValue {
+ register: (zone: Zone) => () => void;
+}
+
+const MouseContext = createContext(null);
+
+/** Position of a node relative to `rootNode`, by summing Yoga offsets up the tree. */
+function positionRelativeTo(node: DOMElement, rootNode: DOMElement | null) {
+ const yoga = (node as unknown as { yogaNode?: any }).yogaNode;
+ const rootYoga = (rootNode as unknown as { yogaNode?: any } | null)?.yogaNode;
+ if (!yoga) return null;
+ let left = 0;
+ let top = 0;
+ let current: any = yoga;
+ while (current && current !== rootYoga) {
+ left += current.getComputedLeft?.() ?? 0;
+ top += current.getComputedTop?.() ?? 0;
+ current = current.getParent?.();
+ }
+ return {
+ left,
+ top,
+ width: yoga.getComputedWidth?.() ?? 0,
+ height: yoga.getComputedHeight?.() ?? 0,
+ };
+}
+
+/**
+ * Enables click-only mouse tracking once, parses press events from stdin, and
+ * dispatches to the topmost registered zone. `rootRef` must point at the
+ * bottom-anchored dynamic region so we can map absolute screen rows to it.
+ */
+export function MouseProvider({
+ rootRef,
+ children,
+}: {
+ rootRef: RefObject;
+ children: ReactNode;
+}) {
+ const { stdin, setRawMode, isRawModeSupported } = useStdin();
+ const { stdout } = useStdout();
+ const zones = useRef>(new Set());
+
+ const register = useCallback((zone: Zone) => {
+ zones.current.add(zone);
+ return () => {
+ zones.current.delete(zone);
+ };
+ }, []);
+
+ useEffect(() => {
+ if (!stdin || !isRawModeSupported) return;
+ setRawMode(true);
+ stdout.write(SGR_ENABLE);
+
+ const dispatch = (cx: number, cy: number) => {
+ const rows = stdout.rows ?? 24;
+ const height = rootRef.current ? measureElement(rootRef.current).height : 0;
+ // The live region's last line (composer) sits at the bottom of the terminal
+ // output, so its top screen row is (rows - height). This is correct once the
+ // content fills the screen (including long forms); for a short exchange it's
+ // approximate, so keyboard remains the exact path there.
+ const offsetY = height > 0 ? rows - height : 0;
+
+ let hit: Zone | null = null;
+ let hitInfo = "miss";
+ for (const zone of zones.current) {
+ const node = zone.ref.current;
+ if (!node) continue;
+ const p = positionRelativeTo(node, rootRef.current);
+ if (!p) continue;
+ const top = p.top + offsetY;
+ if (DEBUG) hitInfo += ` | zone[l${p.left},t${top},w${p.width},h${p.height}]`;
+ if (cx >= p.left && cx < p.left + p.width && cy >= top && cy < top + p.height) {
+ hit = zone;
+ hitInfo = `hit@[l${p.left},t${top},w${p.width},h${p.height}]`;
+ break;
+ }
+ }
+
+ if (DEBUG) {
+ try {
+ appendFileSync("/tmp/mouse-debug.log", `click(${cx},${cy}) rows=${rows} offY=${offsetY} ${hitInfo}\n`);
+ } catch {
+ // ignore
+ }
+ }
+ if (hit) hit.onClick();
+ };
+
+ const onData = (data: Buffer) => {
+ const s = data.toString("utf8");
+ PRESS_RE.lastIndex = 0;
+ let m: RegExpExecArray | null;
+ while ((m = PRESS_RE.exec(s)) !== null) {
+ const cb = Number(m[1]);
+ if ((cb & 3) !== 0 || (cb & 64) !== 0) continue; // left-button presses only
+ dispatch(Number(m[2]) - 1, Number(m[3]) - 1);
+ }
+ };
+
+ stdin.on("data", onData);
+ const cleanupOnExit = () => stdout.write(SGR_DISABLE);
+ process.once("exit", cleanupOnExit);
+
+ return () => {
+ stdin.off("data", onData);
+ stdout.write(SGR_DISABLE);
+ process.off("exit", cleanupOnExit);
+ };
+ }, [stdin, setRawMode, isRawModeSupported, stdout, rootRef]);
+
+ return {children};
+}
+
+/**
+ * True for ordinary typed text; false for escape/control/mouse sequences that
+ * land on the same stdin when mouse tracking is enabled.
+ */
+export function isTypedText(input: string): boolean {
+ if (!input) return false;
+ // eslint-disable-next-line no-control-regex
+ if (/[\u0000-\u001f]/.test(input)) return false; // control chars incl. ESC
+ if (input.includes("[<")) return false; // SGR mouse marker (ESC already stripped)
+ return true;
+}
+
+/** Register a click zone for the given ref. No-op when there is no MouseProvider. */
+export function useClickable(ref: RefObject, onClick: () => void) {
+ const ctx = useContext(MouseContext);
+ const cbRef = useRef(onClick);
+ cbRef.current = onClick;
+ useEffect(() => {
+ if (!ctx) return;
+ return ctx.register({ ref, onClick: () => cbRef.current() });
+ }, [ctx, ref]);
+}
+
+/** Wrap children in a Box that fires `onClick` when clicked (mouse). */
+export function Clickable({ onClick, children }: { onClick: () => void; children: ReactNode }) {
+ const ref = useRef(null);
+ useClickable(ref, onClick);
+ return {children};
+}
diff --git a/examples/openui-tui-chat/src/genui/state.tsx b/examples/openui-tui-chat/src/genui/state.tsx
new file mode 100644
index 000000000..73d19bb92
--- /dev/null
+++ b/examples/openui-tui-chat/src/genui/state.tsx
@@ -0,0 +1,151 @@
+import {
+ createStore,
+ createStreamingParser,
+ evaluateElementProps,
+ type EvaluationContext,
+ type Library,
+ type ParseResult,
+ type Store,
+} from "@openuidev/lang-core";
+import { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from "react";
+import type { TuiContextValue } from "./context.js";
+
+/** Unwrap the { value, componentType } wrapper the store keeps for form fields. */
+function unwrap(v: unknown): unknown {
+ if (v && typeof v === "object" && !Array.isArray(v) && "value" in (v as Record)) {
+ return (v as Record).value;
+ }
+ return v;
+}
+
+export interface GenUiState {
+ /** Evaluated parse result (props resolved to concrete values). */
+ result: ParseResult | null;
+ ctx: TuiContextValue;
+}
+
+/**
+ * Trimmed, terminal-oriented port of react-lang's useOpenUIState: streaming
+ * parse → runtime store → evaluate props → action/field helpers. No queries or
+ * DOM. `messageId` scopes the parser to a single assistant turn.
+ */
+export function useGenUi(
+ library: Library,
+ messageId: string | null,
+ response: string | null,
+ isStreaming: boolean,
+ onSend: (content: string) => void,
+ interactive = true,
+): GenUiState {
+ const onSendRef = useRef(onSend);
+ onSendRef.current = onSend;
+
+ // Fresh streaming parser per assistant turn (set() resets on replacement anyway).
+ const sp = useMemo(
+ () => createStreamingParser(library.toJSONSchema(), library.root),
+ [library, messageId],
+ );
+
+ const parseResult = useMemo(() => {
+ if (!response) return null;
+ try {
+ return sp.set(response);
+ } catch {
+ return null;
+ }
+ }, [sp, response]);
+
+ const store = useMemo(() => createStore(), [messageId]);
+
+ useEffect(() => {
+ store.initialize(parseResult?.stateDeclarations ?? {}, {});
+ }, [parseResult?.stateDeclarations, store]);
+
+ const snapshot = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
+
+ const evaluationContext = useMemo(
+ () => ({
+ getState: (name: string) => unwrap(store.get(name)),
+ resolveRef: () => undefined,
+ }),
+ [store],
+ );
+
+ const result = useMemo(() => {
+ if (!parseResult?.root) return parseResult;
+ try {
+ const root = evaluateElementProps(parseResult.root, {
+ ctx: evaluationContext,
+ library,
+ store,
+ errors: [],
+ });
+ return { ...parseResult, root };
+ } catch {
+ return parseResult;
+ }
+ // snapshot is a dependency so form edits re-evaluate reactive props.
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [parseResult, evaluationContext, library, store, snapshot]);
+
+ const getFieldValue = useCallback(
+ (formName, name) => {
+ if (!formName) return unwrap(store.get(name));
+ const formData = store.get(formName);
+ if (!formData || typeof formData !== "object" || Array.isArray(formData)) return undefined;
+ return unwrap((formData as Record)[name]);
+ },
+ [store],
+ );
+
+ const setFieldValue = useCallback(
+ (formName, componentType, name, value) => {
+ const wrapped = { value, componentType };
+ if (!formName) {
+ store.set(name, wrapped);
+ return;
+ }
+ const raw = store.get(formName);
+ const formData =
+ raw && typeof raw === "object" && !Array.isArray(raw) ? (raw as Record) : {};
+ store.set(formName, { ...formData, [name]: wrapped });
+ },
+ [store],
+ );
+
+ const triggerAction = useCallback(
+ (userMessage, formName, action) => {
+ let message = userMessage;
+ const steps =
+ action && typeof action === "object" && Array.isArray((action as { steps?: unknown }).steps)
+ ? ((action as { steps: { type?: string; message?: string }[] }).steps)
+ : null;
+ if (steps) {
+ const toAssistant = steps.find((s) => s?.type === "continue_conversation" || typeof s?.message === "string");
+ if (toAssistant?.message) message = toAssistant.message;
+ }
+
+ let content = message;
+ if (formName) {
+ const raw = store.get(formName);
+ const values: Record = {};
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
+ for (const [k, v] of Object.entries(raw as Record)) values[k] = unwrap(v);
+ }
+ content = `${message}\n\n[form "${formName}" values: ${JSON.stringify(values)}]`;
+ }
+ onSendRef.current(content);
+ },
+ [store],
+ );
+
+ const ctx = useMemo(
+ () => ({ library, interactive, triggerAction, getFieldValue, setFieldValue }),
+ [library, interactive, triggerAction, getFieldValue, setFieldValue],
+ );
+
+ // isStreaming currently only affects display in the app; kept for parity/future use.
+ void isStreaming;
+
+ return { result, ctx };
+}
diff --git a/examples/openui-tui-chat/src/llm.ts b/examples/openui-tui-chat/src/llm.ts
new file mode 100644
index 000000000..31bc62eb8
--- /dev/null
+++ b/examples/openui-tui-chat/src/llm.ts
@@ -0,0 +1,38 @@
+import type { Message } from "@openuidev/react-headless";
+import { openAIMessageFormat } from "@openuidev/react-headless";
+import OpenAI from "openai";
+import type { ChatCompletionMessageParam } from "openai/resources/chat/completions";
+
+/**
+ * Build a react-headless `processMessage` that streams from an OpenAI-compatible
+ * endpoint. Returns a Response wrapping the SDK's NDJSON ReadableStream, which
+ * pairs with `openAIReadableStreamAdapter`.
+ */
+export function makeProcessMessage(systemPrompt: string) {
+ const client = new OpenAI({
+ apiKey: process.env.OPENAI_API_KEY,
+ baseURL: process.env.OPENAI_BASE_URL || undefined,
+ });
+ const model = process.env.OPENAI_MODEL || "gpt-5.5";
+
+ return async ({
+ messages,
+ abortController,
+ }: {
+ threadId: string;
+ messages: Message[];
+ abortController: AbortController;
+ }): Promise => {
+ const apiMessages: ChatCompletionMessageParam[] = [
+ { role: "system", content: systemPrompt },
+ ...(openAIMessageFormat.toApi(messages) as ChatCompletionMessageParam[]),
+ ];
+
+ const stream = await client.chat.completions.create(
+ { model, messages: apiMessages, stream: true },
+ { signal: abortController.signal },
+ );
+
+ return new Response(stream.toReadableStream() as unknown as ReadableStream);
+ };
+}
diff --git a/examples/openui-tui-chat/tsconfig.json b/examples/openui-tui-chat/tsconfig.json
new file mode 100644
index 000000000..8bb361f5a
--- /dev/null
+++ b/examples/openui-tui-chat/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "jsx": "react-jsx",
+ "strict": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "types": ["node"]
+ },
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
+ "exclude": ["node_modules"]
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 759229d5a..b337db1ae 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -320,7 +320,7 @@ importers:
version: 0.0.45
'@ag-ui/mastra':
specifier: ^1.0.1
- version: 1.0.1(mo2d2k6urt4bfbrhfsfscm4ram)
+ version: 1.0.1(dd1f7da5383fb7dbf1cafaa81aeabe83)
'@mastra/core':
specifier: 1.15.0
version: 1.15.0(@cfworker/json-schema@4.1.1)(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@1.0.0)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@1.0.0)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(openapi-types@12.1.3)(zod@4.3.6)
@@ -703,6 +703,55 @@ importers:
specifier: ~5.9.2
version: 5.9.3
+ examples/openui-tui-chat:
+ dependencies:
+ '@openuidev/lang-core':
+ specifier: workspace:*
+ version: link:../../packages/lang-core
+ '@openuidev/react-headless':
+ specifier: workspace:*
+ version: link:../../packages/react-headless
+ ink:
+ specifier: ^5.1.0
+ version: 5.2.1(@types/react@19.2.14)(react@18.3.1)
+ ink-big-text:
+ specifier: ^2.0.0
+ version: 2.0.0(ink@5.2.1(@types/react@19.2.14)(react@18.3.1))(react@18.3.1)
+ ink-spinner:
+ specifier: ^5.0.0
+ version: 5.0.0(ink@5.2.1(@types/react@19.2.14)(react@18.3.1))(react@18.3.1)
+ openai:
+ specifier: ^6.22.0
+ version: 6.34.0(ws@8.20.0)(zod@4.3.6)
+ react:
+ specifier: ^18.3.1
+ version: 18.3.1
+ zod:
+ specifier: ^4.3.6
+ version: 4.3.6
+ zustand:
+ specifier: ^4.5.5
+ version: 4.5.7(@types/react@19.2.14)(react@18.3.1)
+ devDependencies:
+ '@types/node':
+ specifier: ^20
+ version: 20.19.35
+ '@types/react':
+ specifier: ^19
+ version: 19.2.14
+ ink-testing-library:
+ specifier: ^4.0.0
+ version: 4.0.0(@types/react@19.2.14)
+ tsx:
+ specifier: ^4.19.2
+ version: 4.20.3
+ typescript:
+ specifier: ^5.9.3
+ version: 5.9.3
+ vitest:
+ specifier: ^4.0.18
+ version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.35)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3)
+
examples/react-email:
dependencies:
'@openuidev/cli':
@@ -1752,6 +1801,10 @@ packages:
peerDependencies:
vue: ^3.3.4
+ '@alcalzone/ansi-tokenize@0.1.3':
+ resolution: {integrity: sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw==}
+ engines: {node: '>=14.13.1'}
+
'@alloc/quick-lru@5.2.0':
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
@@ -2420,10 +2473,12 @@ packages:
'@copilotkitnext/agent@0.0.0-mme-ag-ui-0-0-46-20260227141603':
resolution: {integrity: sha512-HAaAVKWD+WS1/GTxY6xLMj65Ro9evnOM5UC0DueTFwlmgCkuHPVE4rDveiGVaNc0x4X75tofi5Ul9g6Tb9FT/w==}
engines: {node: '>=18'}
+ deprecated: Moved into @copilotkit/runtime. Import from '@copilotkit/runtime/v2'.
'@copilotkitnext/runtime@0.0.0-mme-ag-ui-0-0-46-20260227141603':
resolution: {integrity: sha512-c6vosi7xzKvyujmmwb4rNvAnlr656ybCrPeeX3kO1V70zrnUVkS4EXlSz1T0fGqqNgf5Tfqmssy3xqyLLZwgbQ==}
engines: {node: '>=18'}
+ deprecated: Moved into @copilotkit/runtime. Import from '@copilotkit/runtime/v2'.
peerDependencies:
'@ag-ui/client': 0.0.46
'@ag-ui/core': 0.0.46
@@ -2433,6 +2488,7 @@ packages:
'@copilotkitnext/shared@0.0.0-mme-ag-ui-0-0-46-20260227141603':
resolution: {integrity: sha512-tbw37m+MgOO58dxYsXvGTN9YqHt6DPLMqtDEQftJHrUrQkNqXOxhOporx4p2DG0R+RiQqWrT+r44D2eRCQhlkA==}
engines: {node: '>=18'}
+ deprecated: Use @copilotkit/shared instead.
'@csstools/color-helpers@5.1.0':
resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==}
@@ -3583,89 +3639,105 @@ packages:
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linux-arm@1.2.4':
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
cpu: [arm]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linux-ppc64@1.2.4':
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linux-riscv64@1.2.4':
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linux-s390x@1.2.4':
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linux-x64@1.2.4':
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@img/sharp-linux-arm64@0.34.5':
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@img/sharp-linux-arm@0.34.5':
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm]
os: [linux]
+ libc: [glibc]
'@img/sharp-linux-ppc64@0.34.5':
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@img/sharp-linux-riscv64@0.34.5':
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@img/sharp-linux-s390x@0.34.5':
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@img/sharp-linux-x64@0.34.5':
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@img/sharp-linuxmusl-arm64@0.34.5':
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@img/sharp-linuxmusl-x64@0.34.5':
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@img/sharp-wasm32@0.34.5':
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
@@ -4078,72 +4150,84 @@ packages:
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@next/swc-linux-arm64-gnu@16.1.6':
resolution: {integrity: sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@next/swc-linux-arm64-gnu@16.2.3':
resolution: {integrity: sha512-U6vtblPtU/P14Y/b/n9ZY0GOxbbIhTFuaFR7F4/uMBidCi2nSdaOFhA0Go81L61Zd6527+yvuX44T4ksnf8T+Q==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@next/swc-linux-arm64-musl@15.5.12':
resolution: {integrity: sha512-+fpGWvQiITgf7PUtbWY1H7qUSnBZsPPLyyq03QuAKpVoTy/QUx1JptEDTQMVvQhvizCEuNLEeghrQUyXQOekuw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@next/swc-linux-arm64-musl@16.1.6':
resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@next/swc-linux-arm64-musl@16.2.3':
resolution: {integrity: sha512-/YV0LgjHUmfhQpn9bVoGc4x4nan64pkhWR5wyEV8yCOfwwrH630KpvRg86olQHTwHIn1z59uh6JwKvHq1h4QEw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@next/swc-linux-x64-gnu@15.5.12':
resolution: {integrity: sha512-jSLvgdRRL/hrFAPqEjJf1fFguC719kmcptjNVDJl26BnJIpjL3KH5h6mzR4mAweociLQaqvt4UyzfbFjgAdDcw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@next/swc-linux-x64-gnu@16.1.6':
resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@next/swc-linux-x64-gnu@16.2.3':
resolution: {integrity: sha512-/HiWEcp+WMZ7VajuiMEFGZ6cg0+aYZPqCJD3YJEfpVWQsKYSjXQG06vJP6F1rdA03COD9Fef4aODs3YxKx+RDQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@next/swc-linux-x64-musl@15.5.12':
resolution: {integrity: sha512-/uaF0WfmYqQgLfPmN6BvULwxY0dufI2mlN2JbOKqqceZh1G4hjREyi7pg03zjfyS6eqNemHAZPSoP84x17vo6w==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@next/swc-linux-x64-musl@16.1.6':
resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@next/swc-linux-x64-musl@16.2.3':
resolution: {integrity: sha512-Kt44hGJfZSefebhk/7nIdivoDr3Ugp5+oNz9VvF3GUtfxutucUIHfIO0ZYO8QlOPDQloUVQn4NVC/9JvHRk9hw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@next/swc-win32-arm64-msvc@15.5.12':
resolution: {integrity: sha512-xhsL1OvQSfGmlL5RbOmU+FV120urrgFpYLq+6U8C6KIym32gZT6XF/SDE92jKzzlPWskkbjOKCpqk5m4i8PEfg==}
@@ -4580,48 +4664,56 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@oxc-minify/binding-linux-arm64-musl@0.117.0':
resolution: {integrity: sha512-C3zapJconWpl2Y7LR3GkRkH6jxpuV2iVUfkFcHT5Ffn4Zu7l88mZa2dhcfdULZDybN1Phka/P34YUzuskUUrXw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@oxc-minify/binding-linux-ppc64-gnu@0.117.0':
resolution: {integrity: sha512-2T/Bm+3/qTfuNS4gKSzL8qbiYk+ErHW2122CtDx+ilZAzvWcJ8IbqdZIbEWOlwwe03lESTxPwTBLFqVgQU2OeQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@oxc-minify/binding-linux-riscv64-gnu@0.117.0':
resolution: {integrity: sha512-MKLjpldYkeoB4T+yAi4aIAb0waifxUjLcKkCUDmYAY3RqBJTvWK34KtfaKZL0IBMIXfD92CbKkcxQirDUS9Xcg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@oxc-minify/binding-linux-riscv64-musl@0.117.0':
resolution: {integrity: sha512-UFVcbPvKUStry6JffriobBp8BHtjmLLPl4bCY+JMxIn/Q3pykCpZzRwFTcDurG/kY8tm+uSNfKKdRNa5Nh9A7g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
+ libc: [musl]
'@oxc-minify/binding-linux-s390x-gnu@0.117.0':
resolution: {integrity: sha512-B9GyPQ1NKbvpETVAMyJMfRlD3c6UJ7kiuFUAlx9LTYiQL+YIyT6vpuRlq1zgsXxavZluVrfeJv6x0owV4KDx4Q==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@oxc-minify/binding-linux-x64-gnu@0.117.0':
resolution: {integrity: sha512-fXfhtr+WWBGNy4M5GjAF5vu/lpulR4Me34FjTyaK9nDrTZs7LM595UDsP1wliksqp4hD/KdoqHGmbCrC+6d4vA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@oxc-minify/binding-linux-x64-musl@0.117.0':
resolution: {integrity: sha512-jFBgGbx1oLadb83ntJmy1dWlAHSQanXTS21G4PgkxyONmxZdZ/UMKr7KsADzMuoPsd2YhJHxzRpwJd9U+4BFBw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@oxc-minify/binding-openharmony-arm64@0.117.0':
resolution: {integrity: sha512-nxPd9vx1vYz8IlIMdl9HFdOK/ood1H5hzbSFsyO8JU55tkcJoBL8TLCbuFf9pHpOy27l2gcPyV6z3p4eAcTH5Q==}
@@ -4699,48 +4791,56 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@oxc-parser/binding-linux-arm64-musl@0.117.0':
resolution: {integrity: sha512-QagKTDF4lrz8bCXbUi39Uq5xs7C7itAseKm51f33U+Dyar9eJY/zGKqfME9mKLOiahX7Fc1J3xMWVS0AdDXLPg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@oxc-parser/binding-linux-ppc64-gnu@0.117.0':
resolution: {integrity: sha512-RPddpcE/0xxWaommWy0c5i/JdrXcXAkxBS2GOrAUh5LKmyCh03hpJedOAWszG4ADsKQwoUQQ1/tZVGRhZIWtKA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@oxc-parser/binding-linux-riscv64-gnu@0.117.0':
resolution: {integrity: sha512-ur/WVZF9FSOiZGxyP+nfxZzuv6r5OJDYoVxJnUR7fM/hhXLh4V/be6rjbzm9KLCDBRwYCEKJtt+XXNccwd06IA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@oxc-parser/binding-linux-riscv64-musl@0.117.0':
resolution: {integrity: sha512-ujGcAx8xAMvhy7X5sBFi3GXML1EtyORuJZ5z2T6UV3U416WgDX/4OCi3GnoteeenvxIf6JgP45B+YTHpt71vpA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
+ libc: [musl]
'@oxc-parser/binding-linux-s390x-gnu@0.117.0':
resolution: {integrity: sha512-hbsfKjUwRjcMZZvvmpZSc+qS0bHcHRu8aV/I3Ikn9BzOA0ZAgUE7ctPtce5zCU7bM8dnTLi4sJ1Pi9YHdx6Urw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@oxc-parser/binding-linux-x64-gnu@0.117.0':
resolution: {integrity: sha512-1QrTrf8rige7UPJrYuDKJLQOuJlgkt+nRSJLBMHWNm9TdivzP48HaK3f4q18EjNlglKtn03lgjMu4fryDm8X4A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@oxc-parser/binding-linux-x64-musl@0.117.0':
resolution: {integrity: sha512-gRvK6HPzF5ITRL68fqb2WYYs/hGviPIbkV84HWCgiJX+LkaOpp+HIHQl3zVZdyKHwopXToTbXbtx/oFjDjl8pg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@oxc-parser/binding-openharmony-arm64@0.117.0':
resolution: {integrity: sha512-QPJvFbnnDZZY7xc+xpbIBWLThcGBakwaYA9vKV8b3+oS5MGfAZUoTFJcix5+Zg2Ri46sOfrUim6Y6jsKNcssAQ==}
@@ -4824,48 +4924,56 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@oxc-transform/binding-linux-arm64-musl@0.117.0':
resolution: {integrity: sha512-ykxpPQp0eAcSmhy0Y3qKvdanHY4d8THPonDfmCoktUXb6r0X6qnjpJB3V+taN1wevW55bOEZd97kxtjTKjqhmg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@oxc-transform/binding-linux-ppc64-gnu@0.117.0':
resolution: {integrity: sha512-Rvspti4Kr7eq6zSrURK5WjscfWQPvmy/KjJZV45neRKW8RLonE3r9+NgrwSLGoHvQ3F24fbqlkplox1RtlhH5A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@oxc-transform/binding-linux-riscv64-gnu@0.117.0':
resolution: {integrity: sha512-Dr2ZW9ZZ4l1eQ5JUEUY3smBh4JFPCPuybWaDZTLn3ADZjyd8ZtNXEjeMT8rQbbhbgSL9hEgbwaqraole3FNThQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@oxc-transform/binding-linux-riscv64-musl@0.117.0':
resolution: {integrity: sha512-oD1Bnes1bIC3LVBSrWEoSUBj6fvatESPwAVWfJVGVQlqWuOs/ZBn1e4Nmbipo3KGPHK7DJY75r/j7CQCxhrOFQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
+ libc: [musl]
'@oxc-transform/binding-linux-s390x-gnu@0.117.0':
resolution: {integrity: sha512-qT//IAPLvse844t99Kff5j055qEbXfwzWgvCMb0FyjisnB8foy25iHZxZIocNBe6qwrCYWUP1M8rNrB/WyfS1Q==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@oxc-transform/binding-linux-x64-gnu@0.117.0':
resolution: {integrity: sha512-2YEO5X+KgNzFqRVO5dAkhjcI5gwxus4NSWVl/+cs2sI6P0MNPjqE3VWPawl4RTC11LvetiiZdHcujUCPM8aaUw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@oxc-transform/binding-linux-x64-musl@0.117.0':
resolution: {integrity: sha512-3wqWbTSaIFZvDr1aqmTul4cg8PRWYh6VC52E8bLI7ytgS/BwJLW+sDUU2YaGIds4sAf/1yKeJRmudRCDPW9INg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@oxc-transform/binding-openharmony-arm64@0.117.0':
resolution: {integrity: sha512-Ebxx6NPqhzlrjvx4+PdSqbOq+li0f7X59XtJljDghkbJsbnkHvhLmPR09ifHt5X32UlZN63ekjwcg/nbmHLLlA==}
@@ -4925,36 +5033,42 @@ packages:
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
+ libc: [glibc]
'@parcel/watcher-linux-arm-musl@2.5.1':
resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
+ libc: [musl]
'@parcel/watcher-linux-arm64-glibc@2.5.1':
resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@parcel/watcher-linux-arm64-musl@2.5.1':
resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@parcel/watcher-linux-x64-glibc@2.5.1':
resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@parcel/watcher-linux-x64-musl@2.5.1':
resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@parcel/watcher-wasm@2.5.6':
resolution: {integrity: sha512-byAiBZ1t3tXQvc8dMD/eoyE7lTXYorhn+6uVW5AC+JGI1KtJC/LvDche5cfUE+qiefH+Ybq0bUCJU0aB1cSHUA==}
@@ -6883,6 +6997,7 @@ packages:
'@rolldown/binding-darwin-arm64@1.0.0-rc.16':
resolution: {integrity: sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==}
engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
os: [darwin]
'@rolldown/binding-darwin-x64@1.0.0-rc.12':
@@ -6908,36 +7023,42 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@rolldown/binding-linux-arm64-musl@1.0.0-rc.12':
resolution: {integrity: sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12':
resolution: {integrity: sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12':
resolution: {integrity: sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@rolldown/binding-linux-x64-gnu@1.0.0-rc.12':
resolution: {integrity: sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@rolldown/binding-linux-x64-musl@1.0.0-rc.12':
resolution: {integrity: sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@rolldown/binding-openharmony-arm64@1.0.0-rc.12':
resolution: {integrity: sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==}
@@ -7107,121 +7228,145 @@ packages:
resolution: {integrity: sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==}
cpu: [arm]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-arm-gnueabihf@4.60.1':
resolution: {integrity: sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==}
cpu: [arm]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.43.0':
resolution: {integrity: sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==}
cpu: [arm]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-arm-musleabihf@4.60.1':
resolution: {integrity: sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==}
cpu: [arm]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.43.0':
resolution: {integrity: sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-arm64-gnu@4.60.1':
resolution: {integrity: sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.43.0':
resolution: {integrity: sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-arm64-musl@4.60.1':
resolution: {integrity: sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-loong64-gnu@4.60.1':
resolution: {integrity: sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==}
cpu: [loong64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-loong64-musl@4.60.1':
resolution: {integrity: sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==}
cpu: [loong64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-loongarch64-gnu@4.43.0':
resolution: {integrity: sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==}
cpu: [loong64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-powerpc64le-gnu@4.43.0':
resolution: {integrity: sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-ppc64-gnu@4.60.1':
resolution: {integrity: sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-ppc64-musl@4.60.1':
resolution: {integrity: sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==}
cpu: [ppc64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-riscv64-gnu@4.43.0':
resolution: {integrity: sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-riscv64-gnu@4.60.1':
resolution: {integrity: sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.43.0':
resolution: {integrity: sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==}
cpu: [riscv64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-riscv64-musl@4.60.1':
resolution: {integrity: sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==}
cpu: [riscv64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.43.0':
resolution: {integrity: sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-s390x-gnu@4.60.1':
resolution: {integrity: sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.43.0':
resolution: {integrity: sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.60.1':
resolution: {integrity: sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.43.0':
resolution: {integrity: sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-linux-x64-musl@4.60.1':
resolution: {integrity: sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@rollup/rollup-openbsd-x64@4.60.1':
resolution: {integrity: sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==}
@@ -7752,48 +7897,56 @@ packages:
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@tailwindcss/oxide-linux-arm64-gnu@4.2.2':
resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@tailwindcss/oxide-linux-arm64-musl@4.2.1':
resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@tailwindcss/oxide-linux-arm64-musl@4.2.2':
resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@tailwindcss/oxide-linux-x64-gnu@4.2.1':
resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@tailwindcss/oxide-linux-x64-gnu@4.2.2':
resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@tailwindcss/oxide-linux-x64-musl@4.2.1':
resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@tailwindcss/oxide-linux-x64-musl@4.2.2':
resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@tailwindcss/oxide-wasm32-wasi@4.2.1':
resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==}
@@ -7876,24 +8029,28 @@ packages:
engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@takumi-rs/core-linux-arm64-musl@0.68.17':
resolution: {integrity: sha512-4CiEF518wDnujF0fjql2XN6uO+OXl0svy0WgAF2656dCx2gJtWscaHytT2rsQ0ZmoFWE0dyWcDW1g/FBVPvuvA==}
engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@takumi-rs/core-linux-x64-gnu@0.68.17':
resolution: {integrity: sha512-jm8lTe2E6Tfq2b97GJC31TWK1JAEv+MsVbvL9DCLlYcafgYFlMXDUnOkZFMjlrmh0HcFAYDaBkniNDgIQfXqzg==}
engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@takumi-rs/core-linux-x64-musl@0.68.17':
resolution: {integrity: sha512-nbdzQgC4ywzltDDV1fer1cKswwGE+xXZHdDiacdd7RM5XBng209Bmo3j1iv9dsX+4xXhByzCCGbxdWhhHqVXmw==}
engines: {node: '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0'}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@takumi-rs/core-win32-arm64-msvc@0.68.17':
resolution: {integrity: sha512-kE4F0LRmuhSwiNkFG7dTY9ID8+B7zb97QedyN/IO2fBJmRQDkqCGcip2gloh8YPPhCuKGjCqqqh2L+Tg9PKW7w==}
@@ -8369,41 +8526,49 @@ packages:
resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
'@unrs/resolver-binding-linux-arm64-musl@1.11.1':
resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==}
cpu: [arm64]
os: [linux]
+ libc: [musl]
'@unrs/resolver-binding-linux-ppc64-gnu@1.11.1':
resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==}
cpu: [ppc64]
os: [linux]
+ libc: [glibc]
'@unrs/resolver-binding-linux-riscv64-gnu@1.11.1':
resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==}
cpu: [riscv64]
os: [linux]
+ libc: [glibc]
'@unrs/resolver-binding-linux-riscv64-musl@1.11.1':
resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==}
cpu: [riscv64]
os: [linux]
+ libc: [musl]
'@unrs/resolver-binding-linux-s390x-gnu@1.11.1':
resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==}
cpu: [s390x]
os: [linux]
+ libc: [glibc]
'@unrs/resolver-binding-linux-x64-gnu@1.11.1':
resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==}
cpu: [x64]
os: [linux]
+ libc: [glibc]
'@unrs/resolver-binding-linux-x64-musl@1.11.1':
resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==}
cpu: [x64]
os: [linux]
+ libc: [musl]
'@unrs/resolver-binding-wasm32-wasi@1.11.1':
resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==}
@@ -8845,6 +9010,10 @@ packages:
resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
engines: {node: '>=12'}
+ ansi-regex@6.2.2:
+ resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
+ engines: {node: '>=12'}
+
ansi-styles@3.2.1:
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
engines: {node: '>=4'}
@@ -8989,6 +9158,10 @@ packages:
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
engines: {node: '>=8.0.0'}
+ auto-bind@5.0.1:
+ resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
autoprefixer@10.4.27:
resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==}
engines: {node: ^10 || ^12 || >=14}
@@ -9301,6 +9474,11 @@ packages:
ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+ cfonts@3.3.1:
+ resolution: {integrity: sha512-ZGEmN3W9mViWEDjsuPo4nK4h39sfh6YtoneFYp9WLPI/rw8BaSSrfQC6jkrGW3JMvV3ZnExJB/AEqXc/nHYxkw==}
+ engines: {node: '>=10'}
+ hasBin: true
+
chai@5.2.0:
resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
engines: {node: '>=12'}
@@ -9437,10 +9615,18 @@ packages:
class-variance-authority@0.7.1:
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
+ cli-boxes@3.0.0:
+ resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
+ engines: {node: '>=10'}
+
cli-cursor@2.1.0:
resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==}
engines: {node: '>=4'}
+ cli-cursor@4.0.0:
+ resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
cli-highlight@2.1.11:
resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==}
engines: {node: '>=8.0.0', npm: '>=5.0.0'}
@@ -9454,6 +9640,10 @@ packages:
resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==}
engines: {node: 10.* || >= 12.*}
+ cli-truncate@4.0.0:
+ resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
+ engines: {node: '>=18'}
+
cli-width@4.1.0:
resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
engines: {node: '>= 12'}
@@ -9488,6 +9678,10 @@ packages:
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
engines: {node: '>=0.10.0'}
+ code-excerpt@4.0.0:
+ resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
collapse-white-space@2.1.0:
resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
@@ -9618,6 +9812,10 @@ packages:
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+ convert-to-spaces@2.0.1:
+ resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
cookie-es@1.2.2:
resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==}
@@ -10049,6 +10247,10 @@ packages:
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
engines: {node: '>= 0.4'}
+ define-property@1.0.0:
+ resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==}
+ engines: {node: '>=0.10.0'}
+
defu@6.1.4:
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
@@ -10306,6 +10508,9 @@ packages:
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
engines: {node: '>= 0.4'}
+ es-toolkit@1.50.0:
+ resolution: {integrity: sha512-OyZKhUVvEep9ITEiwHn8GKnMRQIVqoSIX7WnRbkWgJkllCujilqP2rD0u979tkl8wqyc8ICwlc1UBVv/Sl1G6w==}
+
esast-util-from-estree@2.0.0:
resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==}
@@ -11238,6 +11443,10 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
+ hasown@2.0.4:
+ resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
+ engines: {node: '>= 0.4'}
+
hast-util-from-dom@5.0.1:
resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==}
@@ -11479,6 +11688,10 @@ packages:
resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
engines: {node: '>=8'}
+ indent-string@5.0.0:
+ resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
+ engines: {node: '>=12'}
+
inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
@@ -11493,6 +11706,42 @@ packages:
resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ ink-big-text@2.0.0:
+ resolution: {integrity: sha512-Juzqv+rIOLGuhMJiE50VtS6dg6olWfzFdL7wsU/EARSL5Eaa5JNXMogMBm9AkjgzO2Y3UwWCOh87jbhSn8aNdw==}
+ engines: {node: '>=14.16'}
+ peerDependencies:
+ ink: '>=4'
+ react: '>=18'
+
+ ink-spinner@5.0.0:
+ resolution: {integrity: sha512-EYEasbEjkqLGyPOUc8hBJZNuC5GvXGMLu0w5gdTNskPc7Izc5vO3tdQEYnzvshucyGCBXc86ig0ujXPMWaQCdA==}
+ engines: {node: '>=14.16'}
+ peerDependencies:
+ ink: '>=4.0.0'
+ react: '>=18.0.0'
+
+ ink-testing-library@4.0.0:
+ resolution: {integrity: sha512-yF92kj3pmBvk7oKbSq5vEALO//o7Z9Ck/OaLNlkzXNeYdwfpxMQkSowGTFUCS5MSu9bWfSZMewGpp7bFc66D7Q==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/react': '>=18.0.0'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ ink@5.2.1:
+ resolution: {integrity: sha512-BqcUyWrG9zq5HIwW6JcfFHsIYebJkWWb4fczNah1goUO0vv5vneIlfwuS85twyJ5hYR/y18FlAYUxrO9ChIWVg==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/react': '>=18.0.0'
+ react: '>=18.0.0'
+ react-devtools-core: ^4.19.1
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react-devtools-core:
+ optional: true
+
inline-style-parser@0.2.4:
resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==}
@@ -11537,6 +11786,10 @@ packages:
iron-webcrypto@1.2.1:
resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
+ is-accessor-descriptor@1.0.2:
+ resolution: {integrity: sha512-AIbwAcazqP3R65dGvqk1V+a+vE5Fg1yu/ZKMOiBWSUIXXiwQkYmXQcVa2O0nh0tSDKDFKxG2mY7dB1Sr4hEP1g==}
+ engines: {node: '>= 0.4'}
+
is-alphabetical@1.0.4:
resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==}
@@ -11573,6 +11826,9 @@ packages:
resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==}
engines: {node: '>= 0.4'}
+ is-buffer@1.1.6:
+ resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
+
is-bun-module@2.0.0:
resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==}
@@ -11584,6 +11840,10 @@ packages:
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
engines: {node: '>= 0.4'}
+ is-data-descriptor@1.0.1:
+ resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==}
+ engines: {node: '>= 0.4'}
+
is-data-view@1.0.2:
resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==}
engines: {node: '>= 0.4'}
@@ -11598,6 +11858,10 @@ packages:
is-decimal@2.0.1:
resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
+ is-descriptor@1.0.4:
+ resolution: {integrity: sha512-bv5z95W0dDtLfKwDfkTNxaRxmISBD3eQBKJeVxv2AQ7MjuUnDNG7cIQqvFtMOUYhsILWHhMayWdoGqNqYYYjww==}
+ engines: {node: '>= 0.4'}
+
is-docker@2.2.1:
resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
engines: {node: '>=8'}
@@ -11624,6 +11888,14 @@ packages:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
+ is-fullwidth-code-point@4.0.0:
+ resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
+ engines: {node: '>=12'}
+
+ is-fullwidth-code-point@5.1.0:
+ resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==}
+ engines: {node: '>=18'}
+
is-generator-function@1.1.0:
resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==}
engines: {node: '>= 0.4'}
@@ -11638,6 +11910,11 @@ packages:
is-hexadecimal@2.0.1:
resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
+ is-in-ci@1.0.0:
+ resolution: {integrity: sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
is-in-ssh@1.0.0:
resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==}
engines: {node: '>=20'}
@@ -11670,6 +11947,10 @@ packages:
resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==}
engines: {node: '>= 0.4'}
+ is-number@3.0.0:
+ resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==}
+ engines: {node: '>=0.10.0'}
+
is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
@@ -11952,6 +12233,10 @@ packages:
khroma@2.1.0:
resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==}
+ kind-of@3.2.2:
+ resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==}
+ engines: {node: '>=0.10.0'}
+
kind-of@6.0.3:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'}
@@ -12098,48 +12383,56 @@ packages:
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
lightningcss-linux-arm64-gnu@1.32.0:
resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
lightningcss-linux-arm64-musl@1.31.1:
resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
lightningcss-linux-arm64-musl@1.32.0:
resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
+ libc: [musl]
lightningcss-linux-x64-gnu@1.31.1:
resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
lightningcss-linux-x64-gnu@1.32.0:
resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
+ libc: [glibc]
lightningcss-linux-x64-musl@1.31.1:
resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
+ libc: [musl]
lightningcss-linux-x64-musl@1.32.0:
resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
+ libc: [musl]
lightningcss-win32-arm64-msvc@1.31.1:
resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==}
@@ -12724,6 +13017,10 @@ packages:
resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==}
engines: {node: '>=4'}
+ mimic-fn@2.1.0:
+ resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
+ engines: {node: '>=6'}
+
mimic-fn@4.0.0:
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
engines: {node: '>=12'}
@@ -13132,6 +13429,10 @@ packages:
resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==}
engines: {node: '>=4'}
+ onetime@5.1.2:
+ resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
+ engines: {node: '>=6'}
+
onetime@6.0.0:
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
engines: {node: '>=12'}
@@ -13316,6 +13617,10 @@ packages:
partial-json@0.1.7:
resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==}
+ patch-console@2.0.0:
+ resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
path-browserify@1.0.1:
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
@@ -13983,6 +14288,12 @@ packages:
react-promise-suspense@0.3.4:
resolution: {integrity: sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==}
+ react-reconciler@0.29.2:
+ resolution: {integrity: sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==}
+ engines: {node: '>=0.10.0'}
+ peerDependencies:
+ react: ^18.3.1
+
react-refresh@0.14.2:
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
engines: {node: '>=0.10.0'}
@@ -14053,6 +14364,10 @@ packages:
react: '>=16.6.0'
react-dom: '>=16.6.0'
+ react@18.3.1:
+ resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
+ engines: {node: '>=0.10.0'}
+
react@19.2.0:
resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==}
engines: {node: '>=0.10.0'}
@@ -14283,6 +14598,10 @@ packages:
resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==}
engines: {node: '>=4'}
+ restore-cursor@4.0.0:
+ resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
retry@0.13.1:
resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==}
engines: {node: '>= 4'}
@@ -14417,6 +14736,9 @@ packages:
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
engines: {node: '>=v12.22.7'}
+ scheduler@0.23.2:
+ resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
+
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
@@ -14577,6 +14899,14 @@ packages:
resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
engines: {node: '>=14.16'}
+ slice-ansi@5.0.0:
+ resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
+ engines: {node: '>=12'}
+
+ slice-ansi@7.1.2:
+ resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==}
+ engines: {node: '>=18'}
+
slugify@1.6.8:
resolution: {integrity: sha512-HVk9X1E0gz3mSpoi60h/saazLKXKaZThMLU3u/aNwoYn8/xQyX2MGxL0ui2eaokkD7tF+Zo+cKTHUbe1mmmGzA==}
engines: {node: '>=8.0.0'}
@@ -14747,6 +15077,10 @@ packages:
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
engines: {node: '>=12'}
+ strip-ansi@7.2.0:
+ resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
+ engines: {node: '>=12'}
+
strip-bom-string@1.0.0:
resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==}
engines: {node: '>=0.10.0'}
@@ -15175,6 +15509,10 @@ packages:
resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==}
engines: {node: '>=8'}
+ type-fest@4.41.0:
+ resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
+ engines: {node: '>=16'}
+
type-fest@5.5.0:
resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==}
engines: {node: '>=20'}
@@ -15991,6 +16329,15 @@ packages:
engines: {node: '>=8'}
hasBin: true
+ widest-line@5.0.0:
+ resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==}
+ engines: {node: '>=18'}
+
+ window-size@1.1.1:
+ resolution: {integrity: sha512-5D/9vujkmVQ7pSmc0SCBmHXbkv6eaHwXEx65MywhmUMsI8sGqJ972APq1lotfcwMKPFLuCFfL8xGHLIp7jaBmA==}
+ engines: {node: '>= 0.10.0'}
+ hasBin: true
+
wonka@6.3.5:
resolution: {integrity: sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw==}
@@ -16040,18 +16387,6 @@ packages:
utf-8-validate:
optional: true
- ws@8.18.2:
- resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==}
- engines: {node: '>=10.0.0'}
- peerDependencies:
- bufferutil: ^4.0.1
- utf-8-validate: '>=5.0.2'
- peerDependenciesMeta:
- bufferutil:
- optional: true
- utf-8-validate:
- optional: true
-
ws@8.20.0:
resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==}
engines: {node: '>=10.0.0'}
@@ -16155,6 +16490,9 @@ packages:
resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==}
engines: {node: '>=18'}
+ yoga-layout@3.2.1:
+ resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==}
+
youch-core@0.3.3:
resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==}
@@ -16294,12 +16632,12 @@ snapshots:
- react
- react-dom
- '@ag-ui/mastra@1.0.1(mo2d2k6urt4bfbrhfsfscm4ram)':
+ '@ag-ui/mastra@1.0.1(dd1f7da5383fb7dbf1cafaa81aeabe83)':
dependencies:
'@ag-ui/client': 0.0.49
'@ag-ui/core': 0.0.45
'@ai-sdk/ui-utils': 1.2.11(zod@4.3.6)
- '@copilotkit/runtime': 0.0.0-mme-ag-ui-0-0-46-20260227141603(@ag-ui/encoder@0.0.49)(@cfworker/json-schema@4.1.1)(@copilotkitnext/shared@0.0.0-mme-ag-ui-0-0-46-20260227141603)(@langchain/core@0.3.80(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6)))(@langchain/langgraph-sdk@0.1.10(@langchain/core@0.3.80(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@copilotkit/runtime': 0.0.0-mme-ag-ui-0-0-46-20260227141603(@ag-ui/encoder@0.0.46)(@cfworker/json-schema@4.1.1)(@copilotkitnext/shared@0.0.0-mme-ag-ui-0-0-46-20260227141603)(@langchain/core@0.3.80(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6)))(@langchain/langgraph-sdk@0.1.10(@langchain/core@0.3.80(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@mastra/client-js': 1.11.2(@cfworker/json-schema@4.1.1)(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@1.0.0)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@1.0.0)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(openapi-types@12.1.3)(zod@4.3.6)
'@mastra/core': 1.15.0(@cfworker/json-schema@4.1.1)(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@1.0.0)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@1.0.0)(zod-to-json-schema@3.25.2(zod@4.3.6))(zod@4.3.6))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(zod@4.3.6))(@types/json-schema@7.0.15)(openapi-types@12.1.3)(zod@4.3.6)
rxjs: 7.8.1
@@ -16491,6 +16829,11 @@ snapshots:
transitivePeerDependencies:
- zod
+ '@alcalzone/ansi-tokenize@0.1.3':
+ dependencies:
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 4.0.0
+
'@alloc/quick-lru@5.2.0': {}
'@andrewbranch/untar.js@1.0.3': {}
@@ -16498,7 +16841,7 @@ snapshots:
'@antfu/install-pkg@1.1.0':
dependencies:
package-manager-detector: 1.6.0
- tinyexec: 1.0.2
+ tinyexec: 1.0.4
'@arethetypeswrong/cli@0.18.2':
dependencies:
@@ -17251,7 +17594,7 @@ snapshots:
'@colors/colors@1.5.0':
optional: true
- '@copilotkit/runtime@0.0.0-mme-ag-ui-0-0-46-20260227141603(@ag-ui/encoder@0.0.49)(@cfworker/json-schema@4.1.1)(@copilotkitnext/shared@0.0.0-mme-ag-ui-0-0-46-20260227141603)(@langchain/core@0.3.80(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6)))(@langchain/langgraph-sdk@0.1.10(@langchain/core@0.3.80(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ '@copilotkit/runtime@0.0.0-mme-ag-ui-0-0-46-20260227141603(@ag-ui/encoder@0.0.46)(@cfworker/json-schema@4.1.1)(@copilotkitnext/shared@0.0.0-mme-ag-ui-0-0-46-20260227141603)(@langchain/core@0.3.80(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6)))(@langchain/langgraph-sdk@0.1.10(@langchain/core@0.3.80(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@ag-ui/client': 0.0.46
'@ag-ui/core': 0.0.46
@@ -17260,7 +17603,7 @@ snapshots:
'@ai-sdk/openai': 2.0.101(zod@3.25.76)
'@copilotkit/shared': 0.0.0-mme-ag-ui-0-0-46-20260227141603(@ag-ui/core@0.0.46)
'@copilotkitnext/agent': 0.0.0-mme-ag-ui-0-0-46-20260227141603(@cfworker/json-schema@4.1.1)
- '@copilotkitnext/runtime': 0.0.0-mme-ag-ui-0-0-46-20260227141603(@ag-ui/client@0.0.46)(@ag-ui/core@0.0.46)(@ag-ui/encoder@0.0.49)(@copilotkitnext/shared@0.0.0-mme-ag-ui-0-0-46-20260227141603)
+ '@copilotkitnext/runtime': 0.0.0-mme-ag-ui-0-0-46-20260227141603(@ag-ui/client@0.0.46)(@ag-ui/core@0.0.46)(@ag-ui/encoder@0.0.46)(@copilotkitnext/shared@0.0.0-mme-ag-ui-0-0-46-20260227141603)
'@graphql-yoga/plugin-defer-stream': 3.19.0(graphql-yoga@5.19.0(graphql@16.13.2))(graphql@16.13.2)
'@hono/node-server': 1.19.12(hono@4.12.9)
'@langchain/core': 0.3.80(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.20.0)(zod@4.3.6))
@@ -17320,11 +17663,11 @@ snapshots:
- '@cfworker/json-schema'
- supports-color
- '@copilotkitnext/runtime@0.0.0-mme-ag-ui-0-0-46-20260227141603(@ag-ui/client@0.0.46)(@ag-ui/core@0.0.46)(@ag-ui/encoder@0.0.49)(@copilotkitnext/shared@0.0.0-mme-ag-ui-0-0-46-20260227141603)':
+ '@copilotkitnext/runtime@0.0.0-mme-ag-ui-0-0-46-20260227141603(@ag-ui/client@0.0.46)(@ag-ui/core@0.0.46)(@ag-ui/encoder@0.0.46)(@copilotkitnext/shared@0.0.0-mme-ag-ui-0-0-46-20260227141603)':
dependencies:
'@ag-ui/client': 0.0.46
'@ag-ui/core': 0.0.46
- '@ag-ui/encoder': 0.0.49
+ '@ag-ui/encoder': 0.0.46
'@copilotkitnext/shared': 0.0.0-mme-ag-ui-0-0-46-20260227141603
cors: 2.8.6
express: 4.22.1
@@ -18662,7 +19005,7 @@ snapshots:
dependencies:
string-width: 5.1.2
string-width-cjs: string-width@4.2.3
- strip-ansi: 7.1.0
+ strip-ansi: 7.2.0
strip-ansi-cjs: strip-ansi@6.0.1
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
@@ -19393,7 +19736,7 @@ snapshots:
rc9: 3.0.0
std-env: 3.10.0
- '@nuxt/vite-builder@3.21.2(thirvmyz7u7sotpvl5josuvsem)':
+ '@nuxt/vite-builder@3.21.2(cda632d3acfa8c47554ee5be1e146aef)':
dependencies:
'@nuxt/kit': 3.21.2(magicast@0.5.2)
'@rollup/plugin-replace': 6.0.3(rollup@4.60.1)
@@ -20059,7 +20402,7 @@ snapshots:
'@parcel/watcher-wasm@2.5.6':
dependencies:
is-glob: 4.0.3
- picomatch: 4.0.3
+ picomatch: 4.0.4
'@parcel/watcher-win32-arm64@2.5.1':
optional: true
@@ -23498,10 +23841,10 @@ snapshots:
'@rollup/pluginutils': 5.2.0(rollup@4.60.1)
commondir: 1.0.1
estree-walker: 2.0.2
- fdir: 6.5.0(picomatch@4.0.3)
+ fdir: 6.5.0(picomatch@4.0.4)
is-reference: 1.2.1
magic-string: 0.30.21
- picomatch: 4.0.3
+ picomatch: 4.0.4
optionalDependencies:
rollup: 4.60.1
@@ -24927,7 +25270,7 @@ snapshots:
glob: 13.0.6
graceful-fs: 4.2.11
node-gyp-build: 4.8.4
- picomatch: 4.0.3
+ picomatch: 4.0.4
resolve-from: 5.0.0
transitivePeerDependencies:
- encoding
@@ -25003,6 +25346,14 @@ snapshots:
optionalDependencies:
vite: 6.4.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3)
+ '@vitest/mocker@4.0.18(vite@6.4.1(@types/node@20.19.35)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3))':
+ dependencies:
+ '@vitest/spy': 4.0.18
+ estree-walker: 3.0.3
+ magic-string: 0.30.21
+ optionalDependencies:
+ vite: 6.4.1(@types/node@20.19.35)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3)
+
'@vitest/mocker@4.0.18(vite@6.4.1(@types/node@22.15.32)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3))':
dependencies:
'@vitest/spy': 4.0.18
@@ -25222,7 +25573,7 @@ snapshots:
alien-signals: 3.1.2
muggle-string: 0.4.1
path-browserify: 1.0.1
- picomatch: 4.0.3
+ picomatch: 4.0.4
'@vue/reactivity@3.5.31':
dependencies:
@@ -25481,6 +25832,8 @@ snapshots:
ansi-regex@6.1.0: {}
+ ansi-regex@6.2.2: {}
+
ansi-styles@3.2.1:
dependencies:
color-convert: 1.9.3
@@ -25655,6 +26008,8 @@ snapshots:
atomic-sleep@1.0.0: {}
+ auto-bind@5.0.1: {}
+
autoprefixer@10.4.27(postcss@8.5.8):
dependencies:
browserslist: 4.28.1
@@ -26031,6 +26386,11 @@ snapshots:
ccount@2.0.1: {}
+ cfonts@3.3.1:
+ dependencies:
+ supports-color: 8.1.1
+ window-size: 1.1.1
+
chai@5.2.0:
dependencies:
assertion-error: 2.0.1
@@ -26171,10 +26531,16 @@ snapshots:
dependencies:
clsx: 2.1.1
+ cli-boxes@3.0.0: {}
+
cli-cursor@2.1.0:
dependencies:
restore-cursor: 2.0.0
+ cli-cursor@4.0.0:
+ dependencies:
+ restore-cursor: 4.0.0
+
cli-highlight@2.1.11:
dependencies:
chalk: 4.1.2
@@ -26192,6 +26558,11 @@ snapshots:
optionalDependencies:
'@colors/colors': 1.5.0
+ cli-truncate@4.0.0:
+ dependencies:
+ slice-ansi: 5.0.0
+ string-width: 7.2.0
+
cli-width@4.1.0: {}
client-only@0.0.1: {}
@@ -26217,7 +26588,7 @@ snapshots:
cliui@9.0.1:
dependencies:
string-width: 7.2.0
- strip-ansi: 7.1.0
+ strip-ansi: 7.2.0
wrap-ansi: 9.0.2
clone@1.0.4: {}
@@ -26226,6 +26597,10 @@ snapshots:
cluster-key-slot@1.1.2: {}
+ code-excerpt@4.0.0:
+ dependencies:
+ convert-to-spaces: 2.0.1
+
collapse-white-space@2.1.0: {}
color-convert@1.9.3:
@@ -26346,6 +26721,8 @@ snapshots:
convert-source-map@2.0.0: {}
+ convert-to-spaces@2.0.1: {}
+
cookie-es@1.2.2: {}
cookie-es@2.0.0: {}
@@ -26782,6 +27159,10 @@ snapshots:
has-property-descriptors: 1.0.2
object-keys: 1.1.1
+ define-property@1.0.0:
+ dependencies:
+ is-descriptor: 1.0.4
+
defu@6.1.4: {}
delaunator@5.1.0:
@@ -27056,6 +27437,8 @@ snapshots:
is-date-object: 1.1.0
is-symbol: 1.1.1
+ es-toolkit@1.50.0: {}
+
esast-util-from-estree@2.0.0:
dependencies:
'@types/estree-jsx': 1.0.5
@@ -27235,8 +27618,8 @@ snapshots:
'@next/eslint-plugin-next': 16.1.6
eslint: 9.29.0(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@2.6.1))
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@2.6.1))
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1))
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1))
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.29.0(jiti@2.6.1))
eslint-plugin-react: 7.37.5(eslint@9.29.0(jiti@2.6.1))
eslint-plugin-react-hooks: 7.0.1(eslint@9.29.0(jiti@2.6.1))
@@ -27255,8 +27638,8 @@ snapshots:
'@next/eslint-plugin-next': 16.2.3
eslint: 9.29.0(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@2.6.1))
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@2.6.1))
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1))
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1))
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.29.0(jiti@2.6.1))
eslint-plugin-react: 7.37.5(eslint@9.29.0(jiti@2.6.1))
eslint-plugin-react-hooks: 7.0.1(eslint@9.29.0(jiti@2.6.1))
@@ -27282,7 +27665,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@2.6.1)):
+ eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
debug: 4.4.3
@@ -27293,22 +27676,22 @@ snapshots:
tinyglobby: 0.2.15
unrs-resolver: 1.11.1
optionalDependencies:
- eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@2.6.1))
+ eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1))
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@2.6.1)):
+ eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.29.0(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
- eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.29.0(jiti@2.6.1))
+ eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1))
transitivePeerDependencies:
- supports-color
- eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@2.6.1)):
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -27319,7 +27702,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.29.0(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9
- eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.29.0(jiti@2.6.1))
+ eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.1(eslint@9.29.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1)))(eslint@9.29.0(jiti@2.6.1))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -28326,6 +28709,10 @@ snapshots:
dependencies:
function-bind: 1.1.2
+ hasown@2.0.4:
+ dependencies:
+ function-bind: 1.1.2
+
hast-util-from-dom@5.0.1:
dependencies:
'@types/hast': 3.0.4
@@ -28655,6 +29042,8 @@ snapshots:
indent-string@4.0.0: {}
+ indent-string@5.0.0: {}
+
inflight@1.0.6:
dependencies:
once: 1.4.0
@@ -28666,6 +29055,56 @@ snapshots:
ini@4.1.1: {}
+ ink-big-text@2.0.0(ink@5.2.1(@types/react@19.2.14)(react@18.3.1))(react@18.3.1):
+ dependencies:
+ cfonts: 3.3.1
+ ink: 5.2.1(@types/react@19.2.14)(react@18.3.1)
+ prop-types: 15.8.1
+ react: 18.3.1
+
+ ink-spinner@5.0.0(ink@5.2.1(@types/react@19.2.14)(react@18.3.1))(react@18.3.1):
+ dependencies:
+ cli-spinners: 2.9.2
+ ink: 5.2.1(@types/react@19.2.14)(react@18.3.1)
+ react: 18.3.1
+
+ ink-testing-library@4.0.0(@types/react@19.2.14):
+ optionalDependencies:
+ '@types/react': 19.2.14
+
+ ink@5.2.1(@types/react@19.2.14)(react@18.3.1):
+ dependencies:
+ '@alcalzone/ansi-tokenize': 0.1.3
+ ansi-escapes: 7.3.0
+ ansi-styles: 6.2.1
+ auto-bind: 5.0.1
+ chalk: 5.6.2
+ cli-boxes: 3.0.0
+ cli-cursor: 4.0.0
+ cli-truncate: 4.0.0
+ code-excerpt: 4.0.0
+ es-toolkit: 1.50.0
+ indent-string: 5.0.0
+ is-in-ci: 1.0.0
+ patch-console: 2.0.0
+ react: 18.3.1
+ react-reconciler: 0.29.2(react@18.3.1)
+ scheduler: 0.23.2
+ signal-exit: 3.0.7
+ slice-ansi: 7.1.2
+ stack-utils: 2.0.6
+ string-width: 7.2.0
+ type-fest: 4.41.0
+ widest-line: 5.0.0
+ wrap-ansi: 9.0.2
+ ws: 8.20.0
+ yoga-layout: 3.2.1
+ optionalDependencies:
+ '@types/react': 19.2.14
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+
inline-style-parser@0.2.4: {}
inline-style-prefixer@7.0.1:
@@ -28718,6 +29157,10 @@ snapshots:
iron-webcrypto@1.2.1: {}
+ is-accessor-descriptor@1.0.2:
+ dependencies:
+ hasown: 2.0.4
+
is-alphabetical@1.0.4: {}
is-alphabetical@2.0.1: {}
@@ -28764,6 +29207,8 @@ snapshots:
call-bound: 1.0.4
has-tostringtag: 1.0.2
+ is-buffer@1.1.6: {}
+
is-bun-module@2.0.0:
dependencies:
semver: 7.7.4
@@ -28774,6 +29219,10 @@ snapshots:
dependencies:
hasown: 2.0.2
+ is-data-descriptor@1.0.1:
+ dependencies:
+ hasown: 2.0.2
+
is-data-view@1.0.2:
dependencies:
call-bound: 1.0.4
@@ -28789,6 +29238,11 @@ snapshots:
is-decimal@2.0.1: {}
+ is-descriptor@1.0.4:
+ dependencies:
+ is-accessor-descriptor: 1.0.2
+ is-data-descriptor: 1.0.1
+
is-docker@2.2.1: {}
is-docker@3.0.0: {}
@@ -28803,6 +29257,12 @@ snapshots:
is-fullwidth-code-point@3.0.0: {}
+ is-fullwidth-code-point@4.0.0: {}
+
+ is-fullwidth-code-point@5.1.0:
+ dependencies:
+ get-east-asian-width: 1.5.0
+
is-generator-function@1.1.0:
dependencies:
call-bound: 1.0.4
@@ -28818,6 +29278,8 @@ snapshots:
is-hexadecimal@2.0.1: {}
+ is-in-ci@1.0.0: {}
+
is-in-ssh@1.0.0: {}
is-inside-container@1.0.0:
@@ -28842,6 +29304,10 @@ snapshots:
call-bound: 1.0.4
has-tostringtag: 1.0.2
+ is-number@3.0.0:
+ dependencies:
+ kind-of: 3.2.2
+
is-number@7.0.0: {}
is-path-inside@4.0.0: {}
@@ -29095,7 +29561,7 @@ snapshots:
whatwg-encoding: 3.1.1
whatwg-mimetype: 4.0.0
whatwg-url: 14.2.0
- ws: 8.18.2
+ ws: 8.20.0
xml-name-validator: 5.0.0
transitivePeerDependencies:
- bufferutil
@@ -29155,6 +29621,10 @@ snapshots:
khroma@2.1.0: {}
+ kind-of@3.2.2:
+ dependencies:
+ is-buffer: 1.1.6
+
kind-of@6.0.3: {}
kleur@3.0.3: {}
@@ -30392,6 +30862,8 @@ snapshots:
mimic-fn@1.2.0: {}
+ mimic-fn@2.1.0: {}
+
mimic-fn@4.0.0: {}
min-indent@1.0.1: {}
@@ -30785,7 +31257,7 @@ snapshots:
'@nuxt/nitro-server': 3.21.2(db0@0.3.4)(ioredis@5.10.1)(magicast@0.5.2)(nuxt@3.21.2(@emnapi/core@1.8.1)(@emnapi/runtime@1.8.1)(@parcel/watcher@2.5.1)(@types/node@25.3.2)(@vue/compiler-sfc@3.5.31)(cac@6.7.14)(db0@0.3.4)(eslint@9.29.0(jiti@2.6.1))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.2)(optionator@0.9.4)(rolldown@1.0.0-rc.12(@emnapi/core@1.8.1)(@emnapi/runtime@1.8.1))(rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-rc.12(@emnapi/core@1.8.1)(@emnapi/runtime@1.8.1))(rollup@4.60.1))(rollup@4.60.1)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(typescript@5.9.3)(vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3))(vue-tsc@2.2.12(typescript@5.9.3))(yaml@2.8.3))(rolldown@1.0.0-rc.12(@emnapi/core@1.8.1)(@emnapi/runtime@1.8.1))(typescript@5.9.3)
'@nuxt/schema': 3.21.2
'@nuxt/telemetry': 2.7.0(@nuxt/kit@3.21.2(magicast@0.5.2))
- '@nuxt/vite-builder': 3.21.2(thirvmyz7u7sotpvl5josuvsem)
+ '@nuxt/vite-builder': 3.21.2(cda632d3acfa8c47554ee5be1e146aef)
'@unhead/vue': 2.1.13(vue@3.5.31(typescript@5.9.3))
'@vue/shared': 3.5.31
c12: 3.3.3(magicast@0.5.2)
@@ -31011,6 +31483,10 @@ snapshots:
dependencies:
mimic-fn: 1.2.0
+ onetime@5.1.2:
+ dependencies:
+ mimic-fn: 2.1.0
+
onetime@6.0.0:
dependencies:
mimic-fn: 4.0.0
@@ -31280,6 +31756,8 @@ snapshots:
partial-json@0.1.7: {}
+ patch-console@2.0.0: {}
+
path-browserify@1.0.1: {}
path-data-parser@0.1.0: {}
@@ -32162,6 +32640,12 @@ snapshots:
dependencies:
fast-deep-equal: 2.0.1
+ react-reconciler@0.29.2(react@18.3.1):
+ dependencies:
+ loose-envify: 1.4.0
+ react: 18.3.1
+ scheduler: 0.23.2
+
react-refresh@0.14.2: {}
react-refresh@0.17.0: {}
@@ -32326,6 +32810,10 @@ snapshots:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
+ react@18.3.1:
+ dependencies:
+ loose-envify: 1.4.0
+
react@19.2.0: {}
react@19.2.3: {}
@@ -32669,6 +33157,11 @@ snapshots:
onetime: 2.0.1
signal-exit: 3.0.7
+ restore-cursor@4.0.0:
+ dependencies:
+ onetime: 5.1.2
+ signal-exit: 3.0.7
+
retry@0.13.1: {}
reusify@1.1.0: {}
@@ -32724,7 +33217,7 @@ snapshots:
rollup-plugin-visualizer@7.0.1(rolldown@1.0.0-rc.12(@emnapi/core@1.8.1)(@emnapi/runtime@1.8.1))(rollup@4.60.1):
dependencies:
open: 11.0.0
- picomatch: 4.0.3
+ picomatch: 4.0.4
source-map: 0.7.6
yargs: 18.0.0
optionalDependencies:
@@ -32870,6 +33363,10 @@ snapshots:
dependencies:
xmlchars: 2.2.0
+ scheduler@0.23.2:
+ dependencies:
+ loose-envify: 1.4.0
+
scheduler@0.27.0: {}
schema-utils@4.3.2:
@@ -33111,6 +33608,16 @@ snapshots:
slash@5.1.0: {}
+ slice-ansi@5.0.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 4.0.0
+
+ slice-ansi@7.1.2:
+ dependencies:
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 5.1.0
+
slugify@1.6.8: {}
smob@1.6.1: {}
@@ -33230,7 +33737,7 @@ snapshots:
dependencies:
eastasianwidth: 0.2.0
emoji-regex: 9.2.2
- strip-ansi: 7.1.0
+ strip-ansi: 7.2.0
string-width@7.2.0:
dependencies:
@@ -33311,7 +33818,11 @@ snapshots:
strip-ansi@7.1.0:
dependencies:
- ansi-regex: 6.1.0
+ ansi-regex: 6.2.2
+
+ strip-ansi@7.2.0:
+ dependencies:
+ ansi-regex: 6.2.2
strip-bom-string@1.0.0: {}
@@ -33731,7 +34242,7 @@ snapshots:
tsx@4.20.3:
dependencies:
esbuild: 0.25.12
- get-tsconfig: 4.10.1
+ get-tsconfig: 4.13.7
optionalDependencies:
fsevents: 2.3.3
@@ -33749,6 +34260,8 @@ snapshots:
type-fest@0.7.1: {}
+ type-fest@4.41.0: {}
+
type-fest@5.5.0:
dependencies:
tagged-tag: 1.0.0
@@ -33968,7 +34481,7 @@ snapshots:
unplugin-utils@0.3.1:
dependencies:
pathe: 2.0.3
- picomatch: 4.0.3
+ picomatch: 4.0.4
unplugin-vue-router@0.19.2(@vue/compiler-sfc@3.5.31)(vue-router@4.6.4(vue@3.5.31(typescript@5.9.3)))(vue@3.5.31(typescript@5.9.3)):
dependencies:
@@ -34004,7 +34517,7 @@ snapshots:
dependencies:
'@jridgewell/remapping': 2.3.5
acorn: 8.16.0
- picomatch: 4.0.3
+ picomatch: 4.0.4
webpack-virtual-modules: 0.6.2
unplugin@3.0.0:
@@ -34139,14 +34652,18 @@ snapshots:
dependencies:
react: 19.2.3
- use-sync-external-store@1.5.0(react@19.2.4):
+ use-sync-external-store@1.6.0(react@18.3.1):
dependencies:
- react: 19.2.4
+ react: 18.3.1
use-sync-external-store@1.6.0(react@19.2.3):
dependencies:
react: 19.2.3
+ use-sync-external-store@1.6.0(react@19.2.4):
+ dependencies:
+ react: 19.2.4
+
util-deprecate@1.0.2: {}
util@0.12.5:
@@ -34271,7 +34788,7 @@ snapshots:
chokidar: 4.0.3
npm-run-path: 6.0.0
picocolors: 1.1.1
- picomatch: 4.0.3
+ picomatch: 4.0.4
tiny-invariant: 1.3.3
tinyglobby: 0.2.15
vite: 7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3)
@@ -34321,6 +34838,24 @@ snapshots:
sass: 1.89.2
terser: 5.43.0
+ vite@6.4.1(@types/node@20.19.35)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3):
+ dependencies:
+ esbuild: 0.25.12
+ fdir: 6.5.0(picomatch@4.0.3)
+ picomatch: 4.0.3
+ postcss: 8.5.6
+ rollup: 4.43.0
+ tinyglobby: 0.2.15
+ optionalDependencies:
+ '@types/node': 20.19.35
+ fsevents: 2.3.3
+ jiti: 2.6.1
+ lightningcss: 1.32.0
+ sass: 1.89.2
+ terser: 5.43.0
+ tsx: 4.20.3
+ yaml: 2.8.3
+
vite@6.4.1(@types/node@22.15.32)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3):
dependencies:
esbuild: 0.25.12
@@ -34360,8 +34895,8 @@ snapshots:
vite@7.3.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3):
dependencies:
esbuild: 0.27.4
- fdir: 6.5.0(picomatch@4.0.3)
- picomatch: 4.0.3
+ fdir: 6.5.0(picomatch@4.0.4)
+ picomatch: 4.0.4
postcss: 8.5.8
rollup: 4.60.1
tinyglobby: 0.2.15
@@ -34422,6 +34957,45 @@ snapshots:
- tsx
- yaml
+ vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.35)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3):
+ dependencies:
+ '@vitest/expect': 4.0.18
+ '@vitest/mocker': 4.0.18(vite@6.4.1(@types/node@20.19.35)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3))
+ '@vitest/pretty-format': 4.0.18
+ '@vitest/runner': 4.0.18
+ '@vitest/snapshot': 4.0.18
+ '@vitest/spy': 4.0.18
+ '@vitest/utils': 4.0.18
+ es-module-lexer: 1.7.0
+ expect-type: 1.3.0
+ magic-string: 0.30.21
+ obug: 2.1.1
+ pathe: 2.0.3
+ picomatch: 4.0.4
+ std-env: 3.10.0
+ tinybench: 2.9.0
+ tinyexec: 1.0.4
+ tinyglobby: 0.2.15
+ tinyrainbow: 3.0.3
+ vite: 6.4.1(@types/node@20.19.35)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@opentelemetry/api': 1.9.0
+ '@types/node': 20.19.35
+ jsdom: 26.1.0
+ transitivePeerDependencies:
+ - jiti
+ - less
+ - lightningcss
+ - msw
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - terser
+ - tsx
+ - yaml
+
vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@22.15.32)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3):
dependencies:
'@vitest/expect': 4.0.18
@@ -34436,10 +35010,10 @@ snapshots:
magic-string: 0.30.21
obug: 2.1.1
pathe: 2.0.3
- picomatch: 4.0.3
+ picomatch: 4.0.4
std-env: 3.10.0
tinybench: 2.9.0
- tinyexec: 1.0.2
+ tinyexec: 1.0.4
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
vite: 6.4.1(@types/node@22.15.32)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3)
@@ -34475,10 +35049,10 @@ snapshots:
magic-string: 0.30.21
obug: 2.1.1
pathe: 2.0.3
- picomatch: 4.0.3
+ picomatch: 4.0.4
std-env: 3.10.0
tinybench: 2.9.0
- tinyexec: 1.0.2
+ tinyexec: 1.0.4
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
vite: 6.4.1(@types/node@25.3.2)(jiti@2.6.1)(lightningcss@1.32.0)(sass@1.89.2)(terser@5.43.0)(tsx@4.20.3)(yaml@2.8.3)
@@ -34692,6 +35266,15 @@ snapshots:
siginfo: 2.0.0
stackback: 0.0.2
+ widest-line@5.0.0:
+ dependencies:
+ string-width: 7.2.0
+
+ window-size@1.1.1:
+ dependencies:
+ define-property: 1.0.0
+ is-number: 3.0.0
+
wonka@6.3.5: {}
word-wrap@1.2.5: {}
@@ -34706,7 +35289,7 @@ snapshots:
dependencies:
ansi-styles: 6.2.1
string-width: 5.1.2
- strip-ansi: 7.1.0
+ strip-ansi: 7.2.0
wrap-ansi@9.0.2:
dependencies:
@@ -34727,8 +35310,6 @@ snapshots:
ws@7.5.10: {}
- ws@8.18.2: {}
-
ws@8.20.0: {}
wsl-utils@0.1.0:
@@ -34811,6 +35392,8 @@ snapshots:
yoctocolors@2.1.2: {}
+ yoga-layout@3.2.1: {}
+
youch-core@0.3.3:
dependencies:
'@poppinss/exception': 1.2.3
@@ -34856,9 +35439,16 @@ snapshots:
zod@4.3.6: {}
+ zustand@4.5.7(@types/react@19.2.14)(react@18.3.1):
+ dependencies:
+ use-sync-external-store: 1.6.0(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 19.2.14
+ react: 18.3.1
+
zustand@4.5.7(@types/react@19.2.14)(react@19.2.4):
dependencies:
- use-sync-external-store: 1.5.0(react@19.2.4)
+ use-sync-external-store: 1.6.0(react@19.2.4)
optionalDependencies:
'@types/react': 19.2.14
react: 19.2.4