diff --git a/docs/harness/cli.md b/docs/harness/cli.md index b071f48630..87f364c30c 100644 --- a/docs/harness/cli.md +++ b/docs/harness/cli.md @@ -168,7 +168,7 @@ process.exitCode = await runCli(assistant, { - When `ui` resolves, the CLI disposes the view and `runCli` returns. - To write `Screen`, read [Build your own UI](./custom-ui). -For a full Ink screen with approvals, questions, sign-ins, and child agents, copy [`examples/harness-cli/src/tui.tsx`](https://github.com/TanStack/ai/blob/main/examples/harness-cli/src/tui.tsx). +For an Ink screen with approvals, questions, sign-ins, and child agents, copy [`examples/harness-cli/src/tui.tsx`](https://github.com/TanStack/ai/blob/main/examples/harness-cli/src/tui.tsx). ## What you have now diff --git a/docs/harness/custom-ui.md b/docs/harness/custom-ui.md index a78bbea267..3cd30f2369 100644 --- a/docs/harness/custom-ui.md +++ b/docs/harness/custom-ui.md @@ -103,6 +103,8 @@ await view.send('Summarize the README.') Put the code of steps 1 and 2 in one `.tsx` file, then run it. The screen shows your prompt, then the answer while it streams, then the status `idle`. Press Ctrl+C to quit. +An Ink screen with approvals, questions, sign-ins, and child agents is in [`examples/harness-cli/src/tui.tsx`](https://github.com/TanStack/ai/blob/main/examples/harness-cli/src/tui.tsx). It runs from [`runCli({ ui })`](./cli#run-your-own-screen). + Each TanStack Store adapter reads the store the same way. Vue, Solid, Svelte, and Preact have `useSelector`. Angular has `injectSelector`. With no UI library, subscribe to the store: ```ts group=harness-custom-ui diff --git a/examples/README.md b/examples/README.md index 34a6460347..4ac39cdae9 100644 --- a/examples/README.md +++ b/examples/README.md @@ -12,6 +12,7 @@ Choose an example based on your use case: - **Want typed ticket routing?** → [Evaluate](#evaluate) - **Want a blog desk with three agents?** → [Subagents](#subagents) - **Want your own MCP server?** → [MCP server](#mcp-server) +- **Want an agent in the terminal?** → [Harness CLI](#harness-cli) - **Want a full-stack TypeScript app?** → [TanStack Chat (ts-react-chat)](#tanstack-chat-ts-react-chat) - **Need a live world stream?** → [World generation (ts-react-media)](#world-generation-ts-react-media) - **Need a vanilla JS frontend?** → [Vanilla Chat](#vanilla-chat) @@ -146,6 +147,24 @@ Open http://localhost:3100. Click Call the server. --- +### Harness CLI + +A notes assistant in the terminal. A harness with two tools, run by `runCli`, with a small Ink screen on the session view. + +**Path:** `examples/harness-cli` + +**Getting Started:** + +```bash +OPENAI_API_KEY=sk-... pnpm --filter harness-cli-example start +``` + +Ask it to save a note. Press `y` to approve the write. + +📖 [Full Documentation](harness-cli/README.md) + +--- + ### TanStack Chat (ts-react-chat) A full-featured chat application built with the TanStack ecosystem. diff --git a/examples/harness-cli/.gitignore b/examples/harness-cli/.gitignore new file mode 100644 index 0000000000..f30475e545 --- /dev/null +++ b/examples/harness-cli/.gitignore @@ -0,0 +1,4 @@ +# The notes the assistant saves. +notes/ +# Media the CLI saves (the default --media-dir). +*-media/ diff --git a/examples/harness-cli/README.md b/examples/harness-cli/README.md new file mode 100644 index 0000000000..1ad8102879 --- /dev/null +++ b/examples/harness-cli/README.md @@ -0,0 +1,29 @@ +# Harness CLI example + +A notes assistant in your terminal, built with `@tanstack/ai-harness` and `@tanstack/ai-harness-cli`. Ask it to write a note. It asks you before it saves the file. + +## Run it + +From the repo root: + +1. `pnpm install` +2. `pnpm build:all` (the example uses the local packages) +3. `OPENAI_API_KEY=sk-... pnpm --filter harness-cli-example start` + +Type `Save a note about the moon landing`. The screen shows the `save_note` call. Press `y`, and the note is in `examples/harness-cli/notes/`. + +## What is in it + +- `src/harness.ts`: the harness. One model, a `list_notes` tool, and a `save_note` tool that needs approval. +- `src/cli.ts`: `runCli(assistant, { ui: runTui })`. That is the whole entry file. +- `src/tui.tsx`: an Ink screen on the session view. It shows the messages, tool calls, child agents, sign-ins, approvals (`y` or `n`), and questions. + +## Other modes + +The same entry file has every mode of `runCli`. Run these from `examples/harness-cli`: + +- `pnpm start -p "List my notes"` runs one prompt and prints the answer. +- `echo "List my notes" | pnpm start` uses line mode. +- `pnpm start --serve` serves the session protocol over HTTP with a bearer token. + +Read [Run a harness in the terminal](../../docs/harness/cli.md) and [Build your own UI](../../docs/harness/custom-ui.md). diff --git a/examples/harness-cli/package.json b/examples/harness-cli/package.json new file mode 100644 index 0000000000..4af3c26221 --- /dev/null +++ b/examples/harness-cli/package.json @@ -0,0 +1,25 @@ +{ + "name": "harness-cli-example", + "private": true, + "type": "module", + "description": "A notes assistant in the terminal, built with @tanstack/ai-harness and @tanstack/ai-harness-cli", + "scripts": { + "start": "tsx src/cli.ts", + "test:types": "tsc --noEmit" + }, + "dependencies": { + "@tanstack/ai": "workspace:*", + "@tanstack/ai-harness": "workspace:*", + "@tanstack/ai-harness-cli": "workspace:*", + "@tanstack/ai-openai": "workspace:*", + "@tanstack/react-store": "^0.11.1", + "ink": "^7.1.1", + "react": "^19.2.3", + "zod": "^4.2.0" + }, + "devDependencies": { + "@types/node": "^24.10.1", + "@types/react": "^19.2.7", + "tsx": "^4.23.12" + } +} diff --git a/examples/harness-cli/src/cli.ts b/examples/harness-cli/src/cli.ts new file mode 100644 index 0000000000..8874103bd9 --- /dev/null +++ b/examples/harness-cli/src/cli.ts @@ -0,0 +1,7 @@ +import { runCli } from '@tanstack/ai-harness-cli' +import { assistant } from './harness' +import { runTui } from './tui' + +// A terminal shows the Ink screen of ./tui. Piped input uses line mode, and +// `-p "prompt"` and `--serve` work as in every runCli app. +process.exitCode = await runCli(assistant, { ui: runTui }) diff --git a/examples/harness-cli/src/harness.ts b/examples/harness-cli/src/harness.ts new file mode 100644 index 0000000000..bb9743020f --- /dev/null +++ b/examples/harness-cli/src/harness.ts @@ -0,0 +1,39 @@ +import { mkdir, readdir, writeFile } from 'node:fs/promises' +import { join } from 'node:path' +import { toolDefinition } from '@tanstack/ai' +import { defineHarness } from '@tanstack/ai-harness' +import { openaiText } from '@tanstack/ai-openai' +import { z } from 'zod' + +// The notes go in a `notes` folder where you start the app. +const NOTES = join(process.cwd(), 'notes') + +const listNotes = toolDefinition({ + name: 'list_notes', + description: 'List the file names of the saved notes', + inputSchema: z.object({}), +}).server(async () => ({ notes: await readdir(NOTES).catch(() => []) })) + +// A write asks the user first, so the screen shows an approval. +const saveNote = toolDefinition({ + name: 'save_note', + description: 'Save a note as a Markdown file', + inputSchema: z.object({ title: z.string(), text: z.string() }), + needsApproval: true, +}).server(async ({ title, text }) => { + // The time keeps two notes with the same title apart. + const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, '-') || 'note' + const file = `${Date.now()}-${slug}.md` + await mkdir(NOTES, { recursive: true }) + await writeFile(join(NOTES, file), text) + return { saved: file } +}) + +export const assistant = defineHarness({ + name: 'example/notes', + adapter: openaiText('gpt-6.1-sol'), + systemPrompts: [ + 'You help the user write short notes. Save a note only when the user asks.', + ], + tools: [listNotes, saveNote], +}) diff --git a/examples/harness-cli/src/tui.tsx b/examples/harness-cli/src/tui.tsx new file mode 100644 index 0000000000..6750df488c --- /dev/null +++ b/examples/harness-cli/src/tui.tsx @@ -0,0 +1,166 @@ +import { useState } from 'react' +import { Box, Static, Text, render, useApp, useInput } from 'ink' +import { useSelector } from '@tanstack/react-store' +import type { + SessionView, + ViewMessage, + ViewPart, +} from '@tanstack/ai-harness/view' + +function Part({ part }: { part: ViewPart }) { + switch (part.type) { + case 'text': + return {part.text} + case 'reasoning': + return {part.text} + case 'tool-call': + return ( + + {`* ${part.name} (${part.status})`} + + ) + case 'agent': + return ( + + {`${part.name} (${part.status})`} + {part.parts.map((child, index) => ( + + ))} + + ) + case 'media': + return {`[${part.kind}: ${part.name}]`} + } +} + +function Message({ message }: { message: ViewMessage }) { + if (message.role === 'user') { + return {`> ${message.text}`} + } + if (message.role === 'notice') { + return ( + + {message.text} + + ) + } + return ( + + {message.parts.map((part, index) => ( + + ))} + + ) +} + +/** The typed answer: JSON (a number, a boolean) unless the question wants text. */ +function answerOf(text: string, schema: unknown): unknown { + const wantsText = + typeof schema !== 'object' || + schema === null || + Reflect.get(schema, 'type') === 'string' + if (wantsText) return text + try { + return JSON.parse(text) + } catch { + return text + } +} + +/** The whole screen: the messages, then one line for what waits for you. */ +function Screen({ view }: { view: SessionView }) { + const { exit } = useApp() + const state = useSelector(view.store) + const [line, setLine] = useState('') + // The turn goes on when every approval has an answer, so the screen asks + // them one by one. + const [answered, setAnswered] = useState>([]) + const approval = state.approvals.find(({ id }) => !answered.includes(id)) + const [question] = state.questions + + useInput((input, key) => { + if (key.escape) { + void view.cancel() + return + } + // An approval takes one key: y or n. + if (approval) { + if (input !== 'y' && input !== 'n') return + if (input === 'y') approval.approve() + else approval.reject() + setAnswered((ids) => [...ids, approval.id]) + return + } + if (key.return) { + const text = line.trim() + setLine('') + if (text === '/exit') exit() + else if (question) { + void question + .answer(answerOf(text, question.schema)) + .then((receipt) => { + if (receipt.status === 'rejected') { + view.notice(`Answer again: ${receipt.reason ?? 'not accepted'}`) + } + }) + } + // A `/command` runs the command. Text while a turn runs steers it. + else void view.send(text) + return + } + if (key.backspace || key.delete) { + setLine((value) => value.slice(0, -1)) + return + } + // A paste can hold line breaks. The line stays one line. + if (!key.ctrl && !key.meta) { + setLine((value) => value + input.replace(/[\r\n]+/g, ' ')) + } + }) + + // The turns before the last message you sent do not change, so Ink prints + // them once. Only the running turn redraws. + let lastSent = 0 + state.messages.forEach((message, index) => { + if (message.role === 'user') lastSent = index + }) + const done = state.messages.slice(0, lastSent) + const live = state.messages.slice(lastSent) + + const typed = question?.secret ? '*'.repeat(line.length) : line + return ( + + + {(message) => } + + {live.map((message) => ( + + ))} + {state.signIns.map((signIn) => ( + + {`Sign in to ${signIn.connector}: ${signIn.url ?? ''} ${signIn.userCode ?? ''}`} + + ))} + {approval ? ( + + {`Run ${approval.tool} ${JSON.stringify(approval.args)}? (y/n)`} + + ) : ( + + {question?.url ? ( + {`Open ${question.url}`} + ) : null} + {`${question ? `? ${question.message} ` : '> '}${typed}`} + + )} + + {`${state.status}. Enter sends, Esc cancels, /exit quits.`} + + + ) +} + +/** The `ui` of runCli: show the screen until the user quits. */ +export async function runTui(view: SessionView) { + await render().waitUntilExit() +} diff --git a/examples/harness-cli/tsconfig.json b/examples/harness-cli/tsconfig.json new file mode 100644 index 0000000000..cc93365a78 --- /dev/null +++ b/examples/harness-cli/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "types": ["node"], + "esModuleInterop": true, + "jsx": "react-jsx" + }, + "include": ["src"] +} diff --git a/examples/ts-react-chat/package.json b/examples/ts-react-chat/package.json index 3ce3a7f02d..dace1d669a 100644 --- a/examples/ts-react-chat/package.json +++ b/examples/ts-react-chat/package.json @@ -54,7 +54,7 @@ "@tanstack/react-router-devtools": "^1.158.4", "@tanstack/react-router-ssr-query": "^1.158.4", "@tanstack/react-start": "^1.168.60", - "@tanstack/react-store": "^0.8.0", + "@tanstack/react-store": "^0.11.1", "@tanstack/router-plugin": "^1.168.42", "@tanstack/store": "^0.11.1", "dockerode": "^4.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 071cc1fb86..3dcfdd0fc0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -174,6 +174,43 @@ importers: specifier: ^8.2.1 version: 8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0) + examples/harness-cli: + dependencies: + '@tanstack/ai': + specifier: workspace:* + version: link:../../packages/ai + '@tanstack/ai-harness': + specifier: workspace:* + version: link:../../packages/ai-harness + '@tanstack/ai-harness-cli': + specifier: workspace:* + version: link:../../packages/ai-harness-cli + '@tanstack/ai-openai': + specifier: workspace:* + version: link:../../packages/ai-openai + '@tanstack/react-store': + specifier: ^0.11.1 + version: 0.11.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + ink: + specifier: ^7.1.1 + version: 7.1.1(@types/react@19.2.7)(react-devtools-core@6.1.5)(react@19.2.3) + react: + specifier: ^19.2.3 + version: 19.2.3 + zod: + specifier: ^4.2.0 + version: 4.2.1 + devDependencies: + '@types/node': + specifier: ^24.10.1 + version: 24.10.3 + '@types/react': + specifier: ^19.2.7 + version: 19.2.7 + tsx: + specifier: ^4.23.12 + version: 4.23.12 + examples/react/basic-chat: dependencies: '@tailwindcss/vite': @@ -1191,8 +1228,8 @@ importers: specifier: ^1.168.60 version: 1.168.60(crossws@0.4.6(srvx@0.11.22))(esbuild@0.28.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rolldown@1.2.9)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) '@tanstack/react-store': - specifier: ^0.8.0 - version: 0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^0.11.1 + version: 0.11.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/router-plugin': specifier: ^1.168.42 version: 1.168.42(@tanstack/react-router@1.170.41(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(esbuild@0.28.1)(rolldown@1.2.9)(rollup@4.60.1)(vite-plugin-solid@2.11.14(solid-js@1.9.10)(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)))(vite@8.2.1(@types/node@24.10.3)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.44.1)(tsx@4.23.12)(yaml@2.9.0)) @@ -4053,6 +4090,10 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 + '@alcalzone/ansi-tokenize@0.3.1': + resolution: {integrity: sha512-cUD0PT0YX+rImRhfn7BfMRduP/tX/Zqt/N0dHlAyn2RlcJssCb5KsCJkhln61eh9vuJDkH8wKn3L8zJzzWXPFg==} + engines: {node: '>=18'} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -10869,12 +10910,6 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/react-store@0.8.0': - resolution: {integrity: sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@tanstack/router-core@1.171.34': resolution: {integrity: sha512-X+19pGuuLVPvvAvPYw9v/+ktRk5cCll8AtfpBpOhDRmVgUMrfqze0467xtq8YRVVs/mmo5rVtWn/7Tp32RDBKw==} engines: {node: '>=20.19'} @@ -11952,10 +11987,6 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} - engines: {node: '>=12'} - ansi-regex@6.3.0: resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==} engines: {node: '>=12'} @@ -12073,6 +12104,10 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + auto-bind@5.0.1: + resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + autoprefixer@10.4.22: resolution: {integrity: sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==} engines: {node: ^10 || ^12 || >=14} @@ -12522,6 +12557,10 @@ packages: classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + cli-boxes@4.0.1: + resolution: {integrity: sha512-5IOn+jcCEHEraYolBPs/sT4BxYCe2nHg374OPiItB1O96KZFseS2gthU4twyYzeDcFew4DaUM/xwc5BQf08JJw==} + engines: {node: '>=18.20 <19 || >=20.10'} + cli-cursor@2.1.0: resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} engines: {node: '>=4'} @@ -12530,6 +12569,10 @@ packages: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} + cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-cursor@5.0.0: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} engines: {node: '>=18'} @@ -12546,6 +12589,10 @@ packages: resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} engines: {node: '>=20'} + cli-truncate@6.1.1: + resolution: {integrity: sha512-06p9vyLahLa4zkGcgsGxU6iEkSOiuI4fhCH6Emhe2lPAcoUv73n72DnODsnHA+5wwXGnV0n9M9/qOQJSjYhFhw==} + engines: {node: '>=22'} + cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} @@ -12581,6 +12628,10 @@ packages: code-block-writer@12.0.0: resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==} + code-excerpt@4.0.0: + resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -12711,6 +12762,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==} @@ -13424,6 +13479,9 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} + es-toolkit@1.52.0: + resolution: {integrity: sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==} + esbuild-plugin-solid@0.5.0: resolution: {integrity: sha512-ITK6n+0ayGFeDVUZWNMxX+vLsasEN1ILrg4pISsNOQ+mq4ljlJJiuXotInd+HE0MzwTcA9wExT1yzDE2hsqPsg==} peerDependencies: @@ -13456,6 +13514,10 @@ packages: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -13998,10 +14060,6 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} - engines: {node: '>=18'} - get-east-asian-width@1.7.0: resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} engines: {node: '>=18'} @@ -14397,6 +14455,10 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -14406,6 +14468,19 @@ packages: injection-js@2.6.1: resolution: {integrity: sha512-dbR5bdhi7TWDoCye9cByZqeg/gAfamm8Vu3G1KZOTYkOif8WkuM8CD0oeDPtZYMzT5YH76JAFB7bkmyY9OJi2A==} + ink@7.1.1: + resolution: {integrity: sha512-Y43xxa1ZSPvpmfLHcN5o+OdP8Rf8ykkNJEuKYOUNZKT8wXVNLFTtEm1nSDMQkfBH+YANF4Xuu0hhZ4ejqAtN2w==} + engines: {node: '>=22'} + peerDependencies: + '@types/react': '>=19.2.0' + react: '>=19.2.0' + react-devtools-core: '>=6.1.2' + peerDependenciesMeta: + '@types/react': + optional: true + react-devtools-core: + optional: true + inline-style-parser@0.1.1: resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} @@ -14526,6 +14601,11 @@ packages: resolution: {integrity: sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg==} engines: {node: '>=8'} + is-in-ci@2.0.0: + resolution: {integrity: sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==} + engines: {node: '>=20'} + hasBin: true + is-in-ssh@1.0.0: resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} engines: {node: '>=20'} @@ -16258,6 +16338,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==} @@ -16709,6 +16793,12 @@ packages: '@types/react': optional: true + react-reconciler@0.33.0: + resolution: {integrity: sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==} + engines: {node: '>=0.10.0'} + peerDependencies: + react: ^19.2.0 + react-refresh@0.14.2: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} @@ -16938,6 +17028,10 @@ packages: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} + restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + restore-cursor@5.1.0: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} @@ -17335,6 +17429,10 @@ packages: resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} engines: {node: '>=20'} + slice-ansi@9.0.1: + resolution: {integrity: sha512-aBY19bn/XA+hKOKX0qL7Z0UfdBsbQvc9hn993U8ALUjzxCvDcuZqLoRXjGJrUARWAlwMnsRVD9sw2AFNOYvalA==} + engines: {node: '>=22'} + slugify@1.6.9: resolution: {integrity: sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==} engines: {node: '>=8.0.0'} @@ -17427,6 +17525,10 @@ packages: resolution: {integrity: sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==} engines: {node: '>=10.16.0'} + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -17502,10 +17604,6 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} - string-width@8.2.1: - resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} - engines: {node: '>=20'} - string-width@8.2.2: resolution: {integrity: sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==} engines: {node: '>=20'} @@ -17677,6 +17775,10 @@ packages: resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} engines: {node: '>=8'} + terminal-size@4.0.1: + resolution: {integrity: sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ==} + engines: {node: '>=18'} + terser@5.44.1: resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==} engines: {node: '>=10'} @@ -17915,6 +18017,10 @@ packages: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} + type-fest@5.10.0: + resolution: {integrity: sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==} + engines: {node: '>=20'} + type-fest@5.3.1: resolution: {integrity: sha512-VCn+LMHbd4t6sF3wfU/+HKT63C9OoyrSIf4b+vtWHpt2U7/4InZG467YDNMFMR70DdHjAdpPWmw2lzRdg0Xqqg==} engines: {node: '>=20'} @@ -18801,6 +18907,10 @@ packages: engines: {node: '>=8'} hasBin: true + widest-line@6.0.0: + resolution: {integrity: sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA==} + engines: {node: '>=20'} + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -18825,6 +18935,10 @@ packages: '@cloudflare/workers-types': optional: true + wrap-ansi@10.0.2: + resolution: {integrity: sha512-6OLRNZqRntVGBm26ghZ5eZhCuWWyOkRCSn8XsOIuq5stpCE/tjLbdozd93naILZig0lmD8ANfRwnhn0DLeXGlg==} + engines: {node: '>=20'} + wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -18997,6 +19111,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==} @@ -19054,6 +19171,11 @@ snapshots: dependencies: zod: 4.3.6 + '@alcalzone/ansi-tokenize@0.3.1': + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.13 @@ -21833,7 +21955,7 @@ snapshots: terminal-link: 2.1.1 toqr: 0.1.1 wrap-ansi: 7.0.0 - ws: 8.21.0 + ws: 8.21.3 zod: 3.25.76 optionalDependencies: react-native: 0.85.3(@babel/core@7.29.7)(@types/react@19.2.7)(react@19.2.3)(supports-color@7.2.0) @@ -21908,7 +22030,7 @@ snapshots: terminal-link: 2.1.1 toqr: 0.1.1 wrap-ansi: 7.0.0 - ws: 8.21.0 + ws: 8.21.3 zod: 3.25.76 optionalDependencies: react-native: 0.85.3(@babel/core@7.29.7)(@types/react@19.2.7)(react@19.2.3) @@ -22545,7 +22667,7 @@ snapshots: dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.2 + 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 @@ -27109,7 +27231,7 @@ snapshots: '@tanstack/devtools-event-bus@0.3.3': dependencies: - ws: 8.21.0 + ws: 8.21.3 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -27625,13 +27747,6 @@ snapshots: react-dom: 19.2.3(react@19.2.3) use-sync-external-store: 1.6.0(react@19.2.3) - '@tanstack/react-store@0.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': - dependencies: - '@tanstack/store': 0.8.0 - react: 19.2.3 - react-dom: 19.2.3(react@19.2.3) - use-sync-external-store: 1.6.0(react@19.2.3) - '@tanstack/router-core@1.171.34': dependencies: '@tanstack/history': 1.162.4 @@ -29169,8 +29284,6 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.2: {} - ansi-regex@6.3.0: {} ansi-styles@3.2.1: @@ -29295,6 +29408,8 @@ snapshots: asynckit@0.4.0: {} + auto-bind@5.0.1: {} + autoprefixer@10.4.22(postcss@8.5.26): dependencies: browserslist: 4.28.1 @@ -29922,6 +30037,8 @@ snapshots: classnames@2.5.1: optional: true + cli-boxes@4.0.1: {} + cli-cursor@2.1.0: dependencies: restore-cursor: 2.0.0 @@ -29930,6 +30047,10 @@ snapshots: dependencies: restore-cursor: 3.1.0 + cli-cursor@4.0.0: + dependencies: + restore-cursor: 4.0.0 + cli-cursor@5.0.0: dependencies: restore-cursor: 5.1.0 @@ -29941,7 +30062,12 @@ snapshots: cli-truncate@5.2.0: dependencies: slice-ansi: 8.0.0 - string-width: 8.2.1 + string-width: 8.2.2 + + cli-truncate@6.1.1: + dependencies: + slice-ansi: 9.0.1 + string-width: 8.2.2 cli-width@4.1.0: {} @@ -29977,6 +30103,10 @@ snapshots: code-block-writer@12.0.0: {} + code-excerpt@4.0.0: + dependencies: + convert-to-spaces: 2.0.1 + color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -30092,6 +30222,8 @@ snapshots: convert-source-map@2.0.0: {} + convert-to-spaces@2.0.1: {} + cookie-es@1.2.2: {} cookie-es@2.0.1: {} @@ -30714,6 +30846,8 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.4 + es-toolkit@1.52.0: {} + esbuild-plugin-solid@0.5.0(esbuild@0.28.1)(solid-js@1.9.10): dependencies: '@babel/core': 7.29.7 @@ -30817,6 +30951,8 @@ snapshots: escape-string-regexp@1.0.5: {} + escape-string-regexp@2.0.0: {} + escape-string-regexp@4.0.0: {} escape-string-regexp@5.0.0: {} @@ -31512,8 +31648,6 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.6.0: {} - get-east-asian-width@1.7.0: {} get-intrinsic@1.3.0: @@ -32000,6 +32134,8 @@ snapshots: imurmurhash@0.1.4: {} + indent-string@5.0.0: {} + inherits@2.0.4: {} ini@1.3.8: {} @@ -32008,6 +32144,41 @@ snapshots: dependencies: tslib: 2.8.1 + ink@7.1.1(@types/react@19.2.7)(react-devtools-core@6.1.5)(react@19.2.3): + dependencies: + '@alcalzone/ansi-tokenize': 0.3.1 + ansi-escapes: 7.3.0 + ansi-styles: 6.2.3 + auto-bind: 5.0.1 + chalk: 5.6.2 + cli-boxes: 4.0.1 + cli-cursor: 4.0.0 + cli-truncate: 6.1.1 + code-excerpt: 4.0.0 + es-toolkit: 1.52.0 + indent-string: 5.0.0 + is-in-ci: 2.0.0 + patch-console: 2.0.0 + react: 19.2.3 + react-reconciler: 0.33.0(react@19.2.3) + scheduler: 0.27.0 + signal-exit: 3.0.7 + slice-ansi: 9.0.1 + stack-utils: 2.0.6 + string-width: 8.2.2 + terminal-size: 4.0.1 + type-fest: 5.10.0 + widest-line: 6.0.0 + wrap-ansi: 10.0.2 + ws: 8.21.3 + yoga-layout: 3.2.1 + optionalDependencies: + '@types/react': 19.2.7 + react-devtools-core: 6.1.5 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + inline-style-parser@0.1.1: {} inline-style-parser@0.2.7: {} @@ -32112,7 +32283,7 @@ snapshots: is-fullwidth-code-point@5.1.0: dependencies: - get-east-asian-width: 1.6.0 + get-east-asian-width: 1.7.0 is-glob@4.0.3: dependencies: @@ -32124,6 +32295,8 @@ snapshots: dependencies: html-tags: 3.3.1 + is-in-ci@2.0.0: {} + is-in-ssh@1.0.0: {} is-inside-container@1.0.0: @@ -34861,6 +35034,8 @@ snapshots: partial-json@0.1.7: {} + patch-console@2.0.0: {} + path-browserify@1.0.1: {} path-exists@3.0.0: {} @@ -35228,7 +35403,7 @@ snapshots: devtools-protocol: 0.0.1581282 typed-query-selector: 2.12.1 webdriver-bidi-protocol: 0.4.1 - ws: 8.21.0 + ws: 8.21.3 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -35603,6 +35778,11 @@ snapshots: - supports-color - utf-8-validate + react-reconciler@0.33.0(react@19.2.3): + dependencies: + react: 19.2.3 + scheduler: 0.27.0 + react-refresh@0.14.2: {} react-refresh@0.18.0: {} @@ -35950,6 +36130,11 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 + restore-cursor@4.0.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + restore-cursor@5.1.0: dependencies: onetime: 7.0.0 @@ -36582,6 +36767,11 @@ snapshots: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 + slice-ansi@9.0.1: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + slugify@1.6.9: {} smart-buffer@4.2.0: {} @@ -36676,6 +36866,10 @@ snapshots: cpu-features: 0.0.10 nan: 2.27.0 + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + stackback@0.0.2: {} stackframe@1.3.4: {} @@ -36741,18 +36935,13 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.6.0 - strip-ansi: 7.1.2 - - string-width@8.2.1: - dependencies: - get-east-asian-width: 1.6.0 - strip-ansi: 7.1.2 + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 string-width@8.2.2: dependencies: @@ -36782,7 +36971,7 @@ snapshots: strip-ansi@7.1.2: dependencies: - ansi-regex: 6.2.2 + ansi-regex: 6.3.0 strip-ansi@7.2.0: dependencies: @@ -36980,6 +37169,8 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 + terminal-size@4.0.1: {} + terser@5.44.1: dependencies: '@jridgewell/source-map': 0.3.11 @@ -37253,6 +37444,10 @@ snapshots: type-fest@0.7.1: {} + type-fest@5.10.0: + dependencies: + tagged-tag: 1.0.0 + type-fest@5.3.1: dependencies: tagged-tag: 1.0.0 @@ -38198,6 +38393,10 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + widest-line@6.0.0: + dependencies: + string-width: 8.2.2 + word-wrap@1.2.5: {} workerd@1.20260609.1: @@ -38233,6 +38432,11 @@ snapshots: - bufferutil - utf-8-validate + wrap-ansi@10.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 8.2.2 + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 @@ -38249,7 +38453,7 @@ snapshots: dependencies: ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrap-ansi@9.0.2: dependencies: @@ -38356,6 +38560,8 @@ snapshots: yoctocolors@2.1.2: {} + yoga-layout@3.2.1: {} + youch-core@0.3.3: dependencies: '@poppinss/exception': 1.2.3