diff --git a/.changeset/hip-ducks-perform.md b/.changeset/hip-ducks-perform.md new file mode 100644 index 0000000..1354082 --- /dev/null +++ b/.changeset/hip-ducks-perform.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/mcp': patch +--- + +feat: `use_cases` documentation metadata diff --git a/.cocoignore b/.cocoignore index e28784b..0e2ab02 100644 --- a/.cocoignore +++ b/.cocoignore @@ -1,2 +1,3 @@ .claude -.github \ No newline at end of file +.github +.vscode \ No newline at end of file diff --git a/.cocominify b/.cocominify new file mode 100644 index 0000000..83d7467 --- /dev/null +++ b/.cocominify @@ -0,0 +1 @@ +packages/mcp-server/src/use_cases.json \ No newline at end of file diff --git a/package.json b/package.json index be71d90..1df4e10 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "test": "npm run test:unit -- --run", "test:watch": "npm run test:unit -- --watch", "inspect": "pnpm mcp-inspector", + "generate-summaries": "pnpm --filter @sveltejs/mcp-server run generate-summaries", + "debug:generate-summaries": "pnpm --filter @sveltejs/mcp-server run debug:generate-summaries", "release": "pnpm --filter @sveltejs/mcp run build && changeset publish" }, "keywords": [ diff --git a/packages/mcp-server/.env.example b/packages/mcp-server/.env.example new file mode 100644 index 0000000..8c8c04a --- /dev/null +++ b/packages/mcp-server/.env.example @@ -0,0 +1,2 @@ +# Anthropic API Key from: https://console.anthropic.com/ +ANTHROPIC_API_KEY=your_api_key_here \ No newline at end of file diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index bd6d567..497d283 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -9,7 +9,9 @@ "license": "ISC", "type": "module", "scripts": { - "test": "vitest" + "test": "vitest", + "generate-summaries": "node scripts/generate-summaries.ts --experimental-strip-types", + "debug:generate-summaries": "DEBUG_MODE=1 node scripts/generate-summaries.ts --experimental-strip-types" }, "exports": { ".": "./src/index.ts" @@ -32,6 +34,8 @@ "zimmerframe": "^1.1.4" }, "devDependencies": { + "@anthropic-ai/sdk": "^0.65.0", + "dotenv": "^17.2.3", "@sveltejs/kit": "^2.42.2", "@types/eslint-scope": "^8.3.2", "@types/estree": "^1.0.8", diff --git a/packages/mcp-server/scripts/generate-summaries.ts b/packages/mcp-server/scripts/generate-summaries.ts new file mode 100644 index 0000000..3acd082 --- /dev/null +++ b/packages/mcp-server/scripts/generate-summaries.ts @@ -0,0 +1,244 @@ +#!/usr/bin/env node +import 'dotenv/config'; +import { writeFile, mkdir } from 'fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { get_sections } from '../src/mcp/utils.ts'; +import { AnthropicProvider } from '../src/lib/anthropic.ts'; +import { type AnthropicBatchRequest, type SummaryData } from '../src/lib/schemas.ts'; + +const current_filename = fileURLToPath(import.meta.url); +const current_dirname = path.dirname(current_filename); + +const USE_CASES_PROMPT = ` +You are tasked with analyzing Svelte 5 and SvelteKit documentation pages to identify when they would be useful. + +Your task: +1. Read the documentation page content provided +2. Identify the main use cases, scenarios, or queries where this documentation would be relevant +3. Create a VERY SHORT, comma-separated list of use cases (maximum 200 characters total) +4. Think about what a developer might be trying to build or accomplish when they need this documentation + +Guidelines: +- Focus on WHEN this documentation would be needed, not WHAT it contains +- Consider specific project types (e.g., "e-commerce site", "blog", "dashboard", "social media app") +- Consider specific features (e.g., "authentication", "forms", "data fetching", "animations") +- Consider specific components (e.g., "slider", "modal", "dropdown", "card") +- Consider development stages (e.g., "project setup", "deployment", "testing", "migration") +- Use "always" for fundamental concepts that apply to virtually all Svelte projects +- Be concise but specific +- Use lowercase +- Separate multiple use cases with commas + +Examples of good use_cases: +- "always, any svelte project, core reactivity" +- "authentication, login systems, user management" +- "e-commerce, product listings, shopping carts" +- "forms, user input, data submission" +- "deployment, production builds, hosting setup" +- "animation, transitions, interactive ui" +- "routing, navigation, multi-page apps" +- "blog, content sites, markdown rendering" + +Requirements: +- Maximum 200 characters (including spaces and commas) +- Lowercase only +- Comma-separated list of use cases +- Focus on WHEN/WHY someone would need this, not what it is +- Be specific about project types, features, or components when applicable +- Use "always" sparingly, only for truly universal concepts +- Do not include quotes or special formatting in your response +- Respond with ONLY the use cases text, no additional text + +Here is the documentation page content to analyze: + +`; + +async function fetch_section_content(url: string) { + const response = await fetch(url, { signal: AbortSignal.timeout(30000) }); + if (!response.ok) { + throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`); + } + return await response.text(); +} + +async function main() { + console.log('šŸš€ Starting use cases generation...'); + + // Check for API key + const api_key = process.env.ANTHROPIC_API_KEY; + if (!api_key) { + console.error('āŒ Error: ANTHROPIC_API_KEY environment variable is required'); + console.error('Please set it in packages/mcp-server/.env file or export it:'); + console.error('export ANTHROPIC_API_KEY=your_api_key_here'); + process.exit(1); + } + + // Get all sections + console.log('šŸ“š Fetching documentation sections...'); + let sections = await get_sections(); + console.log(`Found ${sections.length} sections`); + + // Debug mode: limit to 2 sections + const debug_mode = process.env.DEBUG_MODE === '1'; + if (debug_mode) { + console.log('šŸ› DEBUG_MODE enabled - processing only 2 sections'); + sections = sections.slice(0, 2); + } + + // Fetch content for each section + console.log('šŸ“„ Downloading section content...'); + const sections_with_content: Array<{ + section: (typeof sections)[number]; + content: string; + index: number; + }> = []; + const download_errors: Array<{ section: string; error: string }> = []; + + for (let i = 0; i < sections.length; i++) { + const section = sections[i]!; + try { + console.log(`Fetching ${i + 1}/${sections.length}: ${section.title}`); + const content = await fetch_section_content(section.url); + sections_with_content.push({ + section, + content, + index: i, + }); + } catch (error) { + const error_msg = error instanceof Error ? error.message : String(error); + console.error(`āš ļø Failed to fetch ${section.title}:`, error_msg); + download_errors.push({ section: section.title, error: error_msg }); + } + } + + console.log(`āœ… Successfully downloaded ${sections_with_content.length} sections`); + + if (sections_with_content.length === 0) { + console.error('āŒ No sections were successfully downloaded'); + process.exit(1); + } + + // Initialize Anthropic client + console.log('šŸ¤– Initializing Anthropic API...'); + const anthropic = new AnthropicProvider('claude-sonnet-4-5-20250929', api_key); + + // Prepare batch requests + console.log('šŸ“¦ Preparing batch requests...'); + const batch_requests: AnthropicBatchRequest[] = sections_with_content.map( + ({ content, index }) => ({ + custom_id: `section-${index}`, + params: { + model: anthropic.get_model_identifier(), + max_tokens: 250, + messages: [ + { + role: 'user', + content: USE_CASES_PROMPT + content, + }, + ], + temperature: 0, + }, + }), + ); + + // Create and process batch + console.log('šŸš€ Creating batch job...'); + const batch_response = await anthropic.create_batch(batch_requests); + console.log(`āœ… Batch created with ID: ${batch_response.id}`); + + // Poll for completion + console.log('ā³ Waiting for batch to complete...'); + let batch_status = await anthropic.get_batch_status(batch_response.id); + + while (batch_status.processing_status === 'in_progress') { + const { succeeded, processing, errored } = batch_status.request_counts; + console.log(` Progress: ${succeeded} succeeded, ${processing} processing, ${errored} errored`); + await new Promise((resolve) => setTimeout(resolve, 5000)); + batch_status = await anthropic.get_batch_status(batch_response.id); + } + + console.log('āœ… Batch processing completed!'); + + // Get results + if (!batch_status.results_url) { + throw new Error('Batch completed but no results URL available'); + } + + console.log('šŸ“„ Downloading results...'); + const results = await anthropic.get_batch_results(batch_status.results_url); + + // Process results + console.log('šŸ“Š Processing results...'); + const summaries: Record = {}; + const errors: Array<{ section: string; error: string }> = []; + + for (const result of results) { + const index = parseInt(result.custom_id.split('-')[1] ?? '0'); + const section_data = sections_with_content.find((s) => s.index === index); + + if (!section_data) { + console.warn(`āš ļø Could not find section for index ${index}`); + continue; + } + + const { section } = section_data; + + if (result.result.type !== 'succeeded' || !result.result.message) { + const error_msg = result.result.error?.message || 'Failed or no message'; + console.error(` āŒ ${section.title}: ${error_msg}`); + errors.push({ section: section.title, error: error_msg }); + continue; + } + + const output_content = result.result.message.content[0]?.text; + if (output_content) { + summaries[section.slug] = output_content.trim(); + console.log(` āœ… ${section.title}`); + } + } + + // Write output to JSON file + console.log('šŸ’¾ Writing results to file...'); + const output_path = path.join(current_dirname, '../src/use_cases.json'); + const output_dir = path.dirname(output_path); + + await mkdir(output_dir, { recursive: true }); + + const summary_data: SummaryData = { + generated_at: new Date().toISOString(), + model: anthropic.get_model_identifier(), + total_sections: sections.length, + successful_summaries: Object.keys(summaries).length, + failed_summaries: errors.length, + summaries, + errors: errors.length > 0 ? errors : undefined, + download_errors: download_errors.length > 0 ? download_errors : undefined, + }; + + await writeFile(output_path, JSON.stringify(summary_data, null, 2), 'utf-8'); + + // Print summary + console.log('\nšŸ“Š Summary:'); + console.log(` Total sections: ${sections.length}`); + console.log(` Successfully downloaded: ${sections_with_content.length}`); + console.log(` Download failures: ${download_errors.length}`); + console.log(` Successfully analyzed: ${Object.keys(summaries).length}`); + console.log(` Analysis failures: ${errors.length}`); + console.log(`\nāœ… Results written to: ${output_path}`); + + if (download_errors.length > 0) { + console.log('\nāš ļø Some sections failed to download:'); + download_errors.forEach((e) => console.log(` - ${e.section}: ${e.error}`)); + } + + if (errors.length > 0) { + console.log('\nāš ļø Some sections failed to analyze:'); + errors.forEach((e) => console.log(` - ${e.section}: ${e.error}`)); + } +} + +main().catch((error) => { + console.error('āŒ Fatal error:', error); + process.exit(1); +}); diff --git a/packages/mcp-server/scripts/tsconfig.json b/packages/mcp-server/scripts/tsconfig.json new file mode 100644 index 0000000..29ad2eb --- /dev/null +++ b/packages/mcp-server/scripts/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "allowImportingTsExtensions": true + } +} diff --git a/packages/mcp-server/src/lib/anthropic.ts b/packages/mcp-server/src/lib/anthropic.ts new file mode 100644 index 0000000..bdd5b04 --- /dev/null +++ b/packages/mcp-server/src/lib/anthropic.ts @@ -0,0 +1,172 @@ +import { Anthropic } from '@anthropic-ai/sdk'; +import type { Model } from '@anthropic-ai/sdk/resources/messages/messages.js'; +import * as v from 'valibot'; +import { + anthropic_batch_response_schema, + anthropic_batch_result_schema, + type AnthropicBatchRequest, +} from './schemas.js'; + +export class AnthropicProvider { + private client: Anthropic; + private modelId: Model; + private baseUrl: string; + private apiKey: string; + name = 'Anthropic'; + + constructor(model_id: Model, api_key: string) { + if (!api_key) { + throw new Error('ANTHROPIC_API_KEY is required'); + } + this.apiKey = api_key; + this.client = new Anthropic({ apiKey: api_key, timeout: 1800000 }); + this.modelId = model_id; + this.baseUrl = 'https://api.anthropic.com/v1'; + } + + get_client(): Anthropic { + return this.client; + } + + get_model_identifier(): Model { + return this.modelId; + } + + async create_batch(requests: AnthropicBatchRequest[]) { + try { + const response = await fetch(`${this.baseUrl}/messages/batches`, { + method: 'POST', + headers: { + 'x-api-key': this.apiKey, + 'anthropic-version': '2023-06-01', + 'content-type': 'application/json', + }, + body: JSON.stringify({ requests }), + }); + + if (!response.ok) { + const error_text = await response.text(); + throw new Error( + `Failed to create batch: ${response.status} ${response.statusText} - ${error_text}`, + ); + } + + const json_data = await response.json(); + const validated_response = v.safeParse(anthropic_batch_response_schema, json_data); + + if (!validated_response.success) { + throw new Error( + `Invalid batch response from Anthropic API: ${JSON.stringify(validated_response.issues)}`, + ); + } + + return validated_response.output; + } catch (error) { + console.error('Error creating batch with Anthropic:', error); + throw new Error( + `Failed to create batch: ${error instanceof Error ? error.message : String(error)}`, + ); + } + } + + async get_batch_status(batch_id: string, max_retries = 10, retry_delay = 30000) { + let retry_count = 0; + + while (retry_count <= max_retries) { + try { + const response = await fetch(`${this.baseUrl}/messages/batches/${batch_id}`, { + method: 'GET', + headers: { + 'x-api-key': this.apiKey, + 'anthropic-version': '2023-06-01', + }, + }); + + if (!response.ok) { + const error_text = await response.text(); + throw new Error( + `Failed to get batch status: ${response.status} ${response.statusText} - ${error_text}`, + ); + } + + const json_data = await response.json(); + const validated_response = v.safeParse(anthropic_batch_response_schema, json_data); + + if (!validated_response.success) { + throw new Error( + `Invalid batch status response from Anthropic API: ${JSON.stringify(validated_response.issues)}`, + ); + } + + return validated_response.output; + } catch (error) { + retry_count++; + + if (retry_count > max_retries) { + console.error( + `Error getting batch status for ${batch_id} after ${max_retries} retries:`, + error, + ); + throw new Error( + `Failed to get batch status after ${max_retries} retries: ${ + error instanceof Error ? error.message : String(error) + }`, + ); + } + + console.warn( + `Error getting batch status for ${batch_id} (attempt ${retry_count}/${max_retries}):`, + error, + ); + console.log(`Retrying in ${retry_delay / 1000} seconds...`); + + await new Promise((resolve) => setTimeout(resolve, retry_delay)); + } + } + + // This should never be reached due to the throw in the catch block, but TypeScript needs a return + throw new Error(`Failed to get batch status for ${batch_id} after ${max_retries} retries`); + } + + async get_batch_results(results_url: string) { + try { + const response = await fetch(results_url, { + method: 'GET', + headers: { + 'x-api-key': this.apiKey, + 'anthropic-version': '2023-06-01', + }, + }); + + if (!response.ok) { + const error_text = await response.text(); + throw new Error( + `Failed to get batch results: ${response.status} ${response.statusText} - ${error_text}`, + ); + } + + const text = await response.text(); + // Parse JSONL format (one JSON object per line) + const parsed_results = text + .split('\n') + .filter((line) => line.trim()) + .map((line) => JSON.parse(line)); + + // Validate all results + const validated_results = v.safeParse(v.array(anthropic_batch_result_schema), parsed_results); + + if (!validated_results.success) { + throw new Error( + `Invalid batch results from Anthropic API: ${JSON.stringify(validated_results.issues)}`, + ); + } + + return validated_results.output; + } catch (error) { + console.error(`Error getting batch results:`, error); + throw new Error( + `Failed to get batch results: ${error instanceof Error ? error.message : String(error)}`, + ); + } + } +} diff --git a/packages/mcp-server/src/lib/schemas.ts b/packages/mcp-server/src/lib/schemas.ts new file mode 100644 index 0000000..ea951c4 --- /dev/null +++ b/packages/mcp-server/src/lib/schemas.ts @@ -0,0 +1,122 @@ +import * as v from 'valibot'; + +export const documentation_sections_schema = v.record( + v.string(), + v.object({ + metadata: v.object({ + title: v.string(), + use_cases: v.optional(v.string()), + }), + slug: v.string(), + }), +); + +// Valibot schemas for Batch API +export const summary_data_schema = v.object({ + generated_at: v.string(), + model: v.string(), + total_sections: v.number(), + successful_summaries: v.number(), + failed_summaries: v.number(), + summaries: v.record(v.string(), v.string()), + errors: v.optional( + v.array( + v.object({ + section: v.string(), + error: v.string(), + }), + ), + ), + download_errors: v.optional( + v.array( + v.object({ + section: v.string(), + error: v.string(), + }), + ), + ), +}); + +export const anthropic_batch_request_schema = v.object({ + custom_id: v.string(), + params: v.object({ + model: v.string(), + max_tokens: v.number(), + messages: v.array( + v.object({ + role: v.union([v.literal('user'), v.literal('assistant')]), + content: v.union([ + v.string(), + v.array( + v.object({ + type: v.string(), + text: v.string(), + }), + ), + ]), + }), + ), + }), +}); + +export const anthropic_batch_response_schema = v.object({ + id: v.string(), + type: v.string(), + processing_status: v.union([v.literal('in_progress'), v.literal('ended')]), + request_counts: v.object({ + processing: v.number(), + succeeded: v.number(), + errored: v.number(), + canceled: v.number(), + expired: v.number(), + }), + ended_at: v.nullable(v.string()), + created_at: v.string(), + expires_at: v.string(), + cancel_initiated_at: v.nullable(v.string()), + results_url: v.nullable(v.string()), +}); + +export const anthropic_batch_result_schema = v.object({ + custom_id: v.string(), + result: v.object({ + type: v.union([ + v.literal('succeeded'), + v.literal('errored'), + v.literal('canceled'), + v.literal('expired'), + ]), + message: v.optional( + v.object({ + id: v.string(), + type: v.string(), + role: v.string(), + model: v.string(), + content: v.array( + v.object({ + type: v.string(), + text: v.string(), + }), + ), + stop_reason: v.string(), + stop_sequence: v.nullable(v.string()), + usage: v.object({ + input_tokens: v.number(), + output_tokens: v.number(), + }), + }), + ), + error: v.optional( + v.object({ + type: v.string(), + message: v.string(), + }), + ), + }), +}); + +// Export inferred types +export type SummaryData = v.InferOutput; +export type AnthropicBatchRequest = v.InferOutput; +export type AnthropicBatchResponse = v.InferOutput; +export type AnthropicBatchResult = v.InferOutput; diff --git a/packages/mcp-server/src/mcp/handlers/prompts/svelte-task.ts b/packages/mcp-server/src/mcp/handlers/prompts/svelte-task.ts index 705f5b7..bb7674e 100644 --- a/packages/mcp-server/src/mcp/handlers/prompts/svelte-task.ts +++ b/packages/mcp-server/src/mcp/handlers/prompts/svelte-task.ts @@ -1,6 +1,6 @@ import type { SvelteMcp } from '../../index.js'; import * as v from 'valibot'; -import { get_sections } from '../../utils.js'; +import { format_sections_list } from '../../utils.js'; export function setup_svelte_task(server: SvelteMcp) { server.prompt( @@ -14,7 +14,7 @@ export function setup_svelte_task(server: SvelteMcp) { }), }, async ({ task }) => { - const available_docs: string[] = (await get_sections()).map((s) => s.title); + const available_docs = await format_sections_list(); return { messages: [ @@ -22,10 +22,10 @@ export function setup_svelte_task(server: SvelteMcp) { role: 'user', content: { type: 'text', - text: `You are a Svelte expert tasked to build components and utilities for Svelte developers. If you need documentation for anything related to Svelte you can invoke the tool \`get-documentation\` with one of the following paths: - -${JSON.stringify(available_docs, null, 2)} - + text: `You are a Svelte expert tasked to build components and utilities for Svelte developers. If you need documentation for anything related to Svelte you can invoke the tool \`get_documentation\` with one of the following paths: + +${available_docs} + Every time you write a Svelte component or a Svelte module you MUST invoke the \`svelte-autofixer\` tool providing the code. The tool will return a list of issues or suggestions. If there are any issues or suggestions you MUST fix them and call the tool again with the updated code. You MUST keep doing this until the tool returns no issues or suggestions. Only then you can return the code to the user. diff --git a/packages/mcp-server/src/mcp/handlers/tools/get-documentation.ts b/packages/mcp-server/src/mcp/handlers/tools/get-documentation.ts index 3df2e19..411faa1 100644 --- a/packages/mcp-server/src/mcp/handlers/tools/get-documentation.ts +++ b/packages/mcp-server/src/mcp/handlers/tools/get-documentation.ts @@ -1,6 +1,6 @@ import type { SvelteMcp } from '../../index.js'; import * as v from 'valibot'; -import { get_sections, fetch_with_timeout } from '../../utils.js'; +import { get_sections, fetch_with_timeout, format_sections_list } from '../../utils.js'; import { SECTIONS_LIST_INTRO, SECTIONS_LIST_OUTRO } from './prompts.js'; export function get_documentation(server: SvelteMcp) { @@ -9,12 +9,12 @@ export function get_documentation(server: SvelteMcp) { name: 'get-documentation', enabled: () => false, description: - 'Retrieves full documentation content for Svelte 5 or SvelteKit sections. Supports flexible search by title (e.g., "$state", "routing") or file path (e.g., "docs/svelte/state.md"). Can accept a single section name or an array of sections. Before running this, make sure to analyze the users query, as well as the output from list-sections (which should be called first). Then ask for ALL relevant sections the user might require. For example, if the user asks to build anything interactive, you will need to fetch all relevant runes, and so on.', + 'Retrieves full documentation content for Svelte 5 or SvelteKit sections. Supports flexible search by title (e.g., "$state", "routing") or file path (e.g., "cli/overview"). Can accept a single section name or an array of sections. Before running this, make sure to analyze the users query, as well as the output from list-sections (which should be called first). Then ask for ALL relevant sections the user might require. For example, if the user asks to build anything interactive, you will need to fetch all relevant runes, and so on.', schema: v.object({ section: v.pipe( v.union([v.string(), v.array(v.string())]), v.description( - 'The section name(s) to retrieve. Can search by title (e.g., "$state", "load functions") or file path (e.g., "docs/svelte/state.md"). Supports single string and array of strings', + 'The section name(s) to retrieve. Can search by title (e.g., "$state", "load functions") or file path (e.g., "cli/overview"). Supports single string and array of strings', ), ), }), @@ -52,6 +52,7 @@ export function get_documentation(server: SvelteMcp) { const matched_section = available_sections.find( (s) => s.title.toLowerCase() === requested_section.toLowerCase() || + s.slug === requested_section || s.url === requested_section, ); @@ -97,12 +98,7 @@ export function get_documentation(server: SvelteMcp) { let final_text = results.map((r) => r.content).join('\n\n---\n\n'); if (!has_any_success) { - const formatted_sections = available_sections - .map( - (section) => - `* title: ${section.title}, use_cases: ${section.use_cases}, path: ${section.url}`, - ) - .join('\n'); + const formatted_sections = await format_sections_list(); final_text += `\n\n---\n\n${SECTIONS_LIST_INTRO}\n\n${formatted_sections}\n\n${SECTIONS_LIST_OUTRO}`; } diff --git a/packages/mcp-server/src/mcp/handlers/tools/list-sections.ts b/packages/mcp-server/src/mcp/handlers/tools/list-sections.ts index 28db496..11102cc 100644 --- a/packages/mcp-server/src/mcp/handlers/tools/list-sections.ts +++ b/packages/mcp-server/src/mcp/handlers/tools/list-sections.ts @@ -1,5 +1,5 @@ import type { SvelteMcp } from '../../index.js'; -import { get_sections } from '../../utils.js'; +import { format_sections_list } from '../../utils.js'; import { SECTIONS_LIST_INTRO, SECTIONS_LIST_OUTRO } from './prompts.js'; export function list_sections(server: SvelteMcp) { @@ -8,16 +8,10 @@ export function list_sections(server: SvelteMcp) { name: 'list-sections', enabled: () => false, description: - 'Lists all available Svelte 5 and SvelteKit documentation sections in a structured format. Returns sections as a list of "* title: [section_title], use_cases: [use_cases], path: [file_path]" - you can use either the title or path when querying a specific section via the get_documentation tool. Always run list-sections first for any query related to Svelte development to discover available content.', + 'Lists all available Svelte 5 and SvelteKit documentation sections in a structured format. Each section includes a "use_cases" field that describes WHEN this documentation would be useful. You should carefully analyze the use_cases field to determine which sections are relevant for the user\'s query. The use_cases contain comma-separated keywords describing project types (e.g., "e-commerce", "blog"), features (e.g., "authentication", "forms"), components (e.g., "slider", "modal"), development stages (e.g., "deployment", "testing"), or "always" for fundamental concepts. Match these use_cases against the user\'s intent - for example, if building an e-commerce site, fetch sections with use_cases containing "e-commerce", "product listings", "shopping cart", etc. If building a slider, look for "slider", "carousel", "animation", etc. Returns sections as "* title: [section_title], use_cases: [use_cases], path: [file_path]". Always run list-sections FIRST for any Svelte query, then analyze ALL use_cases to identify relevant sections, and finally use get_documentation to fetch ALL relevant sections at once.', }, async () => { - const sections = await get_sections(); - const formatted_sections = sections - .map( - (section) => - `* title: ${section.title}, use_cases: ${section.use_cases}, path: ${section.url}`, - ) - .join('\n'); + const formatted_sections = await format_sections_list(); return { content: [ diff --git a/packages/mcp-server/src/mcp/handlers/tools/prompts.ts b/packages/mcp-server/src/mcp/handlers/tools/prompts.ts index e574058..a6f9d41 100644 --- a/packages/mcp-server/src/mcp/handlers/tools/prompts.ts +++ b/packages/mcp-server/src/mcp/handlers/tools/prompts.ts @@ -1,5 +1,5 @@ export const SECTIONS_LIST_INTRO = - 'List of available Svelte documentation sections and its inteneded uses:'; + 'List of available Svelte documentation sections with their intended use cases. The "use_cases" field describes WHEN each section would be useful - analyze these carefully to determine which sections match the user\'s query:'; export const SECTIONS_LIST_OUTRO = - 'Use the title or path with the get-documentation tool to get more details about a specific section.'; + "Carefully analyze the use_cases field for each section to identify which documentation is relevant for the user's specific query. The use_cases contain keywords for project types, features, components, and development stages. After identifying relevant sections, use the get-documentation tool with ALL relevant section titles or paths at once (can pass multiple sections as an array)."; diff --git a/packages/mcp-server/src/mcp/schemas/index.ts b/packages/mcp-server/src/mcp/schemas/index.ts deleted file mode 100644 index 0bdc3ce..0000000 --- a/packages/mcp-server/src/mcp/schemas/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as v from 'valibot'; - -export const documentation_sections_schema = v.record( - v.string(), - v.object({ - metadata: v.object({ - title: v.string(), - use_cases: v.optional(v.string()), - }), - slug: v.string(), - }), -); diff --git a/packages/mcp-server/src/mcp/utils.ts b/packages/mcp-server/src/mcp/utils.ts index 0ed3ad1..f0d54b3 100644 --- a/packages/mcp-server/src/mcp/utils.ts +++ b/packages/mcp-server/src/mcp/utils.ts @@ -1,5 +1,6 @@ import * as v from 'valibot'; -import { documentation_sections_schema } from '../mcp/schemas/index.js'; +import { documentation_sections_schema } from '../lib/schemas.js'; +import summary_data from '../use_cases.json' with { type: 'json' }; export async function fetch_with_timeout( url: string, @@ -16,16 +17,40 @@ export async function fetch_with_timeout( } } +const summaries = (summary_data.summaries || {}) as Record; + export async function get_sections() { const sections = await fetch_with_timeout( 'https://svelte.dev/docs/experimental/sections.json', ).then((res) => res.json()); const validated_sections = v.safeParse(documentation_sections_schema, sections); if (!validated_sections.success) return []; - return Object.entries(validated_sections.output).map(([, section]) => ({ - title: section.metadata.title, - use_cases: section.metadata.use_cases ?? 'read document for use cases', - slug: section.slug, - url: `https://svelte.dev/${section.slug}/llms.txt`, - })); + + const mapped_sections = Object.entries(validated_sections.output).map(([, section]) => { + const original_slug = section.slug; + const cleaned_slug = original_slug.startsWith('docs/') + ? original_slug.slice('docs/'.length) + : original_slug; + + return { + title: section.metadata.title, + use_cases: + section.metadata.use_cases ?? + summaries[original_slug] ?? + summaries[cleaned_slug] ?? + 'use title and path to estimate use case', + slug: cleaned_slug, + // Use original slug in URL to ensure it still works + url: `https://svelte.dev/${original_slug}/llms.txt`, + }; + }); + + return mapped_sections; +} + +export async function format_sections_list() { + const sections = await get_sections(); + return sections + .map((s) => `* title: ${s.title}, use_cases: ${s.use_cases}, path: ${s.slug}`) + .join('\n'); } diff --git a/packages/mcp-server/src/use_cases.json b/packages/mcp-server/src/use_cases.json new file mode 100644 index 0000000..6081a07 --- /dev/null +++ b/packages/mcp-server/src/use_cases.json @@ -0,0 +1,176 @@ +{ + "generated_at": "2025-10-02T20:29:23.410Z", + "model": "claude-sonnet-4-5-20250929", + "total_sections": 167, + "successful_summaries": 167, + "failed_summaries": 0, + "summaries": { + "docs/cli/overview": "project setup, creating new svelte apps, scaffolding, cli tools, initializing projects", + "docs/cli/faq": "project setup, initializing new svelte projects, troubleshooting cli installation, package manager configuration", + "docs/cli/sv-create": "project setup, starting new sveltekit app, initializing project, creating from playground, choosing project template", + "docs/cli/sv-add": "project setup, adding features to existing projects, integrating tools, testing setup, styling setup, authentication, database setup, deployment adapters", + "docs/cli/sv-check": "code quality, ci/cd pipelines, error checking, typescript projects, pre-commit hooks, finding unused css, accessibility auditing, production builds", + "docs/cli/sv-migrate": "migration, upgrading svelte versions, upgrading sveltekit versions, modernizing codebase, svelte 3 to 4, svelte 4 to 5, sveltekit 1 to 2, adopting runes, refactoring deprecated apis", + "docs/cli/devtools-json": "development setup, chrome devtools integration, browser-based editing, local development workflow, debugging setup", + "docs/cli/drizzle": "database setup, sql queries, orm integration, data modeling, postgresql, mysql, sqlite, server-side data access, database migrations, type-safe queries", + "docs/cli/eslint": "code quality, linting, error detection, project setup, code standards, team collaboration, typescript projects", + "docs/cli/lucia": "authentication, login systems, user management, registration pages, session handling, auth setup", + "docs/cli/mdsvex": "blog, content sites, markdown rendering, documentation sites, technical writing, cms integration, article pages", + "docs/cli/paraglide": "internationalization, multi-language sites, i18n, translation, localization, language switching, global apps, multilingual content", + "docs/cli/playwright": "browser testing, e2e testing, integration testing, test automation, quality assurance, ci/cd pipelines, testing user flows", + "docs/cli/prettier": "code formatting, project setup, code style consistency, team collaboration, linting configuration", + "docs/cli/storybook": "component development, design systems, ui library, isolated component testing, documentation, visual testing, component showcase", + "docs/cli/sveltekit-adapter": "deployment, production builds, hosting setup, choosing deployment platform, configuring adapters, static site generation, node server, vercel, cloudflare, netlify", + "docs/cli/tailwind": "project setup, styling, css framework, rapid prototyping, utility-first css, design systems, responsive design, adding tailwind to svelte", + "docs/cli/vitest": "testing, unit tests, component testing, test setup, quality assurance, ci/cd pipelines, test-driven development", + "docs/kit/introduction": "learning sveltekit, project setup, understanding framework basics, choosing between svelte and sveltekit, getting started with full-stack apps", + "docs/kit/creating-a-project": "project setup, starting new sveltekit app, initial development environment, first-time sveltekit users, scaffolding projects", + "docs/kit/project-types": "deployment, project setup, choosing adapters, ssg, spa, ssr, serverless, mobile apps, desktop apps, pwa, offline apps, browser extensions, separate backend, docker containers", + "docs/kit/project-structure": "project setup, understanding file structure, organizing code, starting new project, learning sveltekit basics", + "docs/kit/web-standards": "always, any sveltekit project, data fetching, forms, api routes, server-side rendering, deployment to various platforms", + "docs/kit/routing": "routing, navigation, multi-page apps, project setup, file structure, api endpoints, data loading, layouts, error pages, always", + "docs/kit/load": "data fetching, api calls, database queries, dynamic routes, page initialization, loading states, authentication checks, ssr data, form data, content rendering", + "docs/kit/form-actions": "forms, user input, data submission, authentication, login systems, user registration, progressive enhancement, validation errors", + "docs/kit/page-options": "prerendering static sites, ssr configuration, spa setup, client-side rendering control, url trailing slash handling, adapter deployment config, build optimization", + "docs/kit/state-management": "sveltekit, server-side rendering, ssr, state management, authentication, data persistence, load functions, context api, navigation, component lifecycle", + "docs/kit/remote-functions": "data fetching, server-side logic, database queries, type-safe client-server communication, forms, user input, mutations, authentication, crud operations, optimistic updates", + "docs/kit/building-your-app": "production builds, deployment preparation, build process optimization, adapter configuration, preview before deployment", + "docs/kit/adapters": "deployment, production builds, hosting setup, choosing deployment platform, configuring adapters", + "docs/kit/adapter-auto": "deployment, production builds, hosting setup, choosing deployment platform, ci/cd configuration", + "docs/kit/adapter-node": "deployment, production builds, node.js hosting, custom server setup, environment configuration, reverse proxy setup, docker deployment, systemd services", + "docs/kit/adapter-static": "static site generation, ssg, prerendering, deployment, github pages, spa mode, blogs, documentation sites, marketing sites", + "docs/kit/single-page-apps": "spa mode, single-page apps, client-only rendering, static hosting, mobile app wrappers, no server-side logic, adapter-static setup, fallback pages", + "docs/kit/adapter-cloudflare": "deployment, cloudflare workers, cloudflare pages, hosting setup, production builds, serverless deployment, edge computing", + "docs/kit/adapter-cloudflare-workers": "deploying to cloudflare workers, cloudflare workers sites deployment, legacy cloudflare adapter, wrangler configuration, cloudflare platform bindings", + "docs/kit/adapter-netlify": "deployment, netlify hosting, production builds, serverless functions, edge functions, static site hosting", + "docs/kit/adapter-vercel": "deployment, vercel hosting, production builds, serverless functions, edge functions, isr, image optimization, environment variables", + "docs/kit/writing-adapters": "custom deployment, building adapters, unsupported platforms, adapter development, custom hosting environments", + "docs/kit/advanced-routing": "advanced routing, dynamic routes, file viewers, nested paths, custom 404 pages, url validation, route parameters, multi-level navigation", + "docs/kit/hooks": "authentication, logging, error tracking, request interception, api proxying, custom routing, internationalization, database initialization, middleware logic, session management", + "docs/kit/errors": "error handling, custom error pages, 404 pages, api error responses, production error logging, error tracking, type-safe errors", + "docs/kit/link-options": "routing, navigation, multi-page apps, performance optimization, link preloading, forms with get method, search functionality, focus management, scroll behavior", + "docs/kit/service-workers": "offline support, pwa, caching strategies, performance optimization, precaching assets, network resilience, progressive web apps", + "docs/kit/server-only-modules": "api keys, environment variables, sensitive data protection, backend security, preventing data leaks, server-side code isolation", + "docs/kit/snapshots": "forms, user input, preserving form data, multi-step forms, navigation state, preventing data loss, textarea content, input fields, comment systems, surveys", + "docs/kit/shallow-routing": "modals, dialogs, image galleries, overlays, history-driven ui, mobile-friendly navigation, photo viewers, lightboxes, drawer menus", + "docs/kit/observability": "performance monitoring, debugging, observability, tracing requests, production diagnostics, analyzing slow requests, finding bottlenecks, monitoring server-side operations", + "docs/kit/packaging": "building component libraries, publishing npm packages, creating reusable svelte components, library development, package distribution", + "docs/kit/auth": "authentication, login systems, user management, session handling, jwt tokens, protected routes, user credentials, authorization checks", + "docs/kit/performance": "performance optimization, slow loading pages, production deployment, debugging performance issues, reducing bundle size, improving load times", + "docs/kit/icons": "icons, ui components, styling, css frameworks, tailwind, unocss, performance optimization, dependency management", + "docs/kit/images": "image optimization, responsive images, performance, hero images, product photos, galleries, cms integration, cdn setup, asset management", + "docs/kit/accessibility": "always, any sveltekit project, screen reader support, keyboard navigation, multi-page apps, client-side routing, internationalization, multilingual sites", + "docs/kit/seo": "seo optimization, search engine ranking, content sites, blogs, marketing sites, public-facing apps, sitemaps, amp pages, meta tags, performance optimization", + "docs/kit/faq": "troubleshooting package imports, library compatibility issues, client-side code execution, external api integration, middleware setup, database configuration, view transitions, yarn configuration", + "docs/kit/integrations": "project setup, css preprocessors, postcss, scss, sass, less, stylus, typescript setup, adding integrations, tailwind, testing, auth, linting, formatting", + "docs/kit/debugging": "debugging, breakpoints, development workflow, troubleshooting issues, vscode setup, ide configuration, inspecting code execution", + "docs/kit/migrating-to-sveltekit-2": "migration, upgrading from sveltekit 1 to 2, breaking changes, version updates", + "docs/kit/migrating": "migrating from sapper, upgrading legacy projects, sapper to sveltekit conversion, project modernization", + "docs/kit/additional-resources": "troubleshooting, getting help, finding examples, learning sveltekit, project templates, common issues, community support", + "docs/kit/glossary": "rendering strategies, performance optimization, deployment configuration, seo requirements, static sites, spas, server-side rendering, prerendering, edge deployment, pwa development", + "docs/kit/@sveltejs-kit": "forms, form actions, server-side validation, form submission, error handling, redirects, json responses, http errors, server utilities", + "docs/kit/@sveltejs-kit-hooks": "middleware, request processing, authentication chains, logging, multiple hooks, request/response transformation", + "docs/kit/@sveltejs-kit-node-polyfills": "node.js environments, custom servers, non-standard runtimes, ssr setup, web api compatibility, polyfill requirements", + "docs/kit/@sveltejs-kit-node": "node.js adapter, custom server setup, http integration, streaming files, node deployment, server-side rendering with node", + "docs/kit/@sveltejs-kit-vite": "project setup, vite configuration, initial sveltekit setup, build tooling", + "docs/kit/$app-environment": "always, conditional logic, client-side code, server-side code, build-time logic, prerendering, development vs production, environment detection", + "docs/kit/$app-forms": "forms, user input, data submission, progressive enhancement, custom form handling, form validation", + "docs/kit/$app-navigation": "routing, navigation, multi-page apps, programmatic navigation, data reloading, preloading, shallow routing, navigation lifecycle, scroll handling, view transitions", + "docs/kit/$app-paths": "static assets, images, fonts, public files, base path configuration, subdirectory deployment, cdn setup, asset urls, links, navigation", + "docs/kit/$app-server": "remote functions, server-side logic, data fetching, form handling, api endpoints, client-server communication, prerendering, file reading, batch queries", + "docs/kit/$app-state": "routing, navigation, multi-page apps, loading states, url parameters, form handling, error states, version updates, page metadata, shallow routing", + "docs/kit/$app-stores": "legacy projects, sveltekit pre-2.12, migration from stores to runes, maintaining older codebases, accessing page data, navigation state, app version updates", + "docs/kit/$app-types": "routing, navigation, type safety, route parameters, dynamic routes, link generation, pathname validation, multi-page apps", + "docs/kit/$env-dynamic-private": "api keys, secrets management, server-side config, environment variables, backend logic, deployment-specific settings, private data handling", + "docs/kit/$env-dynamic-public": "environment variables, client-side config, runtime configuration, public api keys, deployment-specific settings, multi-environment apps", + "docs/kit/$env-static-private": "server-side api keys, backend secrets, database credentials, private configuration, build-time optimization, server endpoints, authentication tokens", + "docs/kit/$env-static-public": "environment variables, public config, client-side data, api endpoints, build-time configuration, public constants", + "docs/kit/$lib": "project setup, component organization, importing shared components, reusable ui elements, code structure", + "docs/kit/$service-worker": "offline support, pwa, service workers, caching strategies, progressive web apps, offline-first apps", + "docs/kit/configuration": "project setup, configuration, adapters, deployment, build settings, environment variables, routing customization, prerendering, csp security, csrf protection, path configuration, typescript setup", + "docs/kit/cli": "project setup, typescript configuration, generated types, ./$types imports, initial project configuration", + "docs/kit/types": "typescript, type safety, route parameters, api endpoints, load functions, form actions, generated types, jsconfig setup", + "docs/svelte/overview": "always, any svelte project, getting started, learning svelte, introduction, project setup, understanding framework basics", + "docs/svelte/getting-started": "project setup, starting new svelte project, initial installation, choosing between sveltekit and vite, editor configuration", + "docs/svelte/svelte-files": "always, any svelte project, component creation, project setup, learning svelte basics", + "docs/svelte/svelte-js-files": "shared reactive state, reusable reactive logic, state management across components, global stores, custom reactive utilities", + "docs/svelte/what-are-runes": "always, any svelte 5 project, understanding core syntax, learning svelte 5, migration from svelte 4", + "docs/svelte/$state": "always, any svelte project, core reactivity, state management, counters, forms, todo apps, interactive ui, data updates, class-based components", + "docs/svelte/$derived": "always, any svelte project, computed values, reactive calculations, derived data, transforming state, dependent values", + "docs/svelte/$effect": "canvas drawing, third-party library integration, dom manipulation, side effects, intervals, timers, network requests, analytics tracking", + "docs/svelte/$props": "always, any svelte project, passing data to components, component communication, reusable components, component props", + "docs/svelte/$bindable": "forms, user input, two-way data binding, custom input components, parent-child communication, reusable form fields", + "docs/svelte/$inspect": "debugging, development, tracking state changes, reactive state monitoring, troubleshooting reactivity issues", + "docs/svelte/$host": "custom elements, web components, dispatching custom events, component library, framework-agnostic components", + "docs/svelte/basic-markup": "always, any svelte project, basic markup, html templating, component structure, attributes, events, props, text rendering", + "docs/svelte/if": "always, conditional rendering, showing/hiding content, dynamic ui, user permissions, loading states, error handling, form validation", + "docs/svelte/each": "always, lists, arrays, iteration, product listings, todos, tables, grids, dynamic content, shopping carts, user lists, comments, feeds", + "docs/svelte/key": "animations, transitions, component reinitialization, forcing component remount, value-based ui updates, resetting component state", + "docs/svelte/await": "async data fetching, api calls, loading states, promises, error handling, lazy loading components, dynamic imports", + "docs/svelte/snippet": "reusable markup, component composition, passing content to components, table rows, list items, conditional rendering, reducing duplication", + "docs/svelte/@render": "reusable ui patterns, component composition, conditional rendering, fallback content, layout components, slot alternatives, template reuse", + "docs/svelte/@html": "rendering html strings, cms content, rich text editors, markdown to html, blog posts, wysiwyg output, sanitized html injection, dynamic html content", + "docs/svelte/@attach": "tooltips, popovers, dom manipulation, third-party libraries, canvas drawing, element lifecycle, interactive ui, custom directives, wrapper components", + "docs/svelte/@const": "computed values in loops, derived calculations in blocks, local variables in each iterations, complex list rendering", + "docs/svelte/@debug": "debugging, development, troubleshooting, tracking state changes, monitoring variables, reactive data inspection", + "docs/svelte/bind": "forms, user input, two-way data binding, interactive ui, media players, file uploads, checkboxes, radio buttons, select dropdowns, contenteditable, dimension tracking", + "docs/svelte/use": "custom directives, dom manipulation, third-party library integration, tooltips, click outside, gestures, focus management, element lifecycle hooks", + "docs/svelte/transition": "animations, interactive ui, modals, dropdowns, notifications, conditional content, show/hide elements, smooth state changes", + "docs/svelte/in-and-out": "animation, transitions, interactive ui, conditional rendering, independent enter/exit effects, modals, tooltips, notifications", + "docs/svelte/animate": "sortable lists, drag and drop, reorderable items, todo lists, kanban boards, playlist editors, priority queues, animated list reordering", + "docs/svelte/style": "dynamic styling, conditional styles, theming, dark mode, responsive design, interactive ui, component styling", + "docs/svelte/class": "always, conditional styling, dynamic classes, tailwind css, component styling, reusable components, responsive design", + "docs/svelte/await-expressions": "async data fetching, loading states, server-side rendering, awaiting promises in components, async validation, concurrent data loading", + "docs/svelte/scoped-styles": "always, styling components, scoped css, component-specific styles, preventing style conflicts, animations, keyframes", + "docs/svelte/global-styles": "global styles, third-party libraries, css resets, animations, styling body/html, overriding component styles, shared keyframes, base styles", + "docs/svelte/custom-properties": "theming, custom styling, reusable components, design systems, dynamic colors, component libraries, ui customization", + "docs/svelte/nested-style-elements": "component styling, scoped styles, dynamic styles, conditional styling, nested style tags, custom styling logic", + "docs/svelte/svelte-boundary": "error handling, async data loading, loading states, error recovery, flaky components, error reporting, resilient ui", + "docs/svelte/svelte-window": "keyboard shortcuts, scroll tracking, window resize handling, responsive layouts, online/offline detection, viewport dimensions, global event listeners", + "docs/svelte/svelte-document": "document events, visibility tracking, fullscreen detection, pointer lock, focus management, document-level interactions", + "docs/svelte/svelte-body": "mouse tracking, hover effects, cursor interactions, global body events, drag and drop, custom cursors, interactive backgrounds, body-level actions", + "docs/svelte/svelte-head": "seo optimization, page titles, meta tags, social media sharing, dynamic head content, multi-page apps, blog posts, product pages", + "docs/svelte/svelte-element": "dynamic content, cms integration, user-generated content, configurable ui, runtime element selection, flexible components", + "docs/svelte/svelte-options": "migration, custom elements, web components, legacy mode compatibility, runes mode setup, svg components, mathml components, css injection control", + "docs/svelte/stores": "shared state, cross-component data, reactive values, async data streams, manual control over updates, rxjs integration, extracting logic", + "docs/svelte/context": "shared state, avoiding prop drilling, component communication, theme providers, user context, authentication state, configuration sharing, deeply nested components", + "docs/svelte/lifecycle-hooks": "component initialization, cleanup tasks, timers, subscriptions, dom measurements, chat windows, autoscroll features, migration from svelte 4", + "docs/svelte/imperative-component-api": "project setup, client-side rendering, server-side rendering, ssr, hydration, testing, programmatic component creation, tooltips, dynamic mounting", + "docs/svelte/testing": "testing, quality assurance, unit tests, integration tests, component tests, e2e tests, vitest setup, playwright setup, test automation", + "docs/svelte/typescript": "typescript setup, type safety, component props typing, generic components, wrapper components, dom type augmentation, project configuration", + "docs/svelte/custom-elements": "web components, custom elements, component library, design system, framework-agnostic components, embedding svelte in non-svelte apps, shadow dom", + "docs/svelte/v4-migration-guide": "upgrading svelte 3 to 4, version migration, updating dependencies, breaking changes, legacy project maintenance", + "docs/svelte/v5-migration-guide": "migrating from svelte 4 to 5, upgrading projects, learning svelte 5 syntax changes, runes migration, event handler updates", + "docs/svelte/faq": "getting started, learning svelte, beginner setup, project initialization, vs code setup, formatting, testing, routing, mobile apps, troubleshooting, community support", + "docs/svelte/svelte": "migration from svelte 4 to 5, upgrading legacy code, component lifecycle hooks, context api, mounting components, event dispatchers, typescript component types", + "docs/svelte/svelte-action": "typescript types, actions, use directive, dom manipulation, element lifecycle, custom behaviors, third-party library integration", + "docs/svelte/svelte-animate": "animated lists, sortable items, drag and drop, reordering elements, todo lists, kanban boards, playlist management, smooth position transitions", + "docs/svelte/svelte-attachments": "library development, component libraries, programmatic element manipulation, migrating from actions to attachments, spreading props onto elements", + "docs/svelte/svelte-compiler": "build tools, custom compilers, ast manipulation, preprocessors, code transformation, migration scripts, syntax analysis, bundler plugins, dev tools", + "docs/svelte/svelte-easing": "animations, transitions, custom easing, smooth motion, interactive ui, modals, dropdowns, carousels, page transitions, scroll effects", + "docs/svelte/svelte-events": "window events, document events, global event listeners, event delegation, programmatic event handling, cleanup functions, media queries", + "docs/svelte/svelte-legacy": "migration from svelte 4 to svelte 5, upgrading legacy code, event modifiers, class components, imperative component instantiation", + "docs/svelte/svelte-motion": "animation, smooth transitions, interactive ui, sliders, counters, physics-based motion, drag gestures, accessibility, reduced motion", + "docs/svelte/svelte-reactivity-window": "responsive design, viewport tracking, scroll effects, window resize handling, online/offline detection, zoom level tracking", + "docs/svelte/svelte-reactivity": "reactive data structures, state management with maps/sets, game boards, selection tracking, url manipulation, query params, real-time clocks, media queries, responsive design", + "docs/svelte/svelte-server": "server-side rendering, ssr, static site generation, seo optimization, initial page load, pre-rendering, node.js server, custom server setup", + "docs/svelte/svelte-store": "state management, shared data, reactive stores, cross-component communication, global state, computed values, data synchronization, legacy svelte projects", + "docs/svelte/svelte-transition": "animations, transitions, interactive ui, modals, dropdowns, tooltips, notifications, svg animations, list animations, page transitions", + "docs/svelte/compiler-errors": "animation, transitions, keyed each blocks, list animations", + "docs/svelte/compiler-warnings": "accessibility, a11y compliance, wcag standards, screen readers, keyboard navigation, aria attributes, semantic html, interactive elements", + "docs/svelte/runtime-errors": "debugging errors, error handling, troubleshooting runtime issues, migration to svelte 5, component binding, effects and reactivity", + "docs/svelte/runtime-warnings": "debugging state proxies, console logging reactive values, inspecting state changes, development troubleshooting", + "docs/svelte/legacy-overview": "migrating from svelte 3/4 to svelte 5, maintaining legacy components, understanding deprecated features, gradual upgrade process", + "docs/svelte/legacy-let": "migration, legacy svelte projects, upgrading from svelte 4, understanding old reactivity, maintaining existing code, learning runes differences", + "docs/svelte/legacy-reactive-assignments": "legacy mode, migration from svelte 4, reactive statements, computed values, derived state, side effects", + "docs/svelte/legacy-export-let": "legacy mode, migration from svelte 4, maintaining older projects, component props without runes, exporting component methods, renaming reserved word props", + "docs/svelte/legacy-$$props-and-$$restProps": "legacy mode migration, component wrappers, prop forwarding, button components, reusable ui components, spreading props to child elements", + "docs/svelte/legacy-on": "legacy mode, event handling, button clicks, forms, user interactions, component communication, event forwarding, event modifiers", + "docs/svelte/legacy-slots": "legacy mode, migrating from svelte 4, component composition, reusable components, passing content to components, modals, layouts, wrappers", + "docs/svelte/legacy-$$slots": "legacy mode, conditional slot rendering, optional content sections, checking if slots provided, migrating from legacy to runes", + "docs/svelte/legacy-svelte-fragment": "named slots, component composition, layout systems, avoiding wrapper divs, legacy svelte projects, slot content organization", + "docs/svelte/legacy-svelte-component": "dynamic components, component switching, conditional rendering, legacy mode migration, tabbed interfaces, multi-step forms", + "docs/svelte/legacy-svelte-self": "recursive components, tree structures, nested menus, file explorers, comment threads, hierarchical data", + "docs/svelte/legacy-component-api": "migration from svelte 3/4 to 5, legacy component api, maintaining old projects, understanding deprecated patterns" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a54d240..6f9f5fd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,7 +31,7 @@ importers: version: 10.1.8(eslint@9.36.0(jiti@2.6.0)) eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint@9.36.0(jiti@2.6.0)) + version: 2.32.0(eslint@9.36.0(jiti@2.6.0)) eslint-plugin-svelte: specifier: ^3.12.3 version: 3.12.4(eslint@9.36.0(jiti@2.6.0))(svelte@5.39.6)(ts-node@10.9.2(@types/node@24.5.2)(typescript@5.9.2)) @@ -55,7 +55,7 @@ importers: version: 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2) vitest: specifier: ^3.2.3 - version: 3.2.4(@types/node@24.5.2)(jiti@2.6.0) + version: 3.2.4(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) apps/mcp-remote: dependencies: @@ -86,13 +86,13 @@ importers: version: 0.16.8(@types/node@24.5.2)(typescript@5.9.2) '@sveltejs/adapter-vercel': specifier: ^5.6.3 - version: 5.10.2(@sveltejs/kit@2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)))(rollup@4.52.2) + version: 5.10.2(@sveltejs/kit@2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)))(rollup@4.52.2) '@sveltejs/kit': specifier: ^2.22.0 - version: 2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + version: 2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)) '@sveltejs/vite-plugin-svelte': specifier: ^6.0.0 - version: 6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + version: 6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)) '@types/node': specifier: ^24.3.1 version: 24.5.2 @@ -134,13 +134,13 @@ importers: version: 5.9.2 vite: specifier: ^7.0.4 - version: 7.1.7(@types/node@24.5.2)(jiti@2.6.0) + version: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) vite-plugin-devtools-json: specifier: ^1.0.0 - version: 1.0.0(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + version: 1.0.0(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)) vitest: specifier: ^3.2.3 - version: 3.2.4(@types/node@24.5.2)(jiti@2.6.0) + version: 3.2.4(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) packages/mcp-schema: dependencies: @@ -185,14 +185,17 @@ importers: version: 1.1.0(typescript@5.9.2) vitest: specifier: ^3.2.4 - version: 3.2.4(@types/node@24.5.2)(jiti@2.6.0) + version: 3.2.4(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) zimmerframe: specifier: ^1.1.4 version: 1.1.4 devDependencies: + '@anthropic-ai/sdk': + specifier: ^0.65.0 + version: 0.65.0(zod@3.25.76) '@sveltejs/kit': specifier: ^2.42.2 - version: 2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + version: 2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)) '@types/eslint-scope': specifier: ^8.3.2 version: 8.3.2 @@ -202,6 +205,9 @@ importers: '@typescript-eslint/types': specifier: ^8.44.0 version: 8.44.1 + dotenv: + specifier: ^17.2.3 + version: 17.2.3 packages/mcp-stdio: dependencies: @@ -229,10 +235,19 @@ importers: version: 5.9.2 vitest: specifier: ^3.1.3 - version: 3.2.4(@types/node@22.18.6)(jiti@2.6.0) + version: 3.2.4(@types/node@22.18.6)(jiti@2.6.0)(tsx@4.20.6) packages: + '@anthropic-ai/sdk@0.65.0': + resolution: {integrity: sha512-zIdPOcrCVEI8t3Di40nH4z9EoeyGZfXbYSvWdDLsB/KkaSYMnEgC7gmcgWu83g2NTn1ZTpbMvpdttWDGGIk6zw==} + hasBin: true + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + '@babel/generator@7.28.3': resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} engines: {node: '>=6.9.0'} @@ -2200,6 +2215,10 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + drizzle-kit@0.30.6: resolution: {integrity: sha512-U4wWit0fyZuGuP7iNmRleQyK2V8wCuv57vf5l3MnG4z4fzNTjY/U13M8owyQ5RavqvqxBifWORaR3wIUzlN64g==} hasBin: true @@ -2956,6 +2975,10 @@ packages: json-rpc-2.0@1.7.1: resolution: {integrity: sha512-JqZjhjAanbpkXIzFE7u8mE/iFblawwlXtONaCvRqI+pyABVz7B4M1EUNpyVW+dZjqgQ2L5HFmZCmOCgUKm00hg==} + json-schema-to-ts@3.1.1: + resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} + engines: {node: '>=16'} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -3791,6 +3814,9 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + ts-algebra@2.0.0: + resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} + ts-api-utils@2.1.0: resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} @@ -3836,6 +3862,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.20.6: + resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + engines: {node: '>=18.0.0'} + hasBin: true + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -4140,6 +4171,12 @@ packages: snapshots: + '@anthropic-ai/sdk@0.65.0(zod@3.25.76)': + dependencies: + json-schema-to-ts: 3.1.1 + optionalDependencies: + zod: 3.25.76 + '@babel/generator@7.28.3': dependencies: '@babel/parser': 7.28.4 @@ -5328,9 +5365,9 @@ snapshots: dependencies: acorn: 8.15.0 - '@sveltejs/adapter-vercel@5.10.2(@sveltejs/kit@2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)))(rollup@4.52.2)': + '@sveltejs/adapter-vercel@5.10.2(@sveltejs/kit@2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)))(rollup@4.52.2)': dependencies: - '@sveltejs/kit': 2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + '@sveltejs/kit': 2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)) '@vercel/nft': 0.30.1(rollup@4.52.2) esbuild: 0.25.10 transitivePeerDependencies: @@ -5338,11 +5375,11 @@ snapshots: - rollup - supports-color - '@sveltejs/kit@2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0))': + '@sveltejs/kit@2.43.5(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 @@ -5355,26 +5392,26 @@ snapshots: set-cookie-parser: 2.7.1 sirv: 3.0.2 svelte: 5.39.6 - vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) - '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)) debug: 4.4.3 svelte: 5.39.6 - vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0))': + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)))(svelte@5.39.6)(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)) debug: 4.4.3 deepmerge: 4.3.1 magic-string: 0.30.19 svelte: 5.39.6 - vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0) - vitefu: 1.1.1(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) + vitefu: 1.1.1(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)) transitivePeerDependencies: - supports-color @@ -5582,13 +5619,21 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0))': + '@vitest/mocker@3.2.4(vite@7.1.7(@types/node@22.18.6)(jiti@2.6.0)(tsx@4.20.6))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.19 + optionalDependencies: + vite: 7.1.7(@types/node@22.18.6)(jiti@2.6.0)(tsx@4.20.6) + + '@vitest/mocker@3.2.4(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: - vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) '@vitest/pretty-format@3.2.4': dependencies: @@ -5997,6 +6042,8 @@ snapshots: dotenv@16.6.1: {} + dotenv@17.2.3: {} + drizzle-kit@0.30.6: dependencies: '@drizzle-team/brocli': 0.10.2 @@ -6228,17 +6275,16 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.0)): + eslint-module-utils@2.12.1(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.0)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2) eslint: 9.36.0(jiti@2.6.0) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint@9.36.0(jiti@2.6.0)): + eslint-plugin-import@2.32.0(eslint@9.36.0(jiti@2.6.0)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -6249,7 +6295,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.36.0(jiti@2.6.0) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.0)) + eslint-module-utils: 2.12.1(eslint-import-resolver-node@0.3.9)(eslint@9.36.0(jiti@2.6.0)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -6260,8 +6306,6 @@ snapshots: semver: 6.3.1 string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.44.1(eslint@9.36.0(jiti@2.6.0))(typescript@5.9.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -6846,6 +6890,11 @@ snapshots: json-rpc-2.0@1.7.1: {} + json-schema-to-ts@3.1.1: + dependencies: + '@babel/runtime': 7.28.4 + ts-algebra: 2.0.0 + json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} @@ -7705,6 +7754,8 @@ snapshots: tree-kill@1.2.2: {} + ts-algebra@2.0.0: {} + ts-api-utils@2.1.0(typescript@5.9.2): dependencies: typescript: 5.9.2 @@ -7761,6 +7812,14 @@ snapshots: tslib@2.8.1: {} + tsx@4.20.6: + dependencies: + esbuild: 0.25.10 + get-tsconfig: 4.10.1 + optionalDependencies: + fsevents: 2.3.3 + optional: true + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -7868,13 +7927,13 @@ snapshots: vary@1.1.2: {} - vite-node@3.2.4(@types/node@22.18.6)(jiti@2.6.0): + vite-node@3.2.4(@types/node@22.18.6)(jiti@2.6.0)(tsx@4.20.6): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.7(@types/node@22.18.6)(jiti@2.6.0) + vite: 7.1.7(@types/node@22.18.6)(jiti@2.6.0)(tsx@4.20.6) transitivePeerDependencies: - '@types/node' - jiti @@ -7889,13 +7948,13 @@ snapshots: - tsx - yaml - vite-node@3.2.4(@types/node@24.5.2)(jiti@2.6.0): + vite-node@3.2.4(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) transitivePeerDependencies: - '@types/node' - jiti @@ -7910,12 +7969,12 @@ snapshots: - tsx - yaml - vite-plugin-devtools-json@1.0.0(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)): + vite-plugin-devtools-json@1.0.0(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)): dependencies: uuid: 11.1.0 - vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) - vite@7.1.7(@types/node@22.18.6)(jiti@2.6.0): + vite@7.1.7(@types/node@22.18.6)(jiti@2.6.0)(tsx@4.20.6): dependencies: esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) @@ -7927,8 +7986,9 @@ snapshots: '@types/node': 22.18.6 fsevents: 2.3.3 jiti: 2.6.0 + tsx: 4.20.6 - vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0): + vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6): dependencies: esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) @@ -7940,16 +8000,17 @@ snapshots: '@types/node': 24.5.2 fsevents: 2.3.3 jiti: 2.6.0 + tsx: 4.20.6 - vitefu@1.1.1(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)): + vitefu@1.1.1(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)): optionalDependencies: - vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) - vitest@3.2.4(@types/node@22.18.6)(jiti@2.6.0): + vitest@3.2.4(@types/node@22.18.6)(jiti@2.6.0)(tsx@4.20.6): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + '@vitest/mocker': 3.2.4(vite@7.1.7(@types/node@22.18.6)(jiti@2.6.0)(tsx@4.20.6)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -7967,8 +8028,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.7(@types/node@22.18.6)(jiti@2.6.0) - vite-node: 3.2.4(@types/node@22.18.6)(jiti@2.6.0) + vite: 7.1.7(@types/node@22.18.6)(jiti@2.6.0)(tsx@4.20.6) + vite-node: 3.2.4(@types/node@22.18.6)(jiti@2.6.0)(tsx@4.20.6) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.18.6 @@ -7986,11 +8047,11 @@ snapshots: - tsx - yaml - vitest@3.2.4(@types/node@24.5.2)(jiti@2.6.0): + vitest@3.2.4(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)) + '@vitest/mocker': 3.2.4(vite@7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -8008,8 +8069,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0) - vite-node: 3.2.4(@types/node@24.5.2)(jiti@2.6.0) + vite: 7.1.7(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) + vite-node: 3.2.4(@types/node@24.5.2)(jiti@2.6.0)(tsx@4.20.6) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.5.2