From a882bbf9c87d47a1259e155d3903a572e90a77b7 Mon Sep 17 00:00:00 2001 From: Marcus Schiesser Date: Thu, 15 May 2025 12:25:33 +0700 Subject: [PATCH 1/2] chore: copied doc-workflow example from CL --- examples/agents/workflow/doc-workflow.ts | 332 +++++++++++++++++++++++ examples/agents/workflow/runner.ts | 149 ++++++++++ 2 files changed, 481 insertions(+) create mode 100644 examples/agents/workflow/doc-workflow.ts create mode 100644 examples/agents/workflow/runner.ts diff --git a/examples/agents/workflow/doc-workflow.ts b/examples/agents/workflow/doc-workflow.ts new file mode 100644 index 0000000000..0708e38e68 --- /dev/null +++ b/examples/agents/workflow/doc-workflow.ts @@ -0,0 +1,332 @@ +import { ChatMemoryBuffer, ChatMessage, LLM, MessageContent } from "llamaindex"; + +import { + agentStreamEvent, + createStatefulMiddleware, + createWorkflow, + startAgentEvent, + stopAgentEvent, + workflowEvent, +} from "@llamaindex/workflow"; + +import { z } from "zod"; + +export const DocumentRequirementSchema = z.object({ + type: z.enum(["markdown", "html"]), + title: z.string(), + requirement: z.string(), +}); + +export type DocumentRequirement = z.infer; + +export const UIEventSchema = z.object({ + type: z.literal("ui_event"), + data: z.object({ + state: z + .enum(["plan", "generate", "completed"]) + .describe( + "The current state of the workflow: 'plan', 'generate', or 'completed'.", + ), + requirement: z + .string() + .optional() + .describe( + "An optional requirement creating or updating a document, if applicable.", + ), + }), +}); +export type UIEvent = z.infer; +export const uiEvent = workflowEvent(); + +const planEvent = workflowEvent<{ + userInput: MessageContent; + context?: string | undefined; +}>(); + +const generateArtifactEvent = workflowEvent<{ + requirement: DocumentRequirement; +}>(); + +const synthesizeAnswerEvent = workflowEvent<{ + requirement: DocumentRequirement; + generatedArtifact: string; +}>(); + +const ArtifactSchema = z.object({ + type: z.literal("artifact"), + data: z.object({ + type: z.literal("document"), + data: z.object({ + title: z.string(), + content: z.string(), + type: z.string(), + }), + created_at: z.number(), + }), +}); +type Artifact = z.infer; +export const artifactEvent = workflowEvent(); + +export function createDocumentArtifactWorkflow( + llm: LLM, + chatHistory: ChatMessage[], + lastArtifact: Artifact | undefined, +) { + const { withState, getContext } = createStatefulMiddleware(() => { + return { + memory: new ChatMemoryBuffer({ + llm, + chatHistory: chatHistory, + }), + lastArtifact: lastArtifact, + }; + }); + const workflow = withState(createWorkflow()); + + workflow.handle([startAgentEvent], async ({ data: { userInput } }) => { + // Prepare chat history + const { state } = getContext(); + // Put user input to the memory + if (!userInput) { + throw new Error("Missing user input to start the workflow"); + } + state.memory.put({ + role: "user", + content: userInput, + }); + return planEvent.with({ + userInput, + context: state.lastArtifact + ? JSON.stringify(state.lastArtifact) + : undefined, + }); + }); + + workflow.handle([planEvent], async ({ data: planData }) => { + const { sendEvent } = getContext(); + const { state } = getContext(); + sendEvent( + uiEvent.with({ + type: "ui_event", + data: { + state: "plan", + }, + }), + ); + const user_msg = planData.userInput; + const context = planData.context + ? `## The context is: \n${planData.context}\n` + : ""; + const prompt = ` + You are a documentation analyst responsible for analyzing the user's request and providing requirements for document generation or update. + Follow these instructions: + 1. Carefully analyze the conversation history and the user's request to determine what has been done and what the next step should be. + 2. From the user's request, provide requirements for the next step of the document generation or update. + 3. Do not be verbose; only return the requirements for the next step of the document generation or update. + 4. Only the following document types are allowed: "markdown", "html". + 5. The requirement should be in the following format: + \`\`\`json + { + "type": "markdown" | "html", + "title": string, + "requirement": string + } + \`\`\` + + ## Example: + User request: Create a project guideline document. + You should return: + \`\`\`json + { + "type": "markdown", + "title": "Project Guideline", + "requirement": "Generate a Markdown document that outlines the project goals, deliverables, and timeline. Include sections for introduction, objectives, deliverables, and timeline." + } + \`\`\` + + User request: Add a troubleshooting section to the guideline. + You should return: + \`\`\`json + { + "type": "markdown", + "title": "Project Guideline", + "requirement": "Add a 'Troubleshooting' section at the end of the document with common issues and solutions." + } + \`\`\` + + ${context} + + Now, please plan for the user's request: + ${user_msg} + `; + + const response = await llm.complete({ + prompt, + }); + // Parse the response to DocumentRequirement + const jsonBlock = response.text.match(/```json\s*([\s\S]*?)\s*```/); + if (!jsonBlock) { + throw new Error("No JSON block found in the response."); + } + const requirement = DocumentRequirementSchema.parse( + JSON.parse(jsonBlock[1]), + ); + state.memory.put({ + role: "assistant", + content: `Planning for the document generation: \n${response.text}`, + }); + return generateArtifactEvent.with({ + requirement, + }); + }); + + workflow.handle( + [generateArtifactEvent], + async ({ data: { requirement } }) => { + const { sendEvent } = getContext(); + const { state } = getContext(); + + sendEvent( + uiEvent.with({ + type: "ui_event", + data: { + state: "generate", + requirement: requirement.requirement, + }, + }), + ); + + const previousArtifact = state.lastArtifact + ? JSON.stringify(state.lastArtifact) + : ""; + const requirementStr = JSON.stringify(requirement); + + const prompt = ` + You are a skilled technical writer who can help users with documentation. + You are given a task to generate or update a document for a given requirement. + + ## Follow these instructions: + **1. Carefully read the user's requirements.** + If any details are ambiguous or missing, make reasonable assumptions and clearly reflect those in your output. + If the previous document is provided: + + Carefully analyze the document with the request to make the right changes. + + Avoid making unnecessary changes from the previous document if the request is not to rewrite it from scratch. + **2. For document requests:** + - If the user does not specify a type, default to Markdown. + - Ensure the document is clear, well-structured, and grammatically correct. + - Only generate content relevant to the user's request—do not add extra boilerplate. + **3. Do not be verbose in your response.** + - No other text or comments; only return the document content wrapped by the appropriate code block (\`\`\`markdown or \`\`\`html). + - If the user's request is to update the document, only return the updated document. + **4. Only the following types are allowed: "markdown", "html".** + **5. If there is no change to the document, return the reason without any code block.** + + ## Example: + \`\`\`markdown + # Project Guideline + + ## Introduction + ... + \`\`\` + + The previous content is: + ${previousArtifact} + + Now, please generate the document for the following requirement: + ${requirementStr} + `; + + const response = await llm.complete({ + prompt, + }); + + // Extract the document from the response + const docMatch = response.text.match(/```(markdown|html)([\s\S]*)```/); + const generatedContent = response.text; + + if (docMatch) { + const content = docMatch[2].trim(); + const docType = docMatch[1] as "markdown" | "html"; + + // Put the generated document to the memory + state.memory.put({ + role: "assistant", + content: `Generated document: \n${response.text}`, + }); + + // To show the Canvas panel for the artifact + sendEvent( + artifactEvent.with({ + type: "artifact", + data: { + type: "document", + created_at: Date.now(), + data: { + title: requirement.title, + content: content, + type: docType, + }, + }, + }), + ); + } + + return synthesizeAnswerEvent.with({ + requirement, + generatedArtifact: generatedContent, + }); + }, + ); + + workflow.handle([synthesizeAnswerEvent], async ({ data }) => { + const { sendEvent } = getContext(); + const { state } = getContext(); + + const chatHistory = await state.memory.getMessages(); + const messages = [ + ...chatHistory, + { + role: "system" as const, + content: ` + Your responsibility is to explain the work to the user. + If there is no document to update, explain the reason. + If the document is updated, just summarize what changed. Don't need to include the whole document again in the response. + `, + }, + ]; + + const responseStream = await llm.chat({ + messages, + stream: true, + }); + + sendEvent( + uiEvent.with({ + type: "ui_event", + data: { + state: "completed", + requirement: data.requirement.requirement, + }, + }), + ); + + let response = ""; + for await (const chunk of responseStream) { + response += chunk.delta; + sendEvent( + agentStreamEvent.with({ + delta: chunk.delta, + response: "", + currentAgentName: "assistant", + raw: chunk, + }), + ); + } + + return stopAgentEvent.with({ + result: response, + }); + }); + + return workflow; +} diff --git a/examples/agents/workflow/runner.ts b/examples/agents/workflow/runner.ts new file mode 100644 index 0000000000..79ee01e471 --- /dev/null +++ b/examples/agents/workflow/runner.ts @@ -0,0 +1,149 @@ +import { openai } from "@llamaindex/openai"; + +import { + agentStreamEvent, + startAgentEvent, + stopAgentEvent, +} from "@llamaindex/workflow"; + +import { + artifactEvent, + createDocumentArtifactWorkflow, + uiEvent, +} from "./doc-workflow"; + +const llm = openai({ model: "gpt-4.1-mini" }); + +async function main() { + const workflow = createDocumentArtifactWorkflow(llm, [], undefined); + const { stream, sendEvent } = workflow.createContext(); + sendEvent( + startAgentEvent.with({ userInput: "Create a project guideline document." }), + ); + + for await (const event of stream.until(stopAgentEvent)) { + if (agentStreamEvent.include(event)) { + process.stdout.write(event.data.delta); + } else if (uiEvent.include(event)) { + renderUIEvent(event.data.data); + } else if (artifactEvent.include(event)) { + console.log(event.data); + } + } +} + +function renderUIEvent(eventData: UIEvent["data"]) { + // Helper function to wrap text to a given width + function wrapText(text: string | undefined, maxWidth: number): string[] { + if (!text) return [""]; + if (maxWidth <= 0) return [text]; // Avoid issues with zero or negative max width + + const lines: string[] = []; + const paragraphs = text.split("\n"); // Handle existing newlines + + for (const paragraph of paragraphs) { + const words = paragraph.split(" "); // Changed let to const + let currentLine = ""; + for (const word of words) { + // If a single word is longer than maxWidth, it needs to be broken. + if (word.length > maxWidth) { + if (currentLine !== "") { + // Push whatever is in currentLine first + lines.push(currentLine); + currentLine = ""; + } + // Break the long word + for (let i = 0; i < word.length; i += maxWidth) { + lines.push(word.substring(i, i + maxWidth)); + } + } else { + // Standard word wrapping + if ((currentLine + word).length + (currentLine ? 1 : 0) <= maxWidth) { + currentLine += (currentLine ? " " : "") + word; + } else { + lines.push(currentLine); + currentLine = word; // This new word is guaranteed to be <= maxWidth here + } + } + } + if (currentLine) { + lines.push(currentLine); + } + } + return lines.length > 0 ? lines : [""]; // Ensure at least one line (empty if text was empty) + } + + const contentWidth = 60; // Define content width for text area inside borders + const stateColorMap = { + plan: "\x1b[33m", // Yellow + generate: "\x1b[34m", // Blue + completed: "\x1b[32m", // Green + }; + const resetColor = "\x1b[0m"; + + const state = eventData.state; + const coloredState = `${stateColorMap[state]}${state.toUpperCase()}${resetColor}`; + + // Box drawing characters + const horizontalLine = "─".repeat(contentWidth + 2); // +2 for padding spaces around content + const topBorder = `┌${horizontalLine}┐`; + const bottomBorder = `└${horizontalLine}┘`; + const midSeparator = `├${horizontalLine}┤`; + + console.log(`\n${topBorder}`); + + // Center the title "💡 Workflow Event" + const title = "💡 Workflow Event"; + // Calculate padding for centering the title + const titleVisibleLength = title.length; // Assuming title has no ANSI codes + const titlePaddingTotal = Math.max(0, contentWidth - titleVisibleLength); + const titleLeftPadding = " ".repeat(Math.floor(titlePaddingTotal / 2)); + const titleRightPadding = " ".repeat(Math.ceil(titlePaddingTotal / 2)); + console.log(`│ ${titleLeftPadding}${title}${titleRightPadding} │`); + + console.log(midSeparator); + + // State line + const stateLabel = "State: "; + const visibleStateText = state.toUpperCase(); + const stateLineVisibleLength = stateLabel.length + visibleStateText.length; + const statePadding = " ".repeat( + Math.max(0, contentWidth - stateLineVisibleLength), + ); + console.log(`│ ${stateLabel}${coloredState}${statePadding} │`); + + // Requirement section + if (eventData.requirement !== undefined) { + // Check if requirement key exists + const requirementLabel = "Requirement: "; + const requirementTextMaxWidth = contentWidth - requirementLabel.length; + const requirementLines = wrapText( + eventData.requirement, + requirementTextMaxWidth, + ); + + if ( + requirementLines.length > 0 && + !(requirementLines.length === 1 && requirementLines[0] === "") + ) { + // First line with label + console.log( + `│ ${requirementLabel}${requirementLines[0].padEnd(requirementTextMaxWidth, " ")} │`, + ); + // Subsequent lines, indented under the requirement text part + for (let i = 1; i < requirementLines.length; i++) { + console.log( + `│ ${" ".repeat(requirementLabel.length)}${requirementLines[i].padEnd(requirementTextMaxWidth, " ")} │`, + ); + } + } else { + // Requirement is present but empty, or only contains empty strings after wrapping + console.log( + `│ ${requirementLabel}${" ".repeat(requirementTextMaxWidth)} │`, + ); + } + } + console.log(`${bottomBorder}\n`); +} + +main().catch(console.error); From 9aeea6f1eac7a98394d12df9cf8aa6cb504391cd Mon Sep 17 00:00:00 2001 From: Marcus Schiesser Date: Mon, 19 May 2025 13:36:08 +0700 Subject: [PATCH 2/2] feat: use ink to render workflow --- examples/agents/workflow/doc-workflow.ts | 2 +- examples/agents/workflow/runner.ts | 149 ------------- examples/agents/workflow/runner.tsx | 162 ++++++++++++++ examples/package.json | 4 + examples/tsconfig.json | 11 +- pnpm-lock.yaml | 262 +++++++++++++++++++++-- 6 files changed, 413 insertions(+), 177 deletions(-) delete mode 100644 examples/agents/workflow/runner.ts create mode 100644 examples/agents/workflow/runner.tsx diff --git a/examples/agents/workflow/doc-workflow.ts b/examples/agents/workflow/doc-workflow.ts index 0708e38e68..8fc9c0e695 100644 --- a/examples/agents/workflow/doc-workflow.ts +++ b/examples/agents/workflow/doc-workflow.ts @@ -64,7 +64,7 @@ const ArtifactSchema = z.object({ created_at: z.number(), }), }); -type Artifact = z.infer; +export type Artifact = z.infer; export const artifactEvent = workflowEvent(); export function createDocumentArtifactWorkflow( diff --git a/examples/agents/workflow/runner.ts b/examples/agents/workflow/runner.ts deleted file mode 100644 index 79ee01e471..0000000000 --- a/examples/agents/workflow/runner.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { openai } from "@llamaindex/openai"; - -import { - agentStreamEvent, - startAgentEvent, - stopAgentEvent, -} from "@llamaindex/workflow"; - -import { - artifactEvent, - createDocumentArtifactWorkflow, - uiEvent, -} from "./doc-workflow"; - -const llm = openai({ model: "gpt-4.1-mini" }); - -async function main() { - const workflow = createDocumentArtifactWorkflow(llm, [], undefined); - const { stream, sendEvent } = workflow.createContext(); - sendEvent( - startAgentEvent.with({ userInput: "Create a project guideline document." }), - ); - - for await (const event of stream.until(stopAgentEvent)) { - if (agentStreamEvent.include(event)) { - process.stdout.write(event.data.delta); - } else if (uiEvent.include(event)) { - renderUIEvent(event.data.data); - } else if (artifactEvent.include(event)) { - console.log(event.data); - } - } -} - -function renderUIEvent(eventData: UIEvent["data"]) { - // Helper function to wrap text to a given width - function wrapText(text: string | undefined, maxWidth: number): string[] { - if (!text) return [""]; - if (maxWidth <= 0) return [text]; // Avoid issues with zero or negative max width - - const lines: string[] = []; - const paragraphs = text.split("\n"); // Handle existing newlines - - for (const paragraph of paragraphs) { - const words = paragraph.split(" "); // Changed let to const - let currentLine = ""; - for (const word of words) { - // If a single word is longer than maxWidth, it needs to be broken. - if (word.length > maxWidth) { - if (currentLine !== "") { - // Push whatever is in currentLine first - lines.push(currentLine); - currentLine = ""; - } - // Break the long word - for (let i = 0; i < word.length; i += maxWidth) { - lines.push(word.substring(i, i + maxWidth)); - } - } else { - // Standard word wrapping - if ((currentLine + word).length + (currentLine ? 1 : 0) <= maxWidth) { - currentLine += (currentLine ? " " : "") + word; - } else { - lines.push(currentLine); - currentLine = word; // This new word is guaranteed to be <= maxWidth here - } - } - } - if (currentLine) { - lines.push(currentLine); - } - } - return lines.length > 0 ? lines : [""]; // Ensure at least one line (empty if text was empty) - } - - const contentWidth = 60; // Define content width for text area inside borders - const stateColorMap = { - plan: "\x1b[33m", // Yellow - generate: "\x1b[34m", // Blue - completed: "\x1b[32m", // Green - }; - const resetColor = "\x1b[0m"; - - const state = eventData.state; - const coloredState = `${stateColorMap[state]}${state.toUpperCase()}${resetColor}`; - - // Box drawing characters - const horizontalLine = "─".repeat(contentWidth + 2); // +2 for padding spaces around content - const topBorder = `┌${horizontalLine}┐`; - const bottomBorder = `└${horizontalLine}┘`; - const midSeparator = `├${horizontalLine}┤`; - - console.log(`\n${topBorder}`); - - // Center the title "💡 Workflow Event" - const title = "💡 Workflow Event"; - // Calculate padding for centering the title - const titleVisibleLength = title.length; // Assuming title has no ANSI codes - const titlePaddingTotal = Math.max(0, contentWidth - titleVisibleLength); - const titleLeftPadding = " ".repeat(Math.floor(titlePaddingTotal / 2)); - const titleRightPadding = " ".repeat(Math.ceil(titlePaddingTotal / 2)); - console.log(`│ ${titleLeftPadding}${title}${titleRightPadding} │`); - - console.log(midSeparator); - - // State line - const stateLabel = "State: "; - const visibleStateText = state.toUpperCase(); - const stateLineVisibleLength = stateLabel.length + visibleStateText.length; - const statePadding = " ".repeat( - Math.max(0, contentWidth - stateLineVisibleLength), - ); - console.log(`│ ${stateLabel}${coloredState}${statePadding} │`); - - // Requirement section - if (eventData.requirement !== undefined) { - // Check if requirement key exists - const requirementLabel = "Requirement: "; - const requirementTextMaxWidth = contentWidth - requirementLabel.length; - const requirementLines = wrapText( - eventData.requirement, - requirementTextMaxWidth, - ); - - if ( - requirementLines.length > 0 && - !(requirementLines.length === 1 && requirementLines[0] === "") - ) { - // First line with label - console.log( - `│ ${requirementLabel}${requirementLines[0].padEnd(requirementTextMaxWidth, " ")} │`, - ); - // Subsequent lines, indented under the requirement text part - for (let i = 1; i < requirementLines.length; i++) { - console.log( - `│ ${" ".repeat(requirementLabel.length)}${requirementLines[i].padEnd(requirementTextMaxWidth, " ")} │`, - ); - } - } else { - // Requirement is present but empty, or only contains empty strings after wrapping - console.log( - `│ ${requirementLabel}${" ".repeat(requirementTextMaxWidth)} │`, - ); - } - } - console.log(`${bottomBorder}\n`); -} - -main().catch(console.error); diff --git a/examples/agents/workflow/runner.tsx b/examples/agents/workflow/runner.tsx new file mode 100644 index 0000000000..a8183fa96d --- /dev/null +++ b/examples/agents/workflow/runner.tsx @@ -0,0 +1,162 @@ +import { openai } from "@llamaindex/openai"; +import { Box, render, Text } from "ink"; +import React from "react"; + +import { + agentStreamEvent, + startAgentEvent, + stopAgentEvent, +} from "@llamaindex/workflow"; + +import { + artifactEvent, + createDocumentArtifactWorkflow, + uiEvent, + UIEvent, +} from "./doc-workflow"; + +// Import Artifact type (assuming it's exported from doc-workflow.ts) +// If not exported, we'd define a simplified version here or use 'any' temporarily. +// Based on the read file, Artifact is a Zod schema inference. +// We can either import it or define a similar structure for props. +// For now, let's assume it's available from './doc-workflow'. +import type { Artifact } from "./doc-workflow"; // Assuming Artifact is exported + +const llm = openai({ model: "gpt-4.1-mini" }); + +// Define the props for our UI component +interface WorkflowUIProps { + uiEvent: UIEvent; +} + +// React component to render the UI using Ink +const WorkflowUI: React.FC = ({ uiEvent }) => { + const contentWidth = 60; + const stateColorMap: { [key: string]: string } = { + plan: "yellow", + generate: "blue", + completed: "green", + }; + + const state = uiEvent.data.state; + const coloredStateText = ( + {state.toUpperCase()} + ); + + const title = "💡 Workflow Event"; + const requirementLabel = "Requirement: "; + + return ( + + + {title} + + + + + + + State: + {coloredStateText} + + + {uiEvent.data.requirement !== undefined && ( + + {requirementLabel} + + {uiEvent.data.requirement} + + + )} + + + ); +}; + +// --- BEGIN NEW ARTIFACT UI COMPONENT --- +interface ArtifactUIProps { + artifact: Artifact; // Use the imported Artifact type +} + +const ArtifactUI: React.FC = ({ artifact }) => { + const artifactData = artifact.data.data; // Access nested data + const contentWidth = 80; // Allow more width for artifact content + + return ( + + + + 📄 Artifact Generated: {artifactData.title} + + + + + + + + Title: + {artifactData.title} + + + Type: + {artifactData.type} + + + Content: + {/* Add a Box for content to allow it to take up space and wrap */} + + {artifactData.content} + + + + + Created At: {new Date(artifact.data.created_at).toLocaleString()} + + + + + ); +}; + +async function main() { + const workflow = createDocumentArtifactWorkflow(llm, [], undefined); + const { stream, sendEvent } = workflow.createContext(); + + const { rerender, unmount, clear } = render( + Waiting for workflow to start..., + ); + + sendEvent( + startAgentEvent.with({ userInput: "Create a project guideline document." }), + ); + + for await (const event of stream.until(stopAgentEvent)) { + if (agentStreamEvent.include(event)) { + process.stdout.write(event.data.delta); + } else if (uiEvent.include(event)) { + if (event.data.data.state !== "completed") { + rerender(); + } + } else if (artifactEvent.include(event)) { + rerender(); + } + } + + unmount(); + + console.log("\nWorkflow finished."); +} + +main().catch(console.error); diff --git a/examples/package.json b/examples/package.json index ca16c38631..ba950dd44b 100644 --- a/examples/package.json +++ b/examples/package.json @@ -2,6 +2,7 @@ "name": "@llamaindex/examples", "version": "0.3.16", "private": true, + "type": "module", "scripts": { "lint": "eslint .", "start": "tsx ./starter.ts" @@ -63,15 +64,18 @@ "ajv": "^8.17.1", "commander": "^12.1.0", "dotenv": "^16.4.5", + "ink": "^5.2.1", "js-tiktoken": "^1.0.14", "llamaindex": "^0.11.0", "mongodb": "6.7.0", "postgres": "^3.4.4", + "react": "^18.3.1", "wikipedia": "^2.1.2", "zod": "^3.23.8" }, "devDependencies": { "@types/node": "^22.9.0", + "@types/react": "^18.3.21", "tsx": "^4.19.3", "typescript": "^5.7.3" }, diff --git a/examples/tsconfig.json b/examples/tsconfig.json index 8dcc2b578f..4687525ccc 100644 --- a/examples/tsconfig.json +++ b/examples/tsconfig.json @@ -10,13 +10,8 @@ "outDir": "./lib", "tsBuildInfoFile": "./lib/.tsbuildinfo", "incremental": true, - "composite": true + "composite": true, + "jsx": "react-jsx" }, - "ts-node": { - "files": true, - "compilerOptions": { - "module": "commonjs" - } - }, - "include": ["./**/*.ts"] + "include": ["./**/*.ts", "./**/*.tsx"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 27340bec63..7688c05f69 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -754,7 +754,7 @@ importers: version: 0.10.0 ai: specifier: ^4.0.0 - version: 4.3.7(react@19.1.0)(zod@3.24.2) + version: 4.3.7(react@18.3.1)(zod@3.24.2) ajv: specifier: ^8.17.1 version: 8.17.1 @@ -764,6 +764,9 @@ importers: dotenv: specifier: ^16.4.5 version: 16.5.0 + ink: + specifier: ^5.2.1 + version: 5.2.1(@types/react@18.3.21)(bufferutil@4.0.9)(react@18.3.1) js-tiktoken: specifier: ^1.0.14 version: 1.0.19 @@ -776,6 +779,9 @@ importers: postgres: specifier: ^3.4.4 version: 3.4.5 + react: + specifier: ^18.3.1 + version: 18.3.1 wikipedia: specifier: ^2.1.2 version: 2.1.2 @@ -786,6 +792,9 @@ importers: '@types/node': specifier: ^22.9.0 version: 22.9.0 + '@types/react': + specifier: ^18.3.21 + version: 18.3.21 tsx: specifier: ^4.19.3 version: 4.19.3 @@ -830,7 +839,7 @@ importers: version: 1.11.21(@swc/helpers@0.5.17) jotai: specifier: 2.10.2 - version: 2.10.2(@types/react@19.1.2)(react@19.1.0) + version: 2.10.2(@types/react@19.1.4)(react@19.1.0) openai: specifier: ^4 version: 4.94.0(ws@8.18.1(bufferutil@4.0.9))(zod@3.24.4) @@ -1991,6 +2000,10 @@ packages: vue: optional: true + '@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'} @@ -5923,11 +5936,14 @@ packages: peerDependencies: '@types/react': ^19.0.0 + '@types/react@18.3.21': + resolution: {integrity: sha512-gXLBtmlcRJeT09/sI4PxVwyrku6SaNUj/6cMubjE6T6XdY1fDmBL7r0nX0jbSZPU/Xr0KuwLLZh6aOYY5d91Xw==} + '@types/react@19.0.10': resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==} - '@types/react@19.1.2': - resolution: {integrity: sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==} + '@types/react@19.1.4': + resolution: {integrity: sha512-EB1yiiYdvySuIITtD5lhW4yPyJ31RkJkkDw794LaQYrxCSaQV/47y5o1FMC4zF9ZyjUjzJMZwbovEnT5yHTW6g==} '@types/readable-stream@4.0.18': resolution: {integrity: sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA==} @@ -6664,6 +6680,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.21: resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} engines: {node: ^10 || ^12 || >=14} @@ -7025,10 +7045,18 @@ packages: resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} engines: {node: '>= 10.0'} + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + cli-cursor@3.1.0: 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'} @@ -7067,6 +7095,10 @@ packages: code-block-writer@13.0.3: resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} + code-excerpt@4.0.0: + resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + codemirror@6.0.1: resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==} @@ -7200,6 +7232,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} + convict@6.2.4: resolution: {integrity: sha512-qN60BAwdMVdofckX7AlohVJ2x9UvjTNoKVXCL2LxFk1l7757EJqf1nySdMkPQer0bt8kQ5lQiyZ9/2NvrFBuwQ==} engines: {node: '>=6'} @@ -7635,6 +7671,9 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + es-toolkit@1.38.0: + resolution: {integrity: sha512-OT3AxczYYd3W50bCj4V0hKoOAfqIy9tof0leNQYekEDxVKir3RTVTJOLij7VAe6fsCNsGhC0JqIkURpMXTCSEA==} + es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} @@ -7666,6 +7705,10 @@ packages: escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + 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'} @@ -8773,6 +8816,10 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} + 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. @@ -8786,6 +8833,19 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + 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.1.1: resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} @@ -8906,6 +8966,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-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} engines: {node: '>=14.16'} @@ -10656,6 +10721,10 @@ packages: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} + 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==} @@ -11206,6 +11275,12 @@ packages: '@types/react': optional: true + 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'} @@ -11264,6 +11339,10 @@ packages: react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + react@19.0.0: resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} engines: {node: '>=0.10.0'} @@ -11465,6 +11544,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'} @@ -11600,6 +11683,9 @@ packages: sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scheduler@0.25.0: resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} @@ -11890,6 +11976,10 @@ packages: stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + 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==} @@ -13145,6 +13235,10 @@ packages: wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + widest-line@5.0.0: + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} + engines: {node: '>=18'} + wikipedia@2.1.2: resolution: {integrity: sha512-RAYaMpXC9/E873RaSEtlEa8dXK4e0p5k98GKOd210MtkE5emm6fcnwD+N6ZA4cuffjDWagvhaQKtp/mGp2BOVQ==} engines: {node: '>=10'} @@ -13323,6 +13417,9 @@ packages: resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} engines: {node: '>=18'} + yoga-layout@3.2.1: + resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} + youch@3.3.4: resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==} @@ -13401,6 +13498,16 @@ snapshots: react: 19.1.0 zod: 3.24.2 + '@ai-sdk/react@1.2.9(react@18.3.1)(zod@3.24.2)': + dependencies: + '@ai-sdk/provider-utils': 2.2.7(zod@3.24.2) + '@ai-sdk/ui-utils': 1.2.8(zod@3.24.2) + react: 18.3.1 + swr: 2.3.3(react@18.3.1) + throttleit: 2.1.0 + optionalDependencies: + zod: 3.24.2 + '@ai-sdk/react@1.2.9(react@19.0.0)(zod@3.24.4)': dependencies: '@ai-sdk/provider-utils': 2.2.7(zod@3.24.4) @@ -13472,6 +13579,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': {} '@ampproject/remapping@2.3.0': @@ -18711,14 +18823,18 @@ snapshots: dependencies: '@types/react': 19.0.10 + '@types/react@18.3.21': + dependencies: + '@types/prop-types': 15.7.14 + csstype: 3.1.3 + '@types/react@19.0.10': dependencies: csstype: 3.1.3 - '@types/react@19.1.2': + '@types/react@19.1.4': dependencies: csstype: 3.1.3 - optional: true '@types/readable-stream@4.0.18': dependencies: @@ -19319,7 +19435,7 @@ snapshots: '@wojtekmaj/react-hooks@1.17.2(react@19.1.0)': dependencies: - '@types/react': 19.0.10 + '@types/react': 19.1.4 react: 19.1.0 '@xhmikosr/archive-type@7.0.0': @@ -19477,6 +19593,18 @@ snapshots: - solid-js - vue + ai@4.3.7(react@18.3.1)(zod@3.24.2): + dependencies: + '@ai-sdk/provider': 1.1.3 + '@ai-sdk/provider-utils': 2.2.7(zod@3.24.2) + '@ai-sdk/react': 1.2.9(react@18.3.1)(zod@3.24.2) + '@ai-sdk/ui-utils': 1.2.8(zod@3.24.2) + '@opentelemetry/api': 1.9.0 + jsondiffpatch: 0.6.0 + zod: 3.24.2 + optionalDependencies: + react: 18.3.1 + ai@4.3.7(react@19.0.0)(zod@3.24.4): dependencies: '@ai-sdk/provider': 1.1.3 @@ -19721,6 +19849,8 @@ snapshots: asynckit@0.4.0: {} + auto-bind@5.0.1: {} + autoprefixer@10.4.21(postcss@8.5.3): dependencies: browserslist: 4.24.4 @@ -20132,10 +20262,16 @@ snapshots: dependencies: source-map: 0.6.1 + cli-boxes@3.0.0: {} + cli-cursor@3.1.0: 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 @@ -20165,6 +20301,10 @@ snapshots: code-block-writer@13.0.3: {} + code-excerpt@4.0.0: + dependencies: + convert-to-spaces: 2.0.1 + codemirror@6.0.1: dependencies: '@codemirror/autocomplete': 6.18.6 @@ -20327,6 +20467,8 @@ snapshots: convert-source-map@2.0.0: {} + convert-to-spaces@2.0.1: {} + convict@6.2.4: dependencies: lodash.clonedeep: 4.5.0 @@ -20790,6 +20932,8 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + es-toolkit@1.38.0: {} + es6-error@4.1.1: {} esast-util-from-estree@2.0.0: @@ -20889,6 +21033,8 @@ snapshots: escape-html@1.0.3: {} + escape-string-regexp@2.0.0: {} + escape-string-regexp@4.0.0: {} escape-string-regexp@5.0.0: {} @@ -20938,7 +21084,7 @@ snapshots: '@typescript-eslint/parser': 8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3) eslint: 9.22.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.22.0(jiti@2.4.2)) eslint-plugin-react: 7.37.2(eslint@9.22.0(jiti@2.4.2)) @@ -20968,35 +21114,35 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)): + eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 enhanced-resolve: 5.18.1 - eslint: 9.22.0(jiti@2.4.2) + eslint: 9.16.0(jiti@2.4.2) fast-glob: 3.3.3 get-tsconfig: 4.10.0 is-bun-module: 1.3.0 is-glob: 4.0.3 stable-hash: 0.0.4 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)): + eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 enhanced-resolve: 5.18.1 - eslint: 9.16.0(jiti@2.4.2) + eslint: 9.22.0(jiti@2.4.2) fast-glob: 3.3.3 get-tsconfig: 4.10.0 is-bun-module: 1.3.0 is-glob: 4.0.3 stable-hash: 0.0.4 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -21011,14 +21157,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3) eslint: 9.22.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)) + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)) transitivePeerDependencies: - supports-color @@ -21062,7 +21208,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.22.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -22591,6 +22737,8 @@ snapshots: imurmurhash@0.1.4: {} + indent-string@5.0.0: {} + inflight@1.0.6: dependencies: once: 1.4.0 @@ -22604,6 +22752,39 @@ snapshots: ini@1.3.8: {} + ink@5.2.1(@types/react@18.3.21)(bufferutil@4.0.9)(react@18.3.1): + dependencies: + '@alcalzone/ansi-tokenize': 0.1.3 + ansi-escapes: 7.0.0 + ansi-styles: 6.2.1 + auto-bind: 5.0.1 + chalk: 5.4.1 + cli-boxes: 3.0.0 + cli-cursor: 4.0.0 + cli-truncate: 4.0.0 + code-excerpt: 4.0.0 + es-toolkit: 1.38.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.0 + stack-utils: 2.0.6 + string-width: 7.2.0 + type-fest: 4.40.0 + widest-line: 5.0.0 + wrap-ansi: 9.0.0 + ws: 8.18.1(bufferutil@4.0.9) + yoga-layout: 3.2.1 + optionalDependencies: + '@types/react': 18.3.21 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + inline-style-parser@0.1.1: {} inline-style-parser@0.2.4: {} @@ -22720,6 +22901,8 @@ snapshots: is-hexadecimal@2.0.1: {} + is-in-ci@1.0.0: {} + is-inside-container@1.0.0: dependencies: is-docker: 3.0.0 @@ -22872,9 +23055,9 @@ snapshots: jiti@2.4.2: {} - jotai@2.10.2(@types/react@19.1.2)(react@19.1.0): + jotai@2.10.2(@types/react@19.1.4)(react@19.1.0): optionalDependencies: - '@types/react': 19.1.2 + '@types/react': 19.1.4 react: 19.1.0 js-base64@3.7.2: {} @@ -25068,6 +25251,8 @@ snapshots: parseurl@1.3.3: {} + patch-console@2.0.0: {} + path-browserify@1.0.1: {} path-exists@4.0.0: {} @@ -25613,6 +25798,12 @@ snapshots: optionalDependencies: '@types/react': 19.0.10 + 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-remove-scroll-bar@2.3.8(@types/react@19.0.10)(react@19.1.0): @@ -25664,6 +25855,10 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + react@19.0.0: {} react@19.1.0: {} @@ -26004,6 +26199,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 @@ -26221,6 +26421,10 @@ snapshots: sax@1.4.1: {} + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + scheduler@0.25.0: {} scheduler@0.26.0: {} @@ -26596,6 +26800,10 @@ snapshots: stack-trace@0.0.10: {} + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + stackback@0.0.2: {} stacktracey@2.1.8: @@ -26849,6 +27057,12 @@ snapshots: magic-string: 0.30.17 zimmerframe: 1.1.2 + swr@2.3.3(react@18.3.1): + dependencies: + dequal: 2.0.3 + react: 18.3.1 + use-sync-external-store: 1.4.0(react@18.3.1) + swr@2.3.3(react@19.0.0): dependencies: dequal: 2.0.3 @@ -27477,6 +27691,10 @@ snapshots: dependencies: react: 19.1.0 + use-sync-external-store@1.4.0(react@18.3.1): + dependencies: + react: 18.3.1 + use-sync-external-store@1.4.0(react@19.0.0): dependencies: react: 19.0.0 @@ -28222,6 +28440,10 @@ snapshots: string-width: 4.2.3 optional: true + widest-line@5.0.0: + dependencies: + string-width: 7.2.0 + wikipedia@2.1.2: dependencies: axios: 1.8.4 @@ -28409,6 +28631,8 @@ snapshots: yoctocolors-cjs@2.1.2: {} + yoga-layout@3.2.1: {} + youch@3.3.4: dependencies: cookie: 0.7.2