diff --git a/.husky/pre-commit b/.husky/pre-commit index a0e3a53df53..1617d49b070 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,3 +1,4 @@ +#!/usr/bin/env sh branch="$(git rev-parse --abbrev-ref HEAD)" if [ "$branch" = "main" ]; then @@ -5,23 +6,7 @@ if [ "$branch" = "main" ]; then exit 1 fi -# Detect if running on Windows and use pnpm.cmd, otherwise use pnpm. -if [ "$OS" = "Windows_NT" ]; then - pnpm_cmd="pnpm.cmd" -else - if command -v pnpm >/dev/null 2>&1; then - pnpm_cmd="pnpm" - else - pnpm_cmd="npx pnpm" - fi -fi - -# Detect if running on Windows and use npx.cmd, otherwise use npx. -if [ "$OS" = "Windows_NT" ]; then - npx_cmd="npx.cmd" -else - npx_cmd="npx" -fi - -$npx_cmd lint-staged -$pnpm_cmd lint +# Use npx to run lint-staged and pnpm for lint +# Git Bash on Windows automatically resolves pnpm to pnpm.cmd +npx lint-staged +pnpm lint diff --git a/.husky/pre-push b/.husky/pre-push index 4cf91d95800..6dea9deeafd 100644 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1,3 +1,4 @@ +#!/usr/bin/env sh branch="$(git rev-parse --abbrev-ref HEAD)" if [ "$branch" = "main" ]; then @@ -5,29 +6,19 @@ if [ "$branch" = "main" ]; then exit 1 fi -# Detect if running on Windows and use pnpm.cmd, otherwise use pnpm. -if [ "$OS" = "Windows_NT" ]; then - pnpm_cmd="pnpm.cmd" -else - if command -v pnpm >/dev/null 2>&1; then - pnpm_cmd="pnpm" - else - pnpm_cmd="npx pnpm" - fi -fi - -$pnpm_cmd run check-types +# Git Bash on Windows automatically resolves pnpm to pnpm.cmd +pnpm run check-types # Use dotenvx to securely load .env.local and run commands that depend on it if [ -f ".env.local" ]; then # Check if RUN_TESTS_ON_PUSH is set to true and run tests with dotenvx if npx dotenvx get RUN_TESTS_ON_PUSH -f .env.local 2>/dev/null | grep -q "^true$"; then - npx dotenvx run -f .env.local -- $pnpm_cmd run test + npx dotenvx run -f .env.local -- pnpm run test fi else # Fallback: run tests if RUN_TESTS_ON_PUSH is set in regular environment if [ "$RUN_TESTS_ON_PUSH" = "true" ]; then - $pnpm_cmd run test + pnpm run test fi fi diff --git a/apps/cli/turbo.json b/apps/cli/turbo.json new file mode 100644 index 00000000000..943e0d4b9e3 --- /dev/null +++ b/apps/cli/turbo.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "build": { + "dependsOn": ["@roo-code/types#build", "@roo-code/core#build", "@roo-code/vscode-shim#build"] + } + } +} diff --git a/apps/web-evals/next-env.d.ts b/apps/web-evals/next-env.d.ts index 7506fe6afbc..7a70f65a1ee 100644 --- a/apps/web-evals/next-env.d.ts +++ b/apps/web-evals/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts" +import "./.next/types/routes.d.ts" // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/web-evals/next.config.ts b/apps/web-evals/next.config.ts index b5f54a87be8..09ac4f0deec 100644 --- a/apps/web-evals/next.config.ts +++ b/apps/web-evals/next.config.ts @@ -1,7 +1,11 @@ +import path from "path" import type { NextConfig } from "next" const nextConfig: NextConfig = { - turbopack: {}, + turbopack: { + root: path.join(__dirname, "../.."), + }, + transpilePackages: ["@roo-code/types"], } export default nextConfig diff --git a/apps/web-evals/package.json b/apps/web-evals/package.json index 83d69edd592..3fb8d83ab5a 100644 --- a/apps/web-evals/package.json +++ b/apps/web-evals/package.json @@ -54,6 +54,7 @@ "@roo-code/config-typescript": "workspace:^", "@tailwindcss/postcss": "^4", "@types/archiver": "^7.0.0", + "@types/node": "^25.5.2", "@types/ps-tree": "^1.1.6", "@types/react": "^18.3.23", "@types/react-dom": "^18.3.5", diff --git a/package.json b/package.json index de8dff751cb..f22ada9e212 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "roo-code", - "packageManager": "pnpm@10.8.1", + "packageManager": "pnpm@10.33.0", "engines": { "node": "20.19.2" }, diff --git a/packages/core/package.json b/packages/core/package.json index 25e6224e8ca..9d7d8c55f2f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -16,7 +16,7 @@ }, "dependencies": { "@roo-code/types": "workspace:^", - "esbuild": "^0.25.0", + "esbuild-wasm": "^0.25.12", "execa": "^9.5.2", "ignore": "^7.0.3", "openai": "^5.12.2", diff --git a/packages/types/package.json b/packages/types/package.json index d66d87ac72d..905a207f031 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -5,8 +5,8 @@ "main": "./dist/index.cjs", "exports": { ".": { - "types": "./src/index.ts", - "import": "./src/index.ts", + "types": "./dist/index.d.ts", + "import": "./dist/index.js", "require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" diff --git a/packages/types/src/mcp.ts b/packages/types/src/mcp.ts index f1bfde325de..e673e91e469 100644 --- a/packages/types/src/mcp.ts +++ b/packages/types/src/mcp.ts @@ -99,22 +99,35 @@ export type McpResourceResponse = { }> } +// Annotations for content items in tool call responses +export type McpContentAnnotations = { + audience?: Array<"user" | "assistant"> + priority?: number + lastModified?: string +} + export type McpToolCallResponse = { _meta?: Record // eslint-disable-line @typescript-eslint/no-explicit-any content: Array< | { type: "text" text: string + annotations?: McpContentAnnotations + _meta?: Record // eslint-disable-line @typescript-eslint/no-explicit-any } | { type: "image" data: string mimeType: string + annotations?: McpContentAnnotations + _meta?: Record // eslint-disable-line @typescript-eslint/no-explicit-any } | { type: "audio" data: string mimeType: string + annotations?: McpContentAnnotations + _meta?: Record // eslint-disable-line @typescript-eslint/no-explicit-any } | { type: "resource" @@ -124,6 +137,25 @@ export type McpToolCallResponse = { text?: string blob?: string } + annotations?: McpContentAnnotations + _meta?: Record // eslint-disable-line @typescript-eslint/no-explicit-any + } + | { + type: "resource_link" + uri: string + name: string + description?: string + mimeType?: string + size?: number + annotations?: McpContentAnnotations + _meta?: Record // eslint-disable-line @typescript-eslint/no-explicit-any + icons?: Array<{ + src: string + mimeType?: string + sizes?: string[] + theme?: "light" | "dark" + }> + title?: string } > isError?: boolean diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 859792d7c36..5d138138340 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -15,6 +15,7 @@ import { openAiNativeModels, qwenCodeModels, sambaNovaModels, + nvidiaModels, vertexModels, vscodeLlmModels, xaiModels, @@ -117,6 +118,7 @@ export const providerNames = [ "qwen-code", "roo", "sambanova", + "nvidia", "vertex", "xai", "zai", @@ -350,6 +352,11 @@ const sambaNovaSchema = apiModelIdProviderModelSchema.extend({ sambaNovaApiKey: z.string().optional(), }) +const nvidiaSchema = apiModelIdProviderModelSchema.extend({ + nvidiaApiKey: z.string().optional(), + nvidiaBaseUrl: z.string().optional(), +}) + export const zaiApiLineSchema = z.enum(["international_coding", "china_coding", "international_api", "china_api"]) export type ZaiApiLine = z.infer @@ -409,6 +416,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv basetenSchema.merge(z.object({ apiProvider: z.literal("baseten") })), litellmSchema.merge(z.object({ apiProvider: z.literal("litellm") })), sambaNovaSchema.merge(z.object({ apiProvider: z.literal("sambanova") })), + nvidiaSchema.merge(z.object({ apiProvider: z.literal("nvidia") })), zaiSchema.merge(z.object({ apiProvider: z.literal("zai") })), fireworksSchema.merge(z.object({ apiProvider: z.literal("fireworks") })), qwenCodeSchema.merge(z.object({ apiProvider: z.literal("qwen-code") })), @@ -442,6 +450,7 @@ export const providerSettingsSchema = z.object({ ...basetenSchema.shape, ...litellmSchema.shape, ...sambaNovaSchema.shape, + ...nvidiaSchema.shape, ...zaiSchema.shape, ...fireworksSchema.shape, ...qwenCodeSchema.shape, @@ -517,6 +526,7 @@ export const modelIdKeysByProvider: Record = { baseten: "apiModelId", litellm: "litellmModelId", sambanova: "apiModelId", + nvidia: "apiModelId", zai: "apiModelId", fireworks: "apiModelId", roo: "apiModelId", @@ -617,6 +627,11 @@ export const MODELS_BY_PROVIDER: Record< label: "SambaNova", models: Object.keys(sambaNovaModels), }, + nvidia: { + id: "nvidia", + label: "NVIDIA NIM", + models: Object.keys(nvidiaModels), + }, vertex: { id: "vertex", label: "GCP Vertex AI", diff --git a/packages/types/src/providers/index.ts b/packages/types/src/providers/index.ts index 6bb959c7056..52866802285 100644 --- a/packages/types/src/providers/index.ts +++ b/packages/types/src/providers/index.ts @@ -17,6 +17,7 @@ export * from "./qwen-code.js" export * from "./requesty.js" export * from "./roo.js" export * from "./sambanova.js" +export * from "./nvidia.js" export * from "./unbound.js" export * from "./vertex.js" export * from "./vscode-llm.js" @@ -40,6 +41,7 @@ import { qwenCodeDefaultModelId } from "./qwen-code.js" import { requestyDefaultModelId } from "./requesty.js" import { rooDefaultModelId } from "./roo.js" import { sambaNovaDefaultModelId } from "./sambanova.js" +import { nvidiaDefaultModelId } from "./nvidia.js" import { unboundDefaultModelId } from "./unbound.js" import { vertexDefaultModelId } from "./vertex.js" import { vscodeLlmDefaultModelId } from "./vscode-llm.js" @@ -101,6 +103,8 @@ export function getProviderDefaultModelId( return vscodeLlmDefaultModelId case "sambanova": return sambaNovaDefaultModelId + case "nvidia": + return nvidiaDefaultModelId case "fireworks": return fireworksDefaultModelId case "roo": diff --git a/packages/types/src/providers/nvidia.ts b/packages/types/src/providers/nvidia.ts new file mode 100644 index 00000000000..b97a7fea71c --- /dev/null +++ b/packages/types/src/providers/nvidia.ts @@ -0,0 +1,93 @@ +import type { ModelInfo } from "../model.js" + +// NVIDIA NIM API model IDs +// Reference: https://build.nvidia.com/explore/discover/models +export type NvidiaModelId = + | "deepseek-ai/deepseek-r1" + | "google/gemma-4-31b-it" + | "meta/llama-3.1-405b-instruct" + | "meta/llama-3.3-70b-instruct" + | "z-ai/glm5" + | "qwen/qwen3.5-397b-a17b" + | "qwen/qwen3.5-122b-a10b" + +export const nvidiaDefaultModelId: NvidiaModelId = "deepseek-ai/deepseek-r1" + +export const nvidiaModels = { + // DeepSeek R1 - reasoning model with enable_thinking support + "deepseek-ai/deepseek-r1": { + maxTokens: 16384, + contextWindow: 128000, + supportsImages: false, + supportsPromptCache: false, + // Critical: This flag enables the reasoning toggle in UI + supportsReasoningBinary: true, + inputPrice: 0.0, // NVIDIA NIM pricing varies by deployment + outputPrice: 0.0, + description: + "DeepSeek R1 reasoning model via NVIDIA NIM API. Supports chain-of-thought reasoning with enable_thinking parameter.", + }, + // Google Gemma 4 - reasoning model with enable_thinking support + "google/gemma-4-31b-it": { + maxTokens: 16384, + contextWindow: 128000, + supportsImages: false, + supportsPromptCache: false, + supportsReasoningBinary: true, + inputPrice: 0.0, + outputPrice: 0.0, + description: + "Google Gemma 4 31B reasoning model via NVIDIA NIM API. Supports chain-of-thought reasoning with enable_thinking parameter.", + }, + // Llama models - no reasoning support, included for completeness + "meta/llama-3.1-405b-instruct": { + maxTokens: 8192, + contextWindow: 128000, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0.0, + outputPrice: 0.0, + description: "Meta Llama 3.1 405B Instruct model via NVIDIA NIM API.", + }, + "meta/llama-3.3-70b-instruct": { + maxTokens: 8192, + contextWindow: 128000, + supportsImages: true, + supportsPromptCache: false, + inputPrice: 0.0, + outputPrice: 0.0, + description: "Meta Llama 3.3 70B Instruct model via NVIDIA NIM API.", + }, + // GLM5 - Z.AI reasoning model with enable_thinking support + "z-ai/glm5": { + maxTokens: 32768, + contextWindow: 204800, + supportsImages: false, + supportsPromptCache: false, + supportsReasoningBinary: true, + inputPrice: 1.0, + outputPrice: 3.2, + description: "Z.AI GLM5 reasoning model via NVIDIA NIM API. Supports chain-of-thought reasoning.", + }, + // Qwen 3.5 models - reasoning models with enable_thinking support + "qwen/qwen3.5-397b-a17b": { + maxTokens: 32768, + contextWindow: 262144, + supportsImages: false, + supportsPromptCache: false, + supportsReasoningBinary: true, + inputPrice: 0.0, + outputPrice: 0.0, + description: "Qwen 3.5 397B reasoning model via NVIDIA NIM API. Supports chain-of-thought reasoning.", + }, + "qwen/qwen3.5-122b-a10b": { + maxTokens: 32768, + contextWindow: 262144, + supportsImages: false, + supportsPromptCache: false, + supportsReasoningBinary: true, + inputPrice: 0.0, + outputPrice: 0.0, + description: "Qwen 3.5 122B reasoning model via NVIDIA NIM API. Supports chain-of-thought reasoning.", + }, +} as const satisfies Record diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d95c2f02346..6979c31eca1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -319,6 +319,9 @@ importers: '@types/archiver': specifier: ^7.0.0 version: 7.0.0 + '@types/node': + specifier: ^25.5.2 + version: 25.5.2 '@types/ps-tree': specifier: ^1.1.6 version: 1.1.6 @@ -333,7 +336,7 @@ importers: version: 4.1.6 vitest: specifier: ^3.2.3 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.2.1)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@25.5.2)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) apps/web-roo-code: dependencies: @@ -558,9 +561,9 @@ importers: '@roo-code/types': specifier: workspace:^ version: link:../types - esbuild: - specifier: '>=0.25.0' - version: 0.25.9 + esbuild-wasm: + specifier: ^0.25.12 + version: 0.25.12 execa: specifier: ^9.5.2 version: 9.6.0 @@ -787,7 +790,7 @@ importers: version: 3.922.0 '@google/genai': specifier: ^1.29.1 - version: 1.29.1(@modelcontextprotocol/sdk@1.12.0) + version: 1.29.1(@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)) '@lmstudio/sdk': specifier: ^1.1.1 version: 1.2.0 @@ -795,8 +798,8 @@ importers: specifier: ^1.9.18 version: 1.9.18(zod@3.25.76) '@modelcontextprotocol/sdk': - specifier: 1.12.0 - version: 1.12.0 + specifier: ^1.29.0 + version: 1.29.0(zod@3.25.76) '@qdrant/js-client-rest': specifier: ^1.14.0 version: 1.14.0(typescript@5.8.3) @@ -1863,24 +1866,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@basetenlabs/performance-client-linux-riscv64-gnu@0.0.10': resolution: {integrity: sha512-2KUvdK4wuoZdIqNnJhx7cu6ybXCwtiwGAtlrEvhai3FOkUQ3wE2Xa+TQ33mNGSyFbw6wAvLawYtKVFmmw27gJw==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] + libc: [glibc] '@basetenlabs/performance-client-linux-x64-gnu@0.0.10': resolution: {integrity: sha512-9jjQPjHLiVOGwUPlmhnBl7OmmO7hQ8WMt+v3mJuxkS5JTNDmVOngfmgGlbN9NjBhQMENjdcMUVOquVo7HeybGQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@basetenlabs/performance-client-linux-x64-musl@0.0.10': resolution: {integrity: sha512-bjYB8FKcPvEa251Ep2Gm3tvywADL9eavVjZsikdf0AvJ1K5pT+vLLvJBU9ihBsTPWnbF4pJgxVjwS6UjVObsQA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@basetenlabs/performance-client-win32-arm64-msvc@0.0.10': resolution: {integrity: sha512-Vxq5UXEmfh3C3hpwXdp3Daaf0dnLR9zFH2x8MJ1Hf/TcilmOP1clneewNpIv0e7MrnT56Z4pM6P3d8VFMZqBKg==} @@ -2281,6 +2288,12 @@ packages: '@modelcontextprotocol/sdk': optional: true + '@hono/node-server@1.19.13': + resolution: {integrity: sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + '@hookform/resolvers@5.1.1': resolution: {integrity: sha512-J/NVING3LMAEvexJkyTLjruSm7aOFx7QX21pzkiJfMoNG0wl5aFEjLTl7ay7IQb9EWY6AkrBy7tHL2Alijpdcg==} peerDependencies: @@ -2342,89 +2355,105 @@ packages: resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.2.4': resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.2.4': resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-ppc64@0.34.5': resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-linux-riscv64@0.34.5': resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.34.5': resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} @@ -2628,9 +2657,15 @@ packages: '@mixmark-io/domino@2.2.0': resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} - '@modelcontextprotocol/sdk@1.12.0': - resolution: {integrity: sha512-m//7RlINx1F3sz3KqwY1WWzVgTcYX52HYk4bJ1hkBXV3zccAEth+jRvG8DBRrdaQuRsPAJOx2MH3zaHNCKL7Zg==} + '@modelcontextprotocol/sdk@1.29.0': + resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: 3.25.76 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true '@mswjs/interceptors@0.39.6': resolution: {integrity: sha512-bndDP83naYYkfayr/qhBHMhk0YGwS1iv6vaEGcr0SQbO0IZtbOPqjKjds/WcG+bJA+1T5vCx6kprKOzn5Bg+Vw==} @@ -2671,24 +2706,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@next/swc-linux-arm64-musl@16.1.6': resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@next/swc-linux-x64-gnu@16.1.6': resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@next/swc-linux-x64-musl@16.1.6': resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@next/swc-win32-arm64-msvc@16.1.6': resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==} @@ -2755,24 +2794,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@node-rs/crc32-linux-arm64-musl@1.10.6': resolution: {integrity: sha512-k8ra/bmg0hwRrIEE8JL1p32WfaN9gDlUUpQRWsbxd1WhjqvXea7kKO6K4DwVxyxlPhBS9Gkb5Urq7Y4mXANzaw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@node-rs/crc32-linux-x64-gnu@1.10.6': resolution: {integrity: sha512-IfjtqcuFK7JrSZ9mlAFhb83xgium30PguvRjIMI45C3FJwu18bnLk1oR619IYb/zetQT82MObgmqfKOtgemEKw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@node-rs/crc32-linux-x64-musl@1.10.6': resolution: {integrity: sha512-LbFYsA5M9pNunOweSt6uhxenYQF94v3bHDAQRPTQ3rnjn+mK6IC7YTAYoBjvoJP8lVzcvk9hRj8wp4Jyh6Y80g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@node-rs/crc32-wasm32-wasi@1.10.6': resolution: {integrity: sha512-KaejdLgHMPsRaxnM+OG9L9XdWL2TabNx80HLdsCOoX9BVhEkfh39OeahBo8lBmidylKbLGMQoGfIKDjq0YMStw==} @@ -2925,31 +2968,37 @@ packages: resolution: {integrity: sha512-BhEzNLjn4HjP8+Q18D3/jeIDBxW7OgoJYIjw2CaaysnYneoTlij8hPTKxHfyqq4IGM3fFs9TLR/k338M3zkQ7g==} cpu: [arm64] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-arm64-musl@11.2.0': resolution: {integrity: sha512-yxbMYUgRmN2V8x8XoxmD/Qq6aG7YIW3ToMDILfmcfeeRRVieEJ3DOWBT0JSE+YgrOy79OyFDH/1lO8VnqLmDQQ==} cpu: [arm64] os: [linux] + libc: [musl] '@oxc-resolver/binding-linux-riscv64-gnu@11.2.0': resolution: {integrity: sha512-QG1UfgC2N2qhW1tOnDCgB/26vn1RCshR5sYPhMeaxO1gMQ3kEKbZ3QyBXxrG1IX5qsXYj5hPDJLDYNYUjRcOpg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-s390x-gnu@11.2.0': resolution: {integrity: sha512-uqTDsQdi6mrkSV1gvwbuT8jf/WFl6qVDVjNlx7IPSaAByrNiJfPrhTmH8b+Do58Dylz7QIRZgxQ8CHIZSyBUdg==} cpu: [s390x] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-x64-gnu@11.2.0': resolution: {integrity: sha512-GZdHXhJ7p6GaQg9MjRqLebwBf8BLvGIagccI6z5yMj4fV3LU4QuDfwSEERG+R6oQ/Su9672MBqWwncvKcKT68w==} cpu: [x64] os: [linux] + libc: [glibc] '@oxc-resolver/binding-linux-x64-musl@11.2.0': resolution: {integrity: sha512-YBAC3GOicYznReG2twE7oFPSeK9Z1f507z1EYWKg6HpGYRYRlJyszViu7PrhMT85r/MumDTs429zm+CNqpFWOA==} cpu: [x64] os: [linux] + libc: [musl] '@oxc-resolver/binding-wasm32-wasi@11.2.0': resolution: {integrity: sha512-+qlIg45CPVPy+Jn3vqU1zkxA/AAv6e/2Ax/ImX8usZa8Tr2JmQn/93bmSOOOnr9fXRV9d0n4JyqYzSWxWPYDEw==} @@ -3784,56 +3833,67 @@ packages: resolution: {integrity: sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.40.2': resolution: {integrity: sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.40.2': resolution: {integrity: sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.40.2': resolution: {integrity: sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loongarch64-gnu@4.40.2': resolution: {integrity: sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-powerpc64le-gnu@4.40.2': resolution: {integrity: sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.40.2': resolution: {integrity: sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.40.2': resolution: {integrity: sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.40.2': resolution: {integrity: sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.40.2': resolution: {integrity: sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.40.2': resolution: {integrity: sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.40.2': resolution: {integrity: sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==} @@ -4164,48 +4224,56 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-gnu@4.1.8': resolution: {integrity: sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.1.6': resolution: {integrity: sha512-8kjivE5xW0qAQ9HX9reVFmZj3t+VmljDLVRJpVBEoTR+3bKMnvC7iLcoSGNIUJGOZy1mLVq7x/gerVg0T+IsYw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-arm64-musl@4.1.8': resolution: {integrity: sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.1.6': resolution: {integrity: sha512-A4spQhwnWVpjWDLXnOW9PSinO2PTKJQNRmL/aIl2U/O+RARls8doDfs6R41+DAXK0ccacvRyDpR46aVQJJCoCg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-gnu@4.1.8': resolution: {integrity: sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.1.6': resolution: {integrity: sha512-YRee+6ZqdzgiQAHVSLfl3RYmqeeaWVCk796MhXhLQu2kJu2COHBkqlqsqKYx3p8Hmk5pGCQd2jTAoMWWFeyG2A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-musl@4.1.8': resolution: {integrity: sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.1.6': resolution: {integrity: sha512-qAp4ooTYrBQ5pk5jgg54/U1rCJ/9FLYOkkQ/nTE+bVMseMfB6O7J8zb19YTpWuu4UdfRf5zzOrNKfl6T64MNrQ==} @@ -4559,6 +4627,9 @@ packages: '@types/node@24.2.1': resolution: {integrity: sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==} + '@types/node@25.5.2': + resolution: {integrity: sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==} + '@types/prop-types@15.7.14': resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} @@ -4892,9 +4963,20 @@ packages: peerDependencies: zod: 3.25.76 + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -5161,8 +5243,8 @@ packages: bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} boolbase@1.0.0: @@ -6518,14 +6600,14 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - express-rate-limit@7.5.0: - resolution: {integrity: sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==} + express-rate-limit@8.3.2: + resolution: {integrity: sha512-77VmFeJkO0/rvimEDuUC5H30oqUC4EyOhyGccfqoLebB0oiEYfM7nwPrsDsBL1gsTpwfzX8SFy2MT3TDyRq+bg==} engines: {node: '>= 16'} peerDependencies: - express: ^4.11 || 5 || ^5.0.0-beta.1 + express: '>= 4.11' - express@5.1.0: - resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} exsolve@1.0.7: @@ -6577,6 +6659,9 @@ packages: fast-shallow-equal@1.0.0: resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fast-xml-parser@5.2.3: resolution: {integrity: sha512-OdCYfRqfpuLUFonTNjvd30rCBZUneHpSQkCqfaeWQ9qrKcl6XlWeDBNVwGb+INAIxRshuN2jF+BE0L6gbBO2mw==} hasBin: true @@ -7057,6 +7142,10 @@ packages: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} + hono@4.12.12: + resolution: {integrity: sha512-p1JfQMKaceuCbpJKAPKVqyqviZdS0eUxH9v82oWo1kb9xjQ5wA6iP3FNVAPDFlz5/p7d45lO+BpSk1tuSZMF4Q==} + engines: {node: '>=16.9.0'} + hosted-git-info@4.1.0: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} engines: {node: '>=10'} @@ -7087,6 +7176,10 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -7231,6 +7324,10 @@ packages: resolution: {integrity: sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==} engines: {node: '>=12.22.0'} + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + ip-address@9.0.5: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} @@ -7543,6 +7640,9 @@ packages: resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} hasBin: true + jose@6.2.2: + resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -7605,6 +7705,12 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + json-schema@0.4.0: resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} @@ -7773,48 +7879,56 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-gnu@1.30.1: resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.29.2: resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-arm64-musl@1.30.1: resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.29.2: resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-gnu@1.30.1: resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.29.2: resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-linux-x64-musl@1.30.1: resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.29.2: resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==} @@ -9087,6 +9201,10 @@ packages: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} + qs@6.15.0: + resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} + engines: {node: '>=0.6'} + quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} @@ -9107,6 +9225,10 @@ packages: resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} engines: {node: '>= 0.8'} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -9386,6 +9508,10 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + resize-observer-polyfill@1.5.1: resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} @@ -9784,6 +9910,10 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} @@ -10352,6 +10482,9 @@ packages: undici-types@7.10.0: resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + undici@6.21.3: resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} engines: {node: '>=18.17'} @@ -11002,6 +11135,11 @@ packages: peerDependencies: zod: 3.25.76 + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: 3.25.76 + zod-to-ts@1.2.0: resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==} peerDependencies: @@ -11869,7 +12007,7 @@ snapshots: '@babel/parser': 7.27.2 '@babel/template': 7.27.2 '@babel/types': 7.27.1 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -12347,17 +12485,21 @@ snapshots: '@floating-ui/utils@0.2.9': {} - '@google/genai@1.29.1(@modelcontextprotocol/sdk@1.12.0)': + '@google/genai@1.29.1(@modelcontextprotocol/sdk@1.29.0(zod@3.25.76))': dependencies: google-auth-library: 10.5.0 ws: 8.18.3 optionalDependencies: - '@modelcontextprotocol/sdk': 1.12.0 + '@modelcontextprotocol/sdk': 1.29.0(zod@3.25.76) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate + '@hono/node-server@1.19.13(hono@4.12.12)': + dependencies: + hono: 4.12.12 + '@hookform/resolvers@5.1.1(react-hook-form@7.57.0(react@18.3.1))': dependencies: '@standard-schema/utils': 0.3.0 @@ -12705,19 +12847,25 @@ snapshots: '@mixmark-io/domino@2.2.0': {} - '@modelcontextprotocol/sdk@1.12.0': + '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)': dependencies: - ajv: 6.12.6 + '@hono/node-server': 1.19.13(hono@4.12.12) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) content-type: 1.0.5 cors: 2.8.5 cross-spawn: 7.0.6 eventsource: 3.0.7 - express: 5.1.0 - express-rate-limit: 7.5.0(express@5.1.0) + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 8.3.2(express@5.2.1) + hono: 4.12.12 + jose: 6.2.2 + json-schema-typed: 8.0.2 pkce-challenge: 5.0.0 raw-body: 3.0.0 zod: 3.25.76 - zod-to-json-schema: 3.24.5(zod@3.25.76) + zod-to-json-schema: 3.25.2(zod@3.25.76) transitivePeerDependencies: - supports-color @@ -14695,6 +14843,10 @@ snapshots: dependencies: undici-types: 7.10.0 + '@types/node@25.5.2': + dependencies: + undici-types: 7.18.2 + '@types/prop-types@15.7.14': {} '@types/proper-lockfile@4.1.4': @@ -14760,7 +14912,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 24.2.1 + '@types/node': 25.5.2 optional: true '@types/yargs-parser@21.0.3': {} @@ -14812,7 +14964,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 8.32.1(typescript@5.8.3) '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.3) - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 eslint: 9.27.0(jiti@2.4.2) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 @@ -14825,7 +14977,7 @@ snapshots: dependencies: '@typescript-eslint/types': 8.32.1 '@typescript-eslint/visitor-keys': 8.32.1 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -14920,6 +15072,14 @@ snapshots: optionalDependencies: vite: 6.3.5(@types/node@24.2.1)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@25.5.2)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 6.3.5(@types/node@25.5.2)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + '@vitest/mocker@4.0.18(vite@6.3.6(@types/node@20.17.57)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0))': dependencies: '@vitest/spy': 4.0.18 @@ -15137,6 +15297,10 @@ snapshots: '@opentelemetry/api': 1.9.0 zod: 3.25.76 + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -15144,6 +15308,13 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-colors@4.1.3: {} ansi-escapes@7.0.0: @@ -15445,16 +15616,16 @@ snapshots: bluebird@3.7.2: {} - body-parser@2.2.0: + body-parser@2.2.2: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 http-errors: 2.0.0 - iconv-lite: 0.6.3 + iconv-lite: 0.7.0 on-finished: 2.4.1 - qs: 6.14.0 - raw-body: 3.0.0 + qs: 6.15.0 + raw-body: 3.0.2 type-is: 2.0.1 transitivePeerDependencies: - supports-color @@ -16897,19 +17068,21 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - express-rate-limit@7.5.0(express@5.1.0): + express-rate-limit@8.3.2(express@5.2.1): dependencies: - express: 5.1.0 + express: 5.2.1 + ip-address: 10.1.0 - express@5.1.0: + express@5.2.1: dependencies: accepts: 2.0.0 - body-parser: 2.2.0 + body-parser: 2.2.2 content-disposition: 1.0.0 content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 + depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -16945,7 +17118,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -16986,6 +17159,8 @@ snapshots: fast-shallow-equal@1.0.0: {} + fast-uri@3.1.0: {} + fast-xml-parser@5.2.3: dependencies: strnum: 2.1.1 @@ -17050,7 +17225,7 @@ snapshots: finalhandler@2.1.0: dependencies: - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 @@ -17298,7 +17473,7 @@ snapshots: dependencies: basic-ftp: 5.0.5 data-uri-to-buffer: 6.0.2 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -17577,6 +17752,8 @@ snapshots: highlight.js@11.11.1: {} + hono@4.12.12: {} + hosted-git-info@4.1.0: dependencies: lru-cache: 6.0.0 @@ -17612,6 +17789,14 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.3 @@ -17760,6 +17945,8 @@ snapshots: transitivePeerDependencies: - supports-color + ip-address@10.1.0: {} + ip-address@9.0.5: dependencies: jsbn: 1.1.0 @@ -18048,6 +18235,8 @@ snapshots: jiti@2.4.2: {} + jose@6.2.2: {} + joycon@3.1.1: {} js-base64@3.7.8: @@ -18115,6 +18304,10 @@ snapshots: json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + json-schema@0.4.0: {} json-stable-stringify-without-jsonify@1.0.1: {} @@ -18996,7 +19189,7 @@ snapshots: micromark@2.11.4: dependencies: - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 parse-entities: 2.0.0 transitivePeerDependencies: - supports-color @@ -19503,7 +19696,7 @@ snapshots: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.3 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 get-uri: 6.0.4 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 @@ -19855,7 +20048,7 @@ snapshots: proxy-agent@6.5.0: dependencies: agent-base: 7.1.3 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 lru-cache: 7.18.3 @@ -19924,6 +20117,10 @@ snapshots: dependencies: side-channel: 1.1.0 + qs@6.15.0: + dependencies: + side-channel: 1.1.0 + quansync@0.2.11: {} query-selector-shadow-dom@1.0.1: {} @@ -19943,6 +20140,13 @@ snapshots: iconv-lite: 0.6.3 unpipe: 1.0.0 + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.0 + unpipe: 1.0.0 + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -20328,6 +20532,8 @@ snapshots: require-directory@2.1.1: {} + require-from-string@2.0.2: {} + resize-observer-polyfill@1.5.1: {} resolve-from@4.0.0: {} @@ -20423,7 +20629,7 @@ snapshots: router@2.2.0: dependencies: - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 @@ -20540,7 +20746,7 @@ snapshots: send@1.2.0: dependencies: - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -20741,7 +20947,7 @@ snapshots: socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.3 - debug: 4.4.1(supports-color@8.1.1) + debug: 4.4.3 socks: 2.8.4 transitivePeerDependencies: - supports-color @@ -20819,6 +21025,8 @@ snapshots: statuses@2.0.1: {} + statuses@2.0.2: {} + std-env@3.10.0: {} std-env@3.9.0: {} @@ -21415,6 +21623,8 @@ snapshots: undici-types@7.10.0: {} + undici-types@7.18.2: {} + undici@6.21.3: {} unicode-trie@2.0.0: @@ -21720,6 +21930,27 @@ snapshots: - tsx - yaml + vite-node@3.2.4(@types/node@25.5.2)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): + dependencies: + cac: 6.7.14 + debug: 4.4.1(supports-color@8.1.1) + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 6.3.6(@types/node@25.5.2)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vite@6.3.5(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): dependencies: esbuild: 0.25.9 @@ -21768,6 +21999,22 @@ snapshots: tsx: 4.19.4 yaml: 2.8.0 + vite@6.3.5(@types/node@25.5.2)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): + dependencies: + esbuild: 0.25.9 + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.6 + rollup: 4.40.2 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 25.5.2 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + tsx: 4.19.4 + yaml: 2.8.0 + vite@6.3.6(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): dependencies: esbuild: 0.25.9 @@ -21816,6 +22063,22 @@ snapshots: tsx: 4.19.4 yaml: 2.8.0 + vite@6.3.6(@types/node@25.5.2)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): + dependencies: + esbuild: 0.25.9 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.4 + rollup: 4.40.2 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 25.5.2 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + tsx: 4.19.4 + yaml: 2.8.0 + vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.17.50)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 @@ -21948,6 +22211,50 @@ snapshots: - tsx - yaml + vitest@3.2.4(@types/debug@4.1.12)(@types/node@25.5.2)(@vitest/ui@3.2.4)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): + dependencies: + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@25.5.2)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + debug: 4.4.1(supports-color@8.1.1) + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 2.0.3 + picomatch: 4.0.2 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.14 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 6.3.5(@types/node@25.5.2)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + vite-node: 3.2.4(@types/node@25.5.2)(jiti@2.4.2)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/debug': 4.1.12 + '@types/node': 25.5.2 + '@vitest/ui': 3.2.4(vitest@3.2.4) + jsdom: 26.1.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.17.57)(jiti@2.4.2)(jsdom@26.1.0)(lightningcss@1.30.1)(tsx@4.19.4)(yaml@2.8.0): dependencies: '@vitest/expect': 4.0.18 @@ -22267,6 +22574,10 @@ snapshots: dependencies: zod: 3.25.76 + zod-to-json-schema@3.25.2(zod@3.25.76): + dependencies: + zod: 3.25.76 + zod-to-ts@1.2.0(typescript@5.8.3)(zod@3.25.76): dependencies: typescript: 5.8.3 diff --git a/src/api/index.ts b/src/api/index.ts index ebc2682a1a8..ba34c4aeb65 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -27,6 +27,7 @@ import { LiteLLMHandler, QwenCodeHandler, SambaNovaHandler, + NvidiaHandler, ZAiHandler, FireworksHandler, RooHandler, @@ -162,6 +163,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler { return new LiteLLMHandler(options) case "sambanova": return new SambaNovaHandler(options) + case "nvidia": + return new NvidiaHandler(options) case "zai": return new ZAiHandler(options) case "fireworks": diff --git a/src/api/providers/__tests__/nvidia.spec.ts b/src/api/providers/__tests__/nvidia.spec.ts new file mode 100644 index 00000000000..f341cb8d1b7 --- /dev/null +++ b/src/api/providers/__tests__/nvidia.spec.ts @@ -0,0 +1,222 @@ +// npx vitest run src/api/providers/__tests__/nvidia.spec.ts + +import OpenAI from "openai" +import { Anthropic } from "@anthropic-ai/sdk" + +import { type NvidiaModelId, nvidiaDefaultModelId, nvidiaModels } from "@roo-code/types" + +import { NvidiaHandler } from "../nvidia" + +vitest.mock("openai", () => { + const createMock = vitest.fn() + return { + default: vitest.fn(() => ({ chat: { completions: { create: createMock } } })), + } +}) + +describe("NvidiaHandler", () => { + let handler: NvidiaHandler + let mockCreate: any + + beforeEach(() => { + vitest.clearAllMocks() + mockCreate = (OpenAI as unknown as any)().chat.completions.create + handler = new NvidiaHandler({ nvidiaApiKey: "test-nvidia-api-key" }) + }) + + describe("Constructor", () => { + it("should use the correct NVIDIA NIM base URL", () => { + new NvidiaHandler({ nvidiaApiKey: "test-api-key" }) + expect(OpenAI).toHaveBeenCalledWith( + expect.objectContaining({ baseURL: "https://integrate.api.nvidia.com/v1" }), + ) + }) + + it("should use custom base URL when provided", () => { + const customUrl = "https://custom.nvidia.endpoint/v1" + new NvidiaHandler({ nvidiaApiKey: "test-api-key", nvidiaBaseUrl: customUrl }) + expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({ baseURL: customUrl })) + }) + + it("should use the provided API key", () => { + const nvidiaApiKey = "test-nvidia-api-key" + new NvidiaHandler({ nvidiaApiKey }) + expect(OpenAI).toHaveBeenCalledWith(expect.objectContaining({ apiKey: nvidiaApiKey })) + }) + }) + + describe("getModel", () => { + it("should return default model when no model is specified", () => { + const model = handler.getModel() + expect(model.id).toBe(nvidiaDefaultModelId) + expect(model.info).toEqual(nvidiaModels[nvidiaDefaultModelId]) + }) + + it("should return specified model when valid model is provided", () => { + const testModelId: NvidiaModelId = "deepseek-ai/deepseek-r1" + const handlerWithModel = new NvidiaHandler({ + apiModelId: testModelId, + nvidiaApiKey: "test-api-key", + }) + const model = handlerWithModel.getModel() + expect(model.id).toBe(testModelId) + expect(model.info).toEqual(nvidiaModels[testModelId]) + }) + }) + + describe("createMessage with reasoning", () => { + it("should inject chat_template_kwargs when reasoning is enabled for reasoning-capable model", async () => { + const handlerWithReasoning = new NvidiaHandler({ + nvidiaApiKey: "test-api-key", + apiModelId: "deepseek-ai/deepseek-r1", + enableReasoningEffort: true, + }) + + mockCreate.mockImplementationOnce(() => ({ + [Symbol.asyncIterator]: () => ({ + next: vitest.fn().mockResolvedValueOnce({ done: true }), + }), + })) + + const stream = handlerWithReasoning.createMessage("system prompt", []) + await stream.next() + + // Verify chat_template_kwargs was injected + expect(mockCreate).toHaveBeenCalledWith( + expect.objectContaining({ + chat_template_kwargs: { enable_thinking: true, clear_thinking: false }, + }), + undefined, + ) + }) + + it("should NOT inject chat_template_kwargs when reasoning is disabled", async () => { + const handlerWithoutReasoning = new NvidiaHandler({ + nvidiaApiKey: "test-api-key", + apiModelId: "deepseek-ai/deepseek-r1", + enableReasoningEffort: false, + }) + + mockCreate.mockImplementationOnce(() => ({ + [Symbol.asyncIterator]: () => ({ + next: vitest.fn().mockResolvedValueOnce({ done: true }), + }), + })) + + const stream = handlerWithoutReasoning.createMessage("system prompt", []) + await stream.next() + + // Verify chat_template_kwargs was NOT injected + const callArgs = mockCreate.mock.calls[0][0] + expect(callArgs.chat_template_kwargs).toBeUndefined() + }) + + it("should NOT inject chat_template_kwargs for non-reasoning models even if enabled", async () => { + const handlerWithNonReasoning = new NvidiaHandler({ + nvidiaApiKey: "test-api-key", + apiModelId: "meta/llama-3.3-70b-instruct", + enableReasoningEffort: true, // Even if enabled + }) + + mockCreate.mockImplementationOnce(() => ({ + [Symbol.asyncIterator]: () => ({ + next: vitest.fn().mockResolvedValueOnce({ done: true }), + }), + })) + + const stream = handlerWithNonReasoning.createMessage("system prompt", []) + await stream.next() + + // Verify chat_template_kwargs was NOT injected (model doesn't support) + const callArgs = mockCreate.mock.calls[0][0] + expect(callArgs.chat_template_kwargs).toBeUndefined() + }) + }) + + describe("createMessage yields content", () => { + it("should yield text content from stream", async () => { + const testContent = "This is test content from NVIDIA stream" + + mockCreate.mockImplementationOnce(() => ({ + [Symbol.asyncIterator]: () => ({ + next: vitest + .fn() + .mockResolvedValueOnce({ + done: false, + value: { choices: [{ delta: { content: testContent } }] }, + }) + .mockResolvedValueOnce({ done: true }), + }), + })) + + const stream = handler.createMessage("system prompt", []) + const firstChunk = await stream.next() + + expect(firstChunk.done).toBe(false) + expect(firstChunk.value).toEqual({ type: "text", text: testContent }) + }) + + it("should yield reasoning_content from stream", async () => { + const reasoningContent = "Chain of thought reasoning..." + + mockCreate.mockImplementationOnce(() => ({ + [Symbol.asyncIterator]: () => ({ + next: vitest + .fn() + .mockResolvedValueOnce({ + done: false, + value: { choices: [{ delta: { reasoning_content: reasoningContent } }] }, + }) + .mockResolvedValueOnce({ done: true }), + }), + })) + + const stream = handler.createMessage("system prompt", []) + const firstChunk = await stream.next() + + expect(firstChunk.done).toBe(false) + expect(firstChunk.value).toEqual({ type: "reasoning", text: reasoningContent }) + }) + }) + + describe("completePrompt", () => { + it("should return text from NVIDIA API", async () => { + const expectedResponse = "This is a test response from NVIDIA" + mockCreate.mockResolvedValueOnce({ + choices: [{ message: { content: expectedResponse } }], + }) + + const result = await handler.completePrompt("test prompt") + expect(result).toBe(expectedResponse) + }) + + it("should inject chat_template_kwargs for reasoning models when enabled", async () => { + const handlerWithReasoning = new NvidiaHandler({ + nvidiaApiKey: "test-api-key", + apiModelId: "deepseek-ai/deepseek-r1", + enableReasoningEffort: true, + }) + + mockCreate.mockResolvedValueOnce({ + choices: [{ message: { content: "response" } }], + }) + + await handlerWithReasoning.completePrompt("test") + + expect(mockCreate).toHaveBeenCalledWith( + expect.objectContaining({ + chat_template_kwargs: { enable_thinking: true, clear_thinking: false }, + }), + ) + }) + + it("should handle errors", async () => { + const errorMessage = "NVIDIA API error" + mockCreate.mockRejectedValueOnce(new Error(errorMessage)) + + await expect(handler.completePrompt("test prompt")).rejects.toThrow( + `NVIDIA completion error: ${errorMessage}`, + ) + }) + }) +}) diff --git a/src/api/providers/index.ts b/src/api/providers/index.ts index b6de7952104..6f0a59c23a6 100644 --- a/src/api/providers/index.ts +++ b/src/api/providers/index.ts @@ -17,6 +17,7 @@ export { OpenRouterHandler } from "./openrouter" export { QwenCodeHandler } from "./qwen-code" export { RequestyHandler } from "./requesty" export { SambaNovaHandler } from "./sambanova" +export { NvidiaHandler } from "./nvidia" export { UnboundHandler } from "./unbound" export { VertexHandler } from "./vertex" export { VsCodeLmHandler } from "./vscode-lm" diff --git a/src/api/providers/nvidia.ts b/src/api/providers/nvidia.ts new file mode 100644 index 00000000000..be19e02a0d4 --- /dev/null +++ b/src/api/providers/nvidia.ts @@ -0,0 +1,109 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import OpenAI from "openai" + +import { type NvidiaModelId, nvidiaDefaultModelId, nvidiaModels } from "@roo-code/types" + +import { type ApiHandlerOptions, getModelMaxOutputTokens } from "../../shared/api" +import { BaseOpenAiCompatibleProvider } from "./base-openai-compatible-provider" +import type { ApiHandlerCreateMessageMetadata } from "../index" +import { ApiStream } from "../transform/stream" +import { convertToOpenAiMessages } from "../transform/openai-format" +import { handleOpenAIError } from "./utils/openai-error-handler" + +export class NvidiaHandler extends BaseOpenAiCompatibleProvider { + constructor(options: ApiHandlerOptions) { + super({ + ...options, + providerName: "NVIDIA", + // Default to NVIDIA NIM API endpoint + baseURL: options.nvidiaBaseUrl || "https://integrate.api.nvidia.com/v1", + apiKey: options.nvidiaApiKey, + defaultProviderModelId: nvidiaDefaultModelId, + providerModels: nvidiaModels, + defaultTemperature: 0.7, + }) + } + + /** + * Override createStream to inject NVIDIA-specific parameters. + * + * Key difference from base implementation: + * - Uses `chat_template_kwargs: { enable_thinking: true }` for reasoning + * - Unlike OpenAI's `thinking: { type: "enabled" }` or DeepSeek's approach + */ + protected override createStream( + systemPrompt: string, + messages: Anthropic.Messages.MessageParam[], + metadata?: ApiHandlerCreateMessageMetadata, + requestOptions?: OpenAI.RequestOptions, + ) { + const { id: model, info } = this.getModel() + + // Get max tokens using centralized logic + const max_tokens = + getModelMaxOutputTokens({ + modelId: model, + model: info, + settings: this.options, + format: "openai", + }) ?? undefined + + const temperature = this.options.modelTemperature ?? info.defaultTemperature ?? this.defaultTemperature + + // Build base params (same as parent class) + const params: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = { + model, + max_tokens, + temperature, + messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)], + stream: true, + stream_options: { include_usage: true }, + tools: this.convertToolsForOpenAI(metadata?.tools), + tool_choice: metadata?.tool_choice, + parallel_tool_calls: metadata?.parallelToolCalls ?? true, + } + + // NVIDIA-specific: Inject chat_template_kwargs for reasoning + // This is the KEY difference - NVIDIA uses chat_template_kwargs.enable_thinking + // instead of the `thinking` parameter used by OpenAI/DeepSeek + if (this.options.enableReasoningEffort && info.supportsReasoningBinary) { + ;(params as any).chat_template_kwargs = { + enable_thinking: true, + clear_thinking: false, + } + } + + try { + return this.client.chat.completions.create(params, requestOptions) + } catch (error) { + throw handleOpenAIError(error, this.providerName) + } + } + + /** + * Override completePrompt to inject chat_template_kwargs for non-streaming. + */ + override async completePrompt(prompt: string): Promise { + const { id: modelId, info: modelInfo } = this.getModel() + + const params: OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming = { + model: modelId, + messages: [{ role: "user", content: prompt }], + } + + // Inject reasoning parameter for supported models + if (this.options.enableReasoningEffort && modelInfo.supportsReasoningBinary) { + ;(params as any).chat_template_kwargs = { + enable_thinking: true, + clear_thinking: false, + } + } + + try { + const response = await this.client.chat.completions.create(params) + return response.choices?.[0]?.message.content || "" + } catch (error) { + throw handleOpenAIError(error, this.providerName) + } + } +} diff --git a/src/package.json b/src/package.json index 7c4889abd89..766032c7b9b 100644 --- a/src/package.json +++ b/src/package.json @@ -463,7 +463,7 @@ "@google/genai": "^1.29.1", "@lmstudio/sdk": "^1.1.1", "@mistralai/mistralai": "^1.9.18", - "@modelcontextprotocol/sdk": "1.12.0", + "@modelcontextprotocol/sdk": "^1.29.0", "@qdrant/js-client-rest": "^1.14.0", "@roo-code/cloud": "workspace:^", "@roo-code/core": "workspace:^", diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 4d914a4833a..7406d8d11c0 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -25,6 +25,7 @@ import { bedrockDefaultModelId, vertexDefaultModelId, sambaNovaDefaultModelId, + nvidiaDefaultModelId, internationalZAiDefaultModelId, mainlandZAiDefaultModelId, fireworksDefaultModelId, @@ -84,6 +85,7 @@ import { Requesty, Roo, SambaNova, + Nvidia, Unbound, Vertex, VSCodeLM, @@ -348,6 +350,7 @@ const ApiOptions = ({ bedrock: { field: "apiModelId", default: bedrockDefaultModelId }, vertex: { field: "apiModelId", default: vertexDefaultModelId }, sambanova: { field: "apiModelId", default: sambaNovaDefaultModelId }, + nvidia: { field: "apiModelId", default: nvidiaDefaultModelId }, zai: { field: "apiModelId", default: @@ -681,6 +684,13 @@ const ApiOptions = ({ /> )} + {selectedProvider === "nvidia" && ( + + )} + {selectedProvider === "zai" && ( )} diff --git a/webview-ui/src/components/settings/constants.ts b/webview-ui/src/components/settings/constants.ts index 46789cb67a6..94cad91d478 100644 --- a/webview-ui/src/components/settings/constants.ts +++ b/webview-ui/src/components/settings/constants.ts @@ -13,6 +13,7 @@ import { vertexModels, xaiModels, sambaNovaModels, + nvidiaModels, internationalZAiModels, fireworksModels, minimaxModels, @@ -32,6 +33,7 @@ export const MODELS_BY_PROVIDER: Partial void +} + +export const Nvidia = ({ apiConfiguration, setApiConfigurationField }: NvidiaProps) => { + const { t } = useAppTranslation() + + const handleInputChange = useCallback( + ( + field: K, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, + ) => + (event: E | Event) => { + setApiConfigurationField(field, transform(event as E)) + }, + [setApiConfigurationField], + ) + + return ( + <> + + + +
+ {t("settings:providers.apiKeyStorageNotice")} +
+ + {/* Optional: Custom base URL for self-hosted NVIDIA NIM deployments */} + + + + + {!apiConfiguration?.nvidiaApiKey && ( + + {t("settings:providers.getNvidiaApiKey")} + + )} + + ) +} diff --git a/webview-ui/src/components/settings/providers/index.ts b/webview-ui/src/components/settings/providers/index.ts index 597caffd1d7..c95a81c0991 100644 --- a/webview-ui/src/components/settings/providers/index.ts +++ b/webview-ui/src/components/settings/providers/index.ts @@ -14,6 +14,7 @@ export { QwenCode } from "./QwenCode" export { Roo } from "./Roo" export { Requesty } from "./Requesty" export { SambaNova } from "./SambaNova" +export { Nvidia } from "./Nvidia" export { Unbound } from "./Unbound" export { Vertex } from "./Vertex" export { VSCodeLM } from "./VSCodeLM" diff --git a/webview-ui/src/components/settings/utils/providerModelConfig.ts b/webview-ui/src/components/settings/utils/providerModelConfig.ts index fa718143905..f531f93b73a 100644 --- a/webview-ui/src/components/settings/utils/providerModelConfig.ts +++ b/webview-ui/src/components/settings/utils/providerModelConfig.ts @@ -11,6 +11,7 @@ import { vertexDefaultModelId, xaiDefaultModelId, sambaNovaDefaultModelId, + nvidiaDefaultModelId, internationalZAiDefaultModelId, mainlandZAiDefaultModelId, fireworksDefaultModelId, @@ -37,6 +38,7 @@ export const PROVIDER_SERVICE_CONFIG: Partial> = vertex: vertexDefaultModelId, xai: xaiDefaultModelId, sambanova: sambaNovaDefaultModelId, + nvidia: nvidiaDefaultModelId, zai: internationalZAiDefaultModelId, fireworks: fireworksDefaultModelId, minimax: minimaxDefaultModelId, diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index c32a08990c8..43d4e6caf85 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -19,6 +19,7 @@ import { vscodeLlmDefaultModelId, openAiCodexModels, sambaNovaModels, + nvidiaModels, internationalZAiModels, mainlandZAiModels, fireworksModels, @@ -307,6 +308,11 @@ function getSelectedModel({ const info = sambaNovaModels[id as keyof typeof sambaNovaModels] return { id, info } } + case "nvidia": { + const id = apiConfiguration.apiModelId ?? defaultModelId + const info = nvidiaModels[id as keyof typeof nvidiaModels] + return { id, info } + } case "fireworks": { const id = apiConfiguration.apiModelId ?? defaultModelId const info = fireworksModels[id as keyof typeof fireworksModels]