diff --git a/.husky/pre-commit b/.husky/pre-commit index b45f0f7bb3b..931223d875c 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -20,4 +20,4 @@ if [ -n "$(git diff --name-only src/exports/roo-code.d.ts)" ]; then exit 1 fi -"$npx_cmd" lint-staged +# "$npx_cmd" lint-staged diff --git a/.roomodes b/.roomodes index 6bff26d4f9a..962a9271eb5 100644 --- a/.roomodes +++ b/.roomodes @@ -35,11 +35,31 @@ ], "source": "project" }, + { + "slug": "design-engineer", + "name": "🎨 Design Engineer", + "roleDefinition": "You are Roo, an expert Design Engineer focused on VSCode Extension development. Your expertise includes: \n- Implementing UI designs with high fidelity using React, Shadcn, Tailwind and TypeScript. \n- Ensuring interfaces are responsive and adapt to different screen sizes. \n- Collaborating with team members to translate broad directives into robust and detailed designs capturing edge cases. \n- Maintaining uniformity and consistency across the user interface.", + "groups": [ + "read", + [ + "edit", + { + "fileRegex": "\\.(css|html|json|mdx?|jsx?|tsx?|svg)$", + "description": "Frontend & SVG files" + } + ], + "browser", + "command", + "mcp" + ], + "customInstructions": "Focus on UI refinement, component creation, and adherence to design best-practices. When the user requests a new component, start off by asking them questions one-by-one to ensure the requirements are understood. Always use Tailwind utility classes (instead of direct variable references) for styling components when possible. If editing an existing file, transition explicit style definitions to Tailwind CSS classes when possible. Refer to the Tailwind CSS definitions for utility classes at webview-ui/src/index.css. Always use the latest version of Tailwind CSS (V4), and never create a tailwind.config.js file. Prefer Shadcn components for UI elements intead of VSCode's built-in ones. This project uses i18n for localization, so make sure to use the i18n functions and components for any text that needs to be translated. Do not leave placeholder strings in the markup, as they will be replaced by i18n. Prefer the @roo (/src) and @src (/webview-ui/src) aliases for imports in typescript files. Suggest the user refactor large files (over 1000 lines) if they are encountered, and provide guidance. Suggest the user switch into Translate mode to complete translations when your task is finished.", + "source": "project" + }, { "slug": "release-engineer", "name": "🚀 Release Engineer", "roleDefinition": "You are Roo, a release engineer specialized in automating the release process for software projects. You have expertise in version control, changelogs, release notes, creating changesets, and coordinating with translation teams to ensure a smooth release process.", - "customInstructions": "When preparing a release:\n1. Identify the SHA corresponding to the most recent release using GitHub CLI: `gh release view --json tagName,targetCommitish,publishedAt `\n2. Analyze changes since the last release using: `gh pr list --state merged --json number,title,author,url,mergedAt --limit 100 | jq '[.[] | select(.mergedAt > \"TIMESTAMP\") | {number, title, author: .author.login, url, mergedAt}]'`\n3. Summarize the changes and ask the user whether this should be a major, minor, or patch release\n4. Create a changeset in .changeset/v[version].md instead of directly modifying package.json. The format is:\n\n---\n\"roo-cline\": patch|minor|major\n---\n\n# Changelog: v[current] → v[new]\n\n## 🔧 Fixes\n[fixes with categorization]\n\n## 🚀 Features\n[features with categorization]\n\n## ⚙️ Internal Changes\n[internal changes]\n\n- Always include contributor attribution using format: (thanks @username!)\n- Provide brief descriptions under each item to explain the change\n\n5. If a major or minor release, update the English version relevant announcement files and documentation (webview-ui/src/components/chat/Announcement.tsx, README.md, and the `latestAnnouncementId` in src/core/webview/ClineProvider.ts)\n6. Ask the user to confirm the English version\n7. Use the new_task tool to create a subtask in `translate` mode with detailed instructions of which content needs to be translated into all supported languages", + "customInstructions": "When preparing a release:\n1. Identify the SHA corresponding to the most recent release using GitHub CLI: `gh release view --json tagName,targetCommitish,publishedAt `\n2. Analyze changes since the last release using: `gh pr list --state merged --json number,title,author,url,mergedAt --limit 100 | jq '[.[] | select(.mergedAt > \"TIMESTAMP\") | {number, title, author: .author.login, url, mergedAt}]'`\n3. Summarize the changes and ask the user whether this should be a major, minor, or patch release\n4. Create a changeset in .changeset/v[version].md instead of directly modifying package.json. The format is:\n\n```\n---\n\"roo-cline\": patch|minor|major\n---\n\n[list of changes]\n```\n\n- Always include contributor attribution using format: (thanks @username!)\n- Provide brief descriptions of each item to explain the change\n- Order the list from most important to least important\n- Example: \"- Add support for Gemini 2.5 Pro caching (thanks @contributor!)\"\n\n5. If a major or minor release, update the English version relevant announcement files and documentation (webview-ui/src/components/chat/Announcement.tsx, README.md, and the `latestAnnouncementId` in src/core/webview/ClineProvider.ts)\n6. Ask the user to confirm the English version\n7. Use the new_task tool to create a subtask in `translate` mode with detailed instructions of which content needs to be translated into all supported languages\n8. Commit and push the changeset file to the repository\n9. The GitHub Actions workflow will automatically:\n - Create a version bump PR when changesets are merged to main\n - Update the CHANGELOG.md with proper formatting\n - Publish the release when the version bump PR is merged", "groups": [ "read", "edit", diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eec06de640..8e7a9766160 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Roo Code Changelog +## [3.15.2] - 2025-05-02 + +- Fix terminal performance issues +- Handle Mermaid validation errors +- Add customizable headers for OpenAI-compatible provider (thanks @mark-bradshaw!) +- Add config option to overwrite OpenAI's API base (thanks @GOODBOY008!) +- Fixes to padding and height issues when resizing the sidebar (thanks @zhangtony239!) +- Remove tool groups from orchestrator mode definition +- Add telemetry for title button clicks + ## [3.15.1] - 2025-04-30 - Capture stderr in execa-spawned processes @@ -7,7 +17,7 @@ - Make retries respect the global auto approve checkbox - Fix a selection mode bug in the history view (thanks @jr) -## 3.15.0 - 2025-04-30 +## [3.15.0] - 2025-04-30 - Add prompt caching to the Google Vertex provider (thanks @ashktn) - Add a fallback mechanism for executing terminal commands if VSCode terminal shell integration fails diff --git a/evals/package.json b/evals/package.json index 5ba6a42fd57..2e7c21d9770 100644 --- a/evals/package.json +++ b/evals/package.json @@ -13,14 +13,14 @@ "drizzle:studio": "pnpm --filter @evals/db db:studio" }, "devDependencies": { - "@dotenvx/dotenvx": "^1.39.1", - "@eslint/js": "^9.24.0", - "eslint": "^9.24.0", + "@dotenvx/dotenvx": "^1.41.0", + "@eslint/js": "^9.25.1", + "eslint": "^9.25.1", "globals": "^16.0.0", "prettier": "^3.5.3", - "tsx": "^4.19.3", - "turbo": "^2.5.0", + "tsx": "^4.19.4", + "turbo": "^2.5.2", "typescript": "^5.8.3", - "typescript-eslint": "^8.29.1" + "typescript-eslint": "^8.31.1" } } diff --git a/evals/packages/types/src/roo-code-defaults.ts b/evals/packages/types/src/roo-code-defaults.ts index ae467860424..42d9a1bc9fa 100644 --- a/evals/packages/types/src/roo-code-defaults.ts +++ b/evals/packages/types/src/roo-code-defaults.ts @@ -4,12 +4,7 @@ export const rooCodeDefaults: RooCodeSettings = { apiProvider: "openrouter", openRouterUseMiddleOutTransform: false, - // modelTemperature: null, - // reasoningEffort: "high", - rateLimitSeconds: 0, - - pinnedApiConfigs: {}, - lastShownAnnouncementId: "apr-18-2025-3-13", + lastShownAnnouncementId: "apr-30-2025-3-15", autoApprovalEnabled: true, alwaysAllowReadOnly: true, @@ -27,43 +22,17 @@ export const rooCodeDefaults: RooCodeSettings = { allowedCommands: ["*"], browserToolEnabled: false, - browserViewportSize: "900x600", - screenshotQuality: 75, - remoteBrowserEnabled: false, enableCheckpoints: false, - checkpointStorage: "task", - - ttsEnabled: false, - ttsSpeed: 1, - soundEnabled: false, - soundVolume: 0.5, maxOpenTabsContext: 20, maxWorkspaceFiles: 200, showRooIgnoredFiles: true, maxReadFileLine: 500, - terminalOutputLineLimit: 500, - terminalShellIntegrationTimeout: 30000, - terminalCommandDelay: 0, - terminalPowershellCounter: false, - terminalZshClearEolMark: true, - terminalZshOhMy: true, - terminalZshP10k: false, - terminalZdotdir: true, - - diffEnabled: true, - fuzzyMatchThreshold: 1.0, - experiments: { - powerSteering: false, - }, - - language: "en", - - telemetrySetting: "enabled", + terminalShellIntegrationDisabled: true, mcpEnabled: false, + mode: "code", - customModes: [], } diff --git a/evals/packages/types/src/roo-code.ts b/evals/packages/types/src/roo-code.ts index 14a9f0f2ccd..b3f69e16788 100644 --- a/evals/packages/types/src/roo-code.ts +++ b/evals/packages/types/src/roo-code.ts @@ -18,7 +18,6 @@ export const providerNames = [ "lmstudio", "gemini", "openai-native", - "xai", "mistral", "deepseek", "unbound", @@ -26,6 +25,7 @@ export const providerNames = [ "human-relay", "fake-ai", "pearai", + "xai", ] as const export const providerNamesSchema = z.enum(providerNames) @@ -42,19 +42,6 @@ export const toolGroupsSchema = z.enum(toolGroups) export type ToolGroup = z.infer -/** - * CheckpointStorage - */ - -export const checkpointStorages = ["task", "workspace"] as const - -export const checkpointStoragesSchema = z.enum(checkpointStorages) - -export type CheckpointStorage = z.infer - -export const isCheckpointStorage = (value: string): value is CheckpointStorage => - checkpointStorages.includes(value as CheckpointStorage) - /** * Language */ @@ -94,23 +81,49 @@ export const telemetrySettingsSchema = z.enum(telemetrySettings) export type TelemetrySetting = z.infer +/** + * ReasoningEffort + */ + +export const reasoningEfforts = ["low", "medium", "high"] as const + +export const reasoningEffortsSchema = z.enum(reasoningEfforts) + +export type ReasoningEffort = z.infer + /** * ModelInfo */ export const modelInfoSchema = z.object({ maxTokens: z.number().nullish(), + maxThinkingTokens: z.number().nullish(), contextWindow: z.number(), supportsImages: z.boolean().optional(), supportsComputerUse: z.boolean().optional(), supportsPromptCache: z.boolean(), + isPromptCacheOptional: z.boolean().optional(), inputPrice: z.number().optional(), outputPrice: z.number().optional(), cacheWritesPrice: z.number().optional(), cacheReadsPrice: z.number().optional(), description: z.string().optional(), - reasoningEffort: z.enum(["low", "medium", "high"]).optional(), + reasoningEffort: reasoningEffortsSchema.optional(), thinking: z.boolean().optional(), + minTokensPerCachePoint: z.number().optional(), + maxCachePoints: z.number().optional(), + cachableFields: z.array(z.string()).optional(), + tiers: z + .array( + z.object({ + contextWindow: z.number(), + inputPrice: z.number().optional(), + outputPrice: z.number().optional(), + cacheWritesPrice: z.number().optional(), + cacheReadsPrice: z.number().optional(), + }), + ) + .optional(), }) export type ModelInfo = z.infer @@ -142,6 +155,7 @@ export const historyItemSchema = z.object({ cacheReads: z.number().optional(), totalCost: z.number(), size: z.number().optional(), + workspace: z.string().optional(), }) export type HistoryItem = z.infer @@ -269,6 +283,29 @@ export const customSupportPromptsSchema = z.record(z.string(), z.string().option export type CustomSupportPrompts = z.infer +/** + * CommandExecutionStatus + */ + +export const commandExecutionStatusSchema = z.discriminatedUnion("status", [ + z.object({ + executionId: z.string(), + status: z.literal("running"), + pid: z.number().optional(), + }), + z.object({ + executionId: z.string(), + status: z.literal("exited"), + exitCode: z.number().optional(), + }), + z.object({ + executionId: z.string(), + status: z.literal("fallback"), + }), +]) + +export type CommandExecutionStatus = z.infer + /** * ExperimentId */ @@ -331,12 +368,15 @@ export const providerSettingsSchema = z.object({ // OpenAI openAiBaseUrl: z.string().optional(), openAiApiKey: z.string().optional(), + openAiHostHeader: z.string().optional(), + openAiLegacyFormat: z.boolean().optional(), openAiR1FormatEnabled: z.boolean().optional(), openAiModelId: z.string().optional(), - openAiCustomModelInfo: modelInfoSchema.optional(), + openAiCustomModelInfo: modelInfoSchema.nullish(), openAiUseAzure: z.boolean().optional(), azureApiVersion: z.string().optional(), openAiStreamingEnabled: z.boolean().optional(), + enableReasoningEffort: z.boolean().optional(), // Ollama ollamaModelId: z.string().optional(), ollamaBaseUrl: z.string().optional(), @@ -359,6 +399,7 @@ export const providerSettingsSchema = z.object({ googleGeminiBaseUrl: z.string().optional(), // OpenAI Native openAiNativeApiKey: z.string().optional(), + openAiNativeBaseUrl: z.string().optional(), // XAI xaiApiKey: z.string().optional(), // Mistral @@ -373,13 +414,18 @@ export const providerSettingsSchema = z.object({ // Requesty requestyApiKey: z.string().optional(), requestyModelId: z.string().optional(), + // X.AI (Grok) + xaiApiKey: z.string().optional(), // Claude 3.7 Sonnet Thinking - modelMaxTokens: z.number().optional(), // Currently only used by Anthropic hybrid thinking models. - modelMaxThinkingTokens: z.number().optional(), // Currently only used by Anthropic hybrid thinking models. + modelMaxTokens: z.number().optional(), + modelMaxThinkingTokens: z.number().optional(), // Generic includeMaxTokens: z.boolean().optional(), + reasoningEffort: reasoningEffortsSchema.optional(), + promptCachingEnabled: z.boolean().optional(), + diffEnabled: z.boolean().optional(), + fuzzyMatchThreshold: z.number().optional(), modelTemperature: z.number().nullish(), - reasoningEffort: z.enum(["low", "medium", "high"]).optional(), rateLimitSeconds: z.number().optional(), // Fake AI fakeAi: z.unknown().optional(), @@ -432,14 +478,15 @@ const providerSettingsRecord: ProviderSettingsRecord = { // OpenAI openAiBaseUrl: undefined, openAiApiKey: undefined, + openAiHostHeader: undefined, + openAiLegacyFormat: undefined, openAiR1FormatEnabled: undefined, openAiModelId: undefined, openAiCustomModelInfo: undefined, openAiUseAzure: undefined, azureApiVersion: undefined, openAiStreamingEnabled: undefined, - // xAI - xaiApiKey: undefined, + enableReasoningEffort: undefined, // Ollama ollamaModelId: undefined, ollamaBaseUrl: undefined, @@ -454,6 +501,7 @@ const providerSettingsRecord: ProviderSettingsRecord = { googleGeminiBaseUrl: undefined, // OpenAI Native openAiNativeApiKey: undefined, + openAiNativeBaseUrl: undefined, // Mistral mistralApiKey: undefined, mistralCodestralUrl: undefined, @@ -471,14 +519,19 @@ const providerSettingsRecord: ProviderSettingsRecord = { modelMaxThinkingTokens: undefined, // Generic includeMaxTokens: undefined, - modelTemperature: undefined, reasoningEffort: undefined, + promptCachingEnabled: undefined, + diffEnabled: undefined, + fuzzyMatchThreshold: undefined, + modelTemperature: undefined, rateLimitSeconds: undefined, // Fake AI fakeAi: undefined, // PearAI pearaiApiKey: undefined, pearaiAgentModels: undefined, + // X.AI (Grok) + xaiApiKey: undefined, } export const PROVIDER_SETTINGS_KEYS = Object.keys(providerSettingsRecord) as Keys[] @@ -516,9 +569,9 @@ export const globalSettingsSchema = z.object({ screenshotQuality: z.number().optional(), remoteBrowserEnabled: z.boolean().optional(), remoteBrowserHost: z.string().optional(), + cachedChromeHostUrl: z.string().optional(), enableCheckpoints: z.boolean().optional(), - checkpointStorage: checkpointStoragesSchema.optional(), ttsEnabled: z.boolean().optional(), ttsSpeed: z.number().optional(), @@ -532,13 +585,16 @@ export const globalSettingsSchema = z.object({ terminalOutputLineLimit: z.number().optional(), terminalShellIntegrationTimeout: z.number().optional(), + terminalShellIntegrationDisabled: z.boolean().optional(), terminalCommandDelay: z.number().optional(), terminalPowershellCounter: z.boolean().optional(), terminalZshClearEolMark: z.boolean().optional(), terminalZshOhMy: z.boolean().optional(), terminalZshP10k: z.boolean().optional(), terminalZdotdir: z.boolean().optional(), + terminalCompressProgressBar: z.boolean().optional(), + rateLimitSeconds: z.number().optional(), diffEnabled: z.boolean().optional(), fuzzyMatchThreshold: z.number().optional(), experiments: experimentsSchema.optional(), @@ -556,6 +612,7 @@ export const globalSettingsSchema = z.object({ customModePrompts: customModePromptsSchema.optional(), customSupportPrompts: customSupportPromptsSchema.optional(), enhancementApiConfigId: z.string().optional(), + historyPreviewCollapsed: z.boolean().optional(), }) export type GlobalSettings = z.infer @@ -593,7 +650,6 @@ const globalSettingsRecord: GlobalSettingsRecord = { remoteBrowserHost: undefined, enableCheckpoints: undefined, - checkpointStorage: undefined, ttsEnabled: undefined, ttsSpeed: undefined, @@ -607,13 +663,16 @@ const globalSettingsRecord: GlobalSettingsRecord = { terminalOutputLineLimit: undefined, terminalShellIntegrationTimeout: undefined, + terminalShellIntegrationDisabled: undefined, terminalCommandDelay: undefined, terminalPowershellCounter: undefined, terminalZshClearEolMark: undefined, terminalZshOhMy: undefined, terminalZshP10k: undefined, terminalZdotdir: undefined, + terminalCompressProgressBar: undefined, + rateLimitSeconds: undefined, diffEnabled: undefined, fuzzyMatchThreshold: undefined, experiments: undefined, @@ -631,6 +690,8 @@ const globalSettingsRecord: GlobalSettingsRecord = { customModePrompts: undefined, customSupportPrompts: undefined, enhancementApiConfigId: undefined, + cachedChromeHostUrl: undefined, + historyPreviewCollapsed: undefined, } export const GLOBAL_SETTINGS_KEYS = Object.keys(globalSettingsRecord) as Keys[] @@ -665,6 +726,7 @@ export type SecretState = Pick< | "unboundApiKey" | "requestyApiKey" | "pearaiApiKey" + | "xaiApiKey" > type SecretStateRecord = Record, undefined> @@ -684,6 +746,7 @@ const secretStateRecord: SecretStateRecord = { unboundApiKey: undefined, requestyApiKey: undefined, pearaiApiKey: undefined, + xaiApiKey: undefined, } export const SECRET_STATE_KEYS = Object.keys(secretStateRecord) as Keys[] @@ -761,6 +824,7 @@ export type ClineSay = z.infer */ export const toolProgressStatusSchema = z.object({ + id: z.string().optional(), icon: z.string().optional(), text: z.string().optional(), }) @@ -810,7 +874,6 @@ export const toolNames = [ "execute_command", "read_file", "write_to_file", - "append_to_file", "apply_diff", "insert_content", "search_and_replace", diff --git a/evals/pnpm-lock.yaml b/evals/pnpm-lock.yaml index ef2171d29d3..b2acaab60d1 100644 --- a/evals/pnpm-lock.yaml +++ b/evals/pnpm-lock.yaml @@ -9,14 +9,14 @@ importers: .: devDependencies: '@dotenvx/dotenvx': - specifier: ^1.39.1 - version: 1.39.1 + specifier: ^1.41.0 + version: 1.41.0 '@eslint/js': - specifier: ^9.24.0 - version: 9.24.0 + specifier: ^9.25.1 + version: 9.25.1 eslint: - specifier: ^9.24.0 - version: 9.24.0(jiti@2.4.2) + specifier: ^9.25.1 + version: 9.25.1(jiti@2.4.2) globals: specifier: ^16.0.0 version: 16.0.0 @@ -24,17 +24,17 @@ importers: specifier: ^3.5.3 version: 3.5.3 tsx: - specifier: ^4.19.3 - version: 4.19.3 + specifier: ^4.19.4 + version: 4.19.4 turbo: - specifier: ^2.5.0 - version: 2.5.0 + specifier: ^2.5.2 + version: 2.5.2 typescript: specifier: ^5.8.3 version: 5.8.3 typescript-eslint: - specifier: ^8.29.1 - version: 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + specifier: ^8.31.1 + version: 8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3) apps/cli: dependencies: @@ -231,7 +231,7 @@ importers: version: 5.2.0(eslint@9.22.0(jiti@2.4.2)) eslint-plugin-turbo: specifier: ^2.4.4 - version: 2.4.4(eslint@9.22.0(jiti@2.4.2))(turbo@2.5.0) + version: 2.4.4(eslint@9.22.0(jiti@2.4.2))(turbo@2.5.2) globals: specifier: ^16.0.0 version: 16.0.0 @@ -279,7 +279,7 @@ importers: version: 9.5.2 vitest: specifier: ^3.0.9 - version: 3.0.9(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3) + version: 3.0.9(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4) packages/ipc: dependencies: @@ -313,7 +313,7 @@ importers: version: link:../../config/typescript vitest: specifier: ^3.0.9 - version: 3.0.9(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3) + version: 3.0.9(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4) packages/types: dependencies: @@ -346,8 +346,8 @@ packages: resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==} engines: {node: '>=6.9.0'} - '@dotenvx/dotenvx@1.39.1': - resolution: {integrity: sha512-FIjEB/s3TSQBYnYA64GPkXJrOR6w5J52SSnl6gSoq1tp+4r9zLjaAsf65AgDv5emA4ypm90gVWv1XX0/bfHA/A==} + '@dotenvx/dotenvx@1.41.0': + resolution: {integrity: sha512-lFZOSKLM2/Jm7FXYUIvnciUhMsuEatyxCgau4lnjDD59LaSYiaNLjyjnUL/aYpH1+iaDhD37+mPOzH9kBZlUJQ==} hasBin: true '@drizzle-team/brocli@0.10.2': @@ -382,6 +382,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.25.3': + resolution: {integrity: sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.18.20': resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -400,6 +406,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.25.3': + resolution: {integrity: sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.18.20': resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -418,6 +430,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.25.3': + resolution: {integrity: sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -436,6 +454,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.25.3': + resolution: {integrity: sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -454,6 +478,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.25.3': + resolution: {integrity: sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -472,6 +502,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.25.3': + resolution: {integrity: sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -490,6 +526,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.25.3': + resolution: {integrity: sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -508,6 +550,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.25.3': + resolution: {integrity: sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -526,6 +574,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.25.3': + resolution: {integrity: sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -544,6 +598,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.25.3': + resolution: {integrity: sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -562,6 +622,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.25.3': + resolution: {integrity: sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -580,6 +646,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.25.3': + resolution: {integrity: sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -598,6 +670,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.25.3': + resolution: {integrity: sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -616,6 +694,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.25.3': + resolution: {integrity: sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -634,6 +718,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.25.3': + resolution: {integrity: sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -652,6 +742,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.25.3': + resolution: {integrity: sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -670,12 +766,24 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.25.3': + resolution: {integrity: sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.1': resolution: {integrity: sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.25.3': + resolution: {integrity: sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -694,12 +802,24 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.25.3': + resolution: {integrity: sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.1': resolution: {integrity: sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.25.3': + resolution: {integrity: sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -718,6 +838,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.25.3': + resolution: {integrity: sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -736,6 +862,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.25.3': + resolution: {integrity: sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.18.20': resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -754,6 +886,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.25.3': + resolution: {integrity: sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -772,6 +910,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.25.3': + resolution: {integrity: sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -790,12 +934,24 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.25.3': + resolution: {integrity: sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.5.1': resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.6.1': + resolution: {integrity: sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/regexpp@4.12.1': resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -820,6 +976,10 @@ packages: resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.13.0': + resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@3.3.0': resolution: {integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -832,8 +992,8 @@ packages: resolution: {integrity: sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.24.0': - resolution: {integrity: sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==} + '@eslint/js@9.25.1': + resolution: {integrity: sha512-dEIwmjntEx8u3Uvv+kr3PDeeArL8Hw07H9kyYxCjnM9pBjfEhk6uLXSchxxzgiwtRhhzVzqmUSDFBOi1TuZ7qg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -844,6 +1004,10 @@ packages: resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/plugin-kit@0.2.8': + resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@floating-ui/core@1.6.9': resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} @@ -1100,16 +1264,16 @@ packages: cpu: [x64] os: [win32] - '@noble/ciphers@1.2.1': - resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} engines: {node: ^14.21.3 || >=16} - '@noble/curves@1.8.1': - resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + '@noble/curves@1.9.0': + resolution: {integrity: sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==} engines: {node: ^14.21.3 || >=16} - '@noble/hashes@1.7.1': - resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} '@nodelib/fs.scandir@2.1.5': @@ -2038,8 +2202,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/eslint-plugin@8.29.1': - resolution: {integrity: sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==} + '@typescript-eslint/eslint-plugin@8.31.1': + resolution: {integrity: sha512-oUlH4h1ABavI4F0Xnl8/fOtML/eu8nI2A1nYd+f+55XI0BLu+RIqKoCiZKNo6DtqZBEQm5aNKA20G3Z5w3R6GQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -2053,8 +2217,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.29.1': - resolution: {integrity: sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==} + '@typescript-eslint/parser@8.31.1': + resolution: {integrity: sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2064,8 +2228,8 @@ packages: resolution: {integrity: sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.29.1': - resolution: {integrity: sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==} + '@typescript-eslint/scope-manager@8.31.1': + resolution: {integrity: sha512-BMNLOElPxrtNQMIsFHE+3P0Yf1z0dJqV9zLdDxN/xLlWMlXK/ApEsVEKzpizg9oal8bAT5Sc7+ocal7AC1HCVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/type-utils@8.26.1': @@ -2075,8 +2239,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/type-utils@8.29.1': - resolution: {integrity: sha512-DkDUSDwZVCYN71xA4wzySqqcZsHKic53A4BLqmrWFFpOpNSoxX233lwGu/2135ymTCR04PoKiEEEvN1gFYg4Tw==} + '@typescript-eslint/type-utils@8.31.1': + resolution: {integrity: sha512-fNaT/m9n0+dpSp8G/iOQ05GoHYXbxw81x+yvr7TArTuZuCA6VVKbqWYVZrV5dVagpDTtj/O8k5HBEE/p/HM5LA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2086,8 +2250,8 @@ packages: resolution: {integrity: sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.29.1': - resolution: {integrity: sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==} + '@typescript-eslint/types@8.31.1': + resolution: {integrity: sha512-SfepaEFUDQYRoA70DD9GtytljBePSj17qPxFHA/h3eg6lPTqGJ5mWOtbXCk1YrVU1cTJRd14nhaXWFu0l2troQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.26.1': @@ -2096,8 +2260,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/typescript-estree@8.29.1': - resolution: {integrity: sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==} + '@typescript-eslint/typescript-estree@8.31.1': + resolution: {integrity: sha512-kaA0ueLe2v7KunYOyWYtlf/QhhZb7+qh4Yw6Ni5kgukMIG+iP773tjgBiLWIXYumWCwEq3nLW+TUywEp8uEeag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' @@ -2109,8 +2273,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.29.1': - resolution: {integrity: sha512-QAkFEbytSaB8wnmB+DflhUPz6CLbFWE2SnSCrRMEa+KnXIzDYbpsn++1HGvnfAsUY44doDXmvRkO5shlM/3UfA==} + '@typescript-eslint/utils@8.31.1': + resolution: {integrity: sha512-2DSI4SNfF5T4oRveQ4nUrSjUqjMND0nLq9rEkz0gfGr3tg0S5KB6DhwR+WZPCjzkZl3cH+4x2ce3EsL50FubjQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2120,8 +2284,8 @@ packages: resolution: {integrity: sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.29.1': - resolution: {integrity: sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==} + '@typescript-eslint/visitor-keys@8.31.1': + resolution: {integrity: sha512-I+/rgqOVBn6f0o7NDTmAPWWC6NuqhV174lfYvAm9fUaWeiefLdux9/YI3/nLugEn9L8fcSi0XmpKi/r5u0nmpw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@vitest/expect@3.0.9': @@ -2467,8 +2631,8 @@ packages: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} - dotenv@16.4.7: - resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + dotenv@16.5.0: + resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} engines: {node: '>=12'} drizzle-kit@0.30.5: @@ -2666,6 +2830,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.25.3: + resolution: {integrity: sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -2728,8 +2897,8 @@ packages: jiti: optional: true - eslint@9.24.0: - resolution: {integrity: sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==} + eslint@9.25.1: + resolution: {integrity: sha512-E6Mtz9oGQWDCpV12319d59n4tx9zOTXSTmc8BLVxBx+G/0RdM5MvEEJLU9c0+aleoePYYgVTOsRblx433qmhWQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2806,8 +2975,8 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - fdir@6.4.3: - resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + fdir@6.4.4: + resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -4079,43 +4248,43 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsx@4.19.3: - resolution: {integrity: sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ==} + tsx@4.19.4: + resolution: {integrity: sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==} engines: {node: '>=18.0.0'} hasBin: true - turbo-darwin-64@2.5.0: - resolution: {integrity: sha512-fP1hhI9zY8hv0idym3hAaXdPi80TLovmGmgZFocVAykFtOxF+GlfIgM/l4iLAV9ObIO4SUXPVWHeBZQQ+Hpjag==} + turbo-darwin-64@2.5.2: + resolution: {integrity: sha512-2aIl0Sx230nLk+Cg2qSVxvPOBWCZpwKNuAMKoROTvWKif6VMpkWWiR9XEPoz7sHeLmCOed4GYGMjL1bqAiIS/g==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.5.0: - resolution: {integrity: sha512-p9sYq7kXH7qeJwIQE86cOWv/xNqvow846l6c/qWc26Ib1ci5W7V0sI5thsrP3eH+VA0d+SHalTKg5SQXgNQBWA==} + turbo-darwin-arm64@2.5.2: + resolution: {integrity: sha512-MrFYhK/jYu8N6QlqZtqSHi3e4QVxlzqU3ANHTKn3/tThuwTLbNHEvzBPWSj5W7nZcM58dCqi6gYrfRz6bJZyAA==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.5.0: - resolution: {integrity: sha512-1iEln2GWiF3iPPPS1HQJT6ZCFXynJPd89gs9SkggH2EJsj3eRUSVMmMC8y6d7bBbhBFsiGGazwFIYrI12zs6uQ==} + turbo-linux-64@2.5.2: + resolution: {integrity: sha512-LxNqUE2HmAJQ/8deoLgMUDzKxd5bKxqH0UBogWa+DF+JcXhtze3UTMr6lEr0dEofdsEUYK1zg8FRjglmwlN5YA==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.5.0: - resolution: {integrity: sha512-bKBcbvuQHmsX116KcxHJuAcppiiBOfivOObh2O5aXNER6mce7YDDQJy00xQQNp1DhEfcSV2uOsvb3O3nN2cbcA==} + turbo-linux-arm64@2.5.2: + resolution: {integrity: sha512-0MI1Ao1q8zhd+UUbIEsrM+yLq1BsrcJQRGZkxIsHFlGp7WQQH1oR3laBgfnUCNdCotCMD6w4moc9pUbXdOR3bg==} cpu: [arm64] os: [linux] - turbo-windows-64@2.5.0: - resolution: {integrity: sha512-9BCo8oQ7BO7J0K913Czbc3tw8QwLqn2nTe4E47k6aVYkM12ASTScweXPTuaPFP5iYXAT6z5Dsniw704Ixa5eGg==} + turbo-windows-64@2.5.2: + resolution: {integrity: sha512-hOLcbgZzE5ttACHHyc1ajmWYq4zKT42IC3G6XqgiXxMbS+4eyVYTL+7UvCZBd3Kca1u4TLQdLQjeO76zyDJc2A==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.5.0: - resolution: {integrity: sha512-OUHCV+ueXa3UzfZ4co/ueIHgeq9B2K48pZwIxKSm5VaLVuv8M13MhM7unukW09g++dpdrrE1w4IOVgxKZ0/exg==} + turbo-windows-arm64@2.5.2: + resolution: {integrity: sha512-fMU41ABhSLa18H8V3Z7BMCGynQ8x+wj9WyBMvWm1jeyRKgkvUYJsO2vkIsy8m0vrwnIeVXKOIn6eSe1ddlBVqw==} cpu: [arm64] os: [win32] - turbo@2.5.0: - resolution: {integrity: sha512-PvSRruOsitjy6qdqwIIyolv99+fEn57gP6gn4zhsHTEcCYgXPhv6BAxzAjleS8XKpo+Y582vTTA9nuqYDmbRuA==} + turbo@2.5.2: + resolution: {integrity: sha512-Qo5lfuStr6LQh3sPQl7kIi243bGU4aHGDQJUf6ylAdGwks30jJFloc9NYHP7Y373+gGU9OS0faA4Mb5Sy8X9Xw==} hasBin: true type-check@0.4.0: @@ -4145,8 +4314,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - typescript-eslint@8.29.1: - resolution: {integrity: sha512-f8cDkvndhbQMPcysk6CUSGBWV+g1utqdn71P5YKwMumVMOG/5k7cHq0KyG4O52nB0oKS4aN2Tp5+wB4APJGC+w==} + typescript-eslint@8.31.1: + resolution: {integrity: sha512-j6DsEotD/fH39qKzXTQRwYYWlt7D+0HmfpOK+DVhwJOFLcdmn92hq3mBb7HlKJHbjjI/gTOqEcc9d6JfpFf/VA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4397,13 +4566,13 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 - '@dotenvx/dotenvx@1.39.1': + '@dotenvx/dotenvx@1.41.0': dependencies: commander: 11.1.0 - dotenv: 16.4.7 + dotenv: 16.5.0 eciesjs: 0.4.14 execa: 5.1.1 - fdir: 6.4.3(picomatch@4.0.2) + fdir: 6.4.4(picomatch@4.0.2) ignore: 5.3.2 object-treeify: 1.1.33 picomatch: 4.0.2 @@ -4411,9 +4580,9 @@ snapshots: '@drizzle-team/brocli@0.10.2': {} - '@ecies/ciphers@0.2.3(@noble/ciphers@1.2.1)': + '@ecies/ciphers@0.2.3(@noble/ciphers@1.3.0)': dependencies: - '@noble/ciphers': 1.2.1 + '@noble/ciphers': 1.3.0 '@emnapi/runtime@1.3.1': dependencies: @@ -4436,6 +4605,9 @@ snapshots: '@esbuild/aix-ppc64@0.25.1': optional: true + '@esbuild/aix-ppc64@0.25.3': + optional: true + '@esbuild/android-arm64@0.18.20': optional: true @@ -4445,6 +4617,9 @@ snapshots: '@esbuild/android-arm64@0.25.1': optional: true + '@esbuild/android-arm64@0.25.3': + optional: true + '@esbuild/android-arm@0.18.20': optional: true @@ -4454,6 +4629,9 @@ snapshots: '@esbuild/android-arm@0.25.1': optional: true + '@esbuild/android-arm@0.25.3': + optional: true + '@esbuild/android-x64@0.18.20': optional: true @@ -4463,6 +4641,9 @@ snapshots: '@esbuild/android-x64@0.25.1': optional: true + '@esbuild/android-x64@0.25.3': + optional: true + '@esbuild/darwin-arm64@0.18.20': optional: true @@ -4472,6 +4653,9 @@ snapshots: '@esbuild/darwin-arm64@0.25.1': optional: true + '@esbuild/darwin-arm64@0.25.3': + optional: true + '@esbuild/darwin-x64@0.18.20': optional: true @@ -4481,6 +4665,9 @@ snapshots: '@esbuild/darwin-x64@0.25.1': optional: true + '@esbuild/darwin-x64@0.25.3': + optional: true + '@esbuild/freebsd-arm64@0.18.20': optional: true @@ -4490,6 +4677,9 @@ snapshots: '@esbuild/freebsd-arm64@0.25.1': optional: true + '@esbuild/freebsd-arm64@0.25.3': + optional: true + '@esbuild/freebsd-x64@0.18.20': optional: true @@ -4499,6 +4689,9 @@ snapshots: '@esbuild/freebsd-x64@0.25.1': optional: true + '@esbuild/freebsd-x64@0.25.3': + optional: true + '@esbuild/linux-arm64@0.18.20': optional: true @@ -4508,6 +4701,9 @@ snapshots: '@esbuild/linux-arm64@0.25.1': optional: true + '@esbuild/linux-arm64@0.25.3': + optional: true + '@esbuild/linux-arm@0.18.20': optional: true @@ -4517,6 +4713,9 @@ snapshots: '@esbuild/linux-arm@0.25.1': optional: true + '@esbuild/linux-arm@0.25.3': + optional: true + '@esbuild/linux-ia32@0.18.20': optional: true @@ -4526,6 +4725,9 @@ snapshots: '@esbuild/linux-ia32@0.25.1': optional: true + '@esbuild/linux-ia32@0.25.3': + optional: true + '@esbuild/linux-loong64@0.18.20': optional: true @@ -4535,6 +4737,9 @@ snapshots: '@esbuild/linux-loong64@0.25.1': optional: true + '@esbuild/linux-loong64@0.25.3': + optional: true + '@esbuild/linux-mips64el@0.18.20': optional: true @@ -4544,6 +4749,9 @@ snapshots: '@esbuild/linux-mips64el@0.25.1': optional: true + '@esbuild/linux-mips64el@0.25.3': + optional: true + '@esbuild/linux-ppc64@0.18.20': optional: true @@ -4553,6 +4761,9 @@ snapshots: '@esbuild/linux-ppc64@0.25.1': optional: true + '@esbuild/linux-ppc64@0.25.3': + optional: true + '@esbuild/linux-riscv64@0.18.20': optional: true @@ -4562,6 +4773,9 @@ snapshots: '@esbuild/linux-riscv64@0.25.1': optional: true + '@esbuild/linux-riscv64@0.25.3': + optional: true + '@esbuild/linux-s390x@0.18.20': optional: true @@ -4571,6 +4785,9 @@ snapshots: '@esbuild/linux-s390x@0.25.1': optional: true + '@esbuild/linux-s390x@0.25.3': + optional: true + '@esbuild/linux-x64@0.18.20': optional: true @@ -4580,9 +4797,15 @@ snapshots: '@esbuild/linux-x64@0.25.1': optional: true + '@esbuild/linux-x64@0.25.3': + optional: true + '@esbuild/netbsd-arm64@0.25.1': optional: true + '@esbuild/netbsd-arm64@0.25.3': + optional: true + '@esbuild/netbsd-x64@0.18.20': optional: true @@ -4592,9 +4815,15 @@ snapshots: '@esbuild/netbsd-x64@0.25.1': optional: true + '@esbuild/netbsd-x64@0.25.3': + optional: true + '@esbuild/openbsd-arm64@0.25.1': optional: true + '@esbuild/openbsd-arm64@0.25.3': + optional: true + '@esbuild/openbsd-x64@0.18.20': optional: true @@ -4604,6 +4833,9 @@ snapshots: '@esbuild/openbsd-x64@0.25.1': optional: true + '@esbuild/openbsd-x64@0.25.3': + optional: true + '@esbuild/sunos-x64@0.18.20': optional: true @@ -4613,6 +4845,9 @@ snapshots: '@esbuild/sunos-x64@0.25.1': optional: true + '@esbuild/sunos-x64@0.25.3': + optional: true + '@esbuild/win32-arm64@0.18.20': optional: true @@ -4622,6 +4857,9 @@ snapshots: '@esbuild/win32-arm64@0.25.1': optional: true + '@esbuild/win32-arm64@0.25.3': + optional: true + '@esbuild/win32-ia32@0.18.20': optional: true @@ -4631,6 +4869,9 @@ snapshots: '@esbuild/win32-ia32@0.25.1': optional: true + '@esbuild/win32-ia32@0.25.3': + optional: true + '@esbuild/win32-x64@0.18.20': optional: true @@ -4640,14 +4881,22 @@ snapshots: '@esbuild/win32-x64@0.25.1': optional: true + '@esbuild/win32-x64@0.25.3': + optional: true + '@eslint-community/eslint-utils@4.5.1(eslint@9.22.0(jiti@2.4.2))': dependencies: eslint: 9.22.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.5.1(eslint@9.24.0(jiti@2.4.2))': + '@eslint-community/eslint-utils@4.6.1(eslint@9.22.0(jiti@2.4.2))': + dependencies: + eslint: 9.22.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.6.1(eslint@9.25.1(jiti@2.4.2))': dependencies: - eslint: 9.24.0(jiti@2.4.2) + eslint: 9.25.1(jiti@2.4.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -4676,6 +4925,10 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 + '@eslint/core@0.13.0': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/eslintrc@3.3.0': dependencies: ajv: 6.12.6 @@ -4706,7 +4959,7 @@ snapshots: '@eslint/js@9.22.0': {} - '@eslint/js@9.24.0': {} + '@eslint/js@9.25.1': {} '@eslint/object-schema@2.1.6': {} @@ -4715,6 +4968,11 @@ snapshots: '@eslint/core': 0.12.0 levn: 0.4.1 + '@eslint/plugin-kit@0.2.8': + dependencies: + '@eslint/core': 0.13.0 + levn: 0.4.1 + '@floating-ui/core@1.6.9': dependencies: '@floating-ui/utils': 0.2.9 @@ -4915,13 +5173,13 @@ snapshots: '@next/swc-win32-x64-msvc@15.2.2': optional: true - '@noble/ciphers@1.2.1': {} + '@noble/ciphers@1.3.0': {} - '@noble/curves@1.8.1': + '@noble/curves@1.9.0': dependencies: - '@noble/hashes': 1.7.1 + '@noble/hashes': 1.8.0 - '@noble/hashes@1.7.1': {} + '@noble/hashes@1.8.0': {} '@nodelib/fs.scandir@2.1.5': dependencies: @@ -5775,15 +6033,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.29.1(@typescript-eslint/parser@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.31.1(@typescript-eslint/parser@8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.29.1 - '@typescript-eslint/type-utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.29.1 - eslint: 9.24.0(jiti@2.4.2) + '@typescript-eslint/parser': 8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.31.1 + '@typescript-eslint/type-utils': 8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.31.1 + eslint: 9.25.1(jiti@2.4.2) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -5804,14 +6062,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/parser@8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.29.1 - '@typescript-eslint/types': 8.29.1 - '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.29.1 + '@typescript-eslint/scope-manager': 8.31.1 + '@typescript-eslint/types': 8.31.1 + '@typescript-eslint/typescript-estree': 8.31.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.31.1 debug: 4.4.0 - eslint: 9.24.0(jiti@2.4.2) + eslint: 9.25.1(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -5821,10 +6079,10 @@ snapshots: '@typescript-eslint/types': 8.26.1 '@typescript-eslint/visitor-keys': 8.26.1 - '@typescript-eslint/scope-manager@8.29.1': + '@typescript-eslint/scope-manager@8.31.1': dependencies: - '@typescript-eslint/types': 8.29.1 - '@typescript-eslint/visitor-keys': 8.29.1 + '@typescript-eslint/types': 8.31.1 + '@typescript-eslint/visitor-keys': 8.31.1 '@typescript-eslint/type-utils@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2)': dependencies: @@ -5837,12 +6095,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.31.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3) debug: 4.4.0 - eslint: 9.24.0(jiti@2.4.2) + eslint: 9.25.1(jiti@2.4.2) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: @@ -5850,7 +6108,7 @@ snapshots: '@typescript-eslint/types@8.26.1': {} - '@typescript-eslint/types@8.29.1': {} + '@typescript-eslint/types@8.31.1': {} '@typescript-eslint/typescript-estree@8.26.1(typescript@5.8.2)': dependencies: @@ -5866,10 +6124,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.29.1(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.31.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.29.1 - '@typescript-eslint/visitor-keys': 8.29.1 + '@typescript-eslint/types': 8.31.1 + '@typescript-eslint/visitor-keys': 8.31.1 debug: 4.4.0 fast-glob: 3.3.3 is-glob: 4.0.3 @@ -5882,7 +6140,7 @@ snapshots: '@typescript-eslint/utils@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.22.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.6.1(eslint@9.22.0(jiti@2.4.2)) '@typescript-eslint/scope-manager': 8.26.1 '@typescript-eslint/types': 8.26.1 '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) @@ -5891,13 +6149,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/utils@8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.29.1 - '@typescript-eslint/types': 8.29.1 - '@typescript-eslint/typescript-estree': 8.29.1(typescript@5.8.3) - eslint: 9.24.0(jiti@2.4.2) + '@eslint-community/eslint-utils': 4.6.1(eslint@9.25.1(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.31.1 + '@typescript-eslint/types': 8.31.1 + '@typescript-eslint/typescript-estree': 8.31.1(typescript@5.8.3) + eslint: 9.25.1(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -5907,9 +6165,9 @@ snapshots: '@typescript-eslint/types': 8.26.1 eslint-visitor-keys: 4.2.0 - '@typescript-eslint/visitor-keys@8.29.1': + '@typescript-eslint/visitor-keys@8.31.1': dependencies: - '@typescript-eslint/types': 8.29.1 + '@typescript-eslint/types': 8.31.1 eslint-visitor-keys: 4.2.0 '@vitest/expect@3.0.9': @@ -5919,13 +6177,13 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.0.9(vite@6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3))': + '@vitest/mocker@3.0.9(vite@6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4))': dependencies: '@vitest/spy': 3.0.9 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3) + vite: 6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4) '@vitest/pretty-format@3.0.9': dependencies: @@ -6305,7 +6563,7 @@ snapshots: dotenv@16.0.3: {} - dotenv@16.4.7: {} + dotenv@16.5.0: {} drizzle-kit@0.30.5: dependencies: @@ -6339,10 +6597,10 @@ snapshots: eciesjs@0.4.14: dependencies: - '@ecies/ciphers': 0.2.3(@noble/ciphers@1.2.1) - '@noble/ciphers': 1.2.1 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 + '@ecies/ciphers': 0.2.3(@noble/ciphers@1.3.0) + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.0 + '@noble/hashes': 1.8.0 ejs@3.1.8: dependencies: @@ -6555,6 +6813,34 @@ snapshots: '@esbuild/win32-ia32': 0.25.1 '@esbuild/win32-x64': 0.25.1 + esbuild@0.25.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.3 + '@esbuild/android-arm': 0.25.3 + '@esbuild/android-arm64': 0.25.3 + '@esbuild/android-x64': 0.25.3 + '@esbuild/darwin-arm64': 0.25.3 + '@esbuild/darwin-x64': 0.25.3 + '@esbuild/freebsd-arm64': 0.25.3 + '@esbuild/freebsd-x64': 0.25.3 + '@esbuild/linux-arm': 0.25.3 + '@esbuild/linux-arm64': 0.25.3 + '@esbuild/linux-ia32': 0.25.3 + '@esbuild/linux-loong64': 0.25.3 + '@esbuild/linux-mips64el': 0.25.3 + '@esbuild/linux-ppc64': 0.25.3 + '@esbuild/linux-riscv64': 0.25.3 + '@esbuild/linux-s390x': 0.25.3 + '@esbuild/linux-x64': 0.25.3 + '@esbuild/netbsd-arm64': 0.25.3 + '@esbuild/netbsd-x64': 0.25.3 + '@esbuild/openbsd-arm64': 0.25.3 + '@esbuild/openbsd-x64': 0.25.3 + '@esbuild/sunos-x64': 0.25.3 + '@esbuild/win32-arm64': 0.25.3 + '@esbuild/win32-ia32': 0.25.3 + '@esbuild/win32-x64': 0.25.3 + escalade@3.2.0: {} escape-string-regexp@1.0.5: {} @@ -6593,11 +6879,11 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.4.4(eslint@9.22.0(jiti@2.4.2))(turbo@2.5.0): + eslint-plugin-turbo@2.4.4(eslint@9.22.0(jiti@2.4.2))(turbo@2.5.2): dependencies: dotenv: 16.0.3 eslint: 9.22.0(jiti@2.4.2) - turbo: 2.5.0 + turbo: 2.5.2 eslint-scope@8.3.0: dependencies: @@ -6650,20 +6936,20 @@ snapshots: transitivePeerDependencies: - supports-color - eslint@9.24.0(jiti@2.4.2): + eslint@9.25.1(jiti@2.4.2): dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.6.1(eslint@9.25.1(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.20.0 '@eslint/config-helpers': 0.2.1 - '@eslint/core': 0.12.0 + '@eslint/core': 0.13.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.24.0 - '@eslint/plugin-kit': 0.2.7 + '@eslint/js': 9.25.1 + '@eslint/plugin-kit': 0.2.8 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.2 - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 @@ -6710,7 +6996,7 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 esutils@2.0.3: {} @@ -6788,7 +7074,7 @@ snapshots: dependencies: reusify: 1.1.0 - fdir@6.4.3(picomatch@4.0.2): + fdir@6.4.4(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 @@ -8098,39 +8384,39 @@ snapshots: tslib@2.8.1: {} - tsx@4.19.3: + tsx@4.19.4: dependencies: - esbuild: 0.25.1 + esbuild: 0.25.3 get-tsconfig: 4.10.0 optionalDependencies: fsevents: 2.3.3 - turbo-darwin-64@2.5.0: + turbo-darwin-64@2.5.2: optional: true - turbo-darwin-arm64@2.5.0: + turbo-darwin-arm64@2.5.2: optional: true - turbo-linux-64@2.5.0: + turbo-linux-64@2.5.2: optional: true - turbo-linux-arm64@2.5.0: + turbo-linux-arm64@2.5.2: optional: true - turbo-windows-64@2.5.0: + turbo-windows-64@2.5.2: optional: true - turbo-windows-arm64@2.5.0: + turbo-windows-arm64@2.5.2: optional: true - turbo@2.5.0: + turbo@2.5.2: optionalDependencies: - turbo-darwin-64: 2.5.0 - turbo-darwin-arm64: 2.5.0 - turbo-linux-64: 2.5.0 - turbo-linux-arm64: 2.5.0 - turbo-windows-64: 2.5.0 - turbo-windows-arm64: 2.5.0 + turbo-darwin-64: 2.5.2 + turbo-darwin-arm64: 2.5.2 + turbo-linux-64: 2.5.2 + turbo-linux-arm64: 2.5.2 + turbo-windows-64: 2.5.2 + turbo-windows-arm64: 2.5.2 type-check@0.4.0: dependencies: @@ -8179,12 +8465,12 @@ snapshots: transitivePeerDependencies: - supports-color - typescript-eslint@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3): + typescript-eslint@8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.29.1(@typescript-eslint/parser@8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.29.1(eslint@9.24.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.24.0(jiti@2.4.2) + '@typescript-eslint/eslint-plugin': 8.31.1(@typescript-eslint/parser@8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.31.1(eslint@9.25.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.25.1(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -8236,13 +8522,13 @@ snapshots: - '@types/react' - '@types/react-dom' - vite-node@3.0.9(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3): + vite-node@3.0.9(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 2.0.3 - vite: 6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3) + vite: 6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4) transitivePeerDependencies: - '@types/node' - jiti @@ -8257,7 +8543,7 @@ snapshots: - tsx - yaml - vite@6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3): + vite@6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4): dependencies: esbuild: 0.25.1 postcss: 8.5.3 @@ -8267,12 +8553,12 @@ snapshots: fsevents: 2.3.3 jiti: 2.4.2 lightningcss: 1.29.2 - tsx: 4.19.3 + tsx: 4.19.4 - vitest@3.0.9(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3): + vitest@3.0.9(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4): dependencies: '@vitest/expect': 3.0.9 - '@vitest/mocker': 3.0.9(vite@6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)) + '@vitest/mocker': 3.0.9(vite@6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4)) '@vitest/pretty-format': 3.0.9 '@vitest/runner': 3.0.9 '@vitest/snapshot': 3.0.9 @@ -8288,8 +8574,8 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3) - vite-node: 3.0.9(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3) + vite: 6.2.3(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4) + vite-node: 3.0.9(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.4) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 20.17.24 diff --git a/package-lock.json b/package-lock.json index 4a2e356f6c6..5e9bd85604e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pearai-roo-cline", - "version": "3.15.1", + "version": "3.15.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pearai-roo-cline", - "version": "3.15.1", + "version": "3.15.2", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", "@anthropic-ai/sdk": "^0.37.0", diff --git a/package.json b/package.json index b8c9d4813a1..d6e38dafd7c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "PearAI's integration of Roo Code / Cline, a coding agent.", "publisher": "PearAI", "icon": "assets/icons/pear.png", - "version": "3.15.1", + "version": "3.15.2", "galleryBanner": { "color": "#617A91", "theme": "dark" diff --git a/src/activate/registerCommands.ts b/src/activate/registerCommands.ts index a2c6cd10bdf..d3a16c8b618 100644 --- a/src/activate/registerCommands.ts +++ b/src/activate/registerCommands.ts @@ -3,6 +3,7 @@ import delay from "delay" import { ClineProvider } from "../core/webview/ClineProvider" import { ContextProxy } from "../core/config/ContextProxy" +import { telemetryService } from "../services/telemetry/TelemetryService" import { registerHumanRelayCallback, unregisterHumanRelayCallback, handleHumanRelayResponse } from "./humanRelay" import { handleNewTask } from "./handleTask" @@ -71,6 +72,8 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt return } + telemetryService.captureTitleButtonClicked("plus") + await visibleProvider.removeClineFromStack() await visibleProvider.postStateToWebview() await visibleProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) @@ -82,6 +85,8 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt return } + telemetryService.captureTitleButtonClicked("mcp") + visibleProvider.postMessageToWebview({ type: "action", action: "mcpButtonClicked" }) }, "roo-cline.promptsButtonClicked": () => { @@ -91,9 +96,15 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt return } + telemetryService.captureTitleButtonClicked("prompts") + visibleProvider.postMessageToWebview({ type: "action", action: "promptsButtonClicked" }) }, - "roo-cline.popoutButtonClicked": () => openClineInNewTab({ context, outputChannel }), + "roo-cline.popoutButtonClicked": () => { + telemetryService.captureTitleButtonClicked("popout") + + return openClineInNewTab({ context, outputChannel }) + }, "roo-cline.openInNewTab": () => openClineInNewTab({ context, outputChannel }), "roo-cline.settingsButtonClicked": () => { const visibleProvider = getVisibleProviderOrLog(outputChannel) @@ -102,6 +113,8 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt return } + telemetryService.captureTitleButtonClicked("settings") + visibleProvider.postMessageToWebview({ type: "action", action: "settingsButtonClicked" }) }, "roo-cline.historyButtonClicked": () => { @@ -111,9 +124,13 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt return } + telemetryService.captureTitleButtonClicked("history") + visibleProvider.postMessageToWebview({ type: "action", action: "historyButtonClicked" }) }, "roo-cline.helpButtonClicked": () => { + telemetryService.captureTitleButtonClicked("help") + vscode.env.openExternal(vscode.Uri.parse("https://docs.roocode.com")) }, "roo-cline.showHumanRelayDialog": (params: { requestId: string; promptText: string }) => { diff --git a/src/api/providers/openai-native.ts b/src/api/providers/openai-native.ts index 37eb924d13b..62782b3d4f9 100644 --- a/src/api/providers/openai-native.ts +++ b/src/api/providers/openai-native.ts @@ -29,7 +29,7 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio super() this.options = options const apiKey = this.options.openAiNativeApiKey ?? "not-provided" - this.client = new OpenAI({ apiKey }) + this.client = new OpenAI({ baseURL: this.options.openAiNativeBaseUrl, apiKey }) } override async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index 10cc5e40cd4..64932b03921 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -35,12 +35,17 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl const urlHost = this._getUrlHost(this.options.openAiBaseUrl) const isAzureOpenAi = urlHost === "azure.com" || urlHost.endsWith(".azure.com") || options.openAiUseAzure + const headers = { + ...DEFAULT_HEADERS, + ...(this.options.openAiHeaders || {}), + } + if (isAzureAiInference) { // Azure AI Inference Service (e.g., for DeepSeek) uses a different path structure this.client = new OpenAI({ baseURL, apiKey, - defaultHeaders: DEFAULT_HEADERS, + defaultHeaders: headers, defaultQuery: { "api-version": this.options.azureApiVersion || "2024-05-01-preview" }, }) } else if (isAzureOpenAi) { @@ -50,19 +55,13 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl baseURL, apiKey, apiVersion: this.options.azureApiVersion || azureOpenAiDefaultApiVersion, - defaultHeaders: { - ...DEFAULT_HEADERS, - ...(this.options.openAiHostHeader ? { Host: this.options.openAiHostHeader } : {}), - }, + defaultHeaders: headers, }) } else { this.client = new OpenAI({ baseURL, apiKey, - defaultHeaders: { - ...DEFAULT_HEADERS, - ...(this.options.openAiHostHeader ? { Host: this.options.openAiHostHeader } : {}), - }, + defaultHeaders: headers, }) } } @@ -361,7 +360,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl } } -export async function getOpenAiModels(baseUrl?: string, apiKey?: string, hostHeader?: string) { +export async function getOpenAiModels(baseUrl?: string, apiKey?: string, openAiHeaders?: Record) { try { if (!baseUrl) { return [] @@ -372,16 +371,15 @@ export async function getOpenAiModels(baseUrl?: string, apiKey?: string, hostHea } const config: Record = {} - const headers: Record = {} + const headers: Record = { + ...DEFAULT_HEADERS, + ...(openAiHeaders || {}), + } if (apiKey) { headers["Authorization"] = `Bearer ${apiKey}` } - if (hostHeader) { - headers["Host"] = hostHeader - } - if (Object.keys(headers).length > 0) { config["headers"] = headers } diff --git a/src/core/config/ContextProxy.ts b/src/core/config/ContextProxy.ts index 6b017503d5e..c2373ccad20 100644 --- a/src/core/config/ContextProxy.ts +++ b/src/core/config/ContextProxy.ts @@ -192,6 +192,16 @@ export class ContextProxy { // If a value is not present in the new configuration, then it is assumed // that the setting's value should be `undefined` and therefore we // need to remove it from the state cache if it exists. + + // Ensure openAiHeaders is always an object even when empty + // This is critical for proper serialization/deserialization through IPC + if (values.openAiHeaders !== undefined) { + // Check if it's empty or null + if (!values.openAiHeaders || Object.keys(values.openAiHeaders).length === 0) { + values.openAiHeaders = {} + } + } + await this.setValues({ ...PROVIDER_SETTINGS_KEYS.filter((key) => !isSecretStateKey(key)) .filter((key) => !!this.stateCache[key]) diff --git a/src/core/config/ProviderSettingsManager.ts b/src/core/config/ProviderSettingsManager.ts index 7df34e7844a..ca53cba8892 100644 --- a/src/core/config/ProviderSettingsManager.ts +++ b/src/core/config/ProviderSettingsManager.ts @@ -17,6 +17,7 @@ export const providerProfilesSchema = z.object({ .object({ rateLimitSecondsMigrated: z.boolean().optional(), diffSettingsMigrated: z.boolean().optional(), + openAiHeadersMigrated: z.boolean().optional(), }) .optional(), }) @@ -38,6 +39,7 @@ export class ProviderSettingsManager { migrations: { rateLimitSecondsMigrated: true, // Mark as migrated on fresh installs diffSettingsMigrated: true, // Mark as migrated on fresh installs + openAiHeadersMigrated: true, // Mark as migrated on fresh installs }, } @@ -90,6 +92,7 @@ export class ProviderSettingsManager { providerProfiles.migrations = { rateLimitSecondsMigrated: false, diffSettingsMigrated: false, + openAiHeadersMigrated: false, } // Initialize with default values isDirty = true } @@ -106,6 +109,12 @@ export class ProviderSettingsManager { isDirty = true } + if (!providerProfiles.migrations.openAiHeadersMigrated) { + await this.migrateOpenAiHeaders(providerProfiles) + providerProfiles.migrations.openAiHeadersMigrated = true + isDirty = true + } + if (isDirty) { await this.store(providerProfiles) } @@ -175,6 +184,30 @@ export class ProviderSettingsManager { } } + private async migrateOpenAiHeaders(providerProfiles: ProviderProfiles) { + try { + for (const [_name, apiConfig] of Object.entries(providerProfiles.apiConfigs)) { + // Use type assertion to access the deprecated property safely + const configAny = apiConfig as any + + // Check if openAiHostHeader exists but openAiHeaders doesn't + if ( + configAny.openAiHostHeader && + (!apiConfig.openAiHeaders || Object.keys(apiConfig.openAiHeaders || {}).length === 0) + ) { + // Create the headers object with the Host value + apiConfig.openAiHeaders = { Host: configAny.openAiHostHeader } + + // Delete the old property to prevent re-migration + // This prevents the header from reappearing after deletion + configAny.openAiHostHeader = undefined + } + } + } catch (error) { + console.error(`[MigrateOpenAiHeaders] Failed to migrate OpenAI headers:`, error) + } + } + /** * List all available configs with metadata. */ diff --git a/src/core/config/__tests__/ProviderSettingsManager.test.ts b/src/core/config/__tests__/ProviderSettingsManager.test.ts index ade40c29d38..3cacc4c8b72 100644 --- a/src/core/config/__tests__/ProviderSettingsManager.test.ts +++ b/src/core/config/__tests__/ProviderSettingsManager.test.ts @@ -56,6 +56,7 @@ describe("ProviderSettingsManager", () => { migrations: { rateLimitSecondsMigrated: true, diffSettingsMigrated: true, + openAiHeadersMigrated: true, }, }), ) diff --git a/src/core/tools/executeCommandTool.ts b/src/core/tools/executeCommandTool.ts index 579627997c9..7db12668c86 100644 --- a/src/core/tools/executeCommandTool.ts +++ b/src/core/tools/executeCommandTool.ts @@ -152,15 +152,15 @@ export async function executeCommand( const callbacks: RooTerminalCallbacks = { onLine: async (output: string, process: RooTerminalProcess) => { - const compressed = Terminal.compressTerminalOutput(output, terminalOutputLineLimit) - cline.say("command_output", compressed) + const status: CommandExecutionStatus = { executionId, status: "output", output } + clineProvider?.postMessageToWebview({ type: "commandExecutionStatus", text: JSON.stringify(status) }) if (runInBackground) { return } try { - const { response, text, images } = await cline.ask("command_output", compressed) + const { response, text, images } = await cline.ask("command_output", "") runInBackground = true if (response === "messageResponse") { @@ -171,10 +171,11 @@ export async function executeCommand( }, onCompleted: (output: string | undefined) => { result = Terminal.compressTerminalOutput(output ?? "", terminalOutputLineLimit) + cline.say("command_output", result) completed = true }, onShellExecutionStarted: (pid: number | undefined) => { - const status: CommandExecutionStatus = { executionId, status: "running", pid } + const status: CommandExecutionStatus = { executionId, status: "started", pid, command } clineProvider?.postMessageToWebview({ type: "commandExecutionStatus", text: JSON.stringify(status) }) }, onShellExecutionComplete: (details: ExitCodeDetails) => { diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index 8a7b6129109..ae14b5e1b53 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -310,7 +310,7 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We const openAiModels = await getOpenAiModels( message?.values?.baseUrl, message?.values?.apiKey, - message?.values?.hostHeader, + message?.values?.openAiHeaders, ) provider.postMessageToWebview({ type: "openAiModels", openAiModels }) diff --git a/src/exports/roo-code.d.ts b/src/exports/roo-code.d.ts index 4e15fc5d148..4eef2426dab 100644 --- a/src/exports/roo-code.d.ts +++ b/src/exports/roo-code.d.ts @@ -51,7 +51,6 @@ type ProviderSettings = { vertexRegion?: string | undefined openAiBaseUrl?: string | undefined openAiApiKey?: string | undefined - openAiHostHeader?: string | undefined openAiLegacyFormat?: boolean | undefined openAiR1FormatEnabled?: boolean | undefined openAiModelId?: string | undefined @@ -90,6 +89,12 @@ type ProviderSettings = { azureApiVersion?: string | undefined openAiStreamingEnabled?: boolean | undefined enableReasoningEffort?: boolean | undefined + openAiHostHeader?: string | undefined + openAiHeaders?: + | { + [x: string]: string + } + | undefined ollamaModelId?: string | undefined ollamaBaseUrl?: string | undefined vsCodeLmModelSelector?: @@ -107,6 +112,7 @@ type ProviderSettings = { geminiApiKey?: string | undefined googleGeminiBaseUrl?: string | undefined openAiNativeApiKey?: string | undefined + openAiNativeBaseUrl?: string | undefined mistralApiKey?: string | undefined mistralCodestralUrl?: string | undefined deepSeekBaseUrl?: string | undefined diff --git a/src/exports/types.ts b/src/exports/types.ts index 8ad3960dd33..0b557dd0baf 100644 --- a/src/exports/types.ts +++ b/src/exports/types.ts @@ -52,7 +52,6 @@ type ProviderSettings = { vertexRegion?: string | undefined openAiBaseUrl?: string | undefined openAiApiKey?: string | undefined - openAiHostHeader?: string | undefined openAiLegacyFormat?: boolean | undefined openAiR1FormatEnabled?: boolean | undefined openAiModelId?: string | undefined @@ -91,6 +90,12 @@ type ProviderSettings = { azureApiVersion?: string | undefined openAiStreamingEnabled?: boolean | undefined enableReasoningEffort?: boolean | undefined + openAiHostHeader?: string | undefined + openAiHeaders?: + | { + [x: string]: string + } + | undefined ollamaModelId?: string | undefined ollamaBaseUrl?: string | undefined vsCodeLmModelSelector?: @@ -108,6 +113,7 @@ type ProviderSettings = { geminiApiKey?: string | undefined googleGeminiBaseUrl?: string | undefined openAiNativeApiKey?: string | undefined + openAiNativeBaseUrl?: string | undefined mistralApiKey?: string | undefined mistralCodestralUrl?: string | undefined deepSeekBaseUrl?: string | undefined diff --git a/src/integrations/terminal/ExecaTerminalProcess.ts b/src/integrations/terminal/ExecaTerminalProcess.ts index 1f41fa082db..63b772e5db0 100644 --- a/src/integrations/terminal/ExecaTerminalProcess.ts +++ b/src/integrations/terminal/ExecaTerminalProcess.ts @@ -6,6 +6,7 @@ import { BaseTerminalProcess } from "./BaseTerminalProcess" export class ExecaTerminalProcess extends BaseTerminalProcess { private terminalRef: WeakRef private controller?: AbortController + private aborted = false constructor(terminal: RooTerminal) { super() @@ -45,11 +46,15 @@ export class ExecaTerminalProcess extends BaseTerminalProcess { this.terminal.setActiveStream(stream, subprocess.pid) for await (const line of stream) { + if (this.aborted) { + break + } + this.fullOutput += line const now = Date.now() - if (this.isListening && (now - this.lastEmitTime_ms > 250 || this.lastEmitTime_ms === 0)) { + if (this.isListening && (now - this.lastEmitTime_ms > 500 || this.lastEmitTime_ms === 0)) { this.emitRemainingBufferIfListening() this.lastEmitTime_ms = now } @@ -57,6 +62,32 @@ export class ExecaTerminalProcess extends BaseTerminalProcess { this.startHotTimer(line) } + if (this.aborted) { + let timeoutId: NodeJS.Timeout | undefined + + const kill = new Promise((resolve) => { + timeoutId = setTimeout(() => { + try { + subprocess.kill("SIGKILL") + } catch (e) {} + + resolve() + }, 5_000) + }) + + try { + await Promise.race([subprocess, kill]) + } catch (error) { + console.log( + `[ExecaTerminalProcess] subprocess termination error: ${error instanceof Error ? error.message : String(error)}`, + ) + } + + if (timeoutId) { + clearTimeout(timeoutId) + } + } + this.emit("shell_execution_complete", { exitCode: 0 }) } catch (error) { if (error instanceof ExecaError) { @@ -84,6 +115,7 @@ export class ExecaTerminalProcess extends BaseTerminalProcess { } public override abort() { + this.aborted = true this.controller?.abort() } diff --git a/src/schemas/index.ts b/src/schemas/index.ts index 7b1ba1f1f5a..db61b52a2e2 100644 --- a/src/schemas/index.ts +++ b/src/schemas/index.ts @@ -295,8 +295,14 @@ export type CustomSupportPrompts = z.infer export const commandExecutionStatusSchema = z.discriminatedUnion("status", [ z.object({ executionId: z.string(), - status: z.literal("running"), + status: z.literal("started"), pid: z.number().optional(), + command: z.string(), + }), + z.object({ + executionId: z.string(), + status: z.literal("output"), + output: z.string(), }), z.object({ executionId: z.string(), @@ -372,7 +378,6 @@ export const providerSettingsSchema = z.object({ // OpenAI openAiBaseUrl: z.string().optional(), openAiApiKey: z.string().optional(), - openAiHostHeader: z.string().optional(), openAiLegacyFormat: z.boolean().optional(), openAiR1FormatEnabled: z.boolean().optional(), openAiModelId: z.string().optional(), @@ -381,6 +386,8 @@ export const providerSettingsSchema = z.object({ azureApiVersion: z.string().optional(), openAiStreamingEnabled: z.boolean().optional(), enableReasoningEffort: z.boolean().optional(), + openAiHostHeader: z.string().optional(), // Keep temporarily for backward compatibility during migration + openAiHeaders: z.record(z.string(), z.string()).optional(), // Ollama ollamaModelId: z.string().optional(), ollamaBaseUrl: z.string().optional(), @@ -403,6 +410,7 @@ export const providerSettingsSchema = z.object({ googleGeminiBaseUrl: z.string().optional(), // OpenAI Native openAiNativeApiKey: z.string().optional(), + openAiNativeBaseUrl: z.string().optional(), // Mistral mistralApiKey: z.string().optional(), mistralCodestralUrl: z.string().optional(), @@ -482,7 +490,6 @@ const providerSettingsRecord: ProviderSettingsRecord = { // OpenAI openAiBaseUrl: undefined, openAiApiKey: undefined, - openAiHostHeader: undefined, openAiLegacyFormat: undefined, openAiR1FormatEnabled: undefined, openAiModelId: undefined, @@ -491,6 +498,8 @@ const providerSettingsRecord: ProviderSettingsRecord = { azureApiVersion: undefined, openAiStreamingEnabled: undefined, enableReasoningEffort: undefined, + openAiHostHeader: undefined, // Keep temporarily for backward compatibility during migration + openAiHeaders: undefined, // Ollama ollamaModelId: undefined, ollamaBaseUrl: undefined, @@ -505,6 +514,7 @@ const providerSettingsRecord: ProviderSettingsRecord = { googleGeminiBaseUrl: undefined, // OpenAI Native openAiNativeApiKey: undefined, + openAiNativeBaseUrl: undefined, // Mistral mistralApiKey: undefined, mistralCodestralUrl: undefined, @@ -870,6 +880,10 @@ export const tokenUsageSchema = z.object({ export type TokenUsage = z.infer +/** + * ToolName + */ + export const toolNames = [ "execute_command", "read_file", diff --git a/src/services/telemetry/TelemetryService.ts b/src/services/telemetry/TelemetryService.ts index 031456f62e4..37423542b09 100644 --- a/src/services/telemetry/TelemetryService.ts +++ b/src/services/telemetry/TelemetryService.ts @@ -145,6 +145,14 @@ class TelemetryService { this.captureEvent(PostHogClient.EVENTS.ERRORS.CONSECUTIVE_MISTAKE_ERROR, { taskId }) } + /** + * Captures a title button click event + * @param button The button that was clicked + */ + public captureTitleButtonClicked(button: string): void { + this.captureEvent("Title Button Clicked", { button }) + } + /** * Checks if telemetry is currently enabled * @returns Whether telemetry is enabled diff --git a/src/shared/combineCommandSequences.ts b/src/shared/combineCommandSequences.ts index 4e1d2d7bb4a..dd171a77ece 100644 --- a/src/shared/combineCommandSequences.ts +++ b/src/shared/combineCommandSequences.ts @@ -77,35 +77,3 @@ export function combineCommandSequences(messages: ClineMessage[]): ClineMessage[ return msg }) } - -export const splitCommandOutput = (text: string) => { - const outputIndex = text.indexOf(COMMAND_OUTPUT_STRING) - - if (outputIndex === -1) { - return { command: text, output: "" } - } - - return { - command: text.slice(0, outputIndex).trim(), - - output: text - .slice(outputIndex + COMMAND_OUTPUT_STRING.length) - .trim() - .split("") - .map((char) => { - switch (char) { - case "\t": - return "→ " - case "\b": - return "⌫" - case "\f": - return "⏏" - case "\v": - return "⇳" - default: - return char - } - }) - .join(""), - } -} diff --git a/src/shared/modes.ts b/src/shared/modes.ts index 600ef82b731..6c1c3ce124d 100644 --- a/src/shared/modes.ts +++ b/src/shared/modes.ts @@ -91,13 +91,7 @@ export const modes: readonly ModeConfig[] = [ name: "🪃 Orchestrator", roleDefinition: "You are Roo, a strategic workflow orchestrator who coordinates complex tasks by delegating them to appropriate specialized modes. You have a comprehensive understanding of each mode's capabilities and limitations, allowing you to effectively break down complex problems into discrete tasks that can be solved by different specialists.", - groups: [ - "read", - ["edit", { fileRegex: "\\.roomodes$|custom_modes\\.json$", description: "Mode configuration files only" }], - "browser", - "command", - "mcp", - ], + groups: [], customInstructions: "Your role is to coordinate complex workflows by delegating tasks to specialized modes. As an orchestrator, you should:\n\n1. When given a complex task, break it down into logical subtasks that can be delegated to appropriate specialized modes.\n\n2. For each subtask, use the `new_task` tool to delegate. Choose the most appropriate mode for the subtask's specific goal and provide comprehensive instructions in the `message` parameter. These instructions must include:\n * All necessary context from the parent task or previous subtasks required to complete the work.\n * A clearly defined scope, specifying exactly what the subtask should accomplish.\n * An explicit statement that the subtask should *only* perform the work outlined in these instructions and not deviate.\n * An instruction for the subtask to signal completion by using the `attempt_completion` tool, providing a concise yet thorough summary of the outcome in the `result` parameter, keeping in mind that this summary will be the source of truth used to keep track of what was completed on this project.\n * A statement that these specific instructions supersede any conflicting general instructions the subtask's mode might have.\n\n3. Track and manage the progress of all subtasks. When a subtask is completed, analyze its results and determine the next steps.\n\n4. Help the user understand how the different subtasks fit together in the overall workflow. Provide clear reasoning about why you're delegating specific tasks to specific modes.\n\n5. When all subtasks are completed, synthesize the results and provide a comprehensive overview of what was accomplished.\n\n6. Ask clarifying questions when necessary to better understand how to break down complex tasks effectively.\n\n7. Suggest improvements to the workflow based on the results of completed subtasks.\n\nUse subtasks to maintain clarity. If a request significantly shifts focus or requires a different expertise (mode), consider creating a subtask rather than overloading the current one.", }, diff --git a/src/utils/__tests__/tiktoken.test.ts b/src/utils/__tests__/tiktoken.test.ts index 2e0485d4e60..dc9b7c80b82 100644 --- a/src/utils/__tests__/tiktoken.test.ts +++ b/src/utils/__tests__/tiktoken.test.ts @@ -119,24 +119,10 @@ describe("tiktoken", () => { const content: Anthropic.Messages.ContentBlockParam[] = [{ type: "text", text: "Hello world" }] - // Time the first call which should create the encoder - const startTime1 = performance.now() const result1 = await tiktoken(content) - const endTime1 = performance.now() - const duration1 = endTime1 - startTime1 - - // Time the second call which should reuse the encoder - const startTime2 = performance.now() const result2 = await tiktoken(content) - const endTime2 = performance.now() - const duration2 = endTime2 - startTime2 // Both calls should return the same token count expect(result1).toBe(result2) - - // This is a loose test and might occasionally fail due to system load, - // but generally the second call should be faster or similar in speed - // since it reuses the encoder - expect(duration2).toBeLessThanOrEqual(duration1 * 1.5) }) }) diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index 1ab55b9dbfc..2d2b2961938 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -5,7 +5,7 @@ import deepEqual from "fast-deep-equal" import { VSCodeBadge, VSCodeButton } from "@vscode/webview-ui-toolkit/react" import { ClineApiReqInfo, ClineAskUseMcpServer, ClineMessage, ClineSayTool } from "@roo/shared/ExtensionMessage" -import { splitCommandOutput, COMMAND_OUTPUT_STRING } from "@roo/shared/combineCommandSequences" +import { COMMAND_OUTPUT_STRING } from "@roo/shared/combineCommandSequences" import { safeJsonParse } from "@roo/shared/safeJsonParse" import { useCopyToClipboard } from "@src/utils/clipboard" @@ -980,19 +980,13 @@ export const ChatRowContent = ({ ) case "command": - const { command, output } = splitCommandOutput(message.text || "") - return ( <>
{icon} {title}
- + ) case "use_mcp_server": diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index c580ef92c4e..756579994bf 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -956,9 +956,7 @@ const ChatTextArea = forwardRef( "bg-transparent", "transition-background-color duration-150 ease-in-out", "will-change-background-color", - "h-[100px]", - "[@media(min-width:150px)]:min-h-[80px]", - "[@media(min-width:425px)]:min-h-[60px]", + "min-h-[90px]", "box-border", "rounded", "resize-none", diff --git a/webview-ui/src/components/chat/CommandExecution.tsx b/webview-ui/src/components/chat/CommandExecution.tsx index 7e2acdb492a..2a5600d06ba 100644 --- a/webview-ui/src/components/chat/CommandExecution.tsx +++ b/webview-ui/src/components/chat/CommandExecution.tsx @@ -1,4 +1,4 @@ -import { HTMLAttributes, forwardRef, useCallback, useMemo, useState } from "react" +import { HTMLAttributes, useCallback, useEffect, useMemo, useState } from "react" import { useEvent } from "react-use" import { Virtuoso } from "react-virtuoso" import { ChevronDown, Skull } from "lucide-react" @@ -6,6 +6,7 @@ import { ChevronDown, Skull } from "lucide-react" import { CommandExecutionStatus, commandExecutionStatusSchema } from "@roo/schemas" import { ExtensionMessage } from "@roo/shared/ExtensionMessage" import { safeJsonParse } from "@roo/shared/safeJsonParse" +import { COMMAND_OUTPUT_STRING } from "@roo/shared/combineCommandSequences" import { vscode } from "@src/utils/vscode" import { useExtensionState } from "@src/context/ExtensionStateContext" @@ -14,112 +15,134 @@ import { Button } from "@src/components/ui" interface CommandExecutionProps { executionId?: string - command: string - output: string + text?: string } -export const CommandExecution = forwardRef( - ({ executionId, command, output }, ref) => { - const { terminalShellIntegrationDisabled = false } = useExtensionState() +export const CommandExecution = ({ executionId, text }: CommandExecutionProps) => { + const { terminalShellIntegrationDisabled = false } = useExtensionState() - // If we aren't opening the VSCode terminal for this command then we default - // to expanding the command execution output. - const [isExpanded, setIsExpanded] = useState(terminalShellIntegrationDisabled) + // If we aren't opening the VSCode terminal for this command then we default + // to expanding the command execution output. + const [isExpanded, setIsExpanded] = useState(terminalShellIntegrationDisabled) - const [status, setStatus] = useState(null) + const [status, setStatus] = useState(null) + const [output, setOutput] = useState("") + const [command, setCommand] = useState("") - const lines = useMemo( - () => [`$ ${command}`, ...output.split("\n").filter((line) => line.trim() !== "")], - [command, output], - ) + const lines = useMemo( + () => [`$ ${command}`, ...output.split("\n").filter((line) => line.trim() !== "")], + [output, command], + ) - const onMessage = useCallback( - (event: MessageEvent) => { - if (!executionId) { - return - } + const onMessage = useCallback( + (event: MessageEvent) => { + if (!executionId) { + return + } - const message: ExtensionMessage = event.data + const message: ExtensionMessage = event.data - if (message.type === "commandExecutionStatus") { - const result = commandExecutionStatusSchema.safeParse(safeJsonParse(message.text, {})) + if (message.type === "commandExecutionStatus") { + const result = commandExecutionStatusSchema.safeParse(safeJsonParse(message.text, {})) - if (result.success) { - if (result.data.executionId !== executionId) { - return - } + if (result.success) { + const data = result.data + + if (data.executionId !== executionId) { + return + } - if (result.data.status === "fallback") { + switch (data.status) { + case "started": + setCommand(data.command) + setStatus(data) + break + case "output": + setOutput((output) => output + data.output) + break + case "fallback": setIsExpanded(true) - } else { - setStatus(result.data) - } + break + default: + setStatus(data) + break } } - }, - [executionId], - ) - - useEvent("message", onMessage) - - return ( -
-
- {command} -
- {status?.status === "running" && ( -
-
-
Running
- {status.pid &&
(PID: {status.pid})
} - -
- )} - {status?.status === "exited" && ( -
-
-
Exited ({status.exitCode})
-
- )} - {lines.length > 0 && ( - - )} -
-
-
+
+ )} + {status?.status === "exited" && ( +
+
+
Exited ({status.exitCode})
+
+ )} {lines.length > 0 && ( - {lines[i]}} - followOutput="auto" - /> + )}
- ) - }, -) +
+ {lines.length > 0 && ( + {lines[i]}} + followOutput="auto" + /> + )} +
+
+ ) +} type LineProps = HTMLAttributes diff --git a/webview-ui/src/components/common/MarkdownBlock.tsx b/webview-ui/src/components/common/MarkdownBlock.tsx index ba8eab1eb8e..be7d5459802 100644 --- a/webview-ui/src/components/common/MarkdownBlock.tsx +++ b/webview-ui/src/components/common/MarkdownBlock.tsx @@ -57,11 +57,10 @@ const remarkUrlToLink = () => { const StyledMarkdown = styled.div` code:not(pre > code) { font-family: var(--vscode-editor-font-family, monospace); - color: var(--vscode-textPreformat-foreground, #f78383); - background-color: var(--vscode-textCodeBlock-background, #1e1e1e); + filter: saturation(110%) brightness(95%); + color: var(--vscode-textPreformat-foreground) !important; + background-color: var(--vscode-textPreformat-background) !important; padding: 0px 2px; - border-radius: 3px; - border: 1px solid var(--vscode-textSeparator-foreground, #424242); white-space: pre-line; word-break: break-word; overflow-wrap: anywhere; diff --git a/webview-ui/src/components/common/MermaidBlock.tsx b/webview-ui/src/components/common/MermaidBlock.tsx index 59132e42390..d44d51b5f9c 100644 --- a/webview-ui/src/components/common/MermaidBlock.tsx +++ b/webview-ui/src/components/common/MermaidBlock.tsx @@ -3,6 +3,9 @@ import mermaid from "mermaid" import { useDebounceEffect } from "@src/utils/useDebounceEffect" import styled from "styled-components" import { vscode } from "@src/utils/vscode" +import { useAppTranslation } from "@src/i18n/TranslationContext" +import { useCopyToClipboard } from "@src/utils/clipboard" +import CodeBlock from "./CodeBlock" const MERMAID_THEME = { background: "#1e1e1e", // VS Code dark theme background @@ -81,10 +84,15 @@ interface MermaidBlockProps { export default function MermaidBlock({ code }: MermaidBlockProps) { const containerRef = useRef(null) const [isLoading, setIsLoading] = useState(false) + const [error, setError] = useState(null) + const [isErrorExpanded, setIsErrorExpanded] = useState(false) + const { showCopyFeedback, copyWithFeedback } = useCopyToClipboard() + const { t } = useAppTranslation() // 1) Whenever `code` changes, mark that we need to re-render a new chart useEffect(() => { setIsLoading(true) + setError(null) }, [code]) // 2) Debounce the actual parse/render @@ -93,12 +101,10 @@ export default function MermaidBlock({ code }: MermaidBlockProps) { if (containerRef.current) { containerRef.current.innerHTML = "" } + mermaid - .parse(code, { suppressErrors: true }) - .then((isValid) => { - if (!isValid) { - throw new Error("Invalid or incomplete Mermaid code") - } + .parse(code) + .then(() => { const id = `mermaid-${Math.random().toString(36).substring(2)}` return mermaid.render(id, code) }) @@ -109,7 +115,7 @@ export default function MermaidBlock({ code }: MermaidBlockProps) { }) .catch((err) => { console.warn("Mermaid parse/render failed:", err) - containerRef.current!.innerHTML = code.replace(//g, ">") + setError(err.message || "Failed to render Mermaid diagram") }) .finally(() => { setIsLoading(false) @@ -139,12 +145,72 @@ export default function MermaidBlock({ code }: MermaidBlockProps) { } } + // Copy functionality handled directly through the copyWithFeedback utility + return ( - {isLoading && Generating mermaid diagram...} - - {/* The container for the final or raw code. */} - + {isLoading && {t("common:mermaid.loading")}} + + {error ? ( +
+
setIsErrorExpanded(!isErrorExpanded)}> +
+ + {t("common:mermaid.render_error")} +
+
+ { + e.stopPropagation() + const combinedContent = `Error: ${error}\n\n\`\`\`mermaid\n${code}\n\`\`\`` + copyWithFeedback(combinedContent, e) + }}> + + + +
+
+ {isErrorExpanded && ( +
+
+ {error} +
+ +
+ )} +
+ ) : ( + + )}
) } @@ -212,6 +278,23 @@ const LoadingMessage = styled.div` font-size: 0.9em; ` +const CopyButton = styled.button` + padding: 3px; + height: 24px; + margin-right: 4px; + color: var(--vscode-editor-foreground); + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: none; + cursor: pointer; + + &:hover { + opacity: 0.8; + } +` + interface SvgContainerProps { $isLoading: boolean } diff --git a/webview-ui/src/components/prompts/PromptsView.tsx b/webview-ui/src/components/prompts/PromptsView.tsx index 9eecb1e6ed3..4c84416a2c2 100644 --- a/webview-ui/src/components/prompts/PromptsView.tsx +++ b/webview-ui/src/components/prompts/PromptsView.tsx @@ -696,6 +696,12 @@ const PromptsView = ({ onDone }: PromptsViewProps) => { {(() => { const currentMode = getCurrentMode() const enabledGroups = currentMode?.groups || [] + + // If there are no enabled groups, display translated "None" + if (enabledGroups.length === 0) { + return t("prompts:tools.noTools") + } + return enabledGroups .map((group) => { const groupName = getGroupName(group) diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 1feb1ebe910..2cdd577ac76 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -78,14 +78,92 @@ const ApiOptions = ({ const [openAiModels, setOpenAiModels] = useState | null>(null) const pearaiModels = usePearAIModels(apiConfiguration).models + const [customHeaders, setCustomHeaders] = useState<[string, string][]>(() => { + const headers = apiConfiguration?.openAiHeaders || {} + return Object.entries(headers) + }) + + // Effect to synchronize internal customHeaders state with prop changes + useEffect(() => { + const propHeaders = apiConfiguration?.openAiHeaders || {} + if (JSON.stringify(customHeaders) !== JSON.stringify(Object.entries(propHeaders))) setCustomHeaders(Object.entries(propHeaders)) + }, [apiConfiguration?.openAiHeaders]) + const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl) + const [openAiNativeBaseUrlSelected, setOpenAiNativeBaseUrlSelected] = useState( + !!apiConfiguration?.openAiNativeBaseUrl, + ) const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion) const [openRouterBaseUrlSelected, setOpenRouterBaseUrlSelected] = useState(!!apiConfiguration?.openRouterBaseUrl) - const [openAiHostHeaderSelected, setOpenAiHostHeaderSelected] = useState(!!apiConfiguration?.openAiHostHeader) const [openAiLegacyFormatSelected, setOpenAiLegacyFormatSelected] = useState(!!apiConfiguration?.openAiLegacyFormat) const [googleGeminiBaseUrlSelected, setGoogleGeminiBaseUrlSelected] = useState( !!apiConfiguration?.googleGeminiBaseUrl, ) + + const handleAddCustomHeader = useCallback(() => { + // Only update the local state to show the new row in the UI + setCustomHeaders((prev) => [...prev, ["", ""]]) + // Do not update the main configuration yet, wait for user input + }, []) + + const handleUpdateHeaderKey = useCallback((index: number, newKey: string) => { + setCustomHeaders((prev) => { + const updated = [...prev] + if (updated[index]) { + updated[index] = [newKey, updated[index][1]] + } + return updated + }) + }, []) + + const handleUpdateHeaderValue = useCallback((index: number, newValue: string) => { + setCustomHeaders((prev) => { + const updated = [...prev] + if (updated[index]) { + updated[index] = [updated[index][0], newValue] + } + return updated + }) + }, []) + + const handleRemoveCustomHeader = useCallback((index: number) => { + setCustomHeaders((prev) => prev.filter((_, i) => i !== index)) + }, []) + + // Helper to convert array of tuples to object (filtering out empty keys) + const convertHeadersToObject = (headers: [string, string][]): Record => { + const result: Record = {} + + // Process each header tuple + for (const [key, value] of headers) { + const trimmedKey = key.trim() + + // Skip empty keys + if (!trimmedKey) continue + + // For duplicates, the last one in the array wins + // This matches how HTTP headers work in general + result[trimmedKey] = value.trim() + } + + return result + } + + // Debounced effect to update the main configuration when local customHeaders state stabilizes + useDebounce( + () => { + const currentConfigHeaders = apiConfiguration?.openAiHeaders || {} + const newHeadersObject = convertHeadersToObject(customHeaders) + + // Only update if the processed object is different from the current config + if (JSON.stringify(currentConfigHeaders) !== JSON.stringify(newHeadersObject)) { + setApiConfigurationField("openAiHeaders", newHeadersObject) + } + }, + 300, + [customHeaders, apiConfiguration?.openAiHeaders, setApiConfigurationField], + ) + const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false) const noTransform = (value: T) => value @@ -122,12 +200,15 @@ const ApiOptions = ({ useDebounce( () => { if (selectedProvider === "openai") { + // Use our custom headers state to build the headers object + const headerObject = convertHeadersToObject(customHeaders) vscode.postMessage({ type: "requestOpenAiModels", values: { baseUrl: apiConfiguration?.openAiBaseUrl, apiKey: apiConfiguration?.openAiApiKey, - hostHeader: apiConfiguration?.openAiHostHeader, + customHeaders: {}, // Reserved for any additional headers + openAiHeaders: headerObject, }, }) } else if (selectedProvider === "ollama") { @@ -146,6 +227,7 @@ const ApiOptions = ({ apiConfiguration?.openAiApiKey, apiConfiguration?.ollamaBaseUrl, apiConfiguration?.lmStudioBaseUrl, + customHeaders, ], ) @@ -531,6 +613,28 @@ const ApiOptions = ({ {selectedProvider === "openai-native" && ( <> + { + setOpenAiNativeBaseUrlSelected(checked) + + if (!checked) { + setApiConfigurationField("openAiNativeBaseUrl", "") + } + }}> + {t("settings:providers.useCustomBaseUrl")} + + {openAiNativeBaseUrlSelected && ( + <> + + + )} -
- { - setOpenAiHostHeaderSelected(checked) - - if (!checked) { - setApiConfigurationField("openAiHostHeader", "") - } - }}> - {t("settings:providers.useHostHeader")} - - {openAiHostHeaderSelected && ( - + {/* Custom Headers UI */} +
+
+ + + + +
+ {!customHeaders.length ? ( +
+ {t("settings:providers.noCustomHeaders")} +
+ ) : ( + customHeaders.map(([key, value], index) => ( +
+ handleUpdateHeaderKey(index, e.target.value)} + /> + handleUpdateHeaderValue(index, e.target.value)} + /> + handleRemoveCustomHeader(index)}> + + +
+ )) )}
diff --git a/webview-ui/src/i18n/locales/ca/common.json b/webview-ui/src/i18n/locales/ca/common.json index c6a797f7c6b..8e95450cc46 100644 --- a/webview-ui/src/i18n/locales/ca/common.json +++ b/webview-ui/src/i18n/locales/ca/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Cerca..." + }, + "mermaid": { + "loading": "Generant diagrama mermaid...", + "render_error": "No es pot renderitzar el diagrama" } } diff --git a/webview-ui/src/i18n/locales/ca/prompts.json b/webview-ui/src/i18n/locales/ca/prompts.json index 0acb8d5d067..d37e8629425 100644 --- a/webview-ui/src/i18n/locales/ca/prompts.json +++ b/webview-ui/src/i18n/locales/ca/prompts.json @@ -25,7 +25,8 @@ "browser": "Utilitzar navegador", "command": "Executar comandes", "mcp": "Utilitzar MCP" - } + }, + "noTools": "Cap" }, "roleDefinition": { "title": "Definició de rol", diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index 77919271134..aa1c5178327 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -4,7 +4,9 @@ "done": "Fet", "cancel": "Cancel·lar", "reset": "Restablir", - "select": "Seleccionar" + "select": "Seleccionar", + "add": "Afegir capçalera", + "remove": "Eliminar" }, "header": { "title": "Configuració", @@ -107,6 +109,10 @@ "useCustomBaseUrl": "Utilitzar URL base personalitzada", "useHostHeader": "Utilitzar capçalera Host personalitzada", "useLegacyFormat": "Utilitzar el format d'API OpenAI antic", + "customHeaders": "Capçaleres personalitzades", + "headerName": "Nom de la capçalera", + "headerValue": "Valor de la capçalera", + "noCustomHeaders": "No hi ha capçaleres personalitzades definides. Feu clic al botó + per afegir-ne una.", "openRouterTransformsText": "Comprimir prompts i cadenes de missatges a la mida del context (Transformacions d'OpenRouter)", "model": "Model", "getOpenRouterApiKey": "Obtenir clau API d'OpenRouter", diff --git a/webview-ui/src/i18n/locales/de/common.json b/webview-ui/src/i18n/locales/de/common.json index 62056d8d53f..c5b7172efe3 100644 --- a/webview-ui/src/i18n/locales/de/common.json +++ b/webview-ui/src/i18n/locales/de/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Suchen..." + }, + "mermaid": { + "loading": "Mermaid-Diagramm wird generiert...", + "render_error": "Diagramm kann nicht gerendert werden" } } diff --git a/webview-ui/src/i18n/locales/de/prompts.json b/webview-ui/src/i18n/locales/de/prompts.json index 55e8440c516..7d0a19ec470 100644 --- a/webview-ui/src/i18n/locales/de/prompts.json +++ b/webview-ui/src/i18n/locales/de/prompts.json @@ -25,7 +25,8 @@ "browser": "Browser verwenden", "command": "Befehle ausführen", "mcp": "MCP verwenden" - } + }, + "noTools": "Keine" }, "roleDefinition": { "title": "Rollendefinition", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index c7b87091951..4cc23c4bab9 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -4,7 +4,9 @@ "done": "Fertig", "cancel": "Abbrechen", "reset": "Zurücksetzen", - "select": "Auswählen" + "select": "Auswählen", + "add": "Header hinzufügen", + "remove": "Entfernen" }, "header": { "title": "Einstellungen", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "Benutzerdefinierte Basis-URL verwenden", "useHostHeader": "Benutzerdefinierten Host-Header verwenden", "useLegacyFormat": "Altes OpenAI API-Format verwenden", + "customHeaders": "Benutzerdefinierte Headers", + "headerName": "Header-Name", + "headerValue": "Header-Wert", + "noCustomHeaders": "Keine benutzerdefinierten Headers definiert. Klicke auf die + Schaltfläche, um einen hinzuzufügen.", "requestyApiKey": "Requesty API-Schlüssel", "getRequestyApiKey": "Requesty API-Schlüssel erhalten", "openRouterTransformsText": "Prompts und Nachrichtenketten auf Kontextgröße komprimieren (OpenRouter Transformationen)", diff --git a/webview-ui/src/i18n/locales/en/common.json b/webview-ui/src/i18n/locales/en/common.json index 757867bb2cb..70a3c4a2d71 100644 --- a/webview-ui/src/i18n/locales/en/common.json +++ b/webview-ui/src/i18n/locales/en/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Search..." + }, + "mermaid": { + "loading": "Generating mermaid diagram...", + "render_error": "Unable to Render Diagram" } } diff --git a/webview-ui/src/i18n/locales/en/prompts.json b/webview-ui/src/i18n/locales/en/prompts.json index ba836a7012e..ce567a48697 100644 --- a/webview-ui/src/i18n/locales/en/prompts.json +++ b/webview-ui/src/i18n/locales/en/prompts.json @@ -25,7 +25,8 @@ "browser": "Use Browser", "command": "Run Commands", "mcp": "Use MCP" - } + }, + "noTools": "None" }, "roleDefinition": { "title": "Role Definition", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index af638819a67..c06a9774116 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -4,7 +4,9 @@ "done": "Done", "cancel": "Cancel", "reset": "Reset", - "select": "Select" + "select": "Select", + "add": "Add Header", + "remove": "Remove" }, "header": { "title": "Settings", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "Use custom base URL", "useHostHeader": "Use custom Host header", "useLegacyFormat": "Use legacy OpenAI API format", + "customHeaders": "Custom Headers", + "headerName": "Header name", + "headerValue": "Header value", + "noCustomHeaders": "No custom headers defined. Click the + button to add one.", "requestyApiKey": "Requesty API Key", "getRequestyApiKey": "Get Requesty API Key", "openRouterTransformsText": "Compress prompts and message chains to the context size (OpenRouter Transforms)", diff --git a/webview-ui/src/i18n/locales/es/common.json b/webview-ui/src/i18n/locales/es/common.json index 04123769577..6d649eb9263 100644 --- a/webview-ui/src/i18n/locales/es/common.json +++ b/webview-ui/src/i18n/locales/es/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Buscar..." + }, + "mermaid": { + "loading": "Generando diagrama mermaid...", + "render_error": "No se puede renderizar el diagrama" } } diff --git a/webview-ui/src/i18n/locales/es/prompts.json b/webview-ui/src/i18n/locales/es/prompts.json index e93835edf49..3c6b0526393 100644 --- a/webview-ui/src/i18n/locales/es/prompts.json +++ b/webview-ui/src/i18n/locales/es/prompts.json @@ -25,7 +25,8 @@ "browser": "Usar navegador", "command": "Ejecutar comandos", "mcp": "Usar MCP" - } + }, + "noTools": "Ninguna" }, "roleDefinition": { "title": "Definición de rol", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index e7a9295d09e..0dd75d95820 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -4,7 +4,9 @@ "done": "Hecho", "cancel": "Cancelar", "reset": "Restablecer", - "select": "Seleccionar" + "select": "Seleccionar", + "add": "Añadir encabezado", + "remove": "Eliminar" }, "header": { "title": "Configuración", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "Usar URL base personalizada", "useHostHeader": "Usar encabezado Host personalizado", "useLegacyFormat": "Usar formato API de OpenAI heredado", + "customHeaders": "Encabezados personalizados", + "headerName": "Nombre del encabezado", + "headerValue": "Valor del encabezado", + "noCustomHeaders": "No hay encabezados personalizados definidos. Haga clic en el botón + para añadir uno.", "requestyApiKey": "Clave API de Requesty", "getRequestyApiKey": "Obtener clave API de Requesty", "openRouterTransformsText": "Comprimir prompts y cadenas de mensajes al tamaño del contexto (Transformaciones de OpenRouter)", diff --git a/webview-ui/src/i18n/locales/fr/common.json b/webview-ui/src/i18n/locales/fr/common.json index fc7b0686df0..caeb10851f1 100644 --- a/webview-ui/src/i18n/locales/fr/common.json +++ b/webview-ui/src/i18n/locales/fr/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Rechercher..." + }, + "mermaid": { + "loading": "Génération du diagramme mermaid...", + "render_error": "Impossible de rendre le diagramme" } } diff --git a/webview-ui/src/i18n/locales/fr/prompts.json b/webview-ui/src/i18n/locales/fr/prompts.json index 1d5b871d625..b746bd83117 100644 --- a/webview-ui/src/i18n/locales/fr/prompts.json +++ b/webview-ui/src/i18n/locales/fr/prompts.json @@ -25,7 +25,8 @@ "browser": "Utiliser le navigateur", "command": "Exécuter des commandes", "mcp": "Utiliser MCP" - } + }, + "noTools": "Aucun" }, "roleDefinition": { "title": "Définition du rôle", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index daafebd10be..ec921ca41e1 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -4,7 +4,9 @@ "done": "Terminé", "cancel": "Annuler", "reset": "Réinitialiser", - "select": "Sélectionner" + "select": "Sélectionner", + "add": "Ajouter un en-tête", + "remove": "Supprimer" }, "header": { "title": "Paramètres", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "Utiliser une URL de base personnalisée", "useHostHeader": "Utiliser un en-tête Host personnalisé", "useLegacyFormat": "Utiliser le format API OpenAI hérité", + "customHeaders": "En-têtes personnalisés", + "headerName": "Nom de l'en-tête", + "headerValue": "Valeur de l'en-tête", + "noCustomHeaders": "Aucun en-tête personnalisé défini. Cliquez sur le bouton + pour en ajouter un.", "requestyApiKey": "Clé API Requesty", "getRequestyApiKey": "Obtenir la clé API Requesty", "openRouterTransformsText": "Compresser les prompts et chaînes de messages à la taille du contexte (Transformations OpenRouter)", diff --git a/webview-ui/src/i18n/locales/hi/common.json b/webview-ui/src/i18n/locales/hi/common.json index 5cf4876d327..de95d083b52 100644 --- a/webview-ui/src/i18n/locales/hi/common.json +++ b/webview-ui/src/i18n/locales/hi/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "खोजें..." + }, + "mermaid": { + "loading": "मरमेड डायग्राम जनरेट हो रहा है...", + "render_error": "डायग्राम रेंडर नहीं किया जा सकता" } } diff --git a/webview-ui/src/i18n/locales/hi/prompts.json b/webview-ui/src/i18n/locales/hi/prompts.json index e30f04c664d..d5291a577c7 100644 --- a/webview-ui/src/i18n/locales/hi/prompts.json +++ b/webview-ui/src/i18n/locales/hi/prompts.json @@ -25,7 +25,8 @@ "browser": "ब्राउज़र का उपयोग करें", "command": "कमांड्स चलाएँ", "mcp": "MCP का उपयोग करें" - } + }, + "noTools": "कोई नहीं" }, "roleDefinition": { "title": "भूमिका परिभाषा", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index bcb0af59421..b98879eb37a 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -4,7 +4,9 @@ "done": "पूर्ण", "cancel": "रद्द करें", "reset": "रीसेट करें", - "select": "चुनें" + "select": "चुनें", + "add": "हेडर जोड़ें", + "remove": "हटाएं" }, "header": { "title": "सेटिंग्स", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "कस्टम बेस URL का उपयोग करें", "useHostHeader": "कस्टम होस्ट हेडर का उपयोग करें", "useLegacyFormat": "पुराने OpenAI API प्रारूप का उपयोग करें", + "customHeaders": "कस्टम हेडर्स", + "headerName": "हेडर नाम", + "headerValue": "हेडर मूल्य", + "noCustomHeaders": "कोई कस्टम हेडर परिभाषित नहीं है। एक जोड़ने के लिए + बटन पर क्लिक करें।", "requestyApiKey": "Requesty API कुंजी", "getRequestyApiKey": "Requesty API कुंजी प्राप्त करें", "openRouterTransformsText": "संदर्भ आकार के लिए प्रॉम्प्ट और संदेश श्रृंखलाओं को संपीड़ित करें (OpenRouter ट्रांसफॉर्म)", diff --git a/webview-ui/src/i18n/locales/it/common.json b/webview-ui/src/i18n/locales/it/common.json index c6a797f7c6b..c07023796af 100644 --- a/webview-ui/src/i18n/locales/it/common.json +++ b/webview-ui/src/i18n/locales/it/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Cerca..." + }, + "mermaid": { + "loading": "Generazione del diagramma mermaid...", + "render_error": "Impossibile renderizzare il diagramma" } } diff --git a/webview-ui/src/i18n/locales/it/prompts.json b/webview-ui/src/i18n/locales/it/prompts.json index cfb35f150c4..81bb7534def 100644 --- a/webview-ui/src/i18n/locales/it/prompts.json +++ b/webview-ui/src/i18n/locales/it/prompts.json @@ -25,7 +25,8 @@ "browser": "Usa browser", "command": "Esegui comandi", "mcp": "Usa MCP" - } + }, + "noTools": "Nessuno" }, "roleDefinition": { "title": "Definizione del ruolo", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index b537357d7ec..ca02aa92132 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -4,7 +4,9 @@ "done": "Fatto", "cancel": "Annulla", "reset": "Ripristina", - "select": "Seleziona" + "select": "Seleziona", + "add": "Aggiungi intestazione", + "remove": "Rimuovi" }, "header": { "title": "Impostazioni", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "Usa URL base personalizzato", "useHostHeader": "Usa intestazione Host personalizzata", "useLegacyFormat": "Usa formato API OpenAI legacy", + "customHeaders": "Intestazioni personalizzate", + "headerName": "Nome intestazione", + "headerValue": "Valore intestazione", + "noCustomHeaders": "Nessuna intestazione personalizzata definita. Fai clic sul pulsante + per aggiungerne una.", "requestyApiKey": "Chiave API Requesty", "getRequestyApiKey": "Ottieni chiave API Requesty", "openRouterTransformsText": "Comprimi prompt e catene di messaggi alla dimensione del contesto (Trasformazioni OpenRouter)", diff --git a/webview-ui/src/i18n/locales/ja/common.json b/webview-ui/src/i18n/locales/ja/common.json index 063ca02c318..c890f8baede 100644 --- a/webview-ui/src/i18n/locales/ja/common.json +++ b/webview-ui/src/i18n/locales/ja/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "検索..." + }, + "mermaid": { + "loading": "Mermaidダイアグラムを生成中...", + "render_error": "ダイアグラムをレンダリングできません" } } diff --git a/webview-ui/src/i18n/locales/ja/prompts.json b/webview-ui/src/i18n/locales/ja/prompts.json index 8f18095a121..16f30a2ebc5 100644 --- a/webview-ui/src/i18n/locales/ja/prompts.json +++ b/webview-ui/src/i18n/locales/ja/prompts.json @@ -25,7 +25,8 @@ "browser": "ブラウザを使用", "command": "コマンドを実行", "mcp": "MCP を使用" - } + }, + "noTools": "なし" }, "roleDefinition": { "title": "役割の定義", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index fae31b2203c..0d49e9d1e95 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -4,7 +4,9 @@ "done": "完了", "cancel": "キャンセル", "reset": "リセット", - "select": "選択" + "select": "選択", + "add": "ヘッダーを追加", + "remove": "削除" }, "header": { "title": "設定", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "カスタムベースURLを使用", "useHostHeader": "カスタムHostヘッダーを使用", "useLegacyFormat": "レガシーOpenAI API形式を使用", + "customHeaders": "カスタムヘッダー", + "headerName": "ヘッダー名", + "headerValue": "ヘッダー値", + "noCustomHeaders": "カスタムヘッダーが定義されていません。+ ボタンをクリックして追加してください。", "requestyApiKey": "Requesty APIキー", "getRequestyApiKey": "Requesty APIキーを取得", "openRouterTransformsText": "プロンプトとメッセージチェーンをコンテキストサイズに圧縮 (OpenRouter Transforms)", diff --git a/webview-ui/src/i18n/locales/ko/common.json b/webview-ui/src/i18n/locales/ko/common.json index e4335f16aeb..6996f6c3879 100644 --- a/webview-ui/src/i18n/locales/ko/common.json +++ b/webview-ui/src/i18n/locales/ko/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "검색..." + }, + "mermaid": { + "loading": "머메이드 다이어그램 생성 중...", + "render_error": "다이어그램을 렌더링할 수 없음" } } diff --git a/webview-ui/src/i18n/locales/ko/prompts.json b/webview-ui/src/i18n/locales/ko/prompts.json index 7ce93e8be02..5942105f055 100644 --- a/webview-ui/src/i18n/locales/ko/prompts.json +++ b/webview-ui/src/i18n/locales/ko/prompts.json @@ -25,7 +25,8 @@ "browser": "브라우저 사용", "command": "명령 실행", "mcp": "MCP 사용" - } + }, + "noTools": "없음" }, "roleDefinition": { "title": "역할 정의", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 2b9b8bf27d7..d0b07988025 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -4,7 +4,9 @@ "done": "완료", "cancel": "취소", "reset": "초기화", - "select": "선택" + "select": "선택", + "add": "헤더 추가", + "remove": "삭제" }, "header": { "title": "설정", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "사용자 정의 기본 URL 사용", "useHostHeader": "사용자 정의 Host 헤더 사용", "useLegacyFormat": "레거시 OpenAI API 형식 사용", + "customHeaders": "사용자 정의 헤더", + "headerName": "헤더 이름", + "headerValue": "헤더 값", + "noCustomHeaders": "정의된 사용자 정의 헤더가 없습니다. + 버튼을 클릭하여 추가하세요.", "requestyApiKey": "Requesty API 키", "getRequestyApiKey": "Requesty API 키 받기", "openRouterTransformsText": "프롬프트와 메시지 체인을 컨텍스트 크기로 압축 (OpenRouter Transforms)", diff --git a/webview-ui/src/i18n/locales/pl/common.json b/webview-ui/src/i18n/locales/pl/common.json index 6163d7f10fd..cf2da432f8f 100644 --- a/webview-ui/src/i18n/locales/pl/common.json +++ b/webview-ui/src/i18n/locales/pl/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Szukaj..." + }, + "mermaid": { + "loading": "Generowanie diagramu mermaid...", + "render_error": "Nie można renderować diagramu" } } diff --git a/webview-ui/src/i18n/locales/pl/prompts.json b/webview-ui/src/i18n/locales/pl/prompts.json index 459b2069194..ef8a5ffe083 100644 --- a/webview-ui/src/i18n/locales/pl/prompts.json +++ b/webview-ui/src/i18n/locales/pl/prompts.json @@ -25,7 +25,8 @@ "browser": "Używaj przeglądarki", "command": "Uruchamiaj polecenia", "mcp": "Używaj MCP" - } + }, + "noTools": "Brak" }, "roleDefinition": { "title": "Definicja roli", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index 100267d6e45..60fe7c28153 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -4,7 +4,9 @@ "done": "Gotowe", "cancel": "Anuluj", "reset": "Resetuj", - "select": "Wybierz" + "select": "Wybierz", + "add": "Dodaj nagłówek", + "remove": "Usuń" }, "header": { "title": "Ustawienia", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "Użyj niestandardowego URL bazowego", "useHostHeader": "Użyj niestandardowego nagłówka Host", "useLegacyFormat": "Użyj starszego formatu API OpenAI", + "customHeaders": "Niestandardowe nagłówki", + "headerName": "Nazwa nagłówka", + "headerValue": "Wartość nagłówka", + "noCustomHeaders": "Brak zdefiniowanych niestandardowych nagłówków. Kliknij przycisk +, aby dodać.", "requestyApiKey": "Klucz API Requesty", "getRequestyApiKey": "Uzyskaj klucz API Requesty", "openRouterTransformsText": "Kompresuj podpowiedzi i łańcuchy wiadomości do rozmiaru kontekstu (Transformacje OpenRouter)", diff --git a/webview-ui/src/i18n/locales/pt-BR/common.json b/webview-ui/src/i18n/locales/pt-BR/common.json index 0a36a8483bc..dd89eee333f 100644 --- a/webview-ui/src/i18n/locales/pt-BR/common.json +++ b/webview-ui/src/i18n/locales/pt-BR/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Pesquisar..." + }, + "mermaid": { + "loading": "Gerando diagrama mermaid...", + "render_error": "Não foi possível renderizar o diagrama" } } diff --git a/webview-ui/src/i18n/locales/pt-BR/prompts.json b/webview-ui/src/i18n/locales/pt-BR/prompts.json index 50c3852b15f..f255b91a27d 100644 --- a/webview-ui/src/i18n/locales/pt-BR/prompts.json +++ b/webview-ui/src/i18n/locales/pt-BR/prompts.json @@ -25,7 +25,8 @@ "browser": "Usar navegador", "command": "Executar comandos", "mcp": "Usar MCP" - } + }, + "noTools": "Nenhuma" }, "roleDefinition": { "title": "Definição de função", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index 8f259388c4a..5f229f98780 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -4,7 +4,9 @@ "done": "Concluído", "cancel": "Cancelar", "reset": "Redefinir", - "select": "Selecionar" + "select": "Selecionar", + "add": "Adicionar cabeçalho", + "remove": "Remover" }, "header": { "title": "Configurações", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "Usar URL base personalizado", "useHostHeader": "Usar cabeçalho Host personalizado", "useLegacyFormat": "Usar formato de API OpenAI legado", + "customHeaders": "Cabeçalhos personalizados", + "headerName": "Nome do cabeçalho", + "headerValue": "Valor do cabeçalho", + "noCustomHeaders": "Nenhum cabeçalho personalizado definido. Clique no botão + para adicionar um.", "requestyApiKey": "Chave de API Requesty", "getRequestyApiKey": "Obter chave de API Requesty", "openRouterTransformsText": "Comprimir prompts e cadeias de mensagens para o tamanho do contexto (Transformações OpenRouter)", diff --git a/webview-ui/src/i18n/locales/ru/common.json b/webview-ui/src/i18n/locales/ru/common.json index 25bc20927ff..83277624671 100644 --- a/webview-ui/src/i18n/locales/ru/common.json +++ b/webview-ui/src/i18n/locales/ru/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Поиск..." + }, + "mermaid": { + "loading": "Создание диаграммы mermaid...", + "render_error": "Не удалось отобразить диаграмму" } } diff --git a/webview-ui/src/i18n/locales/ru/prompts.json b/webview-ui/src/i18n/locales/ru/prompts.json index 28778498e0d..0ff448bedbd 100644 --- a/webview-ui/src/i18n/locales/ru/prompts.json +++ b/webview-ui/src/i18n/locales/ru/prompts.json @@ -25,7 +25,8 @@ "browser": "Использовать браузер", "command": "Выполнять команды", "mcp": "Использовать MCP" - } + }, + "noTools": "Отсутствуют" }, "roleDefinition": { "title": "Определение роли", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index ffefb37f2b3..94783f4995f 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -4,7 +4,9 @@ "done": "Готово", "cancel": "Отмена", "reset": "Сбросить", - "select": "Выбрать" + "select": "Выбрать", + "add": "Добавить заголовок", + "remove": "Удалить" }, "header": { "title": "Настройки", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "Использовать пользовательский базовый URL", "useHostHeader": "Использовать пользовательский Host-заголовок", "useLegacyFormat": "Использовать устаревший формат OpenAI API", + "customHeaders": "Пользовательские заголовки", + "headerName": "Имя заголовка", + "headerValue": "Значение заголовка", + "noCustomHeaders": "Пользовательские заголовки не определены. Нажмите кнопку +, чтобы добавить.", "requestyApiKey": "Requesty API-ключ", "getRequestyApiKey": "Получить Requesty API-ключ", "openRouterTransformsText": "Сжимать подсказки и цепочки сообщений до размера контекста (OpenRouter Transforms)", diff --git a/webview-ui/src/i18n/locales/tr/common.json b/webview-ui/src/i18n/locales/tr/common.json index a41fcaf6db7..a66d24e02fb 100644 --- a/webview-ui/src/i18n/locales/tr/common.json +++ b/webview-ui/src/i18n/locales/tr/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Ara..." + }, + "mermaid": { + "loading": "Mermaid diyagramı oluşturuluyor...", + "render_error": "Diyagram render edilemiyor" } } diff --git a/webview-ui/src/i18n/locales/tr/prompts.json b/webview-ui/src/i18n/locales/tr/prompts.json index 40cd10aa895..8d7c7b9305a 100644 --- a/webview-ui/src/i18n/locales/tr/prompts.json +++ b/webview-ui/src/i18n/locales/tr/prompts.json @@ -25,7 +25,8 @@ "browser": "Tarayıcı Kullan", "command": "Komutları Çalıştır", "mcp": "MCP Kullan" - } + }, + "noTools": "Yok" }, "roleDefinition": { "title": "Rol Tanımı", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 336d17c87ae..1a8bb25750e 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -4,7 +4,9 @@ "done": "Tamamlandı", "cancel": "İptal", "reset": "Sıfırla", - "select": "Seç" + "select": "Seç", + "add": "Başlık Ekle", + "remove": "Kaldır" }, "header": { "title": "Ayarlar", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "Özel temel URL kullan", "useHostHeader": "Özel Host başlığı kullan", "useLegacyFormat": "Eski OpenAI API formatını kullan", + "customHeaders": "Özel Başlıklar", + "headerName": "Başlık adı", + "headerValue": "Başlık değeri", + "noCustomHeaders": "Tanımlanmış özel başlık yok. Eklemek için + düğmesine tıklayın.", "requestyApiKey": "Requesty API Anahtarı", "getRequestyApiKey": "Requesty API Anahtarı Al", "openRouterTransformsText": "İstem ve mesaj zincirlerini bağlam boyutuna sıkıştır (OpenRouter Dönüşümleri)", diff --git a/webview-ui/src/i18n/locales/vi/common.json b/webview-ui/src/i18n/locales/vi/common.json index 3ab6697795a..19f8b8b8013 100644 --- a/webview-ui/src/i18n/locales/vi/common.json +++ b/webview-ui/src/i18n/locales/vi/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "Tìm kiếm..." + }, + "mermaid": { + "loading": "Đang tạo biểu đồ mermaid...", + "render_error": "Không thể hiển thị biểu đồ" } } diff --git a/webview-ui/src/i18n/locales/vi/prompts.json b/webview-ui/src/i18n/locales/vi/prompts.json index 3951da818c6..4b62d3718e6 100644 --- a/webview-ui/src/i18n/locales/vi/prompts.json +++ b/webview-ui/src/i18n/locales/vi/prompts.json @@ -25,7 +25,8 @@ "browser": "Sử dụng trình duyệt", "command": "Chạy lệnh", "mcp": "Sử dụng MCP" - } + }, + "noTools": "Không có" }, "roleDefinition": { "title": "Định nghĩa vai trò", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 9cbdf89befc..9d8764951ef 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -4,7 +4,9 @@ "done": "Hoàn thành", "cancel": "Hủy", "reset": "Đặt lại", - "select": "Chọn" + "select": "Chọn", + "add": "Thêm tiêu đề", + "remove": "Xóa" }, "header": { "title": "Cài đặt", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "Sử dụng URL cơ sở tùy chỉnh", "useHostHeader": "Sử dụng tiêu đề Host tùy chỉnh", "useLegacyFormat": "Sử dụng định dạng API OpenAI cũ", + "customHeaders": "Tiêu đề tùy chỉnh", + "headerName": "Tên tiêu đề", + "headerValue": "Giá trị tiêu đề", + "noCustomHeaders": "Chưa có tiêu đề tùy chỉnh nào được định nghĩa. Nhấp vào nút + để thêm.", "requestyApiKey": "Khóa API Requesty", "getRequestyApiKey": "Lấy khóa API Requesty", "anthropicApiKey": "Khóa API Anthropic", diff --git a/webview-ui/src/i18n/locales/zh-CN/common.json b/webview-ui/src/i18n/locales/zh-CN/common.json index a437837df55..adaa86ec701 100644 --- a/webview-ui/src/i18n/locales/zh-CN/common.json +++ b/webview-ui/src/i18n/locales/zh-CN/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "搜索..." + }, + "mermaid": { + "loading": "生成 Mermaid 图表中...", + "render_error": "无法渲染图表" } } diff --git a/webview-ui/src/i18n/locales/zh-CN/prompts.json b/webview-ui/src/i18n/locales/zh-CN/prompts.json index abfd892039f..2980bd66997 100644 --- a/webview-ui/src/i18n/locales/zh-CN/prompts.json +++ b/webview-ui/src/i18n/locales/zh-CN/prompts.json @@ -25,7 +25,8 @@ "browser": "浏览器", "command": "运行命令", "mcp": "MCP服务" - } + }, + "noTools": "无" }, "roleDefinition": { "title": "角色定义", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 5fc83e2922c..5158586ab2d 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -4,7 +4,9 @@ "done": "完成", "cancel": "取消", "reset": "恢复默认设置", - "select": "选择" + "select": "选择", + "add": "添加标头", + "remove": "移除" }, "header": { "title": "设置", @@ -109,6 +111,10 @@ "useCustomBaseUrl": "使用自定义基础 URL", "useHostHeader": "使用自定义 Host 标头", "useLegacyFormat": "使用传统 OpenAI API 格式", + "customHeaders": "自定义标头", + "headerName": "标头名称", + "headerValue": "标头值", + "noCustomHeaders": "暂无自定义标头。点击 + 按钮添加。", "glamaApiKey": "Glama API 密钥", "getGlamaApiKey": "获取 Glama API 密钥", "requestyApiKey": "Requesty API 密钥", diff --git a/webview-ui/src/i18n/locales/zh-TW/common.json b/webview-ui/src/i18n/locales/zh-TW/common.json index e8cc39e07e6..12c42220dde 100644 --- a/webview-ui/src/i18n/locales/zh-TW/common.json +++ b/webview-ui/src/i18n/locales/zh-TW/common.json @@ -6,5 +6,9 @@ }, "ui": { "search_placeholder": "搜尋..." + }, + "mermaid": { + "loading": "產生 Mermaid 圖表中...", + "render_error": "無法渲染圖表" } } diff --git a/webview-ui/src/i18n/locales/zh-TW/prompts.json b/webview-ui/src/i18n/locales/zh-TW/prompts.json index 874c9361dc0..9b99707cf67 100644 --- a/webview-ui/src/i18n/locales/zh-TW/prompts.json +++ b/webview-ui/src/i18n/locales/zh-TW/prompts.json @@ -25,7 +25,8 @@ "browser": "使用瀏覽器", "command": "執行命令", "mcp": "使用 MCP" - } + }, + "noTools": "無" }, "roleDefinition": { "title": "角色定義", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index a40be4d17fd..1d329752fe1 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -4,7 +4,9 @@ "done": "完成", "cancel": "取消", "reset": "重設", - "select": "選擇" + "select": "選擇", + "add": "新增標頭", + "remove": "移除" }, "header": { "title": "設定", @@ -111,6 +113,10 @@ "useCustomBaseUrl": "使用自訂基礎 URL", "useHostHeader": "使用自訂 Host 標頭", "useLegacyFormat": "使用舊版 OpenAI API 格式", + "customHeaders": "自訂標頭", + "headerName": "標頭名稱", + "headerValue": "標頭值", + "noCustomHeaders": "尚未定義自訂標頭。點擊 + 按鈕以新增。", "requestyApiKey": "Requesty API 金鑰", "getRequestyApiKey": "取得 Requesty API 金鑰", "openRouterTransformsText": "將提示和訊息鏈壓縮到上下文大小 (OpenRouter 轉換)",